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
Allow the output of NonceAgg to be infinity #21
Conversation
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.
Concept ACK
It might be worth making a bigger deal about the modified serialization format that can handle infinity.
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.
ACK e2bc4e1
Rebased (which required separating the parts of the inf_aggnonce_test and moving them into the existing tests) and added commit to fix #14. |
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.
Here are a few nits.
Ensuring associativity in NonceAgg is certainly an improvement. But I'd like to think about this exact approach a little bit more before ACKing this. When I proposed this, what I had in mind is that b
will still ensure that the final nonce cannot be infinity but that's obviously wrong...
ACK on the commit addressing the nits
So the PR currently switches to a variant of the scheme where the final nonce There's another possible variant, where we replace Pros:
Cons:
I slightly lean towards this variant. It will be nice to hear your opinions on this. By the way, I'm not exactly sure how either of these variants interact with adaptor sigs. I think both are fine but it would be nice to hear your comments. |
Pro:
Con:
(*) If non-signer Charlie would forget the "aggnonce != bytes(66,0)" check but has valid partial signatures with final nonce equal to infinity, he can still proceed! That's because Charlie knows the secret nonce of the signature (0), can extract the secret key from the sum of the partial signatures and create a Schnorr signature himself. But I suppose we don't want to create an API for this. |
Lol, in principle we could also keep |
To help imagine the consequences, I added a commit that implements the |
Converted the whole PR to the |
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.
ACK mod nits
bip-musig2.mediawiki
Outdated
Given a successful adversary against the security game (EUF-CMA) for the modified scheme, a reduction can win the security game for the original scheme by simulating the modification towards the adversary. | ||
When the adversary provides ''aggnonce' '' such that ''R' '' in ''GetSessionValues'' is the point at infinity, the reduction sets ''aggnonce = cbytes_extended(G) || bytes(33, 0)''. | ||
For any other ''aggnonce' '', the reduction sets ''aggnonce = aggnonce' ''. |
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 the reduction would be clearer if it turned aggnonce' = bytes(33, 0) || bytes(33, 0)
into aggnonce = cbytes_extended(G) || bytes(33, 0)
. This is equivalent to your proposal because the only way to reach R'=0
is aggnonce' = bytes(33, 0) || bytes(33, 0)
(except with negligible probability) but it's more direct. Suggestion:
Given a successful adversary against the security game (EUF-CMA) for the modified scheme, a reduction can win the security game for the original scheme by simulating the modification towards the adversary. | |
When the adversary provides ''aggnonce' '' such that ''R' '' in ''GetSessionValues'' is the point at infinity, the reduction sets ''aggnonce = cbytes_extended(G) || bytes(33, 0)''. | |
For any other ''aggnonce' '', the reduction sets ''aggnonce = aggnonce' ''. | |
Given a successful adversary against the unforgeability game (EUF-CMA) for the modified scheme, a reduction can win the unforgeability game for the original scheme by simulating the modification towards the adversary: | |
When the adversary provides ''aggnonce' = bytes(33, 0) || bytes(33, 0)'', the reduction sets ''aggnonce = cbytes_extended(G) || bytes(33, 0)''. | |
For any other ''aggnonce' '', the reduction sets ''aggnonce = aggnonce' ''. | |
(The case that the adversary provides an ''aggnonce' ≠ bytes(33, 0) || bytes(33, 0) '' but nevertheless ''R' '' in ''GetSessionValues'' is the point at infinity happens only with negligible probability.) |
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.
Good point. Done
bip-musig2.mediawiki
Outdated
The <code>MINOR</code> version is incremented whenever the inputs or the output of an algorithm changes in a backward-compatible way or new backward-compatible functionality is added. | ||
The <code>PATCH</code> version is incremented for other changes that are noteworthy (bug fixes, test vectors, important clarifications, etc.). | ||
|
||
* '''0.4.0''' (2022-06-09): Allow the output of NonceAgg to be infinity and add test vectors |
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.
(maybe update this)
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.
ok
bip-musig2.mediawiki
Outdated
If it happens that ''is_infinite(R'<sub>i</sub>)'' inside ''[[#NonceAgg infinity|NonceAgg]]'' there is at least one dishonest signer (except with negligible probability). | ||
If we fail here, we will never be able to determine who it is. | ||
Therefore, we continue so that the culprit is revealed when collecting and verifying partial signatures. | ||
If it happens that ''is_infinite(R')'' inside ''[[#NonceAgg infinity|GetSessionValues]]'', either the nonce aggregator is dishonest or there is at least one dishonest signer (except with negligible probability). |
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 nonce aggregator is dishonest, then strictly speaking, it doesn't make sense to talk about it running the honest "GetSessionValues" algorithm, so I think it's better to drop the sentence.
Maybe a better way is to rephrase it using the aggnonce:
If it happens that ''is_infinite(R')'' inside ''[[#NonceAgg infinity|GetSessionValues]]'', either the nonce aggregator is dishonest or there is at least one dishonest signer (except with negligible probability). | |
If it happens ''aggnonce = bytes(33,0) || bytes(33,0)'' for the aggregate nonce returned by the signature aggregator, either the nonce aggregator is dishonest or there is at least one dishonest signer (except with negligible probability). |
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 applied your suggestion (after slightly rephrasing it). Do you still propose to drop a sentence?
bip-musig2.mediawiki
Outdated
If the signer aborted in this case, it would be impossible to determine who is dishonest. | ||
Therefore, the signer continues so that the culprit is revealed when collecting and verifying partial signatures. |
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:
If the signer aborted in this case, it would be impossible to determine who is dishonest. | |
Therefore, the signer continues so that the culprit is revealed when collecting and verifying partial signatures. | |
If the signing aborted in this case, it would be impossible to determine who is dishonest. | |
Therefore, the signing continues so that the culprit is revealed when collecting and verifying partial signatures. |
or could also say "the signers". I just thought that "the signer" is a little bit misleading. (Which signer?)
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.
ok
bip-musig2.mediawiki
Outdated
However, the final nonce ''R'' of a BIP340 Schnorr signature can not be the point at infinity. | ||
If this specification would nonetheless allow the final nonce to be the point at infinity, then the scheme would lose the following property: | ||
if ''PartialSigVerify'' succeeds for all partial signatures then ''PartialSigAgg'' will return a valid Schnorr signature. |
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.
grammar nits:
However, the final nonce ''R'' of a BIP340 Schnorr signature can not be the point at infinity. | |
If this specification would nonetheless allow the final nonce to be the point at infinity, then the scheme would lose the following property: | |
if ''PartialSigVerify'' succeeds for all partial signatures then ''PartialSigAgg'' will return a valid Schnorr signature. | |
However, the final nonce ''R'' of a BIP340 Schnorr signature cannot be the point at infinity. | |
If this specification would nonetheless allow the final nonce to be the point at infinity, then the scheme would lose the following property: | |
if ''PartialSigVerify'' succeeds for all partial signatures, then ''PartialSigAgg'' will return a valid Schnorr signature. |
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.
done
bip-musig2.mediawiki
Outdated
* Let ''R<sub>1</sub> = cpoint_extended(aggnonce[0:33]), R<sub>2</sub> = cpoint_extended(aggnonce[33:66])''; fail if that fails | ||
* Let ''R' = R<sub>1</sub> + b⋅R<sub>2</sub>'' | ||
* If ''is_infinite(R'): | ||
** <div id="NonceAgg infinity"></div>Let ''R = G'' (see [[#dealing-with-infinity-in-nonce-aggregation|Dealing with Infinity in Nonce Aggregation]]) |
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.
** <div id="NonceAgg infinity"></div>Let ''R = G'' (see [[#dealing-with-infinity-in-nonce-aggregation|Dealing with Infinity in Nonce Aggregation]]) | |
** Let ''R = G'' (see [[#dealing-with-infinity-in-nonce-aggregation|Dealing with Infinity in Nonce Aggregation]]) |
(could drop this div in case you accept the suggestion below)
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.
yeah
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.
ACK 20ba031
Fixes #20 and #14