Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: 0x6763 on January 20, 2011, 10:47:03 PM



Title: [SOLVED] Java/BouncyCastle - How to create public key with x and y coordinates?
Post by: 0x6763 on January 20, 2011, 10:47:03 PM
From the wiki (https://en.bitcoin.it/wiki/Protocol_specification#Signatures):
Quote
Public keys (in scripts) are given as 04 <x> <y> where x and y are 32 byte strings representing the coordinates of a point on the curve.
I'm using the Java version of the BouncyCastle crypto library, and between the Java crypto classes and the BouncyCastle crypto classes, I can't figure out how I can create a public key object with the x and y coordinates.

Does anyone have any idea how I would go about this?

I'm correct in needing to use these coordinates to create a public key object to use for verifying signatures, right?


Title: Re: Java/BouncyCastle - How to create public key objects with x and y coordinates?
Post by: dirtyfilthy on January 21, 2011, 01:47:30 AM
public static ECPublicKey decodeKey(byte[] encoded) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException{
    ECNamedCurveParameterSpec params = ECNamedCurveTable.getParameterSpec("secp256k1");
    KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC");
    ECCurve curve = params.getCurve();
    java.security.spec.EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, params.getSeed());
    java.security.spec.ECPoint point=ECPointUtil.decodePoint(ellipticCurve, encoded);
    java.security.spec.ECParameterSpec params2=EC5Util.convertSpec(ellipticCurve, params);
    java.security.spec.ECPublicKeySpec keySpec = new java.security.spec.ECPublicKeySpec(point,params2);
    return (ECPublicKey) fact.generatePublic(keySpec);
}


I'm implementation an android client at the moment and would be happy to chat re: any question you have.

Regards, etc.


Title: Re: Java/BouncyCastle - How to create public key objects with x and y coordinates?
Post by: 0x6763 on January 21, 2011, 02:07:11 AM
public static ECPublicKey decodeKey(byte[] encoded) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException{
    ECNamedCurveParameterSpec params = ECNamedCurveTable.getParameterSpec("secp256k1");
    KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC");
    ECCurve curve = params.getCurve();
    java.security.spec.EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, params.getSeed());
    java.security.spec.ECPoint point=ECPointUtil.decodePoint(ellipticCurve, encoded);
    java.security.spec.ECParameterSpec params2=EC5Util.convertSpec(ellipticCurve, params);
    java.security.spec.ECPublicKeySpec keySpec = new java.security.spec.ECPublicKeySpec(point,params2);
    return (ECPublicKey) fact.generatePublic(keySpec);
}


I'm implementation an android client at the moment and would be happy to chat re: any question you have.

Regards, etc.

Works perfectly! Thank you very much!


Title: issues verifying...
Post by: whateverlie on March 06, 2011, 10:21:55 AM
Hey,

So you said you wouldn't mind answering any question regarding this-

So I've been working on a project and I need to verify a signature, given to me.

When I both generate & verify the signature, everything works perfectly, but when I'm trying to verify the other guy's signature it crushes saying: "error decoding signature bytes.", specifically I found out it crushes here:
ASN1InputStream aIn = new ASN1InputStream(signature.getBytes());
try {
       ASN1Sequence s = (ASN1Sequence)aIn.readObject();/*crushes on this line exactly...*/
} catch (IOException e) {

}

I attached the functions related...

private PublicKey generatePublicKey(Point pPublicKey, String sCurve)
         throws IOException, NoSuchAlgorithmException,
         NoSuchProviderException, InvalidKeySpecException,
         InvalidAlgorithmParameterException {
       X9ECParameters ecParams = NISTNamedCurves.getByName(sCurve);
       ECPoint pPublicPoint = ecParams.getCurve().createPoint(pPublicKey.x,
       pPublicKey.y, false);
       ECParameterSpec spec = new ECParameterSpec(ecParams.getCurve(),
       ecParams.getG(), ecParams.getN());
       ECPublicKeySpec publicSpec = new ECPublicKeySpec(pPublicPoint, spec);
       KeyFactory keyfac = KeyFactory.getInstance("ECDSA", "LOCAL_BC");
       return keyfac.generatePublic(publicSpec);
   }

   public ECDSAVerifier(Point pKey, String sHash, String sCurve)
         throws InvalidKeyException, NoSuchAlgorithmException,
         NoSuchProviderException, InvalidKeySpecException, IOException,
         InvalidAlgorithmParameterException {
      this.key = generatePublicKey(pKey, sCurve);
      this.hashName = sHash;
      ECDSAGenerateVerifier();
   }

   private void ECDSAGenerateVerifier() throws NoSuchAlgorithmException,
         NoSuchProviderException, InvalidKeyException {
      this.verifier = Signature.getInstance(this.hashName, "LOCAL_BC");
      this.verifier.initVerify(this.key);
   }

   public Boolean verify(byte[] message, byte[] signature)
         throws SignatureException, InvalidKeyException {
      this.verifier.update(message);
      return this.verifier.verify(signature); /*the code crushes here...*/
   }


Title: Re: issues verifying...
Post by: dirtyfilthy on March 06, 2011, 10:00:04 PM
Hey,

So you said you wouldn't mind answering any question regarding this-

So I've been working on a project and I need to verify a signature, given to me.

When I both generate & verify the signature, everything works perfectly, but when I'm trying to verify the other guy's signature it crushes saying: "error decoding signature bytes.", specifically I found out it crushes here:


Is this a bitcoin signature? Because the bitcoin signature has one byte tacked on to the end that you need to remove (the hashtype) before verifying.


Title: Re: Java/BouncyCastle - How to create public key objects with x and y coordinates?
Post by: clever662002 on December 30, 2014, 08:17:37 PM
public static ECPublicKey decodeKey(byte[] encoded) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException{
    ECNamedCurveParameterSpec params = ECNamedCurveTable.getParameterSpec("secp256k1");
    KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC");
    ECCurve curve = params.getCurve();
    java.security.spec.EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, params.getSeed());
    java.security.spec.ECPoint point=ECPointUtil.decodePoint(ellipticCurve, encoded);
    java.security.spec.ECParameterSpec params2=EC5Util.convertSpec(ellipticCurve, params);
    java.security.spec.ECPublicKeySpec keySpec = new java.security.spec.ECPublicKeySpec(point,params2);
    return (ECPublicKey) fact.generatePublic(keySpec);
}


I'm implementation an android client at the moment and would be happy to chat re: any question you have.

Regards, etc.

Thank you #dirtyfilthy. I have been finding this for a while. Your solution is working. This piece of code is helping me injecting the generated public key from HSM into JCE. Somehow the sample on the boucny castle website is buggy. I hope this can help other ppl who needs importing the public key into JCE.

Cheers