110
|
1 package christie.blockchain;
|
|
2
|
|
3 import org.bouncycastle.asn1.sec.SECNamedCurves;
|
|
4 import org.bouncycastle.asn1.x9.X9ECParameters;
|
|
5 import org.bouncycastle.crypto.params.ECDomainParameters;
|
|
6 import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
7 import org.bouncycastle.jce.spec.ECParameterSpec;
|
|
8 import org.bouncycastle.math.ec.ECPoint;
|
|
9
|
|
10 import java.math.BigInteger;
|
|
11 import java.security.*;
|
|
12 import java.security.interfaces.ECPublicKey;
|
|
13 import java.security.spec.ECGenParameterSpec;
|
|
14
|
|
15
|
|
16 public class ECKey {
|
|
17
|
|
18 public static final ECDomainParameters CURVE;
|
|
19 public static final ECParameterSpec CURVE_SPEC;
|
|
20
|
|
21 public static final BigInteger HALF_CURVE_ORDER;
|
|
22 private static final SecureRandom secureRandom;
|
|
23
|
|
24 private final PrivateKey privateKey;
|
|
25 private final PublicKey publicKey;
|
|
26 private final Provider provider;
|
|
27
|
|
28 static {
|
|
29 X9ECParameters params = SECNamedCurves.getByName("secp256k1");
|
|
30 CURVE = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH());
|
|
31 CURVE_SPEC = new ECParameterSpec(params.getCurve(), params.getG(), params.getN(), params.getH());
|
|
32 HALF_CURVE_ORDER = params.getN().shiftRight(1);
|
|
33 secureRandom = new SecureRandom();
|
|
34 }
|
|
35
|
|
36 public ECKey() {
|
|
37 this(secureRandom);
|
|
38 }
|
|
39
|
|
40 public ECKey(SecureRandom secureRandom) {
|
|
41 this(new BouncyCastleProvider(), secureRandom);
|
|
42 }
|
|
43
|
|
44
|
|
45 public ECKey(Provider provider, SecureRandom secureRandom) {
|
|
46 this.provider = provider;
|
|
47
|
|
48 KeyPairGenerator keyGen;
|
|
49 try {
|
|
50 keyGen = KeyPairGenerator.getInstance("EC");
|
|
51 ECGenParameterSpec SECP256K1_CURVE = new ECGenParameterSpec("secp256k1");
|
|
52 keyGen.initialize(SECP256K1_CURVE);
|
|
53 } catch (NoSuchAlgorithmException ex) {
|
|
54 throw new AssertionError(ex);
|
|
55 } catch (InvalidAlgorithmParameterException ex) {
|
|
56 throw new AssertionError(ex);
|
|
57 }
|
|
58
|
|
59 KeyPair keyPair = keyGen.generateKeyPair();
|
|
60
|
|
61 this.privateKey = keyPair.getPrivate();
|
|
62 this.publicKey = keyPair.getPublic();
|
|
63
|
|
64 }
|
|
65
|
|
66 private static ECPoint extractPublicKey(final ECPublicKey ecPublicKey) {
|
|
67 final java.security.spec.ECPoint publicPointW = ecPublicKey.getW();
|
|
68 final BigInteger xCoord = publicPointW.getAffineX();
|
|
69 final BigInteger yCoord = publicPointW.getAffineY();
|
|
70
|
|
71 return CURVE.getCurve().createPoint(xCoord, yCoord);
|
|
72 }
|
|
73
|
|
74 public byte[] applyECDSASig(byte[] input) {
|
|
75 Signature dsa;
|
|
76 byte[] output;
|
|
77
|
|
78 if (privateKey == null)
|
|
79 throw new RuntimeException();
|
|
80 try {
|
|
81 dsa = Signature.getInstance("ECDSA", "BC");
|
|
82 dsa.initSign(privateKey);
|
|
83 dsa.update(input);
|
|
84 output = dsa.sign();
|
|
85 } catch (Exception e) {
|
|
86 throw new RuntimeException(e);
|
|
87 }
|
|
88 return output;
|
|
89 }
|
|
90
|
|
91 public static boolean verifyECDSASig(byte[] data, byte[] signature, PublicKey publicKey) {
|
|
92 try {
|
|
93 Signature ecdsaVerify = Signature.getInstance("ECDSA", "BC");
|
|
94 ecdsaVerify.initVerify(publicKey);
|
|
95 ecdsaVerify.update(data);
|
|
96 return ecdsaVerify.verify(signature);
|
|
97 }catch(Exception e) {
|
|
98 throw new RuntimeException(e);
|
|
99 }
|
|
100 }
|
|
101
|
|
102 }
|