defuse_crypto/curve/
secp256k1.rs

1use near_sdk::{CryptoHash, env};
2
3use super::{Curve, CurveType, TypedCurve};
4
5pub struct Secp256k1;
6
7impl Curve for Secp256k1 {
8    type PublicKey = [u8; 64];
9
10    /// Concatenated `r`, `s` and `v` (recovery byte).
11    ///
12    /// Note: Ethereum clients shift the recovery byte and this
13    /// logic might depend on chain id, so clients must rollback
14    /// these changes to v ∈ {0, 1}.
15    /// References:
16    /// * <https://github.com/ethereumjs/ethereumjs-monorepo/blob/dc7169c16df6d36adeb6e234fcc66eb6cfc5ea3f/packages/util/src/signature.ts#L31-L62>
17    /// * <https://github.com/ethereum/go-ethereum/issues/19751#issuecomment-504900739>
18    type Signature = [u8; 65];
19
20    // Output of cryptographic hash function
21    type Message = CryptoHash;
22
23    /// ECDSA signatures are recoverable, so you don't need a verifying key
24    type VerifyingKey = ();
25
26    #[inline]
27    fn verify(
28        [signature @ .., v]: &Self::Signature,
29        hash: &Self::Message,
30        _verifying_key: &(),
31    ) -> Option<Self::PublicKey> {
32        env::ecrecover(
33            hash, signature, *v,
34            // Do not accept malleable signatures:
35            // https://github.com/near/nearcore/blob/d73041cc1d1a70af4456fceefaceb1bf7f684fde/core/crypto/src/signature.rs#L448-L455
36            true,
37        )
38    }
39}
40
41impl TypedCurve for Secp256k1 {
42    const CURVE_TYPE: CurveType = CurveType::Secp256k1;
43}