-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathPrivateKey.java
More file actions
79 lines (63 loc) · 2.71 KB
/
Copy pathPrivateKey.java
File metadata and controls
79 lines (63 loc) · 2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package org.arkecosystem.crypto.identities;
import java.math.BigInteger;
import java.util.Arrays;
import org.arkecosystem.crypto.configuration.Network;
import org.arkecosystem.crypto.encoding.Base58;
import org.arkecosystem.crypto.encoding.Hex;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.Sha256Hash;
public class PrivateKey {
public static ECKey fromPassphrase(String passphrase) {
byte[] sha256 = Sha256Hash.hash(passphrase.getBytes());
return ECKey.fromPrivate(sha256, true);
}
public static ECKey fromHex(String privateKey) {
return ECKey.fromPrivate(Hex.decode(privateKey), true);
}
public static ECKey fromWif(String wif) {
byte[] decoded = Base58.decodeChecked(wif);
if (decoded.length < 33) {
throw new IllegalArgumentException("Invalid WIF: payload too short.");
}
int expectedVersion = Network.get().wif() & 0xff;
if ((decoded[0] & 0xff) != expectedVersion) {
throw new IllegalArgumentException(
"Invalid WIF: version byte does not match the active network.");
}
byte[] privateKeyBytes = Arrays.copyOfRange(decoded, 1, 33);
return ECKey.fromPrivate(privateKeyBytes, true);
}
public static byte[] sign(byte[] message, String passphrase) {
return sign(message, fromPassphrase(passphrase));
}
public static byte[] sign(byte[] message, ECKey privateKey) {
ECKey.ECDSASignature signature = privateKey.sign(Sha256Hash.wrap(message));
int recId = -1;
for (int i = 0; i < 4; i++) {
ECKey k = ECKey.recoverFromSignature(i, signature, Sha256Hash.wrap(message), true);
if (k != null && k.getPubKeyPoint().equals(privateKey.getPubKeyPoint())) {
recId = i;
break;
}
}
if (recId == -1) {
throw new RuntimeException("Could not find recId");
}
byte[] rBytes = bigIntegerToBytes(signature.r, 32);
byte[] sBytes = bigIntegerToBytes(signature.s, 32);
byte[] signatureWithRecId = new byte[65];
System.arraycopy(rBytes, 0, signatureWithRecId, 0, 32);
System.arraycopy(sBytes, 0, signatureWithRecId, 32, 32);
signatureWithRecId[64] = (byte) recId;
return signatureWithRecId;
}
private static byte[] bigIntegerToBytes(BigInteger b, int numBytes) {
byte[] src = b.toByteArray();
byte[] dest = new byte[numBytes];
int srcPos = Math.max(0, src.length - numBytes);
int destPos = Math.max(0, numBytes - src.length);
int length = Math.min(src.length, numBytes);
System.arraycopy(src, srcPos, dest, destPos, length);
return dest;
}
}