-
Notifications
You must be signed in to change notification settings - Fork 3
Description
The Keypair:sign function in this package returns the (actually deprecated) hex / byte representation of a signature and not the noble library's Signature object. That representation unfortunately is missing the recovery bit that's required to recover the the signature's public key correctly, however. What oc works is calling the relevant ecdsa verify function with the public key if the verifier knows it at that point.
Due to the x-symmetric nature of the underlying elliptic curve this leads to at least 2 signatures being equally valid over the same (hashed) message. The EVM ecosystem considered this potentially dangerous (not by itself but for implementers) in 2015 / EIP-2 already. Library implementations (OpenZeppelin / viem) always add the recovery bit (v+27 in EVM) to the signature bytes or flip a signature to the only valid side of the curve.
Here's a gist with a happy path and the nillion variant as a starting point to test that issue: https://gist.github.com/elmariachi111/3486fde2d4746d511eb2869ac51076e3
Reading is believing:
- https://ethereum.stackexchange.com/questions/55245/why-is-s-in-transaction-signature-limited-to-n-21
- https://eips.ethereum.org/EIPS/eip-2
- (in cosmos) ECDSA/secp256r1 transaction malleability cosmos/cosmos-sdk#9723
- https://medium.com/@fabien.morrow/ecdsa-maleability-67572bc1aeef
My suggestion would be: either let Keypair:sign return
- the noble Signature object (rather my preference)
- a 65 byte representation with a trailing v-parameter (eg https://viem.sh/docs/utilities/serializeSignature#usage)
- also the recovery bit