-
Notifications
You must be signed in to change notification settings - Fork 1k
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
ecdsa sign-to-contract module, with anti nonce covert chan util functions #669
Conversation
I added a commit ( Seeing this, after fixing up some cosmetics, I would prefer this alternative. |
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.
The approach in this alternative looks good. I didn't find any obvious critical vulnerabilities. It passes valgrind and coverage looks good. Being able to subsume recovery into the signing helper is a nice bonus.
Some of the things in this PR don't make much sense anymore because we're using a different public key type for schnorrsigs (xonly_pubkey
) and therefore there's no reason anymore to have a unified s2c_opening for both ecdsa and schnorr. Also, the ec_commit functions don't apply to xonly_pubkey
. I will rip this out of my PR and see if there's still some code that can be shared.
I'm wondering if a stable s2c api should allow the callers to provide their own hash function through a callback for example to create tagged hashes.
As an aside, this PR taken on its own lacks a detailed explanation for how it works. There is a more detailed writeup in my PR and I don't think we need both the protocol steps in this PR + the more detailed writeup.
There are some api artefacts in this PR (shared with mine) which are not ideal. For example secp256k1_pubkey *client_commit
which isn't a pubkey (but a point).
return 0; | ||
} | ||
|
||
/* Check that sigr (x coordinate of R) matches the x coordinate of the commitment. */ |
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.
nit: stress somehow that sigr is a scalar and the x coordinate of the commitment is a field element. I overlooked it at first. Also that sig[0:32] could be greater than the group order and signature_load won't complain. Perhaps `Check that sigr (x coordinate of R represented by a scalar) matches the x coordinate of the commitment (field element). Note that sig[0:32] can be greater than group order and therefore sigr will be reduced. But in that case ecdsa_verify doesn't pass"
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.
More importantly, there needs to be a sentence explaining why comparing the x coordinate is sufficient. For example, because there's only two y coordinates per x coordinate and given an opening for a point, it's as difficult finding an opening to the negation of the point as to any other point. However, I do think there's some reduction in security because it's more likely to find a collision with a point and it's negation.
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.
nit: stress somehow that sigr is a scalar and the x coordinate of the commitment is a field element.
Will do, though I thought that was clear as it is the same way with regular ecdsa verification.
Note that sig[0:32] can be greater than group order and therefore sigr will be reduced. But in that case ecdsa_verify doesn't pass
That is not true, is it? ecdsa_verify can still pass in this case, as the condition is sig_r == x (mod n)
(the field element x
is also reduced modulo n
).
In the current code a few lines down, there actually might be a "mistake": we memory-compare the byte representation of the scalar sigr
and the field element x
, without first reducing x modulo n
, which might fail for actually valid commitments with very low (negligible) probability.
Shouldn't this be implemented the same way as the actual secp256k1_ecdsa_verify()
? Basically convert the field element x
to a scalar and use secp256k1_scalar_eq()
instead of memcmp
, like here:
Lines 236 to 238 in 074ab58
secp256k1_fe_get_b32(c, &pr_ge.x); | |
secp256k1_scalar_set_b32(&computed_r, c, NULL); | |
return secp256k1_scalar_eq(sigr, &computed_r); |
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.
edit: seems like secp256k1_scalar_set_b32()
reduces modulo n
Generally a bit confused, I don't see "modulo n" reduction happening in signing nor verification despite it being part of the algorithm as described here:
https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm
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.
Added one commit to extend the comment, and one to change to secp256k1_scalar_eq()
to properly compare the values modulo n
. The second comment about the reduced security will follow soon.
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.
More importantly, there needs to be a sentence explaining why comparing the x coordinate is sufficient. For example, because there's only two y coordinates per x coordinate and given an opening for a point, it's as difficult finding an opening to the negation of the point as to any other point. However, I do think there's some reduction in security because it's more likely to find a collision with a point and it's negation.
Done.
93067b1
to
ab49ce1
Compare
Rebased and addressed some comments; I will take care of the others soon. |
ab49ce1
to
e2728ee
Compare
ceedfca
to
ffc0872
Compare
Let me know what to do - I'm okay to move the opening to the module, or keep it as it is and let you figure out what can be reused in your PR (if this PR is merged first).
My feeling is that we should keep it simple for now and move towards merging. If someone comes up with the need for this, I'd be happy to extend it then. It wouldn't be an invasive API change, so clients could update easily.
Maybe once both PRs are merged, we can move the description to |
ffc0872
to
642fb4a
Compare
…eaks of public keys. The functionality is not exposed.
Sign a message while comitting to some data at the same time by by adding `hash(k1*G, data)` to the rfc6979 deterministic nonce. Includes verification function to check that the signature commits to the data.
The body of the recovery sign function is 99% the same secp256k1_ecdsa_sign. Now that this has moved to the sign helper, it can be re-used not only by the sign-to-contract module, but also by the recovery module.
642fb4a
to
1a0f2ed
Compare
Rebased / fixed conflicts. @jonasnick any chance of getting this merged soon? :) |
I think we can merge this into -zkp soon. I have BlockstreamResearch/secp256k1-zkp#111. If you do your own rebase it might be easier to start from that since I did the work of combing the new unified ecdsa/recovery code with this PR's implementation of the same thing. |
😍 😍 😍 I will make time for this as soon as I can. Been eager to get this working in production for a long time. Edit: I did not realize that your PR is already there and rebased. Great. |
This PR was rebased and reopened at BlockstreamResearch/secp256k1-zkp#111, where review and improvements continue. |
47efb5e ecdsa-s2c: add ctime tests (Andrew Poelstra) 396b558 ecdsa-s2c: add anti-klepto protocol (Andrew Poelstra) 290dee5 ecdsa-s2c: add actual sign-to-contract functionality (Andrew Poelstra) 8e46cac ecdsa-s2c: block in module (Andrew Poelstra) 826bd04 add eccommit functionality (Andrew Poelstra) Pull request description: This is a backport and rebase of bitcoin-core/secp256k1#669 ACKs for top commit: jonasnick: ACK 47efb5e real-or-random: ACK 47efb5e Tree-SHA512: e1f3ee3985bc77197eb57c03884b5d4a5f8733523bba50e11309f86388471c6265b7241e9856e1b80a88f4c268f2826c0394e26161292aa438b2246a1ad86aa1
Alternative to #637, where the main s2c signing function lives in
secp256k1.c
. See this thread for some discussion about this: #637 (comment)