ripple_keypairs/algorithm/
secp256k1.rs1use 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 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 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}