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