package org.rockyang.blockchain.crypto; import org.rockyang.blockchain.utils.Numeric; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import java.math.BigInteger; import java.security.KeyPair; import java.security.PrivateKey; import java.security.PublicKey; import java.util.Arrays; /** * 使用椭圆曲线算法生成密钥对 * Elliptic Curve SECP-256k1 generated key pair. * @author yangjian */ public class ECKeyPair { private final PrivateKey privateKey; private final PublicKey publicKey; private final BigInteger privateKeyValue; private final BigInteger publicKeyValue; public ECKeyPair(BigInteger privateKeyValue, BigInteger publicKeyValue) throws Exception { this.privateKeyValue = privateKeyValue; this.publicKeyValue = publicKeyValue; this.privateKey = Sign.privateKeyFromBigInteger(privateKeyValue); this.publicKey = Sign.publicKeyFromPrivate(privateKeyValue); } public ECKeyPair(PrivateKey privateKey, PublicKey publicKey) { this.privateKey = privateKey; this.publicKey = publicKey; // 生成 BigInteger 形式的公钥和私钥 BCECPrivateKey bcecPrivateKey = (BCECPrivateKey) this.privateKey; BCECPublicKey bcecPublicKey = (BCECPublicKey) this.publicKey; // 分别计算公钥和私钥的值 BigInteger privateKeyValue = bcecPrivateKey.getD(); byte[] publicKeyBytes = bcecPublicKey.getQ().getEncoded(false); BigInteger publicKeyValue = new BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 1, publicKeyBytes.length)); this.privateKeyValue = privateKeyValue; this.publicKeyValue = publicKeyValue; } public PrivateKey getPrivateKey() { return privateKey; } /** * export the private key to hex string * @return */ public String exportPrivateKey() { return Numeric.toHexStringNoPrefix(this.getPrivateKeyValue()); } /** * get the address * @return */ public String getAddress() { return Keys.getAddress(this.getPublicKeyValue()); } public PublicKey getPublicKey() { return publicKey; } public BigInteger getPrivateKeyValue() { return privateKeyValue; } public BigInteger getPublicKeyValue() { return publicKeyValue; } public static ECKeyPair create(KeyPair keyPair) { BCECPrivateKey privateKey = (BCECPrivateKey) keyPair.getPrivate(); BCECPublicKey publicKey = (BCECPublicKey) keyPair.getPublic(); return new ECKeyPair(privateKey, publicKey); } public static ECKeyPair create(BigInteger privateKeyValue) throws Exception { PrivateKey privateKey = Sign.privateKeyFromBigInteger(privateKeyValue); PublicKey publicKey = Sign.publicKeyFromPrivate(privateKeyValue); return new ECKeyPair(privateKey, publicKey); } public static ECKeyPair create(byte[] privateKey) throws Exception { return create(Numeric.toBigInt(privateKey)); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } ECKeyPair ecKeyPair = (ECKeyPair) o; if (privateKey != null ? !privateKey.equals(ecKeyPair.privateKey) : ecKeyPair.privateKey != null) { return false; } return publicKey != null ? publicKey.equals(ecKeyPair.publicKey) : ecKeyPair.publicKey == null; } @Override public int hashCode() { int result = privateKey != null ? privateKey.hashCode() : 0; result = 31 * result + (publicKey != null ? publicKey.hashCode() : 0); return result; } }