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