All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.crypto.agreement.ecjpake.ECJPAKECurve Maven / Gradle / Ivy

Go to download

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for JDK 1.4.

The newest version!
package org.bouncycastle.crypto.agreement.ecjpake;

import java.math.BigInteger;

import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;

/**
 * A pre-computed elliptic curve over a prime field, in short-Weierstrass form for use during an EC J-PAKE exchange.
 * 

* In general, J-PAKE can use any elliptic curve or prime order group * that is suitable for public key cryptography. *

* See {@link ECJPAKECurves} for convenient standard curves. *

* NIST publishes * many curves with different forms and levels of security. */ public class ECJPAKECurve { private final ECCurve.Fp curve; private final ECPoint g; /** * Constructs a new {@link ECJPAKECurve}. *

* In general, you should use one of the pre-approved curves from * {@link ECJPAKECurves}, rather than manually constructing one. *

* The following basic checks are performed: * * q must be prime * n must be prime * The curve must not be singular i.e. the discriminant is equal to 0 mod q * G must lie on the curve * n*h must equal the order of the curve * a must be in [0, q-1] * b must be in [0, q-1] * *

* The prime checks are performed using {@link BigInteger#isProbablePrime(int)}, * and are therefore subject to the same probability guarantees. *

* These checks prevent trivial mistakes. * However, due to the small uncertainties if p and q are not prime, * advanced attacks are not prevented. * Use it at your own risk. * * @throws NullPointerException if any argument is null * @throws IllegalArgumentException if any of the above validations fail */ public ECJPAKECurve(BigInteger q, BigInteger a, BigInteger b, BigInteger n, BigInteger h, BigInteger g_x, BigInteger g_y) { ECJPAKEUtil.validateNotNull(a, "a"); ECJPAKEUtil.validateNotNull(b, "b"); ECJPAKEUtil.validateNotNull(q, "q"); ECJPAKEUtil.validateNotNull(n, "n"); ECJPAKEUtil.validateNotNull(h, "h"); ECJPAKEUtil.validateNotNull(g_x, "g_x"); ECJPAKEUtil.validateNotNull(g_y, "g_y"); /* * Don't skip the checks on user-specified groups. */ /* * Note that these checks do not guarantee that n and q are prime. * We just have reasonable certainty that they are prime. */ if (!q.isProbablePrime(20)) { throw new IllegalArgumentException("Field size q must be prime"); } if (a.compareTo(BigInteger.ZERO) < 0 || a.compareTo(q) >= 0) { throw new IllegalArgumentException("The parameter 'a' is not in the field [0, q-1]"); } if (b.compareTo(BigInteger.ZERO) < 0 || b.compareTo(q) >= 0) { throw new IllegalArgumentException("The parameter 'b' is not in the field [0, q-1]"); } BigInteger d = calculateDeterminant(q, a, b); if (d.equals(BigInteger.ZERO)) { throw new IllegalArgumentException("The curve is singular, i.e the discriminant is equal to 0 mod q."); } if (!n.isProbablePrime(20)) { throw new IllegalArgumentException("The order n must be prime"); } /* * TODO It's expensive to calculate the actual total number of points. Probably the best that could be done is * checking that the point count is within the Hasse bound? */ // BigInteger totalPoints = n.multiply(h); ECCurve.Fp curve = new ECCurve.Fp(q, a, b, n, h); ECPoint g = curve.createPoint(g_x, g_y); if (!g.isValid()) { throw new IllegalArgumentException("The base point G does not lie on the curve."); } this.curve = curve; this.g = g; } /** * Internal package-private constructor used by the pre-approved * groups in {@link ECJPAKECurves}. * These pre-approved curves can avoid the expensive checks. */ ECJPAKECurve(ECCurve.Fp curve, ECPoint g) { ECJPAKEUtil.validateNotNull(curve, "curve"); ECJPAKEUtil.validateNotNull(g, "g"); ECJPAKEUtil.validateNotNull(curve.getOrder(), "n"); ECJPAKEUtil.validateNotNull(curve.getCofactor(), "h"); this.curve = curve; this.g = g; } public ECCurve.Fp getCurve() { return curve; } public ECPoint getG() { return g; } public BigInteger getA() { return curve.getA().toBigInteger(); } public BigInteger getB() { return curve.getB().toBigInteger(); } public BigInteger getN() { return curve.getOrder(); } public BigInteger getH() { return curve.getCofactor(); } public BigInteger getQ() { return curve.getQ(); } private static BigInteger calculateDeterminant(BigInteger q, BigInteger a, BigInteger b) { BigInteger a3x4 = a.multiply(a).mod(q).multiply(a).mod(q).shiftLeft(2); BigInteger b2x27 = b.multiply(b).mod(q).multiply(BigInteger.valueOf(27)); return a3x4.add(b2x27).mod(q); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy