cfxkey/
secret.rs

1// Copyright 2015-2019 Parity Technologies (UK) Ltd.
2// This file is part of Parity Ethereum.
3
4// Parity Ethereum is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Parity Ethereum is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Parity Ethereum.  If not, see <http://www.gnu.org/licenses/>.
16
17use 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    /// Creates a `Secret` from the given slice, returning `None` if the slice
58    /// length != 32.
59    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    /// Creates zero key, which is invalid for crypto operations, but valid for
75    /// math operation.
76    pub fn zero() -> Self {
77        Secret {
78            inner: H256::zero(),
79        }
80    }
81
82    /// Imports and validates the key.
83    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    /// Checks validity of this key.
89    pub fn check_validity(&self) -> Result<(), Error> {
90        self.to_secp256k1_secret().map(|_| ())
91    }
92
93    /// Inplace add one secret key to another (scalar + scalar)
94    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    /// Inplace subtract one secret key from another (scalar - scalar)
113    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    /// Inplace decrease secret key (scalar - 1)
133    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    /// Inplace multiply one secret key to another (scalar * scalar)
150    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    /// Inplace negate secret key (-scalar)
169    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    /// Inplace inverse secret key (1 / scalar)
183    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    /// Compute power of secret key inplace (secret ^ pow).
192    /// This function is not intended to be used with large powers.
193    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    /// Create `secp256k1::key::SecretKey` based on this secret
213    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        // Call the existing method but convert the error type
267        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}