Author

Topic: [Solved]BouncyCastle - How to generate Bitcoin compatible keys, signatures... (Read 6629 times)

legendary
Activity: 1526
Merit: 1134
Yes, because you are already doing the hashing yourself. If you don't specify NONEwithECDSA then the implementation will hash a second time and calculate the wrong result.
Activity: -
Merit: -
So referring to your code from the other post you'd simply replace the "ECDSA" String in the methods signData and verifySignedData with "NONEwithECDSA"?

Yes.

There are a lot of choices like "SHA1withECDSA", "SHA256withECDSA", etc., and I'm guessing it's using one of these by default when signing and verifying, so we need "NONEwithECDSA" when signing and verifying.
hero member
Activity: 489
Merit: 505
So referring to your code from the other post you'd simply replace the "ECDSA" String in the methods signData and verifySignedData with "NONEwithECDSA"?
legendary
Activity: 1526
Merit: 1134
Good to hear you have it figured out. I guess that explains the difference ... I didn't use JCE so I never had to specify that magic string.

Next up, successfully receive and send some coins with your implementation Wink
Activity: -
Merit: -
Finally! I figured it out!  Grin

The different methods for signing, verification, and I'm assuming the other method calls (EDIT: only the signing and verification methods) with the string "ECDSA" need to use "NONEwithECDSA" instead.  Now transactions are verifying for me!

I just happened to see "NONEwithECDSA" in section 2.4.3 of the BouncyCastle release notes page: http://www.bouncycastle.org/releasenotes.html
After seeing stuff about different DSA algorithms using SHA-1 and stuff, I wondered if maybe that was the problem and specifying NONEwithECDSA would prevent that.  No idea if that's the reason why it wasn't working, but now it is!

Thanks for all your help everyone!
Hal
vip
Activity: 314
Merit: 4276
Signatures are DER encoded in Bitcoin, and your signature above is in the same format. 30 is a sequence of values, in this case the two ECDSA components, called r and s. 46 is the length of the sequence. Then 02 means integer, 21 is the length, followed by 0x21 bytes which is the r value. Then there's another 02 and length for the s value. If the high bit of r or s is set, they get 00 prepended so it's clear they're positive. Bitcoin sigs have exactly the same format as you can see in any blockexplorer.com dump.
Activity: -
Merit: -
Bitcoin uses a raw format that is not DER encoded, what code are you using to pump out that key? you want to use pubkey.encode() to get the DER version.

I believe I am using all the same code that you posted here: https://bitcointalksearch.org/topic/m.41493

What do you know about the signatures?  Are they encoded in some way in Bitcoin or BouncyCastle?
member
Activity: 77
Merit: 10
Bitcoin uses a raw format that is not DER encoded, what code are you using to pump out that key? you want to use pubkey.encode() to get the DER version.
Activity: -
Merit: -
I wonder if they're using different encodings?  I'm looking at this doc page for the OpenSSL ECDSA stuff (http://www.openssl.org/docs/crypto/ecdsa.html), and there's a lot mentioned about DER encoding...I'm not sure, but I'm guessing Bitcoin is using DER, but I can't say whether or not the Java and BouncyCastle code is using DER or a different encoding.
Hal
vip
Activity: 314
Merit: 4276
Well my attempt to verify that sig in openssl failed, it didn't verify. That's no surprise since the two methods also disagreed about the validity of the bitcoin sig. I hoped I'd see something wrong in the data structures, but I didn't. Your pubkey is a valid EC point on the secp256k1 curve. The signature appears to be properly formatted.

I'll see if I can think of anything else...
Activity: -
Merit: -
Here's what I would suggest. Create a new key pair in your code. Hash and sign something like 'abc'. Then see if you can verify the signature. If it works, publish the key and signature here. I can try to verify the sig with OpenSSL. I was successful at verifying a Bitcoin signature, so this might reveal differences in the two libraries.

I used "abc".

Code:
data: 616263
public key: 04cc2fcc1e68683f61ccc34b83737580bcc574dee4c0ec3c93fcbe8a0fce990187a92ecc95631f90229e853c209d865cd3f69a45a0c346c1a22d06f5103a5d78b5
signature: 3046022100cb4a3dc8cc0a149ef4e29b0501b84689514693c7a0a76107c13f3ecb0ef843d8022100bbc2b4b6b1879fbfa3883d0256fca1358884e215094dee36957759f6407b7502

And I'm able to verify this and other stuff generated by my code...just can't verify stuff from bitcoin, nor do I know if bitcoin will verify this.

Thanks!
Hal
vip
Activity: 314
Merit: 4276
Here's what I would suggest. Create a new key pair in your code. Hash and sign something like 'abc'. Then see if you can verify the signature. If it works, publish the key and signature here. I can try to verify the sig with OpenSSL. I was successful at verifying a Bitcoin signature, so this might reveal differences in the two libraries.
Activity: -
Merit: -
Activity: -
Merit: -
So far, dirtyfilthy and I are using practically the same code for decoding public keys, generating key pairs, signing with private keys, and verifying signatures.  Here is the code: https://bitcointalksearch.org/topic/m.41493

But after finally making sure that I'm giving everything the correct data, getting the correct hashes, cross-checking it all with the data and hashes generated by the official bitcoin client, etc., our signature verification still isn't working.  It could either be that I'm not converting the bytes of the key to an ECPublicKey object correctly, or (what I think is slightly more likely) that I'm not using the right code for signature verification.  I don't know anything about BouncyCastle (and can't find much in the way of documentation outside of the partial Javadocs) or about the low-level details of ECDSA (or public key crypto in general), which makes it much harder to even know where to look.

And I still haven't even tried to generate key pairs or create new transactions to see if the official Bitcoin client verifies them correctly, yet, so I don't know if that code is ok or not, either.

Is there anyone with any Bitcoin and BouncyCastle experience that can help with this?

Thanks
Jump to: