org.bouncycastle.crypto.asymmetric.ECDomainParameters Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bc-fips Show documentation
Show all versions of bc-fips Show documentation
The FIPS 140-3 Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms certified to FIPS 140-3 level 1. This jar contains JCE provider and low-level API for the BC-FJA version 2.0.0, FIPS Certificate #4743. Please see certificate for certified platform details.
package org.bouncycastle.crypto.asymmetric;
import java.math.BigInteger;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X962Parameters;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.Arrays;
/**
* Container class for Elliptic Curve domain parameters.
*/
public class ECDomainParameters
{
private final ECCurve curve;
private final byte[] seed;
private final ECPoint G;
private final BigInteger n;
private final BigInteger h;
private volatile BigInteger hInv = null;
/**
* Constructor that assumes the co-factor h is 1.
*
* @param curve the curve for these domain parameters.
* @param G the base point G for the domain parameters.
* @param n the order for the domain parameters.
*/
public ECDomainParameters(
ECCurve curve,
ECPoint G,
BigInteger n)
{
this(curve, G, n, BigInteger.ONE, null);
}
/**
* Constructor with explicit co-factor.
*
* @param curve the curve for these domain parameters.
* @param G the base point G for the domain parameters.
* @param n the order for the domain parameters.
* @param h the co-factor.
*/
public ECDomainParameters(
ECCurve curve,
ECPoint G,
BigInteger n,
BigInteger h)
{
this(curve, G, n, h, null);
}
/**
* Constructor with explicit co-factor and generation seed.
*
* @param curve the curve for these domain parameters.
* @param G the base point G for the domain parameters.
* @param n the order for the domain parameters.
* @param h the co-factor.
* @param seed the seed value used to generate the domain parameters.
*/
public ECDomainParameters(
ECCurve curve,
ECPoint G,
BigInteger n,
BigInteger h,
byte[] seed)
{
if (curve == null)
{
throw new NullPointerException("curve");
}
if (n == null)
{
throw new NullPointerException("n");
}
// we can't check for h == null here as h is optional in X9.62 as it is not required for ECDSA
this.curve = curve;
this.G = KeyUtils.validated(curve, G);
this.n = n;
this.h = h;
this.seed = Arrays.clone(seed);
}
/**
* Return the curve associated with these domain parameters.
*
* @return the domain parameters' curve.
*/
public ECCurve getCurve()
{
return curve;
}
/**
* Return the base point associated with these domain parameters.
*
* @return the domain parameters' base point.
*/
public ECPoint getG()
{
return G;
}
/**
* Return the order associated with these domain parameters.
*
* @return the domain parameters' order.
*/
public BigInteger getN()
{
return n;
}
/**
* Return the co-factor associated with these domain parameters.
*
* @return the domain parameters' co-factor.
*/
public BigInteger getH()
{
return h;
}
/**
* Return the multiplicative inverse of H over the order N.
*
* @return inverse of H.
*/
public BigInteger getInverseH()
{
// this works as expected in 1.5 and later...
if (hInv == null)
{
if (h == null)
{
throw new IllegalStateException("no H provided for these parameters");
}
synchronized (this)
{
if (hInv == null)
{
hInv = h.modInverse(n);
}
}
}
return hInv;
}
/**
* Return the generation seed associated with these domain parameters.
*
* @return the domain parameters' seed.
*/
public byte[] getSeed()
{
return Arrays.clone(seed);
}
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (!(o instanceof ECDomainParameters))
{
return false;
}
ECDomainParameters that = (ECDomainParameters)o;
if (!G.equals(that.G))
{
return false;
}
if (!curve.equals(that.curve))
{
return false;
}
if (!h.equals(that.h))
{
return false;
}
if (!n.equals(that.n))
{
return false;
}
// we need to ignore the seed as it will not always be set (JDK issue)
return true;
}
@Override
public int hashCode()
{
int result = curve.hashCode();
// we need to ignore the seed as it will not always be set (JDK issue)
result = 31 * result + G.hashCode();
result = 31 * result + n.hashCode();
result = 31 * result + h.hashCode();
return result;
}
static ECDomainParameters decodeCurveParameters(AlgorithmIdentifier algId)
{
if (!algId.getAlgorithm().equals(X9ObjectIdentifiers.id_ecPublicKey))
{
throw new IllegalArgumentException("Unknown algorithm type: " + algId.getAlgorithm());
}
X962Parameters params = X962Parameters.getInstance(algId.getParameters());
X9ECParameters x9;
if (params.isNamedCurve())
{
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
x9 = CustomNamedCurves.getByOID(oid);
if (x9 == null)
{
x9 = ECNamedCurveTable.getByOID(oid);
}
return new NamedECDomainParameters(oid, x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
}
else if (!params.isImplicitlyCA())
{
x9 = X9ECParameters.getInstance(params.getParameters());
return new ECDomainParameters(x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
}
else
{
return new ECImplicitDomainParameters(CryptoServicesRegistrar.getProperty(CryptoServicesRegistrar.Property.EC_IMPLICITLY_CA));
}
}
}