Search code examples
javacryptographybouncycastleecdsa

BouncyCastle validate secp256k1 public key generation


I have the following Java code using bounce castle library:

byte[] privKey = new byte[32];
privKey[31] = 1;


ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1");
ECPoint pointQ = spec.getG().multiply(new BigInteger(1, privKey));

System.out.println(pointQ.getRawXCoord());
System.out.println(pointQ.getRawYCoord());

To be sure I wanted to validate the calculated X and Y aganst a secp256k1 test vector. https://chuckbatson.wordpress.com/2014/11/26/secp256k1-test-vectors/

This only works for k = 1.

But when I use k = 2 as in

byte[] privKey = new byte[32];
privKey[31] = 2;

I get completely different values for X and Y. Am I doing something wrong here?


Solution

  • To speed up ECC calculations we use projective coordinate system. In this case point is represented by 3 numbers: X, Y, Z. In your code you are getting projective coordinates, and that's why X, Y doesn't match to affine coordinates from test vectors.

    You should normalize your point to get affine X and Y:

    byte[] privKey = new byte[32];
    privKey[31] = 2;
    
    ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1");
    ECPoint pointQ = spec.getG().multiply(new BigInteger(1, privKey));
    
    pointQ = pointQ.normalize();
    
    System.out.println(pointQ.getRawXCoord());
    System.out.println(pointQ.getRawYCoord());