1use rand::prelude::*;
3use std::ops::Deref;
4use std::ops::DerefMut;
5use zeroize::Zeroize;
6use zeroize::{ZeroizeOnDrop, Zeroizing};
7
8pub fn rand_seed() -> Zeroizing<[u8; 32]> {
21 let mut rng = rand::thread_rng();
22 let mut output_key_material = Zeroizing::new([0u8; 32]); rng.fill_bytes(&mut *output_key_material);
25
26 Zeroizing::new(*output_key_material)
27}
28
29#[derive(Clone, Debug, PartialEq)]
35pub struct Seed(Zeroizing<[u8; 32]>);
36
37impl Seed {
38 pub fn new(seed: Zeroizing<[u8; 32]>) -> Self {
40 Self(seed)
41 }
42}
43
44impl Default for Seed {
45 fn default() -> Self {
46 Self::new(Zeroizing::new([0u8; 32]))
47 }
48}
49
50impl Zeroize for Seed {
51 fn zeroize(&mut self) {
52 self.0.zeroize();
53 }
54}
55
56impl From<Vec<u8>> for Seed {
57 fn from(seed: Vec<u8>) -> Self {
58 let mut bytes = [0u8; 32];
59 bytes.copy_from_slice(&seed[..32]);
60
61 Self::new(Zeroizing::new(bytes))
62 }
63}
64
65impl ZeroizeOnDrop for Seed {}
67
68impl Deref for Seed {
69 type Target = [u8];
70
71 fn deref(&self) -> &Self::Target {
72 &*self.0
73 }
74}
75
76impl DerefMut for Seed {
77 fn deref_mut(&mut self) -> &mut Self::Target {
78 &mut *self.0
79 }
80}
81
82impl AsRef<[u8]> for Seed {
83 fn as_ref(&self) -> &[u8] {
84 &*self.0
85 }
86}
87
88impl AsRef<[u8; 32]> for Seed {
89 fn as_ref(&self) -> &[u8; 32] {
90 &self.0
91 }
92}
93
94impl PartialEq<Seed> for [u8] {
95 fn eq(&self, other: &Seed) -> bool {
96 self[..] == other[..]
97 }
98}
99
100impl PartialEq<Seed> for [u8; 32] {
101 fn eq(&self, other: &Seed) -> bool {
102 self[..] == other[..]
103 }
104}
105
106#[cfg(test)]
107mod seed_tests {
108 use super::*;
109
110 #[test]
112 fn rand_seed_works() {
113 let seed = rand_seed();
114
115 assert_eq!(seed.len(), 32);
116 }
117}