1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
use super::ensure_initialized; use crate::ffi; use crate::utils; pub const SEEDBYTES: usize = ffi::hydro_random_SEEDBYTES as usize; #[derive(Debug, Clone)] pub struct Seed([u8; SEEDBYTES]); #[inline] pub fn u32() -> u32 { ensure_initialized(); unsafe { ffi::hydro_random_u32() } } #[inline] pub fn uniform(upper_bound: u32) -> u32 { ensure_initialized(); unsafe { ffi::hydro_random_uniform(upper_bound) } } #[inline] pub fn buf_into(out: &mut [u8]) { ensure_initialized(); unsafe { ffi::hydro_random_buf(out.as_mut_ptr() as *mut _, out.len()); } } pub fn buf(out_len: usize) -> Vec<u8> { let mut out = vec![0u8; out_len]; buf_into(&mut out); out } #[inline] pub fn buf_deterministic_into(out: &mut [u8], seed: &Seed) { ensure_initialized(); unsafe { ffi::hydro_random_buf_deterministic(out.as_mut_ptr() as *mut _, out.len(), seed.0.as_ptr()) } } #[inline] pub fn buf_deterministic(out_len: usize, seed: &Seed) -> Vec<u8> { let mut out = vec![0u8; out_len]; buf_deterministic_into(&mut out, seed); out } #[inline] pub fn ratchet() { ensure_initialized(); unsafe { ffi::hydro_random_ratchet(); } } #[inline] pub fn reseed() { ensure_initialized(); unsafe { ffi::hydro_random_reseed(); } } impl Drop for Seed { fn drop(&mut self) { utils::memzero(self) } } impl From<[u8; SEEDBYTES]> for Seed { #[inline] fn from(seed: [u8; SEEDBYTES]) -> Seed { Seed(seed) } } impl Into<[u8; SEEDBYTES]> for Seed { #[inline] fn into(self) -> [u8; SEEDBYTES] { self.0 } } impl AsRef<[u8]> for Seed { fn as_ref(&self) -> &[u8] { &self.0 as &[u8] } } impl PartialEq for Seed { fn eq(&self, other: &Self) -> bool { utils::equal(self, other) } } impl Eq for Seed {} impl Seed { pub fn gen() -> Seed { let mut seed_inner = [0u8; SEEDBYTES]; buf_into(&mut seed_inner); Seed(seed_inner) } } #[cfg(test)] mod tests { use crate::*; #[test] fn test_randombytes() { init().unwrap(); assert_ne!(random::u32() | random::u32() | random::u32(), 0); for _ in 0..100 { let max = random::u32(); assert!(random::uniform(max) < max) } let len = random::uniform(100) as usize + 1; let mut buf = random::buf(len); random::buf_into(&mut buf); let seed = random::Seed::gen(); let buf = random::buf_deterministic(len, &seed); let mut buf2 = vec![0u8; len]; random::buf_deterministic_into(&mut buf2, &seed); assert_eq!(buf, buf2); let seedx: [u8; random::SEEDBYTES] = seed.clone().into(); let seedy: random::Seed = seedx.into(); assert_eq!(seed, seedy); random::ratchet(); random::reseed(); } }