Pages:
Author

Topic: [BOUNTY: 2.0 BTC] [CLAIMED] Message Signing in Armory - page 3. (Read 7978 times)

legendary
Activity: 1428
Merit: 1093
Core Armory Developer
I'll try to be clearer:
  • Bitcoin's base64 is base64( leading byte + r + s )
  • My current code base64 (for v0, v1CS and v1B64) is base64( leading byte + r + s )
  • RFC2440 works with packets:
    • Verifying a clear text needs only a signature packet: base64( type + length + 04 + hash algorithm byte + pubkey type byte + timestamp + ... + MPI(r) + MPI(s) )
    • Verifying with included text needs a signature packet and a literal data packet: base64( type of literal data packet + len of literal data packet + flag + 00 + timestamp + message + type of pubkey packet + length of pubkey packet + 04 + hash algorithm byte + pubkey type byte + timestamp + ... + MPI(r) + MPI(s) )

As you can see, OpenPGP doesn't contain the leading byte so anyway I can't use strict RFC2440 to concatenate sig+data
A choice must be made because we can't use strict RFC2440 rules

Understood.  It's okay to deviate from RFC2440 as long as it's documented.  The goal was simply to follow RFC2440 to standardize the implementation as much as possible, but knowing that there would be slight deviations from RFC2440 where it makes sense to use our Bitcoin conventions.  I am honestly not going to be picky about it, as long as what is chosen is well-defined and documented. 
legendary
Activity: 1176
Merit: 1260
May Bitcoin be touched by his Noodly Appendage
Is the v1-Base64 you identified correctly?  It says "BEGIN SIGNATURE", but it should probably be "BEGINE BITCOIN MESSAGE", I assume the text and signature are both bundled in there.
Nope, RFC2440 divides everything in packets and as you didn't want/need packets I didn't know how to bundle them
Do you need a specific way to bundle them? If not I'll do (1byte header + r + s + message)

I guess I don't understand.  The point v1 non-clearsign is that you get a single block of opaque base64 that contains the original message and the signature, together.  The user should have no idea what's in it until they copy it into their wallet and it will spit out the message only if the signature is valid.  This is considered ideal since users have a tendency to only look for the message header and trust it without checking.  This way, they can't get the message unless they also check the signature.  

Does RFC2440 not mention how to encode and concatenate this data?  You can see what I'm talking about by just doing a regular "gpg --sign --armor file.txt".  Then when you "gpg -v file.txt.asc" it checks the signature, and writes out the signed data to a file.  I don't need the file operations, but I do want the bundling.  
RFC2440 says that you must communicate with blocks of packets, it describes all the types of packets you can create (signature, public key, private key, signer info, literal data, etc) and how to write them.
So yes it does mention how to bundle the sig+data, but as you said you didn't need OpenPGP compatibility I thought I didn't even have to stick to this 'packet rule'.

I'll try to be clearer:
  • Bitcoin's base64 is base64( leading byte + r + s )
  • My current code base64 (for v0, v1CS and v1B64) is base64( leading byte + r + s )
  • RFC2440 works with packets:
    • Verifying a clear text needs only a signature packet: base64( type + length + 04 + hash algorithm byte + pubkey type byte + timestamp + ... + MPI(r) + MPI(s) )
    • Verifying with included text needs a signature packet and a literal data packet: base64( type of literal data packet + len of literal data packet + flag + 00 + timestamp + message + type of pubkey packet + length of pubkey packet + 04 + hash algorithm byte + pubkey type byte + timestamp + ... + MPI(r) + MPI(s) )

As you can see, OpenPGP doesn't contain the leading byte so anyway I can't use strict RFC2440 to concatenate sig+data
A choice must be made because we can't use strict RFC2440 rules
legendary
Activity: 1428
Merit: 1093
Core Armory Developer
I just released on github before your message: https://github.com/jackjack-jj/jasvet/blob/master/jasvet.py

Ok for 64-chars wide blocks and headers, I'll change that
Yes for the dashes, newlines, and key recovery matters

Fantastic.

Is the v1-Base64 you identified correctly?  It says "BEGIN SIGNATURE", but it should probably be "BEGINE BITCOIN MESSAGE", I assume the text and signature are both bundled in there.
Nope, RFC2440 divides everything in packets and as you didn't want/need packets I didn't know how to bundle them
Do you need a specific way to bundle them? If not I'll do (1byte header + r + s + message)

I guess I don't understand.  The point v1 non-clearsign is that you get a single block of opaque base64 that contains the original message and the signature, together.  The user should have no idea what's in it until they copy it into their wallet and it will spit out the message only if the signature is valid.  This is considered ideal since users have a tendency to only look for the message header and trust it without checking.  This way, they can't get the message unless they also check the signature.  

Does RFC2440 not mention how to encode and concatenate this data?  You can see what I'm talking about by just doing a regular "gpg --sign --armor file.txt".  Then when you "gpg -v file.txt.asc" it checks the signature, and writes out the signed data to a file.  I don't need the file operations, but I do want the bundling.  

I didn't say anything about your CPP additional matter. Was I unclear somewhere?

No, I was just clarifying.  There seemed to be some confusion earlier about where the key recovery should happen.  I was just clarifying that it needs to happen in the python code, but I'll give "extra credit" for the Crypto++ implementation.

Thanks!
legendary
Activity: 1176
Merit: 1260
May Bitcoin be touched by his Noodly Appendage
Perhaps, also add a few comments there (or here), describing exactly how the v1 signing is done.  Basically, just mention which parts of RFC2440 were used, and how the signature is created exactly (i.e. I assume it matches the version-0 format, but it should be noted).
Ok!

And while you're at it, can you add a header to the file declaring that the code in this file is being released to the public domain? 
It was the point of CC0, but I'll explicit
legendary
Activity: 1176
Merit: 1260
May Bitcoin be touched by his Noodly Appendage
I just released on github before your message: https://github.com/jackjack-jj/jasvet/blob/master/jasvet.py

Ok for 64-chars wide blocks and headers, I'll change that
Yes for the dashes, newlines, and key recovery matters

Is the v1-Base64 you identified correctly?  It says "BEGIN SIGNATURE", but it should probably be "BEGINE BITCOIN MESSAGE", I assume the text and signature are both bundled in there.
Nope, RFC2440 divides everything in packets and as you didn't want/need packets I didn't know how to bundle them
Do you need a specific way to bundle them? If not I'll do (1byte header + r + s + message)


I didn't say anything about your CPP additional matter. Was I unclear somewhere?



Edit: I deleted my previous post to answer yours
legendary
Activity: 1428
Merit: 1093
Core Armory Developer
Ok, I assumed this was what you wanted
Released on github: https://github.com/jackjack-jj/jasvet/blob/master/jasvet.py

Great, I'll look at it when I get some time.  I won't get to it today, so if you want to tweak it any further, go ahead.  Perhaps, also add a few comments there (or here), describing exactly how the v1 signing is done.  Basically, just mention which parts of RFC2440 were used, and how the signature is created exactly (i.e. I assume it matches the version-0 format, but it should be noted).

And while you're at it, can you add a header to the file declaring that the code in this file is being released to the public domain? 

Thanks! 
legendary
Activity: 1428
Merit: 1093
Core Armory Developer
This is looking good!   

A couple questions/comments.

--GPG keeps the armored blocks to 64-characters wide, not 80.
--Does this do proper dash-escaping? 
--Handles newlines properly?
--Signs the non-dash-escaped, windows-styled-newline string, or something like that (I don't remember the details, that was your job Smiley)
--Make it say "-----BEGIN BITCOIN SIGNED MESSAGE-----" and "-----BEGIN BITCOIN SIGNATURE-----"
--Is the v1-Base64 you identified correctly?  It says "BEGIN SIGNATURE", but it should probably be "BEGINE BITCOIN MESSAGE", I assume the text and signature are both bundled in there.

And these signatures use the key recovery?  I assume that's what the 1+64 bytes comment is. 

I really did want python signing.  But I was saying I would pay an extra 0.5 BTC to additionally implement key recovery in cppForSwig/EncryptionUtils.cpp using Crypto++, but it's not strictly necessary or part of the original bounty.
legendary
Activity: 1176
Merit: 1260
May Bitcoin be touched by his Noodly Appendage
Ok then!
I think/hope that will anyway be useful in the future

For now I have that:
v0
Code:
{
 'message': 'jjj',
 'signature': 'G52Qg26N+v9BE7WlaG+MQUYF+35Or0UF6cWUp9bRVM46LFT8AP+spHCVLds9gpCh+IGcKLOCLYdLWKgFqvP82PY=', // =base64(signature)
 'address': '1BCwRkTsYzK5aNK4sdF7Bpti3PhrkPtLc4'
}

v1 Clear sig
Code:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

ldld
-----BEGIN PGP SIGNATURE-----
iHkEABMIACEFAlGOIpYCGwMGCwkIBwMCBhUIAgkKCwMWAgECHgECF4AACgkQQAqjLBlarMRT3wEA1IED    (OpenPGP packets)
GsDYPz4OTY0bn35RTz6RkyCh59i47DBnjih4S5IA/R3qcXG/V9Mx8uHzjaU1uM6CrS1II1aij+JqU6vR
2Gtp
=D1/a
-----END PGP SIGNATURE-----

v1 Base64
Code:
-----BEGIN SIGNATURE-----
kA0DAAgTU4HmRG72SLABywpiAFGOJKpsZGxkiHkEABMIACEFAlGOJKoCGwMGCwkIBwMCBhUIAgkKCwMW   (OpenPGP packets)
AgECHgECF4AACgkQU4HmRG72SLBCWAD8Db4nEv/poywtioVXy3nRCIwVkVJc8kULlRVpEeW4Os8BAJ2B
8qnmdGqEmyYbl3ZDV+Osp7440Cdl8WgSv3EHvAMf
=5wDl
-----END SIGNATURE-----



So instead of my clear sig, you'd want that, right?
Code:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

ldld
-----BEGIN PGP SIGNATURE-----
G52Qg26N+v9BE7WlaG+MQUYF+35Or0UF6cWUp9bRVM46LFT8AP+spHCVLds9gpCh+IGcKLOCLYdLWKgFqvP82PY= (same data than v0: 1+64 bytes, may be different if contains \n)
=crc24
-----END PGP SIGNATURE-----

But what about the base64 one? Just this?
Code:
-----BEGIN PGP SIGNATURE-----
G52Qg26N+v9BE7WlaG+MQUYF+35Or0UF6cWUp9bRVM46LFT8AP+spHCVLds9gpCh+IGcKLOCLYdLWKgFqvP82PY= (same data than v0: 1+64 bytes)
=crc24
-----END PGP SIGNATURE-----
legendary
Activity: 1428
Merit: 1093
Core Armory Developer
legendary
Activity: 1176
Merit: 1260
May Bitcoin be touched by his Noodly Appendage
Oh ok I misunderstood, I thought you wanted that for Python. I might look at that once the current problem is solved.

That problem is this one: I thought I was making mistakes in my implementation but looking at some codes I realized that there is currently not a single implementation of OpenPGP that accepts secp256k1.
I tried to add it in gnupg-ecc, but no luck yet...

So... I have done what you asked for (message signing with secp256k1 keys that follows RFC2440) but nobody can read those signatures yet.
This leads to two questions

  • 1. Is it enough to claim (a part of) the bounty? I'm not being greedy, it's just that I have other projects and I see that continuing this one (ie implementing OpenPGP verifying) will require some additional hours of work. In all cases, I'll finish and implement that verifying but the ETA's would be different.

  • 2. Say that I'm going to implement that now (bounty or not, it's more about the 'global' 'future' of secp256k1 signing with RFC2440). There's still a problem:
    • GPG needs to have the public key stored in your keyring to verify. AND that keyring doesn't accept secp256k1 keys.
    • GPG doesn't accept to verify signatures if the public key and the signature are in the same block. (Not a word about such behavior in RFCs though.)
    So, well... What should I do?
    • Create two blocks (key export + signature) ? (OK with GPG behavior BUT (1) two blocks to process: importing, then verifying, and (2) GPG doesn't support secp256k1 key import yet)
    • Stick to RFCs, break compatibility with GPG and create big signatures that contain the pubkey? (simpler to verify: only one block BUT will never work with GPG)



Anyway, I'll publish my signing code soon. This week hopefully. With both possibilities for problem 2.


PS: All this post is about Version 1 / OpenPGP signatures, not Version 0, which is done
legendary
Activity: 1428
Merit: 1093
Core Armory Developer

I do have the key recovery in my python code
Techwtf's implementation too

Okay, great. 

I mentioned expanding the Armory C++ utilities because it doesn't use OpenSSL.  It uses Crypto++.  I definitely want that code upgraded, and it might just be one night's worth of work to match the EC-math operations I already have, with the key-recovery algorithm.  Maybe a tad bit of Crypto++ doc searches looking for the needed operations.  That's worth 0.5 BTC to me.

For now, if the key recovery only works in python, that's fine.  It will fit into my interface.  I just wanted the key recovery as part of the C++ operations for other reasons.
legendary
Activity: 1176
Merit: 1260
May Bitcoin be touched by his Noodly Appendage
Thanks scintill,

That's a nice compact implementation.  I like it.  I was just looking through the code...

@jackjack

I forgot that Bitcoin-Qt uses key recovery for the signatures.  Meaning, that you only need to provide the signature, and the public key can only be one of four different values.  Thus, signature and a couple extra bits.  This is something I don't have implemented in any of libraries yet, and it doesn't look trivial.   But the code is all there in the C++ from scintill, and I am considering putting it into my own "EncryptionUtils.h/.cpp".

I assume you're not going into the C++ code in Armory...?  Just making standalone python files?  That will work for now, though I can see that having the C++ key recovery would be useful.

If you want to take a shot at implementing it in EncryptionUtils.h/.cpp, I will throw in another 0.5 BTC (on success, of course!).  I already have EC math operations available in the library.  I'm pretty sure you can do most of it with what's already there.  Though, you might have to add a sqrt-function or something (I cheated with UncompressPoint, by just letting Crypto++ do the uncompression for me, so  I didn't actually implement it).
I do have the key recovery in my python code
Techwtf's implementation too
full member
Activity: 140
Merit: 100
Here is a working bitcoin-qt compatible signer & checker in python, with ECDSA code embedded, it even supports compressed pubkeys.
https://gist.github.com/anonymous/da91bd30fa068ae4a3bb

if I'm qualified to get a proportion of the bounty: 1HFhtvzNEiy9eooLSJRMyZ1XB2FXgYGvCH. I'm still happy even not anyway.

the sign example is taken from brainwallet.org.
missing code:
Code:
import struct
def encode32(i):
  return struct.pack('
def encode64(i):
  return struct.pack('
full member
Activity: 140
Merit: 100
Here is a working bitcoin-qt compatible signer & checker in python, with ECDSA code embedded, it even supports compressed pubkeys.
https://gist.github.com/anonymous/da91bd30fa068ae4a3bb

if I'm qualified to get a proportion of the bounty: 1HFhtvzNEiy9eooLSJRMyZ1XB2FXgYGvCH. I'm still happy even not anyway.

the sign example is taken from brainwallet.org.
legendary
Activity: 1428
Merit: 1093
Core Armory Developer
Thanks scintill,

That's a nice compact implementation.  I like it.  I was just looking through the code...

@jackjack

I forgot that Bitcoin-Qt uses key recovery for the signatures.  Meaning, that you only need to provide the signature, and the public key can only be one of four different values.  Thus, signature and a couple extra bits.  This is something I don't have implemented in any of libraries yet, and it doesn't look trivial.   But the code is all there in the C++ from scintill, and I am considering putting it into my own "EncryptionUtils.h/.cpp".

I assume you're not going into the C++ code in Armory...?  Just making standalone python files?  That will work for now, though I can see that having the C++ key recovery would be useful.

If you want to take a shot at implementing it in EncryptionUtils.h/.cpp, I will throw in another 0.5 BTC (on success, of course!).  I already have EC math operations available in the library.  I'm pretty sure you can do most of it with what's already there.  Though, you might have to add a sqrt-function or something (I cheated with UncompressPoint, by just letting Crypto++ do the uncompression for me, so  I didn't actually implement it).
sr. member
Activity: 448
Merit: 254
The 1 btc additional bounty has been claimed by scintill.  He has provided a patch to the official bitcoin repo that includes a separate verifysig program.

I've rebuilt it outside of the bitcoin repo (copying over stuff it depends on) and put it on github: https://github.com/scintill/bitcoin-signature-tools .  It's a C++ command-line verifier for the bitcoin-qt bare signatures.

It's easier to build than what I gave slothbag originally and won't break if they shuffle files around in the bitcoin repo.  I've just noticed that I somehow missed the fact that slothbag asked for signing, too, and this is only verifying right now.  He paid the bounty so I guess he's happy with it Grin, but since those were the original terms he can still require me to add signing for free if he'd like.  Others can request it too, but I don't have time to make it a priority unless there's a bounty.
sr. member
Activity: 369
Merit: 250
The 1 btc additional bounty has been claimed by scintill.  He has provided a patch to the official bitcoin repo that includes a separate verifysig program.

Cheers
legendary
Activity: 1428
Merit: 1093
Core Armory Developer
Can I add to the bounty.. I need a small standalone C/C++ program written to do the same message signing/verification. I dont need the version 1 proposal, just version 0 which is compatible with bitcoin-qt.

You can copy the code from bitcoin-qt or use something like libccoin, i'm not fussed.  Just as long as its small and fast.

I can add another 1 btc for it Smiley

Sure.  I assume jackjack will be making some python blackboxes, one for each version.  I saw your other thread about this, and it does sound like a good match.  You can easily invoke the python directly.  Alternatively, I have all the ECDSA operations wrapped up nicely in the C++ code which is wrapped up in the python.  You could actually access the C++ code directly in a main.cpp file, but you do need a little bit extra to get it working.  Just a thought...

sr. member
Activity: 369
Merit: 250
Can I add to the bounty.. I need a small standalone C/C++ program written to do the same message signing/verification. I dont need the version 1 proposal, just version 0 which is compatible with bitcoin-qt.

You can copy the code from bitcoin-qt or use something like libccoin, i'm not fussed.  Just as long as its small and fast.

I can add another 1 btc for it Smiley
legendary
Activity: 1176
Merit: 1260
May Bitcoin be touched by his Noodly Appendage
OK, I'm up for that
Pages:
Jump to: