You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// High-S signatures require normalization since our verification implementation
59
+
// rejects them by default. If we had a verifier that does not restrict to
60
+
// low-S only, this step was not needed.
53
61
ifletSome(normalized) = signature.normalize_s(){
54
62
signature = normalized;
55
63
}
@@ -74,6 +82,22 @@ pub fn secp256k1_verify(
74
82
///
75
83
/// Returns the recovered pubkey in compressed form, which can be used
76
84
/// in secp256k1_verify directly.
85
+
///
86
+
/// This implementation accepts both high-S and low-S signatures. This is the
87
+
/// same behavior as Ethereum's `ecrecover`. The reason is that high-S signatures
88
+
/// may be perfectly valid if the application protocol does not disallow them.
89
+
/// Or as [EIP-2] put it "The ECDSA recover precompiled contract remains unchanged
90
+
/// and will keep accepting high s-values; this is useful e.g. if a contract
91
+
/// recovers old Bitcoin signatures.".
92
+
///
93
+
/// See also OpenZeppilin's [ECDSA.recover implementation](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.1/contracts/utils/cryptography/ECDSA.sol#L138-L149)
94
+
/// which adds further restrictions to avoid potential siganture maleability.
95
+
/// Please note that restricting signatures to low-S does not make signatures unique
96
+
/// in the sense that for each (pubkey, message) there is only one signature. The
97
+
/// signer can generate an arbitrary amount of valid signatures.
// Test data from https://github.com/randombit/botan/blob/2.9.0/src/tests/data/pubkey/ecdsa_key_recovery.vec
350
+
// This is a high-s value (`0x81F1A4457589F30D76AB9F89E748A68C8A94C30FE0BAC8FB5C0B54EA70BF6D2F > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0` is true)
330
351
{
331
352
let expected_x = "F3F8BB913AA68589A2C8C607A877AB05252ADBD963E1BE846DDEB8456942AEDC";
332
353
let expected_y = "A2ED51F08CA3EF3DAC0A7504613D54CD539FC1B3CBC92453CD704B6A2D012B2C";
@@ -349,6 +370,32 @@ mod tests {
349
370
let pubkey = secp256k1_recover_pubkey(&message_hash,&r_s, recovery_param).unwrap();
350
371
assert_eq!(pubkey, expected);
351
372
}
373
+
374
+
let file = File::open(COSMOS_SECP256K1_TESTS_JSON).unwrap();
375
+
let reader = BufReader::new(file);
376
+
let codes:Vec<Encoded> = serde_json::from_reader(reader).unwrap();
377
+
for(i, encoded)in(1..).zip(codes){
378
+
let message = hex::decode(&encoded.message).unwrap();
379
+
let signature = hex::decode(&encoded.signature).unwrap();
380
+
let public_key = hex::decode(&encoded.public_key).unwrap();
381
+
382
+
let hash = hex::decode(&encoded.message_hash).unwrap();
0 commit comments