summaryrefslogtreecommitdiff
path: root/bcprov/src/test/java/org/bouncycastle/math/ec/custom/sec/test/SecP256R1FieldTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'bcprov/src/test/java/org/bouncycastle/math/ec/custom/sec/test/SecP256R1FieldTest.java')
-rw-r--r--bcprov/src/test/java/org/bouncycastle/math/ec/custom/sec/test/SecP256R1FieldTest.java175
1 files changed, 175 insertions, 0 deletions
diff --git a/bcprov/src/test/java/org/bouncycastle/math/ec/custom/sec/test/SecP256R1FieldTest.java b/bcprov/src/test/java/org/bouncycastle/math/ec/custom/sec/test/SecP256R1FieldTest.java
new file mode 100644
index 00000000..b59f1924
--- /dev/null
+++ b/bcprov/src/test/java/org/bouncycastle/math/ec/custom/sec/test/SecP256R1FieldTest.java
@@ -0,0 +1,175 @@
+package org.bouncycastle.math.ec.custom.sec.test;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
+import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.crypto.ec.CustomNamedCurves;
+import org.bouncycastle.math.ec.ECFieldElement;
+import org.bouncycastle.math.raw.Nat256;
+
+import junit.framework.TestCase;
+
+public class SecP256R1FieldTest extends TestCase
+{
+ private static final SecureRandom RANDOM = new SecureRandom();
+
+ private static final X9ECParameters DP = CustomNamedCurves
+ .getByOID(SECObjectIdentifiers.secp256r1);
+ private static final BigInteger Q = DP.getCurve().getField().getCharacteristic();
+
+ public void testMultiply1()
+ {
+ int COUNT = 1000;
+
+ for (int i = 0; i < COUNT; ++i)
+ {
+ ECFieldElement x = generateMultiplyInput_Random();
+ ECFieldElement y = generateMultiplyInput_Random();
+
+ BigInteger X = x.toBigInteger(), Y = y.toBigInteger();
+ BigInteger R = X.multiply(Y).mod(Q);
+
+ ECFieldElement z = x.multiply(y);
+ BigInteger Z = z.toBigInteger();
+
+ assertEquals(R, Z);
+ }
+ }
+
+ public void testMultiply2()
+ {
+ int COUNT = 100;
+ ECFieldElement[] inputs = new ECFieldElement[COUNT];
+ BigInteger[] INPUTS = new BigInteger[COUNT];
+
+ for (int i = 0; i < inputs.length; ++i)
+ {
+ inputs[i] = generateMultiplyInput_Random();
+ INPUTS[i] = inputs[i].toBigInteger();
+ }
+
+ for (int j = 0; j < inputs.length; ++j)
+ {
+ for (int k = 0; k < inputs.length; ++k)
+ {
+ BigInteger R = INPUTS[j].multiply(INPUTS[k]).mod(Q);
+
+ ECFieldElement z = inputs[j].multiply(inputs[k]);
+ BigInteger Z = z.toBigInteger();
+
+ assertEquals(R, Z);
+ }
+ }
+ }
+
+ public void testSquare()
+ {
+ int COUNT = 1000;
+
+ for (int i = 0; i < COUNT; ++i)
+ {
+ ECFieldElement x = generateMultiplyInput_Random();
+
+ BigInteger X = x.toBigInteger();
+ BigInteger R = X.multiply(X).mod(Q);
+
+ ECFieldElement z = x.square();
+ BigInteger Z = z.toBigInteger();
+
+ assertEquals(R, Z);
+ }
+ }
+
+ /**
+ * Test multiplication with specifically selected values that triggered a bug in the modular
+ * reduction in OpenSSL (last affected version 0.9.8g).
+ *
+ * See "Practical realisation and elimination of an ECC-related software bug attack", B. B.
+ * Brumley, M. Barbarosa, D. Page, F. Vercauteren.
+ */
+ public void testMultiply_OpenSSLBug()
+ {
+ int COUNT = 100;
+
+ for (int i = 0; i < COUNT; ++i)
+ {
+ ECFieldElement x = generateMultiplyInputA_OpenSSLBug();
+ ECFieldElement y = generateMultiplyInputB_OpenSSLBug();
+
+ BigInteger X = x.toBigInteger(), Y = y.toBigInteger();
+ BigInteger R = X.multiply(Y).mod(Q);
+
+ ECFieldElement z = x.multiply(y);
+ BigInteger Z = z.toBigInteger();
+
+ assertEquals(R, Z);
+ }
+ }
+
+ /**
+ * Test squaring with specifically selected values that triggered a bug in the modular reduction
+ * in OpenSSL (last affected version 0.9.8g).
+ *
+ * See "Practical realisation and elimination of an ECC-related software bug attack", B. B.
+ * Brumley, M. Barbarosa, D. Page, F. Vercauteren.
+ */
+ public void testSquare_OpenSSLBug()
+ {
+ int COUNT = 100;
+
+ for (int i = 0; i < COUNT; ++i)
+ {
+ ECFieldElement x = generateSquareInput_OpenSSLBug();
+
+ BigInteger X = x.toBigInteger();
+ BigInteger R = X.multiply(X).mod(Q);
+
+ ECFieldElement z = x.square();
+ BigInteger Z = z.toBigInteger();
+
+ assertEquals(R, Z);
+ }
+ }
+
+ private ECFieldElement fe(BigInteger x)
+ {
+ return DP.getCurve().fromBigInteger(x);
+ }
+
+ private ECFieldElement generateMultiplyInput_Random()
+ {
+ return fe(new BigInteger(DP.getCurve().getFieldSize() + 32, RANDOM).mod(Q));
+ }
+
+ private ECFieldElement generateMultiplyInputA_OpenSSLBug()
+ {
+ int[] x = Nat256.create();
+ x[0] = RANDOM.nextInt() >>> 1;
+ x[4] = 3;
+ x[7] = -1;
+
+ return fe(Nat256.toBigInteger(x));
+ }
+
+ private ECFieldElement generateMultiplyInputB_OpenSSLBug()
+ {
+ int[] x = Nat256.create();
+ x[0] = RANDOM.nextInt() >>> 1;
+ x[3] = 1;
+ x[7] = -1;
+
+ return fe(Nat256.toBigInteger(x));
+ }
+
+ private ECFieldElement generateSquareInput_OpenSSLBug()
+ {
+ int[] x = Nat256.create();
+ x[0] = RANDOM.nextInt() >>> 1;
+ x[4] = 2;
+ x[7] = -1;
+
+ return fe(Nat256.toBigInteger(x));
+ }
+}