Description
For both signature generation and verification, k256
doesn't seem to handle the case where the y
coordinate of the public key is odd. I guess it is implicitly assuming that the user handles this, but this doesn't match how BIP340 describes the operation.
-
When signing BIP340 specifies that the secret key is negated, if the
y
coordinate ofG*sk
would otherwise be odd.k256
doesn't do this, leading it to produce incorrect signatures for half of all secret keys. -
BIP340 defines verification as taking
pk
the 32-byte encoding of just thex
coordinate. It then verifies on the assumption that they
coordinate is the even one. Howeverk256
seems to assume/require that the public key is a point with bothx
andy
coordinates, andy
is even; thenk256::schnorr::VerifyingKey::try_from
rejects points with odd y. My understanding is that in such a case, the verification key does exist/is well formed; it just is the negation of the input point.
Both issues can be worked around by checking in advance if an odd y
would occur and inverting the private or public key before use.