ECDSAKeyGenerator.java
- /*
- * @copyright defined in LICENSE.txt
- */
- package hera.util.pki;
- import static java.security.Security.addProvider;
- import static java.security.Security.getProvider;
- import static org.bouncycastle.jce.ECNamedCurveTable.getParameterSpec;
- import static org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME;
- import static org.slf4j.LoggerFactory.getLogger;
- import hera.util.Sha256Utils;
- import java.math.BigInteger;
- import java.security.InvalidAlgorithmParameterException;
- import java.security.KeyFactory;
- import java.security.KeyPair;
- import java.security.KeyPairGenerator;
- import java.security.NoSuchAlgorithmException;
- import java.security.NoSuchProviderException;
- import java.security.PrivateKey;
- import java.security.PublicKey;
- import java.security.SecureRandom;
- import java.security.Security;
- import java.security.spec.PKCS8EncodedKeySpec;
- import org.bouncycastle.crypto.params.ECDomainParameters;
- import org.bouncycastle.crypto.prng.FixedSecureRandom;
- import org.bouncycastle.jce.provider.BouncyCastleProvider;
- import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
- import org.bouncycastle.jce.spec.ECPrivateKeySpec;
- import org.bouncycastle.jce.spec.ECPublicKeySpec;
- import org.bouncycastle.math.ec.ECPoint;
- import org.slf4j.Logger;
- public class ECDSAKeyGenerator implements KeyGenerator<ECDSAKey> {
- protected static final String KEY_ALGORITHM = "ECDSA";
- protected static final String CURVE_NAME = "secp256k1";
- protected static final ECNamedCurveParameterSpec ecSpec;
- public static final ECDomainParameters ecParams;
- static {
- java.security.Provider provider = getProvider(PROVIDER_NAME);
- if (provider != null) {
- Security.removeProvider(PROVIDER_NAME);
- }
- addProvider(new BouncyCastleProvider());
- ecSpec = getParameterSpec(CURVE_NAME);
- ecParams = new ECDomainParameters(ecSpec.getCurve(), ecSpec.getG(), ecSpec.getN(),
- ecSpec.getH(), ecSpec.getSeed());
- }
- protected final transient Logger logger = getLogger(getClass());
- protected ECDSAKey generateKey(final SecureRandom secureRandom)
- throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
- final KeyPairGenerator generator = getKeyPairGenerator(secureRandom);
- final KeyPair pair = generator.generateKeyPair();
- final PrivateKey privateKey = pair.getPrivate();
- final PublicKey publicKey = pair.getPublic();
- logger.trace("Public key: {}", publicKey);
- return new ECDSAKey(privateKey, publicKey, ecParams);
- }
- protected KeyPairGenerator getKeyPairGenerator(final SecureRandom secureRandom)
- throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
- final KeyPairGenerator keyPairGenerator =
- KeyPairGenerator.getInstance(KEY_ALGORITHM, PROVIDER_NAME);
- keyPairGenerator.initialize(ecSpec, secureRandom);
- logger.debug("Generator: {}", keyPairGenerator);
- return keyPairGenerator;
- }
- @Override
- public ECDSAKey create() throws Exception {
- return generateKey(new SecureRandom());
- }
- @Override
- public ECDSAKey create(final String seed) throws Exception {
- final byte[] digested = Sha256Utils.digest(seed.getBytes());
- final SecureRandom secureRandom = new FixedSecureRandom(digested);
- return generateKey(secureRandom);
- }
- /**
- * Create key-pair from encoded private key.
- *
- * @param encodedPrivateKey PKCS #8 encoded private key
- * @return key pair to be recovered
- * @throws Exception On failure of recovery
- */
- public ECDSAKey create(final byte[] encodedPrivateKey) throws Exception {
- final KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
- final PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(encodedPrivateKey);
- return create(factory.generatePrivate(spec));
- }
- /**
- * Create key-pair from encoded private key.
- *
- * @param d d value of private key
- * @return key pair to be recovered
- * @throws Exception On failure of recovery
- */
- public ECDSAKey create(final BigInteger d) throws Exception {
- return create(createPrivateKey(d));
- }
- /**
- * Create key-pair from a private key.
- *
- * @param privateKey a private key
- * @return key pair to be recovered
- * @throws Exception On failure of recovery
- */
- public ECDSAKey create(final PrivateKey privateKey) throws Exception {
- final KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
- final ECPoint Q = ecSpec.getG()
- .multiply(((org.bouncycastle.jce.interfaces.ECPrivateKey) privateKey).getD());
- final ECPublicKeySpec ecPublicKeySpec = new ECPublicKeySpec(Q, ecSpec);
- final PublicKey publicKey = factory.generatePublic(ecPublicKeySpec);
- return new ECDSAKey(privateKey, publicKey, ecParams);
- }
- /**
- * Create private key from d value.
- *
- * @param d d value of private key
- * @return a generated private key
- * @throws Exception on failure of create
- */
- public PrivateKey createPrivateKey(final BigInteger d) throws Exception {
- final KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
- final ECPrivateKeySpec spec = new ECPrivateKeySpec(d, ecSpec);
- return factory.generatePrivate(spec);
- }
- /**
- * Create public key from compressed one. The compression format is <code>F<sub>p</sub></code>(
- * X9.62 s 4.2.1).
- *
- * @param compressed an compressed
- * @return a generated public key
- * @throws Exception on failure of create
- */
- public PublicKey createPublicKey(final byte[] compressed) throws Exception {
- return createPublicKey(ecParams.getCurve().decodePoint(compressed));
- }
- /**
- * Create public key from ECPoint x, y value.
- *
- * @param x x value of public key
- * @param y y value of public key
- * @return a generated public key
- * @throws Exception on failure of create
- */
- public PublicKey createPublicKey(final BigInteger x, final BigInteger y) throws Exception {
- return createPublicKey(ecParams.getCurve().createPoint(x, y));
- }
- protected PublicKey createPublicKey(final ECPoint ecPoint) throws Exception {
- final KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
- final ECPublicKeySpec spec = new ECPublicKeySpec(ecPoint, ecSpec);
- return factory.generatePublic(spec);
- }
- }