-
Notifications
You must be signed in to change notification settings - Fork 229
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
Documentation for PublicKey::verify_strict() is misleading #130
Comments
…feature. * FIXES part of dalek-cryptography#130
Hi @abacabadabacaba! Thanks for creating this issue.
I've clarified this in ad2e75f.
Yes, this is misleading, as it only applies to the batch verification equation and isn't relevant here. For that to occur, a torsion component must also be added to the public key, and the signature will probablistically falsely satisfy the batch equation. I've fixed this in 0206d0a.
Clarified in 87731f1.
Yes, I agree. This check is slower and there has been some discussion of this in #20 and #115.
This is a fair point, and I think we should be checking for non-canonical |
The documentation for
PublicKey::verify_strict()
method states that it verifies a signature in a way that eliminates signature malleability. Unfortunately, this is not what it actually does.The first point in the documentation talks about scalar malleability. As it says, both
verify
andverify_strict
check that a scalar is encoded canonically. However, iflegacy_compatibility
feature is enabled, this check is loosened for bothverify
andverify_strict
. A user can expectverify_strict
to remain strict even iflegacy_compatibility
feature is used, but this is not what happens.The second point, which talks about point malleability of R, is more misleading. First, being able to add a small-order component to R is not a source of signature malleability at all: because the value of R is hashed (together with the message and the public key), any change to R, even the addition of a torsion component, will invalidate the signature. So, anyone who is not in possession of a private key cannot change R while keeping the signature valid, just as they can't change the message. And anyone who is in possession of a private key can generate any number of distinct valid signatures of the same message by generating r randomly rather than deterministically.
By the way, the README file is also misleading in this regard. It states that "doing so allows for signature malleability, meaning that there may be two different and "valid" signatures with the same key for the same message, which is obviously incredibly dangerous", but a key holder can generate any number of such signatures that will pass even the most strict checks.
What the function does (and which is not mentioned in the documentation) is rejecting a signature if the key or R consist exclusively of a small-order torsion component. This is because they check those points using
is_small_order()
method. Is this intended? It looks likeis_torsion_free()
is more relevant here.Also,
verify_strict()
doesn't check that the encoding of R is canonical.verify()
does this implicitly, by computing the encoding of the expected value of R and comparing is with the encoding of R byte-wise. Unlikeverify()
,verify_strict()
compares unpacked points, so a point that is encoded non-canonically may go undetected (but this doesn't lead to signature malleability, see above).The text was updated successfully, but these errors were encountered: