I met some problems, when I was trying to write function able to create Bitcoin public key from private key. I was using the tutorial: http://procbits.com/2013/08/27/generating-a-bitcoin-address-with-javascript ---> "Public key" part is most important.
Part of my code looks like this:
public String generatePublicKey(String privateKey)
{
BigInteger privKey = new BigInteger(privateKey,16);
X9ECParameters ecp = SECNamedCurves.getByName("secp256k1");
ECPoint curvePt = ecp.getG().multiply(privKey);
BigInteger x = curvePt.getXCoord().toBigInteger();
BigInteger y = curvePt.getYCoord().toBigInteger();
byte[] xBytes = this.removeSignByte(x.toByteArray());
byte[] yBytes = this.removeSignByte(y.toByteArray());
byte[] pubKeyBytes = new byte[65];
pubKeyBytes[0] = new Byte("04");
System.arraycopy(xBytes,0, pubKeyBytes, 1, xBytes.length);
System.arraycopy(yBytes, 0, pubKeyBytes, 33, yBytes.length);
return this.bytesToHex(pubKeyBytes);}
There are also two functions:
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
int v;
for ( int j = 0; j < bytes.length; j++ ) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
private byte[] removeSignByte(byte[] arr)
{
if(arr.length==33)
{
byte[] newArr = new byte[32];
System.arraycopy(arr, 1, newArr, 0, newArr.length);
return newArr;
}
return arr;
}
However I used bytesToHex() earlier and there weren't any problems. So the thing is that generatePublicKey() does not work properly. I tried to insert private key known from bitcoin wiki:
18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725
(from https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses)
It should create long public key (even before all hashing) - step 2 on wiki:
0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6
Unfortunately the answer is wrong. Could you Guys look at this and point my mistakes?
Ofc, programming language is Java and cryptographic provider was Bouncy Castle.
EDIT: I accidentally solved my problem. When I was writing this function, Eclipse told me function getX() (and getY()) is depracated. So I used getXCoord(), because I thought its result is the same. In feeling hopeless I used getX() instead getXCoord() and whole function magically worked!
What's the difference between getX() and getXCoord() ?
getX()
andgetXCoord()
, you could look at the source. The difference seems to be "normalization", whatever that may be.