-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Belt-HMAC-rng #5
base: master
Are you sure you want to change the base?
Conversation
Benchmark on M1:
|
belt-hmac-rng/src/lib.rs
Outdated
/// Belt-HMAC-HBELT random number generator core. | ||
pub struct BeltHmacRngCore { | ||
r: GenericArray<u8, U32>, | ||
s: GenericArray<u8, U32>, | ||
key: GenericArray<u8, U32>, | ||
} | ||
|
||
impl BeltHmacRngCore { | ||
/// Fill the buffer with random data. | ||
pub fn fill(&mut self, dest: &mut [u8]) { | ||
//SAFETY: Key is always present, by default it is filled with zeros | ||
let mut hmac = HmacHbelt::new_from_slice(&self.key).unwrap(); | ||
// 𝑌𝑖 ← hmac[ℎ](𝐾, 𝑟 ‖ 𝑆); | ||
hmac.update(&self.r); | ||
hmac.update(&self.s); | ||
let y = hmac.finalize_fixed_reset(); | ||
dest[..BUFSIZE].copy_from_slice(&y); | ||
|
||
// 𝑟 ← hmac[ℎ](𝐾, 𝑟). | ||
hmac.update(&self.r); | ||
hmac.finalize_into_reset(&mut self.r); | ||
} | ||
} | ||
|
||
impl BlockRngCore for BeltHmacRngCore { | ||
type Item = u32; | ||
type Results = [u32; 8]; | ||
|
||
fn generate(&mut self, results: &mut Self::Results) { | ||
let mut buf = [0u8; BUFSIZE * BLOCKSIZE]; | ||
self.fill(&mut buf); | ||
for i in 0..BLOCKSIZE { | ||
results[i] = | ||
u32::from_le_bytes([buf[i * 4], buf[i * 4 + 1], buf[i * 4 + 2], buf[i * 4 + 3]]); | ||
} | ||
} | ||
} | ||
|
||
impl SeedableRng for BeltHmacRngCore { | ||
type Seed = GenericArray<u8, U64>; | ||
|
||
fn from_seed(seed: Self::Seed) -> Self { | ||
let key = &seed[..BUFSIZE]; | ||
let iv = &seed[BUFSIZE..BUFSIZE + BUFSIZE]; | ||
|
||
let mut hmac = HmacHbelt::new_from_slice(key).unwrap(); | ||
|
||
// 𝑟 ← hmac[ℎ](𝐾, 𝑆). | ||
hmac.update(iv); | ||
let r = hmac.finalize_fixed_reset(); | ||
|
||
BeltHmacRngCore { | ||
r, | ||
s: GenericArray::<u8, U32>::clone_from_slice(iv), | ||
key: GenericArray::<u8, U32>::clone_from_slice(key), | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not know the plans for this CSPRNGs crate, but I can provide you with a little feedback.
Since the BeltHmacRngCore
contains some secret data, you might want to have it impl ZeroizeOnDrop
.
generate()
appears to use 2 buffers—one named buf
that is temporary and discarded in memory, and the other being results
. One solution for this would be to keep a temporary buffer GenericArray<u8, U32>
member of BeltHmacRngCore
. It would be a little more ideal if finalize_into_reset()
could work with a GenericArray<u32, U8>
, but an alternate solution would be to use core::mem::transmute
, union
, or zerocopy
if the duplicate buffer is a concern.
Having hmac
as a member of BeltHmacRngCore
could improve performance a little by avoiding initialization every time fill/generate
is called.
Then the impl SeedableRng for BeltHmacRngCore
might need to call .zeroize()
on the input seed
, or you could make a wrapper Seed
type that implements ZeroizeOnDrop
when that feature is activated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the BeltHmacRngCore contains some secret data, you might want to have it impl ZeroizeOnDrop.
Implemented, thank you.
Having hmac as a member of BeltHmacRngCore could improve performance a little by avoiding initialization every time fill/generate is called.
Sure, performance is increased from 9MB/s to 12MB/s.
Then the impl SeedableRng for BeltHmacRngCore might need to call .zeroize() on the input seed, or you could make a wrapper Seed type that implements ZeroizeOnDrop when that feature is activated.
generate() appears to use 2 buffers—one named buf that is temporary and discarded in memory, and the other being results. One solution for this would be to keep a temporary buffer GenericArray<u8, U32> member of BeltHmacRngCore. It would be a little more ideal if finalize_into_reset() could work with a GenericArray<u32, U8>, but an alternate solution would be to use core::mem::transmute, union, or zerocopy if the duplicate buffer is a concern.
Transmute will broke big endian platform. Don't wanna use union, because unsafe. Will check it later, thank you so much for advises.
Hello!
Just implemented rng from STB (Belarus Crypto standard)
https://apmi.bsu.by/assets/files/std/brng-spec25.pdf
@newpavlov