From ff0a4cf35b7bbf41174894ccd56793cbca07ddda Mon Sep 17 00:00:00 2001 From: Haibo Huang Date: Tue, 15 Dec 2020 16:12:10 -0800 Subject: Upgrade rust/crates/rand_chacha to 0.3.0 Test: make Change-Id: I327b9a5812630e9622633e0cba33b1b1e535c1c8 --- .cargo_vcs_info.json | 2 +- Android.bp | 5 ++-- CHANGELOG.md | 8 +++++++ Cargo.toml | 13 ++++------- Cargo.toml.orig | 12 ++++------ METADATA | 8 +++---- README.md | 5 ++-- src/chacha.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++------ src/guts.rs | 25 +++++++++++++------- 9 files changed, 99 insertions(+), 43 deletions(-) diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 0739f24..0db4f9b 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,5 @@ { "git": { - "sha1": "e2112c4404c61d3850c0e91f48114db5daf06569" + "sha1": "98e220c30234370fb04ba928799ebd9727fc049a" } } diff --git a/Android.bp b/Android.bp index af926c4..18535ef 100644 --- a/Android.bp +++ b/Android.bp @@ -8,7 +8,6 @@ rust_library { edition: "2018", features: [ "default", - "simd", "std", ], rustlibs: [ @@ -18,5 +17,5 @@ rust_library { } // dependent_library ["feature_list"] -// ppv-lite86-0.2.8 "simd,std" -// rand_core-0.5.1 +// ppv-lite86-0.2.10 "simd,std" +// rand_core-0.6.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 1273895..8a07390 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.0] - 2020-12-08 +- Bump `rand_core` version to 0.6.0 +- Bump MSRV to 1.36 (#1011) +- Remove usage of deprecated feature "simd" of `ppv-lite86` (#979), then revert + this change (#1023) since SIMD is only enabled by default from `ppv-lite86 v0.2.10` +- impl PartialEq+Eq for ChaChaXRng and ChaChaXCore (#979) +- Fix panic on block counter wrap that was occurring in debug builds (#980) + ## [0.2.2] - 2020-03-09 - Integrate `c2-chacha`, reducing dependency count (#931) - Add CryptoRng to ChaChaXCore (#944) diff --git a/Cargo.toml b/Cargo.toml index dea94e9..0f371b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ [package] edition = "2018" name = "rand_chacha" -version = "0.2.2" +version = "0.3.0" authors = ["The Rand Project Developers", "The Rust Project Developers", "The CryptoCorrosion Contributors"] description = "ChaCha random number generator\n" homepage = "https://crates.io/crates/rand_chacha" @@ -24,19 +24,14 @@ categories = ["algorithms", "no-std"] license = "MIT OR Apache-2.0" repository = "https://github.com/rust-random/rand" [dependencies.ppv-lite86] -version = "0.2.6" +version = "0.2.8" features = ["simd"] default-features = false [dependencies.rand_core] -version = "0.5" +version = "0.6.0" [features] -default = ["std", "simd"] +default = ["std"] simd = [] std = ["ppv-lite86/std"] -[badges.appveyor] -repository = "rust-random/rand" - -[badges.travis-ci] -repository = "rust-random/rand" diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 601fef9..8d7dcd7 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "rand_chacha" -version = "0.2.2" +version = "0.3.0" authors = ["The Rand Project Developers", "The Rust Project Developers", "The CryptoCorrosion Contributors"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -14,15 +14,11 @@ keywords = ["random", "rng", "chacha"] categories = ["algorithms", "no-std"] edition = "2018" -[badges] -travis-ci = { repository = "rust-random/rand" } -appveyor = { repository = "rust-random/rand" } - [dependencies] -rand_core = { path = "../rand_core", version = "0.5" } -ppv-lite86 = { version = "0.2.6", default-features = false, features = ["simd"] } +rand_core = { path = "../rand_core", version = "0.6.0" } +ppv-lite86 = { version = "0.2.8", default-features = false, features = ["simd"] } [features] -default = ["std", "simd"] +default = ["std"] std = ["ppv-lite86/std"] simd = [] # deprecated diff --git a/METADATA b/METADATA index 7898235..ba8e6ec 100644 --- a/METADATA +++ b/METADATA @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/rand_chacha/rand_chacha-0.2.2.crate" + value: "https://static.crates.io/crates/rand_chacha/rand_chacha-0.3.0.crate" } - version: "0.2.2" + version: "0.3.0" license_type: NOTICE last_upgrade_date { year: 2020 - month: 6 - day: 18 + month: 12 + day: 15 } } diff --git a/README.md b/README.md index 69a0ce7..edd754d 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ # rand_chacha -[![Build Status](https://travis-ci.org/rust-random/rand.svg)](https://travis-ci.org/rust-random/rand) -[![Build Status](https://ci.appveyor.com/api/projects/status/github/rust-random/rand?svg=true)](https://ci.appveyor.com/project/rust-random/rand) +[![Test Status](https://github.com/rust-random/rand/workflows/Tests/badge.svg?event=push)](https://github.com/rust-random/rand/actions) [![Latest version](https://img.shields.io/crates/v/rand_chacha.svg)](https://crates.io/crates/rand_chacha) [![Book](https://img.shields.io/badge/book-master-yellow.svg)](https://rust-random.github.io/book/) [![API](https://img.shields.io/badge/api-master-yellow.svg)](https://rust-random.github.io/rand/rand_chacha) [![API](https://docs.rs/rand_chacha/badge.svg)](https://docs.rs/rand_chacha) -[![Minimum rustc version](https://img.shields.io/badge/rustc-1.32+-lightgray.svg)](https://github.com/rust-random/rand#rust-version-requirements) +[![Minimum rustc version](https://img.shields.io/badge/rustc-1.36+-lightgray.svg)](https://github.com/rust-random/rand#rust-version-requirements) A cryptographically secure random number generator that uses the ChaCha algorithm. diff --git a/src/chacha.rs b/src/chacha.rs index cf68c52..17bcc55 100644 --- a/src/chacha.rs +++ b/src/chacha.rs @@ -19,6 +19,11 @@ use rand_core::{CryptoRng, Error, RngCore, SeedableRng}; const STREAM_PARAM_NONCE: u32 = 1; const STREAM_PARAM_BLOCK: u32 = 0; +// NB. this must remain consistent with some currently hard-coded numbers in this module +const BUF_BLOCKS: u8 = 4; +// number of 32-bit words per ChaCha block (fixed by algorithm definition) +const BLOCK_WORDS: u8 = 16; + pub struct Array64([T; 64]); impl Default for Array64 where T: Default @@ -65,7 +70,7 @@ impl fmt::Debug for Array64 { macro_rules! chacha_impl { ($ChaChaXCore:ident, $ChaChaXRng:ident, $rounds:expr, $doc:expr) => { #[doc=$doc] - #[derive(Clone)] + #[derive(Clone, PartialEq, Eq)] pub struct $ChaChaXCore { state: ChaCha, } @@ -187,10 +192,19 @@ macro_rules! chacha_impl { /// byte-offset. #[inline] pub fn get_word_pos(&self) -> u128 { - let mut block = u128::from(self.rng.core.state.get_stream_param(STREAM_PARAM_BLOCK)); - // counter is incremented *after* filling buffer - block -= 4; - (block << 4) + self.rng.index() as u128 + let buf_start_block = { + let buf_end_block = self.rng.core.state.get_stream_param(STREAM_PARAM_BLOCK); + 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 blocks_part = buf_offset_words / u64::from(BLOCK_WORDS); + let words_part = buf_offset_words % u64::from(BLOCK_WORDS); + (blocks_part, words_part) + }; + let pos_block = u64::wrapping_add(buf_start_block, buf_offset_blocks); + let pos_block_words = u128::from(pos_block) * u128::from(BLOCK_WORDS); + pos_block_words + u128::from(block_offset_words) } /// Set the offset from the start of the stream, in 32-bit words. @@ -200,12 +214,12 @@ macro_rules! chacha_impl { /// 60 bits. #[inline] pub fn set_word_pos(&mut self, word_offset: u128) { - let block = (word_offset >> 4) as u64; + let block = (word_offset / u128::from(BLOCK_WORDS)) as u64; self.rng .core .state .set_stream_param(STREAM_PARAM_BLOCK, block); - self.rng.generate_and_set((word_offset & 15) as usize); + self.rng.generate_and_set((word_offset % u128::from(BLOCK_WORDS)) as usize); } /// Set the stream number. @@ -241,6 +255,14 @@ macro_rules! chacha_impl { } } } + + impl PartialEq<$ChaChaXRng> for $ChaChaXRng { + fn eq(&self, rhs: &$ChaChaXRng) -> bool { + self.rng.core.state.stream64_eq(&rhs.rng.core.state) + && self.get_word_pos() == rhs.get_word_pos() + } + } + impl Eq for $ChaChaXRng {} } } @@ -456,4 +478,32 @@ mod test { assert_eq!(rng.next_u32(), clone.next_u32()); } } + + #[test] + fn test_chacha_word_pos_wrap_exact() { + use super::{BUF_BLOCKS, BLOCK_WORDS}; + let mut rng = ChaChaRng::from_seed(Default::default()); + // refilling the buffer in set_word_pos will wrap the block counter to 0 + let last_block = (1 << 68) - u128::from(BUF_BLOCKS * BLOCK_WORDS); + rng.set_word_pos(last_block); + assert_eq!(rng.get_word_pos(), last_block); + } + + #[test] + fn test_chacha_word_pos_wrap_excess() { + use super::BLOCK_WORDS; + let mut rng = ChaChaRng::from_seed(Default::default()); + // refilling the buffer in set_word_pos will wrap the block counter past 0 + let last_block = (1 << 68) - u128::from(BLOCK_WORDS); + rng.set_word_pos(last_block); + assert_eq!(rng.get_word_pos(), last_block); + } + + #[test] + fn test_chacha_word_pos_zero() { + let mut rng = ChaChaRng::from_seed(Default::default()); + assert_eq!(rng.get_word_pos(), 0); + rng.set_word_pos(0); + assert_eq!(rng.get_word_pos(), 0); + } } diff --git a/src/guts.rs b/src/guts.rs index 7561c1b..27ff957 100644 --- a/src/guts.rs +++ b/src/guts.rs @@ -21,7 +21,7 @@ const BUFBLOCKS: u64 = 1 << LOG2_BUFBLOCKS; pub(crate) const BUFSZ64: u64 = BLOCK64 * BUFBLOCKS; pub(crate) const BUFSZ: usize = BUFSZ64 as usize; -#[derive(Clone)] +#[derive(Clone, PartialEq, Eq)] pub struct ChaCha { pub(crate) b: vec128_storage, pub(crate) c: vec128_storage, @@ -91,8 +91,17 @@ impl ChaCha { pub fn get_stream_param(&self, param: u32) -> u64 { get_stream_param(self, param) } + + /// Return whether rhs is equal in all parameters except current 64-bit position. + #[inline] + pub fn stream64_eq(&self, rhs: &Self) -> bool { + let self_d: [u32; 4] = self.d.into(); + let rhs_d: [u32; 4] = rhs.d.into(); + self.b == rhs.b && self.c == rhs.c && self_d[3] == rhs_d[3] && self_d[2] == rhs_d[2] + } } +#[allow(clippy::many_single_char_names)] #[inline(always)] fn refill_wide_impl( m: Mach, state: &mut ChaCha, drounds: u32, out: &mut [u8; BUFSZ], @@ -100,11 +109,11 @@ fn refill_wide_impl( let k = m.vec([0x6170_7865, 0x3320_646e, 0x7962_2d32, 0x6b20_6574]); let mut pos = state.pos64(m); let d0: Mach::u32x4 = m.unpack(state.d); - pos += 1; + pos = pos.wrapping_add(1); let d1 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0); - pos += 1; + pos = pos.wrapping_add(1); let d2 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0); - pos += 1; + pos = pos.wrapping_add(1); let d3 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0); let b = m.unpack(state.b); @@ -121,13 +130,13 @@ fn refill_wide_impl( } let mut pos = state.pos64(m); let d0: Mach::u32x4 = m.unpack(state.d); - pos += 1; + pos = pos.wrapping_add(1); let d1 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0); - pos += 1; + pos = pos.wrapping_add(1); let d2 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0); - pos += 1; + pos = pos.wrapping_add(1); let d3 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0); - pos += 1; + pos = pos.wrapping_add(1); let d4 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0); let (a, b, c, d) = ( -- cgit v1.2.3