-
Notifications
You must be signed in to change notification settings - Fork 192
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
getrandom_uninit_slice(dest: &mut [MaybeUninit<u8>]) -> ...
. (#291
) * Add `getrandom_uninit(dest: &mut [MaybeUninit<u8>]) -> ...`. Add a public API for filling an `&mut [MaybeUninit<u8>]`. This will primarily serve as the building block for more typeful APIs for constructing random arrays. Increase the MSRV to 1.36, as `MaybeUninit` was added in that release. Fixes #226. * Revert testing changes Signed-off-by: Joe Richey <[email protected]> * Allow rdrand tests to work with new implementation Signed-off-by: Joe Richey <[email protected]> * Add Additional benchmarks and buffer size Signed-off-by: Joe Richey <[email protected]> * Use pointer casts instead of transmute Signed-off-by: Joe Richey <[email protected]> * Avoid initializing the buffer in `getrandom_uninit` benchmarks. * Benchmarks: Consume the result in `black_box`. Signed-off-by: Joe Richey <[email protected]> Co-authored-by: Joe Richey <[email protected]>
- Loading branch information
1 parent
5c1bb00
commit 47a59dd
Showing
26 changed files
with
211 additions
and
127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,94 +1,64 @@ | ||
#![feature(test)] | ||
extern crate test; | ||
|
||
use std::{ | ||
alloc::{alloc_zeroed, dealloc, Layout}, | ||
ptr::NonNull, | ||
}; | ||
|
||
// AlignedBuffer is like a Box<[u8; N]> except that it is always N-byte aligned | ||
struct AlignedBuffer<const N: usize>(NonNull<[u8; N]>); | ||
#![feature(maybe_uninit_as_bytes)] | ||
|
||
impl<const N: usize> AlignedBuffer<N> { | ||
fn layout() -> Layout { | ||
Layout::from_size_align(N, N).unwrap() | ||
} | ||
|
||
fn new() -> Self { | ||
let p = unsafe { alloc_zeroed(Self::layout()) } as *mut [u8; N]; | ||
Self(NonNull::new(p).unwrap()) | ||
} | ||
|
||
fn buf(&mut self) -> &mut [u8; N] { | ||
unsafe { self.0.as_mut() } | ||
} | ||
} | ||
extern crate test; | ||
|
||
impl<const N: usize> Drop for AlignedBuffer<N> { | ||
fn drop(&mut self) { | ||
unsafe { dealloc(self.0.as_ptr() as *mut u8, Self::layout()) } | ||
} | ||
} | ||
use std::mem::MaybeUninit; | ||
|
||
// Used to benchmark the throughput of getrandom in an optimal scenario. | ||
// The buffer is hot, and does not require initialization. | ||
#[inline(always)] | ||
fn bench<const N: usize>(b: &mut test::Bencher) { | ||
let mut ab = AlignedBuffer::<N>::new(); | ||
let buf = ab.buf(); | ||
fn bench_getrandom<const N: usize>(b: &mut test::Bencher) { | ||
b.bytes = N as u64; | ||
b.iter(|| { | ||
let mut buf = [0u8; N]; | ||
getrandom::getrandom(&mut buf[..]).unwrap(); | ||
test::black_box(&buf); | ||
test::black_box(buf); | ||
}); | ||
b.bytes = N as u64; | ||
} | ||
|
||
// Used to benchmark the throughput of getrandom is a slightly less optimal | ||
// scenario. The buffer is still hot, but requires initialization. | ||
#[inline(always)] | ||
fn bench_with_init<const N: usize>(b: &mut test::Bencher) { | ||
let mut ab = AlignedBuffer::<N>::new(); | ||
let buf = ab.buf(); | ||
fn bench_getrandom_uninit<const N: usize>(b: &mut test::Bencher) { | ||
b.bytes = N as u64; | ||
b.iter(|| { | ||
for byte in buf.iter_mut() { | ||
*byte = 0; | ||
} | ||
getrandom::getrandom(&mut buf[..]).unwrap(); | ||
test::black_box(&buf); | ||
let mut buf: MaybeUninit<[u8; N]> = MaybeUninit::uninit(); | ||
let _ = getrandom::getrandom_uninit(buf.as_bytes_mut()).unwrap(); | ||
let buf: [u8; N] = unsafe { buf.assume_init() }; | ||
test::black_box(buf) | ||
}); | ||
b.bytes = N as u64; | ||
} | ||
|
||
// 32 bytes (256-bit) is the seed sized used for rand::thread_rng | ||
const SEED: usize = 32; | ||
// Common size of a page, 4 KiB | ||
const PAGE: usize = 4096; | ||
// Large buffer to get asymptotic performance, 2 MiB | ||
const LARGE: usize = 1 << 21; | ||
macro_rules! bench { | ||
( $name:ident, $size:expr ) => { | ||
pub mod $name { | ||
#[bench] | ||
pub fn bench_getrandom(b: &mut test::Bencher) { | ||
super::bench_getrandom::<{ $size }>(b); | ||
} | ||
|
||
#[bench] | ||
fn bench_seed(b: &mut test::Bencher) { | ||
bench::<SEED>(b); | ||
} | ||
#[bench] | ||
fn bench_seed_init(b: &mut test::Bencher) { | ||
bench_with_init::<SEED>(b); | ||
#[bench] | ||
pub fn bench_getrandom_uninit(b: &mut test::Bencher) { | ||
super::bench_getrandom_uninit::<{ $size }>(b); | ||
} | ||
} | ||
}; | ||
} | ||
|
||
#[bench] | ||
fn bench_page(b: &mut test::Bencher) { | ||
bench::<PAGE>(b); | ||
} | ||
#[bench] | ||
fn bench_page_init(b: &mut test::Bencher) { | ||
bench_with_init::<PAGE>(b); | ||
} | ||
// 16 bytes (128 bits) is the size of an 128-bit AES key/nonce. | ||
bench!(aes128, 128 / 8); | ||
|
||
#[bench] | ||
fn bench_large(b: &mut test::Bencher) { | ||
bench::<LARGE>(b); | ||
} | ||
#[bench] | ||
fn bench_large_init(b: &mut test::Bencher) { | ||
bench_with_init::<LARGE>(b); | ||
} | ||
// 32 bytes (256 bits) is the seed sized used for rand::thread_rng | ||
// and the `random` value in a ClientHello/ServerHello for TLS. | ||
// This is also the size of a 256-bit AES/HMAC/P-256/Curve25519 key | ||
// and/or nonce. | ||
bench!(p256, 256 / 8); | ||
|
||
// A P-384/HMAC-384 key and/or nonce. | ||
bench!(p384, 384 / 8); | ||
|
||
// Initializing larger buffers is not the primary use case of this library, as | ||
// this should normally be done by a userspace CSPRNG. However, we have a test | ||
// here to see the effects of a lower (amortized) syscall overhead. | ||
bench!(page, 4096); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.