com.xwc1125.chain5j.crypto.ECKeyPair Maven / Gradle / Ivy
package com.xwc1125.chain5j.crypto;
import java.math.BigInteger;
import java.security.KeyPair;
import java.util.Arrays;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.signers.ECDSASigner;
import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import com.xwc1125.chain5j.utils.Numeric;
/**
* Elliptic Curve SECP-256k1 generated key pair.
*/
public class ECKeyPair {
private final BigInteger privateKey;
private final BigInteger publicKey;
public ECKeyPair(BigInteger privateKey, BigInteger publicKey) {
this.privateKey = privateKey;
this.publicKey = publicKey;
}
public BigInteger getPrivateKey() {
return privateKey;
}
public BigInteger getPublicKey() {
return publicKey;
}
/**
* Sign a hash with the private key of this key pair.
* @param transactionHash the hash to sign
* @return An {@link ECDSASignature} of the hash
*/
public ECDSASignature sign(byte[] transactionHash) {
ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest()));
ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(privateKey, Sign.CURVE);
signer.init(true, privKey);
BigInteger[] components = signer.generateSignature(transactionHash);
return new ECDSASignature(components[0], components[1]).toCanonicalised();
}
public static ECKeyPair create(KeyPair keyPair) {
BCECPrivateKey privateKey = (BCECPrivateKey) keyPair.getPrivate();
BCECPublicKey publicKey = (BCECPublicKey) keyPair.getPublic();
BigInteger privateKeyValue = privateKey.getD();
// Ethereum does not use encoded public keys like bitcoin - see
// https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm for details
// Additionally, as the first bit is a constant prefix (0x04) we ignore this value
byte[] publicKeyBytes = publicKey.getQ().getEncoded(false);
BigInteger publicKeyValue =
new BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 1, publicKeyBytes.length));
return new ECKeyPair(privateKeyValue, publicKeyValue);
}
public static ECKeyPair create(BigInteger privateKey) {
return new ECKeyPair(privateKey, Sign.publicKeyFromPrivate(privateKey));
}
public static ECKeyPair create(byte[] privateKey) {
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;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy