diff options
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.java | 175 |
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)); + } +} |