1use crate::{Error, SECP256K1};
18use cfx_crypto::{crypto::Error as CryptoError, SecretKey as CryptoSecretKey};
19use cfx_types::H256;
20use malloc_size_of_derive::MallocSizeOf as DeriveMallocSizeOf;
21use secp256k1::{constants::SECRET_KEY_SIZE as SECP256K1_SECRET_KEY_SIZE, key};
22use std::{fmt, ops::Deref, str::FromStr};
23use zeroize::Zeroize;
24
25#[derive(Clone, PartialEq, Eq, DeriveMallocSizeOf)]
26pub struct Secret {
27 inner: H256,
28}
29
30impl Drop for Secret {
31 fn drop(&mut self) { self.inner.0.zeroize() }
32}
33
34impl fmt::LowerHex for Secret {
35 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
36 self.inner.fmt(fmt)
37 }
38}
39
40impl fmt::Debug for Secret {
41 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
42 self.inner.fmt(fmt)
43 }
44}
45
46impl fmt::Display for Secret {
47 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
48 write!(
49 fmt,
50 "Secret: 0x{:x}{:x}..{:x}{:x}",
51 self.inner[0], self.inner[1], self.inner[30], self.inner[31]
52 )
53 }
54}
55
56impl Secret {
57 pub fn from_slice(key: &[u8]) -> Option<Self> {
60 if key.len() != 32 {
61 return None;
62 }
63 let mut h = H256::zero();
64 h.as_bytes_mut().copy_from_slice(&key[0..32]);
65 Some(Secret { inner: h })
66 }
67
68 pub fn import_key(key: &[u8]) -> Result<Self, Error> {
69 let k = Self::from_slice(key).ok_or(Error::InvalidSecret)?;
70 k.check_validity()?;
71 Ok(k)
72 }
73
74 pub fn zero() -> Self {
77 Secret {
78 inner: H256::zero(),
79 }
80 }
81
82 pub fn from_unsafe_slice(key: &[u8]) -> Result<Self, Error> {
84 let secret = key::SecretKey::from_slice(&super::SECP256K1, key)?;
85 Ok(secret.into())
86 }
87
88 pub fn check_validity(&self) -> Result<(), Error> {
90 self.to_secp256k1_secret().map(|_| ())
91 }
92
93 pub fn add(&mut self, other: &Secret) -> Result<(), Error> {
95 match (self.is_zero(), other.is_zero()) {
96 (true, true) | (false, true) => Ok(()),
97 (true, false) => {
98 *self = other.clone();
99 Ok(())
100 }
101 (false, false) => {
102 let mut key_secret = self.to_secp256k1_secret()?;
103 let other_secret = other.to_secp256k1_secret()?;
104 key_secret.add_assign(&SECP256K1, &other_secret)?;
105
106 *self = key_secret.into();
107 Ok(())
108 }
109 }
110 }
111
112 pub fn sub(&mut self, other: &Secret) -> Result<(), Error> {
114 match (self.is_zero(), other.is_zero()) {
115 (true, true) | (false, true) => Ok(()),
116 (true, false) => {
117 *self = other.clone();
118 self.neg()
119 }
120 (false, false) => {
121 let mut key_secret = self.to_secp256k1_secret()?;
122 let mut other_secret = other.to_secp256k1_secret()?;
123 other_secret.mul_assign(&SECP256K1, &key::MINUS_ONE_KEY)?;
124 key_secret.add_assign(&SECP256K1, &other_secret)?;
125
126 *self = key_secret.into();
127 Ok(())
128 }
129 }
130 }
131
132 pub fn dec(&mut self) -> Result<(), Error> {
134 match self.is_zero() {
135 true => {
136 *self = key::MINUS_ONE_KEY.into();
137 Ok(())
138 }
139 false => {
140 let mut key_secret = self.to_secp256k1_secret()?;
141 key_secret.add_assign(&SECP256K1, &key::MINUS_ONE_KEY)?;
142
143 *self = key_secret.into();
144 Ok(())
145 }
146 }
147 }
148
149 pub fn mul(&mut self, other: &Secret) -> Result<(), Error> {
151 match (self.is_zero(), other.is_zero()) {
152 (true, true) | (true, false) => Ok(()),
153 (false, true) => {
154 *self = Self::zero();
155 Ok(())
156 }
157 (false, false) => {
158 let mut key_secret = self.to_secp256k1_secret()?;
159 let other_secret = other.to_secp256k1_secret()?;
160 key_secret.mul_assign(&SECP256K1, &other_secret)?;
161
162 *self = key_secret.into();
163 Ok(())
164 }
165 }
166 }
167
168 pub fn neg(&mut self) -> Result<(), Error> {
170 match self.is_zero() {
171 true => Ok(()),
172 false => {
173 let mut key_secret = self.to_secp256k1_secret()?;
174 key_secret.mul_assign(&SECP256K1, &key::MINUS_ONE_KEY)?;
175
176 *self = key_secret.into();
177 Ok(())
178 }
179 }
180 }
181
182 pub fn inv(&mut self) -> Result<(), Error> {
184 let mut key_secret = self.to_secp256k1_secret()?;
185 key_secret.inv_assign(&SECP256K1)?;
186
187 *self = key_secret.into();
188 Ok(())
189 }
190
191 pub fn pow(&mut self, pow: usize) -> Result<(), Error> {
194 if self.is_zero() {
195 return Ok(());
196 }
197
198 match pow {
199 0 => *self = key::ONE_KEY.into(),
200 1 => (),
201 _ => {
202 let c = self.clone();
203 for _ in 1..pow {
204 self.mul(&c)?;
205 }
206 }
207 }
208
209 Ok(())
210 }
211
212 pub fn to_secp256k1_secret(&self) -> Result<key::SecretKey, Error> {
214 Ok(key::SecretKey::from_slice(&SECP256K1, &self[..])?)
215 }
216
217 pub fn to_hex(&self) -> String { format!("{:x}", self.inner) }
218}
219
220impl FromStr for Secret {
221 type Err = Error;
222
223 fn from_str(s: &str) -> Result<Self, Self::Err> {
224 Ok(H256::from_str(s)
225 .map_err(|e| Error::Custom(format!("{:?}", e)))?
226 .into())
227 }
228}
229
230impl From<[u8; 32]> for Secret {
231 fn from(k: [u8; 32]) -> Self { Secret { inner: H256(k) } }
232}
233
234impl From<H256> for Secret {
235 fn from(s: H256) -> Self { s.0.into() }
236}
237
238impl From<&'static str> for Secret {
239 fn from(s: &'static str) -> Self {
240 s.parse().unwrap_or_else(|_| {
241 panic!("invalid string literal for {}: '{}'", stringify!(Self), s)
242 })
243 }
244}
245
246impl From<key::SecretKey> for Secret {
247 fn from(key: key::SecretKey) -> Self {
248 let mut a = [0; SECP256K1_SECRET_KEY_SIZE];
249 a.copy_from_slice(&key[0..SECP256K1_SECRET_KEY_SIZE]);
250 a.into()
251 }
252}
253
254impl Deref for Secret {
255 type Target = H256;
256
257 fn deref(&self) -> &Self::Target { &self.inner }
258}
259
260impl AsRef<[u8]> for Secret {
261 fn as_ref(&self) -> &[u8] { self.inner.as_ref() }
262}
263
264impl CryptoSecretKey for Secret {
265 fn from_unsafe_slice(bytes: &[u8]) -> Result<Self, CryptoError> {
266 match Self::from_unsafe_slice(bytes) {
268 Ok(secret) => Ok(secret),
269 Err(e) => Err(match e {
270 Error::InvalidSecret => {
271 CryptoError::Secp(secp256k1::Error::InvalidSecretKey)
272 }
273 Error::Io(e) => CryptoError::Io(e),
274 _ => CryptoError::Secp(secp256k1::Error::InvalidSecretKey),
275 }),
276 }
277 }
278}
279
280#[cfg(test)]
281mod tests {
282 use super::{
283 super::{KeyPairGenerator, Random},
284 Secret,
285 };
286 use std::str::FromStr;
287
288 #[test]
289 fn multiplicating_secret_inversion_with_secret_gives_one() {
290 let secret = Random.generate().unwrap().secret().clone();
291 let mut inversion = secret.clone();
292 inversion.inv().unwrap();
293 inversion.mul(&secret).unwrap();
294 assert_eq!(inversion, Secret::from_str("0000000000000000000000000000000000000000000000000000000000000001").unwrap());
295 }
296
297 #[test]
298 fn secret_inversion_is_reversible_with_inversion() {
299 let secret = Random.generate().unwrap().secret().clone();
300 let mut inversion = secret.clone();
301 inversion.inv().unwrap();
302 inversion.inv().unwrap();
303 assert_eq!(inversion, secret);
304 }
305
306 #[test]
307 fn secret_pow() {
308 let secret = Random.generate().unwrap().secret().clone();
309
310 let mut pow0 = secret.clone();
311 pow0.pow(0).unwrap();
312 assert_eq!(pow0, Secret::from_str("0000000000000000000000000000000000000000000000000000000000000001").unwrap());
313
314 let mut pow1 = secret.clone();
315 pow1.pow(1).unwrap();
316 assert_eq!(pow1, secret);
317
318 let mut pow2 = secret.clone();
319 pow2.pow(2).unwrap();
320 let mut pow2_expected = secret.clone();
321 pow2_expected.mul(&secret).unwrap();
322 assert_eq!(pow2, pow2_expected);
323
324 let mut pow3 = secret.clone();
325 pow3.pow(3).unwrap();
326 let mut pow3_expected = secret.clone();
327 pow3_expected.mul(&secret).unwrap();
328 pow3_expected.mul(&secret).unwrap();
329 assert_eq!(pow3, pow3_expected);
330 }
331
332 #[test]
333 fn secret_sub_and_add() {
334 let secret = Random.generate().unwrap().secret().clone();
335 let secret_one = Secret::from_str(
336 "0000000000000000000000000000000000000000000000000000000000000001",
337 )
338 .unwrap();
339
340 let mut sub1 = secret.clone();
341 sub1.sub(&secret_one).unwrap();
342
343 let mut dec1 = secret.clone();
344 dec1.dec().unwrap();
345
346 assert_eq!(sub1, dec1);
347
348 let mut add1 = sub1.clone();
349 add1.add(&secret_one).unwrap();
350 assert_eq!(add1, secret);
351 }
352
353 #[test]
354 fn secret_neg() {
355 let secret_one = Secret::from_str(
356 "0000000000000000000000000000000000000000000000000000000000000001",
357 )
358 .unwrap();
359 let minus_one = Secret::from(secp256k1::key::MINUS_ONE_KEY);
360
361 let mut inv1 = secret_one.clone();
362 inv1.neg().unwrap();
363 assert_eq!(inv1, minus_one);
364 }
365}