-
Notifications
You must be signed in to change notification settings - Fork 223
Require message in musig protocol in an earlier state #73
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
Require message in musig protocol in an earlier state #73
Conversation
|
Oh nice observation. That the message is fixed upfront is apparently not an artefact of the formal model either... Concept ACK. |
real-or-random
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good except the nits. I haven't tested it yet.
| const secp256k1_pubkey *combined_pk, | ||
| const unsigned char *pk_hash32, | ||
| const unsigned char *const *commitments, | ||
| size_t n_signers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(not touched by this PR:) maybe we can use ARG_CHECK also for the restrictions on n_signers
src/modules/musig/tests_impl.h
Outdated
| CHECK(secp256k1_musig_session_get_public_nonce(ctx, &session, signers, &nonce, ncs, 2) == 1); | ||
|
|
||
| /* Trying to get the nonce without providing a message fails. */ | ||
| CHECK(secp256k1_musig_session_get_public_nonce(ctx, &session, signers, &nonce, ncs, 2, NULL) == 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we ARG_CHECK this violation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the rationale for ARG_CHECKing is still "everything that the rust typesystem would have caught" then I guess no.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could prevent this with session types, i.e. have a Session<NonceUnset> and Session<NonceSet>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered this but thought that this is not exactly the rust type system as you could do something similar with C. But actually this is what we'll be doing in rust. Fixing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
e940896 to
f215a4c
Compare
|
ACK read the code, but did not test it |
| * require sharing public nonces before the message is known | ||
| * because it reduces nonce misuse resistance. If NULL, must be | ||
| * set with `musig_session_set_msg` before signing and verifying. | ||
| * set with `musig_session_get_public_nonce`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably cut this comment down even further to get rid of the "unless you require" clause.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, not sure what exactly you're suggesting. Something like that?
* msg32: the 32-byte message to be signed. Shouldn't be NULL. If NULL, must be
* set with `musig_session_get_public_nonce`.
Seems to be less clear. Also I assume sharing nonce commitments won't be a very exotic thing. Lightning will likely use it to avoid roundtrips. I have an open PR in the scriptless scripts repo (BlockstreamResearch/scriptless-scripts#6) that explains how to do this because I was contacted by someone concerned that MuSig will end up being very expensive in communication costs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if you change "require sharing public nonces" to "require sharing nonce commitments" I'll be happy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
src/modules/musig/tests_impl.h
Outdated
| /* Providing a message should make get_public_nonce succeed. */ | ||
| CHECK(secp256k1_musig_session_get_public_nonce(ctx, &session, signers, &nonce, ncs, 2, msg) == 1); | ||
| /* Trying to set the message again fails. */ | ||
| CHECK(secp256k1_musig_session_get_public_nonce(ctx, &session, signers, &nonce, ncs, 2, msg) == 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a strong opinion but I feel like this should also be an ARG_CHECK (and that rust-secp should prevent it statically)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By using something like a state machine/session types? Yes, fixing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
|
I see a bunch of stuff when I run Edit: oh for some reason I'm compiling with openssl, that's probably all it is. (Which means some broken Arch package must have depended on openssl recently, because it definitely was not installed before..) |
f215a4c to
b934674
Compare
b934674 to
6a57be0
Compare
|
rebased |
remove the set_msg function and require the message in get_public_nonce at the latest.
|
ping @apoelstra |
|
ACK 6a57be0 |
|
ACK 6a57be0 |
This PR removes the
set_msgfunction from the musig module and adds amsgargumentget_public_noncewhich must be non-null if the message has not been set during initialization.The reason for this is that I think that our current
set_msglogic is vulnerable to Wagner's attack. The main problem is that by grinding the message an attacker has control over the final hash being signed.Assume the combined pubkey of Alice and the attacker is
P.The attacker wants to forge a signature on message
m'and opens 3 parallel sessions with Alice.They exchange nonce commitments and nonces.
Let's call the combined nonces
Rifor sessionsi = 0,1,2.Now the attacker draws
kaand setsR' = R0 + R1 + R2 + ka*Gand runs Wagner's algorithm grindingmito findwith about
2^100work (with more parallel sessions requires much less work).Then the attacker and Alice set the message in session
itomiand Alice creates partial signaturessi = ki + H(P, Ri, mi).Now
(R', s' = s0 + s1 + s2)is a valid partial signature under Alice's public keyAas well:This signature is completed by the attacker adding the partial signature using nonce
kawhich results in the forgery.This PR does keeps allows to set the message after nonce commitments have been exchanged, unfortunately the possibility of pre-sharing nonces while not knowing the messages is removed.