-
-
Notifications
You must be signed in to change notification settings - Fork 481
Migrate to new rand_core utility functions
#1686
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
Open
newpavlov
wants to merge
19
commits into
master
Choose a base branch
from
rand_core/block_utils
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+203
−260
Open
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
e9f4e84
Migrate to new `rand_core` utility functions
newpavlov f5cce31
port rand_chacha
newpavlov 90b9fee
patch rand_core for benches
newpavlov 0baca57
fix some warnings
newpavlov 9ba4cad
use rand_chacha instead of chacha20
newpavlov 569262a
fix benches
newpavlov 3f4c4c8
fix warning
newpavlov 4767661
fix doc
newpavlov 60baaba
uncomment default features
newpavlov 2154e9f
fix rand_chacha docs
newpavlov 9110387
add inline attributes
newpavlov e338cd2
remove `criterion-cycles-per-byte` dependency
newpavlov 28c538e
Merge branch 'master' into rand_core/block_utils
newpavlov de706e4
Update to `BlockBuffer`
newpavlov 0045925
new `ThreadRng` impl
newpavlov 8827d15
Add `#[inline]` to `ThreadRng` methods
newpavlov f75c6d7
Add `#[inline]` to `rand_chacha`
newpavlov a6d5133
tweak code
newpavlov 363d488
remove ThreadRngInner
newpavlov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 |
|---|---|---|
|
|
@@ -10,8 +10,7 @@ | |
|
|
||
| use crate::guts::ChaCha; | ||
| use core::fmt; | ||
| use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng}; | ||
| use rand_core::{CryptoRng, RngCore, SeedableRng}; | ||
| use rand_core::{CryptoRng, RngCore, SeedableRng, le::BlockBuffer}; | ||
|
|
||
| #[cfg(feature = "serde")] | ||
| use serde::{Deserialize, Deserializer, Serialize, Serializer}; | ||
|
|
@@ -21,52 +20,6 @@ const BUF_BLOCKS: u8 = 4; | |
| // number of 32-bit words per ChaCha block (fixed by algorithm definition) | ||
| const BLOCK_WORDS: u8 = 16; | ||
|
|
||
| #[repr(transparent)] | ||
| pub struct Array64<T>([T; 64]); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was needed because of the bound It's a nice but ultimately unimportant improvement of the new utility fns. |
||
| impl<T> Default for Array64<T> | ||
| where | ||
| T: Default, | ||
| { | ||
| #[rustfmt::skip] | ||
| fn default() -> Self { | ||
| Self([ | ||
| T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), | ||
| T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), | ||
| T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), | ||
| T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), | ||
| T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), | ||
| T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), | ||
| T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), | ||
| T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), | ||
| ]) | ||
| } | ||
| } | ||
| impl<T> AsRef<[T]> for Array64<T> { | ||
| fn as_ref(&self) -> &[T] { | ||
| &self.0 | ||
| } | ||
| } | ||
| impl<T> AsMut<[T]> for Array64<T> { | ||
| fn as_mut(&mut self) -> &mut [T] { | ||
| &mut self.0 | ||
| } | ||
| } | ||
| impl<T> Clone for Array64<T> | ||
| where | ||
| T: Copy + Default, | ||
| { | ||
| fn clone(&self) -> Self { | ||
| let mut new = Self::default(); | ||
| new.0.copy_from_slice(&self.0); | ||
| new | ||
| } | ||
| } | ||
| impl<T> fmt::Debug for Array64<T> { | ||
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
| write!(f, "Array64 {{}}") | ||
| } | ||
| } | ||
|
|
||
| macro_rules! chacha_impl { | ||
| ($ChaChaXCore:ident, $ChaChaXRng:ident, $rounds:expr, $doc:expr, $abst:ident,) => { | ||
| #[doc=$doc] | ||
|
|
@@ -82,29 +35,28 @@ macro_rules! chacha_impl { | |
| } | ||
| } | ||
|
|
||
| impl BlockRngCore for $ChaChaXCore { | ||
| type Item = u32; | ||
| type Results = Array64<u32>; | ||
|
|
||
| impl $ChaChaXCore { | ||
| /// Create new core state from seed. | ||
| #[inline] | ||
| fn generate(&mut self, r: &mut Self::Results) { | ||
| self.state.refill4($rounds, &mut r.0); | ||
| pub fn from_seed(seed: [u8; 32]) -> Self { | ||
| $ChaChaXCore { | ||
| state: ChaCha::new(&seed, &[0u8; 8]), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl SeedableRng for $ChaChaXCore { | ||
| type Seed = [u8; 32]; | ||
| /// Generate next block. | ||
| #[inline] | ||
| pub fn next_block(&mut self, r: &mut [u32; 64]) { | ||
| self.state.refill4($rounds, r); | ||
| } | ||
|
|
||
| /// Get current block position. | ||
| #[inline] | ||
| fn from_seed(seed: Self::Seed) -> Self { | ||
| $ChaChaXCore { | ||
| state: ChaCha::new(&seed, &[0u8; 8]), | ||
| } | ||
| pub fn block_pos(&self) -> u64 { | ||
| self.state.get_block_pos() | ||
| } | ||
| } | ||
|
|
||
| impl CryptoBlockRng for $ChaChaXCore {} | ||
|
|
||
| /// A cryptographically secure random number generator that uses the ChaCha algorithm. | ||
| /// | ||
| /// ChaCha is a stream cipher designed by Daniel J. Bernstein[^1], that we use as an RNG. It is | ||
|
|
@@ -136,7 +88,7 @@ macro_rules! chacha_impl { | |
| /// ``` | ||
| /// | ||
| /// This implementation uses an output buffer of sixteen `u32` words, and uses | ||
| /// [`BlockRng`] to implement the [`RngCore`] methods. | ||
| /// them to implement the [`RngCore`] methods. | ||
| /// | ||
| /// [^1]: D. J. Bernstein, [*ChaCha, a variant of Salsa20*]( | ||
| /// https://cr.yp.to/chacha.html) | ||
|
|
@@ -145,35 +97,54 @@ macro_rules! chacha_impl { | |
| /// http://www.ecrypt.eu.org/stream/) | ||
| #[derive(Clone, Debug)] | ||
| pub struct $ChaChaXRng { | ||
| rng: BlockRng<$ChaChaXCore>, | ||
| core: $ChaChaXCore, | ||
| buffer: BlockBuffer<u32, 64>, | ||
| } | ||
|
|
||
| impl $ChaChaXRng { | ||
| #[inline] | ||
| fn buffer_index(&self) -> u32 { | ||
| self.buffer.index() | ||
| } | ||
|
|
||
| #[inline] | ||
| fn generate_and_set(&mut self, index: usize) { | ||
| if index == 0 { | ||
| self.buffer.reset(); | ||
| } else { | ||
| self.buffer | ||
| .generate_and_set(index, |block| self.core.next_block(block)); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl SeedableRng for $ChaChaXRng { | ||
| type Seed = [u8; 32]; | ||
|
|
||
| #[inline] | ||
| fn from_seed(seed: Self::Seed) -> Self { | ||
| let core = $ChaChaXCore::from_seed(seed); | ||
| Self { | ||
| rng: BlockRng::new(core), | ||
| core: $ChaChaXCore::from_seed(seed), | ||
| buffer: BlockBuffer::default(), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl RngCore for $ChaChaXRng { | ||
| #[inline] | ||
| fn next_u32(&mut self) -> u32 { | ||
| self.rng.next_u32() | ||
| self.buffer.next_word(|block| self.core.next_block(block)) | ||
| } | ||
|
|
||
| #[inline] | ||
| fn next_u64(&mut self) -> u64 { | ||
| self.rng.next_u64() | ||
| self.buffer.next_u64(|block| self.core.next_block(block)) | ||
| } | ||
|
|
||
| #[inline] | ||
| fn fill_bytes(&mut self, bytes: &mut [u8]) { | ||
| self.rng.fill_bytes(bytes) | ||
| fn fill_bytes(&mut self, dst: &mut [u8]) { | ||
| self.buffer | ||
| .fill_bytes(dst, |block| self.core.next_block(block)); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -190,11 +161,11 @@ macro_rules! chacha_impl { | |
| #[inline] | ||
| pub fn get_word_pos(&self) -> u128 { | ||
| let buf_start_block = { | ||
| let buf_end_block = self.rng.core.state.get_block_pos(); | ||
| let buf_end_block = self.core.state.get_block_pos(); | ||
| u64::wrapping_sub(buf_end_block, BUF_BLOCKS.into()) | ||
| }; | ||
| let (buf_offset_blocks, block_offset_words) = { | ||
| let buf_offset_words = self.rng.index() as u64; | ||
| let buf_offset_words = self.buffer_index() as u64; | ||
| let blocks_part = buf_offset_words / u64::from(BLOCK_WORDS); | ||
| let words_part = buf_offset_words % u64::from(BLOCK_WORDS); | ||
| (blocks_part, words_part) | ||
|
|
@@ -212,9 +183,8 @@ macro_rules! chacha_impl { | |
| #[inline] | ||
| pub fn set_word_pos(&mut self, word_offset: u128) { | ||
| let block = (word_offset / u128::from(BLOCK_WORDS)) as u64; | ||
| self.rng.core.state.set_block_pos(block); | ||
| self.rng | ||
| .generate_and_set((word_offset % u128::from(BLOCK_WORDS)) as usize); | ||
| self.core.state.set_block_pos(block); | ||
| self.generate_and_set((word_offset % u128::from(BLOCK_WORDS)) as usize); | ||
| } | ||
|
|
||
| /// Set the stream number. | ||
|
|
@@ -230,8 +200,8 @@ macro_rules! chacha_impl { | |
| /// indirectly via `set_word_pos`), but this is not directly supported. | ||
| #[inline] | ||
| pub fn set_stream(&mut self, stream: u64) { | ||
| self.rng.core.state.set_nonce(stream); | ||
| if self.rng.index() != 64 { | ||
| self.core.state.set_nonce(stream); | ||
| if self.buffer_index() != 64 { | ||
| let wp = self.get_word_pos(); | ||
| self.set_word_pos(wp); | ||
| } | ||
|
|
@@ -240,13 +210,13 @@ macro_rules! chacha_impl { | |
| /// Get the stream number. | ||
| #[inline] | ||
| pub fn get_stream(&self) -> u64 { | ||
| self.rng.core.state.get_nonce() | ||
| self.core.state.get_nonce() | ||
| } | ||
|
|
||
| /// Get the seed. | ||
| #[inline] | ||
| pub fn get_seed(&self) -> [u8; 32] { | ||
| self.rng.core.state.get_seed() | ||
| self.core.state.get_seed() | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -255,7 +225,8 @@ macro_rules! chacha_impl { | |
| impl From<$ChaChaXCore> for $ChaChaXRng { | ||
| fn from(core: $ChaChaXCore) -> Self { | ||
| $ChaChaXRng { | ||
| rng: BlockRng::new(core), | ||
| core, | ||
| buffer: BlockBuffer::default(), | ||
| } | ||
| } | ||
| } | ||
|
|
||
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.