-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarify if we want to prehash before signing messages #70
Comments
Libsodium includes a prehashing mechanism:
https://download.libsodium.org/doc/public-key_cryptography/public-key_signatures.html This can also be called explicitly:
However, I do not yet fully understand the difference between single and multi part message signing. |
As far as I know we have a few signing mode possibilities:
The first one is simplest, but has limitations if messages are large or any library enforces prehash The second one ed25519ph is recommended by libsodium, but it also seems to use a unique libsodium prehash that is not well documented, and may not be compatible with golang and ledger C implementations. The next set |
One suggestion was not to enforce one mode, but support multiple of these modes (eg. a whitelist of possible modes). Signers may chose which mode to use and return a mode flag along with the signature they produce. The verifier (golang blockchain, maybe also TS wallet) should be able to switch over mode flag and verify any of the officially supported algorithms. This is a better idea that writing a specific KeyringEntry for every mode, just a flag for the pre-processing step. And it only limits us to the set of modes than can be verified in golang. |
For secp256k1 the situation seems pretty open:
|
[bns-codec] Update sign byte calculation to match weave #70
Okay, the ledger requires a prehash. Either sha256, sha512, or keccak. So we must support it. |
I would follow the suggestion of multiple modes, and even generalize it to support multiple hashes. Concretely (in typescript):
Where We can request when signing possibly, but in any case the Keyring should return the signature with the prehashes used, so it can be verified. |
Why is prehash optional in
I think there is always a prehash. It is just a question on which abstraction level it is implemented. I think we should make the explicit in any case |
The current code (weave, bcp-demo, weave-js) doesn't prehash at all and works great. |
I would like to continue supporting signatures on non-prehashed transactions (eg. passing full sign bytes into libsodium) |
"passing full sign bytes into libsodium" means libsodium does the prehashing for you because the API is designed like that: https://github.com/jedisct1/libsodium/blob/569778b517496861a3880e0e690973bf08a52e08/src/libsodium/crypto_sign/ed25519/ref10/sign.c#L65
|
For me prehash means, I pass SHA512(m) into libsodium. |
Nice link for libsodium algorithm btw |
According to https://tools.ietf.org/html/rfc8032#section-4, However, part of Ed25519 is the ability to handle arbitrary sized input messags ( Given that, I think we can consider The situation is different for Secp256k1, where the signing algorithm itself truncates input to be smaller than N (256bit). This must never happen on unprehashed messages. |
i agree with @webmaster128 so far |
If we can avoid making prehash configurable it, I'd rather keep it uniform. libsodium suggests using The main difference between BLAKE2b and sha512 is probably flexible use (not needed in our use case) and speed (not needed in our use case). So I think we can choose whatever is more convenient to use. I like the existence of synchronous JavaScript-only implementation of sha512 that is probably fast enough for the small chunks of data you store in a blockchain. |
Since Blake2b is not an option on the Ledger, and is less supported in libraries, let's go with sha512 and make it required. I will update the backend code to perform sha512 after calculating sign bytes when verifying signatures. Then we can do that in the signers as well. Each keyring is responsible for performing the sha512 either in typescript or in hardware. |
NOTE This issue is not to do any coding, but just make a decision on our architecture
The original golang code uses https://godoc.org/golang.org/x/crypto/ed25519 which will produce the ed25519 signature of whatever we enter it. There is no prehashing here.
Every ledger code I have seen does prehashing on the transaction before signing. I am not sure if this is required, or just a convention. Maybe @rudi-cilibrasi knows better.
I did a little investigation and it seems there is a prehash step (using keccack) in ethereum as well:
When I worked on the first demo ledger app for cosmos, we had to use some flag to specify:
Needless to say this was clunky and didn't seem right. Let's discuss if we will need this prehashing step, and if so, consider doing it everywhere. This will update the signing algorithm used in
weave
,weave-js
and inweb4/@iov-keycontrol
. We can pass the unhashed sign bytes to the keyring entries so they can verify the content (eg. ledger app), but then hash before signing them.I would like some feedback here, especially anyone who has dealt with this issue before.
The text was updated successfully, but these errors were encountered: