-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
TL;DR: Do we want the following to be an invariant of signature.Equal: It returns true for two signatures which are both valid for a given public key and message pair. If we want this to be an invariant we have to mildly adapt the equality implementation for secp256k1.
Secp256k1's signing algorithm is ecdsa. In ecdsa, the signature is of the form (r,s). However anyone given a valid signature on a message can produce a second valid signature (r, -s). So both of these signatures are valid, but have different byte representations.
Currently we load secp256k1 signatures directly from its bytes, and then check equality by checking if the byte representations are equal. However two valid signatures may not be considered equal currently. I think it may be easiest for future functionality to consider these as equal. This is also related to #1664. As far as I can tell, the downsides of this are that we've deviated slightly from the standard, but I'm unsure of how important that is in this case, and that decoding bytes to signature takes a bit more time. The upside is its one less attack / bug vector to be concerned about in downstream usage.
Other alternatives are to adapt the verify method to reject an ecdsa signature whose s is not in canonical form, or to have all validators force convert all s parameters into canonical form. (Canonical as being the smaller value within the finite field)
Of course, this only needs to be changed if this malleability is an issue. (I.e. Perhaps if a certain signature hash is expected)
/cc @ebuchman