ripple_keypairs/algorithm/
secp256k1.rs

1use std::convert::TryInto;
2
3use ring::digest;
4
5use num_bigint::{BigInt, Sign as BigIntSign};
6
7use ::secp256k1::{
8    sign, verify, Message, PublicKey as SecPublicKey, SecretKey as SecPrivateKey,
9    Signature as SecSignature,
10};
11
12use ripple_address_codec::encode_seed;
13
14use crate::{
15    error::{DeriveKeyPairError, InvalidSignature, Result},
16    utils,
17    Algorithm::Secp256k1,
18    EntropyArray, HexBytes, KeyPairResult, PrivateKey, PublicKey,
19};
20
21use super::{Key, Seed, Sign, Verify};
22
23#[derive(Debug)]
24pub(crate) struct PrivateKeyEcDsaSecP256K1;
25
26impl Sign for PrivateKeyEcDsaSecP256K1 {
27    fn sign(&self, message: &[u8], private_key: &[u8]) -> HexBytes {
28        let (signature, _) = sign(
29            &prepare_message(message),
30            &SecPrivateKey::parse_slice(private_key).unwrap(),
31        );
32
33        HexBytes::from_bytes(&signature.serialize_der())
34    }
35}
36
37impl Key for PrivateKeyEcDsaSecP256K1 {
38    fn key_lenght(&self) -> usize {
39        Self::LENGHT
40    }
41
42    fn prefix(&self) -> &[u8] {
43        Self::PREFIX
44    }
45}
46
47impl PrivateKeyEcDsaSecP256K1 {
48    const LENGHT: usize = 32;
49    const PREFIX: &'static [u8] = &[0x00];
50}
51
52#[derive(Debug)]
53pub(crate) struct PublicKeyEcDsaSecP256K1;
54
55impl Verify for PublicKeyEcDsaSecP256K1 {
56    fn verify(&self, message: &[u8], signature: &[u8], public_key: &[u8]) -> Result<()> {
57        let message = &prepare_message(message);
58        let signature = &SecSignature::parse_der(signature)?;
59        let mut compressed = [0; Self::LENGHT];
60        compressed.copy_from_slice(public_key);
61        let pubkey = &SecPublicKey::parse_compressed(&compressed).unwrap();
62
63        match verify(message, signature, pubkey) {
64            true => Ok(()),
65            false => Err(InvalidSignature),
66        }
67    }
68}
69
70impl Key for PublicKeyEcDsaSecP256K1 {
71    fn key_lenght(&self) -> usize {
72        Self::LENGHT
73    }
74
75    fn prefix(&self) -> &[u8] {
76        Self::PREFIX
77    }
78}
79
80impl PublicKeyEcDsaSecP256K1 {
81    const LENGHT: usize = 33;
82    const PREFIX: &'static [u8] = &[];
83}
84
85#[derive(Debug)]
86pub(crate) struct SeedEcDsaSecP256K1;
87
88impl Seed for SeedEcDsaSecP256K1 {
89    fn derive_keypair(&self, entropy: &EntropyArray) -> KeyPairResult {
90        let private_key_bytes = Self::derive_private_key(entropy).ok_or(DeriveKeyPairError)?;
91
92        let private_key =
93            SecPrivateKey::parse(&private_key_bytes).map_err(|_| DeriveKeyPairError)?;
94        let public_key = SecPublicKey::from_secret_key(&private_key);
95        let public_key_bytes = public_key.serialize_compressed();
96
97        let kind = &Secp256k1;
98
99        Ok((
100            PrivateKey {
101                bytes: private_key_bytes.into(),
102                kind,
103            },
104            PublicKey {
105                bytes: public_key_bytes.into(),
106                kind,
107            },
108        ))
109    }
110
111    fn encode(&self, entropy: &EntropyArray) -> String {
112        encode_seed(entropy, &Secp256k1)
113    }
114}
115
116type PrivateKeyBytes = [u8; PrivateKeyEcDsaSecP256K1::LENGHT];
117
118impl SeedEcDsaSecP256K1 {
119    // There is no pub const for order `n` in dependency `libsecp256k1`,
120    // so define it here
121    fn order_n() -> BigInt {
122        let n = b"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141";
123
124        BigInt::parse_bytes(n, 16).unwrap()
125    }
126
127    fn derive_scalar(bytes: &[u8], discrim: Option<u32>) -> BigInt {
128        let order = Self::order_n();
129
130        for i in 0..=0xffffffff as u32 {
131            let mut hasher = digest::Context::new(&digest::SHA512);
132
133            hasher.update(bytes);
134
135            if let Some(d) = discrim {
136                hasher.update(&d.to_be_bytes());
137            }
138
139            hasher.update(&i.to_be_bytes());
140
141            let key = BigInt::from_bytes_be(
142                BigIntSign::Plus,
143                &hasher.finish().as_ref()[..PrivateKeyEcDsaSecP256K1::LENGHT],
144            );
145
146            if key > 0.into() && key < order {
147                return key;
148            }
149        }
150
151        // This line is practically impossible to reach
152        unreachable!();
153    }
154
155    fn derive_private_key(bytes: &EntropyArray) -> Option<PrivateKeyBytes> {
156        let order = Self::order_n();
157
158        let private_gen = Self::derive_scalar(bytes, None);
159
160        let private_bytes = Self::big_int_to_private_key_bytes(&private_gen);
161
162        let private_key = SecPrivateKey::parse(&private_bytes).ok()?;
163        let public_key = SecPublicKey::from_secret_key(&private_key);
164
165        let public = Self::derive_scalar(&public_key.serialize_compressed(), Some(0));
166
167        let result = (public + private_gen) % order;
168
169        Some(Self::big_int_to_private_key_bytes(&result))
170    }
171
172    fn big_int_to_private_key_bytes(big_int: &BigInt) -> PrivateKeyBytes {
173        HexBytes::from_hex_unchecked(&format!("{:064X}", big_int))
174            .as_bytes()
175            .try_into()
176            .unwrap()
177    }
178}
179
180fn prepare_message(message: &[u8]) -> Message {
181    let message_hash = utils::sha512_digest_32(message);
182
183    Message::parse_slice(&message_hash).unwrap()
184}
185
186#[cfg(test)]
187mod tests {
188    use super::*;
189
190    #[test]
191    fn small_big_int_to_32_bytes() {
192        let big_int: BigInt = 1.into();
193
194        assert_eq!(
195            SeedEcDsaSecP256K1::big_int_to_private_key_bytes(&big_int),
196            [
197                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
198                0, 0, 0, 1
199            ]
200        );
201    }
202}