use of java.math.BigInteger in project wycheproof by google.
the class EcUtil method modSqrt.
/**
* Computes a modular square root. Timing and exceptions can leak information about the inputs.
* Therefore this method must only be used in tests.
*
* @param x the square
* @param p the prime modulus
* @returns a value s such that s^2 mod p == x mod p
* @throws GeneralSecurityException if the square root could not be found.
*/
public static BigInteger modSqrt(BigInteger x, BigInteger p) throws GeneralSecurityException {
if (p.signum() != 1) {
throw new GeneralSecurityException("p must be positive");
}
x = x.mod(p);
BigInteger squareRoot = null;
// This check is necessary for Cipolla's algorithm.
if (x.equals(BigInteger.ZERO)) {
return x;
}
if (p.testBit(0) && p.testBit(1)) {
// Case p % 4 == 3
// q = (p + 1) / 4
BigInteger q = p.add(BigInteger.ONE).shiftRight(2);
squareRoot = x.modPow(q, p);
} else if (p.testBit(0) && !p.testBit(1)) {
// Case p % 4 == 1
// For this case we use Cipolla's algorithm.
// This alogorithm is preferrable to Tonelli-Shanks for primes p where p-1 is divisible by
// a large power of 2, which is a frequent choice since it simplifies modular reduction.
BigInteger a = BigInteger.ONE;
BigInteger d = null;
while (true) {
d = a.multiply(a).subtract(x).mod(p);
// Computes the Legendre symbol. Using the Jacobi symbol would be a faster. Using Legendre
// has the advantage, that it detects a non prime p with high probability.
// On the other hand if p = q^2 then the Jacobi (d/p)==1 for almost all d's and thus
// using the Jacobi symbol here can result in an endless loop with invalid inputs.
int t = legendre(d, p);
if (t == -1) {
break;
} else {
a = a.add(BigInteger.ONE);
}
}
// Since d = a^2 - n is a non-residue modulo p, we have
// a - sqrt(d) == (a+sqrt(d))^p (mod p),
// and hence
// n == (a + sqrt(d))(a - sqrt(d) == (a+sqrt(d))^(p+1) (mod p).
// Thus if n is square then (a+sqrt(d))^((p+1)/2) (mod p) is a square root of n.
BigInteger q = p.add(BigInteger.ONE).shiftRight(1);
BigInteger u = a;
BigInteger v = BigInteger.ONE;
for (int bit = q.bitLength() - 2; bit >= 0; bit--) {
// Compute (u + v sqrt(d))^2
BigInteger tmp = u.multiply(v);
u = u.multiply(u).add(v.multiply(v).mod(p).multiply(d)).mod(p);
v = tmp.add(tmp).mod(p);
if (q.testBit(bit)) {
tmp = u.multiply(a).add(v.multiply(d)).mod(p);
v = a.multiply(v).add(u).mod(p);
u = tmp;
}
}
squareRoot = u;
}
// undefined. Hence, it is important to verify that squareRoot is indeed a square root.
if (squareRoot != null && squareRoot.multiply(squareRoot).mod(p).compareTo(x) != 0) {
throw new GeneralSecurityException("Could not find square root");
}
return squareRoot;
}
use of java.math.BigInteger in project wycheproof by google.
the class EcUtil method checkPointOnCurve.
/**
* Checks that a point is on a given elliptic curve. This method implements the partial public key
* validation routine from Section 5.6.2.6 of NIST SP 800-56A
* http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf A partial
* public key validation is sufficient for curves with cofactor 1. See Section B.3 of
* http://www.nsa.gov/ia/_files/SuiteB_Implementer_G-113808.pdf The point validations above are
* taken from recommendations for ECDH, because parameter checks in ECDH are much more important
* than for the case of ECDSA. Performing this test for ECDSA keys is mainly a sanity check.
*
* @param point the point that needs verification
* @param ec the elliptic curve. This must be a curve over a prime order field.
* @throws GeneralSecurityException if the field is binary or if the point is not on the curve.
*/
public static void checkPointOnCurve(ECPoint point, EllipticCurve ec) throws GeneralSecurityException {
BigInteger p = getModulus(ec);
BigInteger x = point.getAffineX();
BigInteger y = point.getAffineY();
if (x == null || y == null) {
throw new GeneralSecurityException("point is at infinity");
}
// Check 0 <= x < p and 0 <= y < p.
if (x.signum() == -1 || x.compareTo(p) != -1) {
throw new GeneralSecurityException("x is out of range");
}
if (y.signum() == -1 || y.compareTo(p) != -1) {
throw new GeneralSecurityException("y is out of range");
}
// Check y^2 == x^3 + a x + b (mod p)
BigInteger lhs = y.multiply(y).mod(p);
BigInteger rhs = x.multiply(x).add(ec.getA()).multiply(x).add(ec.getB()).mod(p);
if (!lhs.equals(rhs)) {
throw new GeneralSecurityException("Point is not on curve");
}
}
use of java.math.BigInteger in project wycheproof by google.
the class RandomUtil method getSeedForPrime.
/** Attempts to find a seed such that it generates the prime p. Returns -1 if no seed is found. */
static long getSeedForPrime(BigInteger p) {
int confidence = 64;
Random rand = new Random();
int size = p.bitLength();
// the seed used for the prime generation.
for (BigInteger x : new BigInteger[] { p, p.clearBit(size - 1) }) {
long seed = getSeedFor(x);
if (seed != -1) {
rand.setSeed(seed);
BigInteger q = new BigInteger(size, confidence, rand);
if (q.equals(p)) {
return seed;
}
}
}
return -1;
}
use of java.math.BigInteger in project wycheproof by google.
the class EcUtil method getWeakPublicKey.
/**
* Returns a weak public key of order 3 such that the public key point is on the curve specified
* in ecParams. This method is used to check ECC implementations for missing step in the
* verification of the public key. E.g. implementations of ECDH must verify that the public key
* contains a point on the curve as well as public and secret key are using the same curve.
*
* @param ecParams the parameters of the key to attack. This must be a curve in Weierstrass form
* over a prime order field.
* @return a weak EC group with a genrator of order 3.
*/
public static ECPublicKeySpec getWeakPublicKey(ECParameterSpec ecParams) throws GeneralSecurityException {
EllipticCurve curve = ecParams.getCurve();
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
keyGen.initialize(ecParams);
BigInteger p = getModulus(curve);
BigInteger three = new BigInteger("3");
while (true) {
// Generate a point on the original curve
KeyPair keyPair = keyGen.generateKeyPair();
ECPublicKey pub = (ECPublicKey) keyPair.getPublic();
ECPoint w = pub.getW();
BigInteger x = w.getAffineX();
BigInteger y = w.getAffineY();
// Find the curve parameters a,b such that 3*w = infinity.
// This is the case if the following equations are satisfied:
// 3x == l^2 (mod p)
// l == (3x^2 + a) / 2*y (mod p)
// y^2 == x^3 + ax + b (mod p)
BigInteger l;
try {
l = modSqrt(x.multiply(three), p);
} catch (GeneralSecurityException ex) {
continue;
}
BigInteger xSqr = x.multiply(x).mod(p);
BigInteger a = l.multiply(y.add(y)).subtract(xSqr.multiply(three)).mod(p);
BigInteger b = y.multiply(y).subtract(x.multiply(xSqr.add(a))).mod(p);
EllipticCurve newCurve = new EllipticCurve(curve.getField(), a, b);
// Just a sanity check.
checkPointOnCurve(w, newCurve);
// Cofactor and order are of course wrong.
ECParameterSpec spec = new ECParameterSpec(newCurve, w, p, 1);
return new ECPublicKeySpec(w, spec);
}
}
use of java.math.BigInteger in project wycheproof by google.
the class EcUtil method getPoint.
/**
* Decompress a point
*
* @param x The x-coordinate of the point
* @param bit0 true if the least significant bit of y is set.
* @param ecParams contains the curve of the point. This must be over a prime order field.
*/
public static ECPoint getPoint(BigInteger x, boolean bit0, ECParameterSpec ecParams) throws GeneralSecurityException {
EllipticCurve ec = ecParams.getCurve();
ECField field = ec.getField();
if (!(field instanceof ECFieldFp)) {
throw new GeneralSecurityException("Only curves over prime order fields are supported");
}
BigInteger p = ((java.security.spec.ECFieldFp) field).getP();
if (x.compareTo(BigInteger.ZERO) == -1 || x.compareTo(p) != -1) {
throw new GeneralSecurityException("x is out of range");
}
// Compute rhs == x^3 + a x + b (mod p)
BigInteger rhs = x.multiply(x).add(ec.getA()).multiply(x).add(ec.getB()).mod(p);
BigInteger y = modSqrt(rhs, p);
if (bit0 != y.testBit(0)) {
y = p.subtract(y).mod(p);
}
return new ECPoint(x, y);
}
Aggregations