wallet_standard_base/
random.rs1use 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}