uckb_key/secp256k1/
secret.rs

1// Copyright (C) 2019-2020 Boyu Yang
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use std::{ops::Drop, ptr, sync::atomic};
10
11use rand::{rngs::StdRng, thread_rng, Rng, SeedableRng};
12
13use super::{kernel, Error, PublicKey, Signature, SECP256K1};
14
15#[derive(Clone, PartialOrd, Ord, PartialEq, Eq)]
16pub struct SecretKey(pub(super) kernel::SecretKey);
17
18impl_std_traits!(SecretKey, kernel::SecretKey);
19
20#[cfg(feature = "insecure")]
21impl ::std::fmt::Debug for SecretKey {
22    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
23        write!(f, "{:?}", self.0)
24    }
25}
26
27#[cfg(feature = "insecure")]
28impl ::std::fmt::Display for SecretKey {
29    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
30        write!(f, "{}", self.0)
31    }
32}
33
34#[cfg(not(feature = "insecure"))]
35impl_std_fmt_masked!(SecretKey);
36
37impl SecretKey {
38    pub fn new<R: Rng + ?Sized>(rng: &mut R) -> Self {
39        Self(kernel::SecretKey::new(rng))
40    }
41
42    pub fn from_slice(data: &[u8]) -> Result<Self, Error> {
43        kernel::SecretKey::from_slice(data).map(Self)
44    }
45
46    pub fn from_seed(seed: u64) -> Self {
47        let mut rng = StdRng::seed_from_u64(seed);
48        Self::new(&mut rng)
49    }
50
51    pub fn random() -> Self {
52        let mut rng = thread_rng();
53        Self::new(&mut rng)
54    }
55
56    pub fn public_key(&self) -> PublicKey {
57        PublicKey::from_secret_key(self)
58    }
59
60    pub fn sign_recoverable(&self, input: &[u8]) -> Result<Signature, Error> {
61        kernel::Message::from_slice(input)
62            .map(|msg| (&*SECP256K1).sign_recoverable(&msg, self))
63            .map(Signature)
64    }
65
66    pub(crate) fn zeroize(&mut self) {
67        let Self(inner) = self;
68        let dst = inner.as_mut_ptr();
69        let len = inner.len();
70        for of in 0..len {
71            unsafe {
72                ptr::write_volatile(dst.add(of), 0);
73            }
74            atomic::compiler_fence(atomic::Ordering::SeqCst);
75        }
76    }
77}
78
79impl Drop for SecretKey {
80    fn drop(&mut self) {
81        self.zeroize()
82    }
83}