Skip to main content

ed25519_compact/
common.rs

1use core::ops::{Deref, DerefMut};
2use core::ptr;
3use core::sync::atomic;
4
5use super::error::Error;
6
7/// A seed, which a key pair can be derived from.
8#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
9pub struct Seed([u8; Seed::BYTES]);
10
11impl From<[u8; 32]> for Seed {
12    fn from(seed: [u8; 32]) -> Self {
13        Seed(seed)
14    }
15}
16
17impl Seed {
18    /// Number of raw bytes in a seed.
19    pub const BYTES: usize = 32;
20
21    /// Creates a seed from raw bytes.
22    pub fn new(seed: [u8; Seed::BYTES]) -> Self {
23        Seed(seed)
24    }
25
26    /// Creates a seed from a slice.
27    pub fn from_slice(seed: &[u8]) -> Result<Self, Error> {
28        let mut seed_ = [0u8; Seed::BYTES];
29        if seed.len() != seed_.len() {
30            return Err(Error::InvalidSeed);
31        }
32        seed_.copy_from_slice(seed);
33        Ok(Seed::new(seed_))
34    }
35
36    /// Tentatively overwrite the content of the seed with zeros.
37    pub fn wipe(self) {
38        let mut seed = self;
39        Mem::wipe(&mut seed.0)
40    }
41
42    /// Overwrite the content of the seed with zeros in-place.
43    pub fn wipe_mut(&mut self) {
44        Mem::wipe(&mut self.0)
45    }
46}
47
48#[cfg(feature = "random")]
49impl Default for Seed {
50    /// Generates a random seed.
51    fn default() -> Self {
52        let mut seed = [0u8; Seed::BYTES];
53        getrandom::fill(&mut seed).expect("RNG failure");
54        Seed(seed)
55    }
56}
57
58#[cfg(feature = "random")]
59impl Seed {
60    /// Generates a random seed.
61    pub fn generate() -> Self {
62        Seed::default()
63    }
64}
65
66impl Deref for Seed {
67    type Target = [u8; Seed::BYTES];
68
69    /// Returns a seed as raw bytes.
70    fn deref(&self) -> &Self::Target {
71        &self.0
72    }
73}
74
75impl DerefMut for Seed {
76    /// Returns a seed as mutable raw bytes.
77    fn deref_mut(&mut self) -> &mut Self::Target {
78        &mut self.0
79    }
80}
81
82pub(crate) struct Mem;
83
84impl Mem {
85    #[inline]
86    pub fn wipe<T: Default>(x: &mut [T]) {
87        for i in 0..x.len() {
88            unsafe {
89                ptr::write_volatile(x.as_mut_ptr().add(i), T::default());
90            }
91        }
92        atomic::compiler_fence(atomic::Ordering::SeqCst);
93        atomic::fence(atomic::Ordering::SeqCst);
94    }
95}