wallet_standard_base/
random.rs

1use core::fmt;
2
3use zeroize::{Zeroize, ZeroizeOnDrop};
4
5pub struct RandomBytes<const N: usize>([u8; N]);
6
7impl<const N: usize> RandomBytes<N> {
8    pub fn new() -> Self {
9        Self::default()
10    }
11
12    pub fn generate_with_buffer(buffer: &mut [u8; N]) {
13        use rand_chacha::ChaCha12Rng;
14        use rand_core::{RngCore, SeedableRng};
15
16        let mut rng = ChaCha12Rng::from_os_rng();
17
18        rng.fill_bytes(buffer);
19    }
20
21    pub fn generate() -> Self {
22        let mut buffer = Self::new();
23
24        Self::generate_with_buffer(&mut buffer.0);
25
26        buffer
27    }
28
29    pub const fn expose(&self) -> &[u8; N] {
30        &self.0
31    }
32}
33
34impl<const N: usize> Zeroize for RandomBytes<N> {
35    fn zeroize(&mut self) {
36        self.0.fill(0u8);
37
38        assert_eq!(self.0, [0u8; N]);
39    }
40}
41impl<const N: usize> ZeroizeOnDrop for RandomBytes<N> {}
42
43impl<const N: usize> Default for RandomBytes<N> {
44    fn default() -> Self {
45        Self([0u8; N])
46    }
47}
48
49impl<const N: usize> fmt::Debug for RandomBytes<N> {
50    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51        write!(f, "RandomBytes(REDACTED[{N}])")
52    }
53}
54
55impl<const N: usize> fmt::Display for RandomBytes<N> {
56    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57        write!(f, "{self:?}")
58    }
59}