ed25519_compact/
common.rs1use core::ops::{Deref, DerefMut};
2use core::ptr;
3use core::sync::atomic;
4
5use super::error::Error;
6
7#[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 pub const BYTES: usize = 32;
20
21 pub fn new(seed: [u8; Seed::BYTES]) -> Self {
23 Seed(seed)
24 }
25
26 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 pub fn wipe(self) {
38 let mut seed = self;
39 Mem::wipe(&mut seed.0)
40 }
41
42 pub fn wipe_mut(&mut self) {
44 Mem::wipe(&mut self.0)
45 }
46}
47
48#[cfg(feature = "random")]
49impl Default for Seed {
50 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 pub fn generate() -> Self {
62 Seed::default()
63 }
64}
65
66impl Deref for Seed {
67 type Target = [u8; Seed::BYTES];
68
69 fn deref(&self) -> &Self::Target {
71 &self.0
72 }
73}
74
75impl DerefMut for Seed {
76 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}