diff -Nru rust-rand-chacha-0.2.2/Cargo.toml rust-rand-chacha-0.3.1/Cargo.toml --- rust-rand-chacha-0.2.2/Cargo.toml 2020-03-10 10:48:55.000000000 +0000 +++ rust-rand-chacha-0.3.1/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 @@ -13,30 +13,33 @@ [package] edition = "2018" name = "rand_chacha" -version = "0.2.2" +version = "0.3.1" 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" -documentation = "https://rust-random.github.io/rand/rand_chacha/" +homepage = "https://rust-random.github.io/book" +documentation = "https://docs.rs/rand_chacha" readme = "README.md" keywords = ["random", "rng", "chacha"] 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" + +[dependencies.serde] +version = "1.0" +features = ["derive"] +optional = true +[dev-dependencies.serde_json] +version = "1.0" [features] -default = ["std", "simd"] +default = ["std"] +serde1 = ["serde"] simd = [] std = ["ppv-lite86/std"] -[badges.appveyor] -repository = "rust-random/rand" - -[badges.travis-ci] -repository = "rust-random/rand" diff -Nru rust-rand-chacha-0.2.2/Cargo.toml.orig rust-rand-chacha-0.3.1/Cargo.toml.orig --- rust-rand-chacha-0.2.2/Cargo.toml.orig 2020-02-28 14:36:58.000000000 +0000 +++ rust-rand-chacha-0.3.1/Cargo.toml.orig 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +1,12 @@ [package] name = "rand_chacha" -version = "0.2.2" +version = "0.3.1" authors = ["The Rand Project Developers", "The Rust Project Developers", "The CryptoCorrosion Contributors"] license = "MIT OR Apache-2.0" readme = "README.md" repository = "https://github.com/rust-random/rand" -documentation = "https://rust-random.github.io/rand/rand_chacha/" -homepage = "https://crates.io/crates/rand_chacha" +documentation = "https://docs.rs/rand_chacha" +homepage = "https://rust-random.github.io/book" description = """ ChaCha random number generator """ @@ -14,15 +14,17 @@ 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"] } +serde = { version = "1.0", features = ["derive"], optional = true } + +[dev-dependencies] +# Only to test serde1 +serde_json = "1.0" [features] -default = ["std", "simd"] +default = ["std"] std = ["ppv-lite86/std"] simd = [] # deprecated +serde1 = ["serde"] diff -Nru rust-rand-chacha-0.2.2/.cargo_vcs_info.json rust-rand-chacha-0.3.1/.cargo_vcs_info.json --- rust-rand-chacha-0.2.2/.cargo_vcs_info.json 2020-03-10 10:48:55.000000000 +0000 +++ rust-rand-chacha-0.3.1/.cargo_vcs_info.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +1,5 @@ { "git": { - "sha1": "e2112c4404c61d3850c0e91f48114db5daf06569" + "sha1": "98a0339f99ecfe0467b2829c329bd8b7525a1c21" } } diff -Nru rust-rand-chacha-0.2.2/CHANGELOG.md rust-rand-chacha-0.3.1/CHANGELOG.md --- rust-rand-chacha-0.2.2/CHANGELOG.md 2020-03-10 10:47:38.000000000 +0000 +++ rust-rand-chacha-0.3.1/CHANGELOG.md 1970-01-01 00:00:00.000000000 +0000 @@ -4,6 +4,19 @@ 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.1] - 2021-06-09 +- add getters corresponding to existing setters: `get_seed`, `get_stream` (#1124) +- add serde support, gated by the `serde1` feature (#1124) +- ensure expected layout via `repr(transparent)` (#1120) + +## [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 -Nru rust-rand-chacha-0.2.2/debian/cargo-checksum.json rust-rand-chacha-0.3.1/debian/cargo-checksum.json --- rust-rand-chacha-0.2.2/debian/cargo-checksum.json 2020-05-05 08:46:10.000000000 +0000 +++ rust-rand-chacha-0.3.1/debian/cargo-checksum.json 2022-02-05 09:04:53.000000000 +0000 @@ -1 +1 @@ -{"package":"f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402","files":{}} +{"package":"e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88","files":{}} diff -Nru rust-rand-chacha-0.2.2/debian/changelog rust-rand-chacha-0.3.1/debian/changelog --- rust-rand-chacha-0.2.2/debian/changelog 2020-05-05 08:46:10.000000000 +0000 +++ rust-rand-chacha-0.3.1/debian/changelog 2022-02-05 09:04:53.000000000 +0000 @@ -1,3 +1,19 @@ +rust-rand-chacha (0.3.1-2) unstable; urgency=medium + + * Team upload. + * Package rand_chacha 0.3.1 from crates.io using debcargo 2.5.0 + * Upload to unstable. + + -- Peter Michael Green Sat, 05 Feb 2022 09:04:53 +0000 + +rust-rand-chacha (0.3.1-1) experimental; urgency=medium + + * Team upload. + * Package rand_chacha 0.3.1 from crates.io using debcargo 2.5.0 + * Use collapse_features = true + + -- Peter Michael Green Sat, 22 Jan 2022 13:23:15 +0000 + rust-rand-chacha (0.2.2-1) unstable; urgency=medium * Package rand_chacha 0.2.2 from crates.io using debcargo 2.4.3 diff -Nru rust-rand-chacha-0.2.2/debian/compat rust-rand-chacha-0.3.1/debian/compat --- rust-rand-chacha-0.2.2/debian/compat 2020-05-05 08:46:10.000000000 +0000 +++ rust-rand-chacha-0.3.1/debian/compat 2022-02-05 09:04:53.000000000 +0000 @@ -1 +1 @@ -11 +12 diff -Nru rust-rand-chacha-0.2.2/debian/control rust-rand-chacha-0.3.1/debian/control --- rust-rand-chacha-0.2.2/debian/control 2020-05-05 08:46:10.000000000 +0000 +++ rust-rand-chacha-0.3.1/debian/control 2022-02-05 09:04:53.000000000 +0000 @@ -1,73 +1,58 @@ Source: rust-rand-chacha Section: rust Priority: optional -Build-Depends: debhelper (>= 11), - dh-cargo (>= 18), +Build-Depends: debhelper (>= 12), + dh-cargo (>= 25), cargo:native , rustc:native , libstd-rust-dev , - librust-ppv-lite86-0.2+simd-dev (>= 0.2.6-~~) , - librust-ppv-lite86-0.2+std-dev (>= 0.2.6-~~) , - librust-rand-core-0.5+default-dev + librust-ppv-lite86-0.2+simd-dev (>= 0.2.8-~~) , + librust-ppv-lite86-0.2+std-dev (>= 0.2.8-~~) , + librust-rand-core-0.6+default-dev Maintainer: Debian Rust Maintainers Uploaders: Wolfgang Silbermayr -Standards-Version: 4.4.1 +Standards-Version: 4.5.1 Vcs-Git: https://salsa.debian.org/rust-team/debcargo-conf.git [src/rand-chacha] Vcs-Browser: https://salsa.debian.org/rust-team/debcargo-conf/tree/master/src/rand-chacha -Homepage: https://crates.io/crates/rand_chacha +Homepage: https://rust-random.github.io/book X-Cargo-Crate: rand_chacha +Rules-Requires-Root: no Package: librust-rand-chacha-dev Architecture: any Multi-Arch: same Depends: ${misc:Depends}, - librust-ppv-lite86-0.2+simd-dev (>= 0.2.6-~~), - librust-rand-core-0.5+default-dev -Recommends: - librust-rand-chacha+default-dev (= ${binary:Version}) -Suggests: - librust-rand-chacha+std-dev (= ${binary:Version}) + librust-ppv-lite86-0.2+simd-dev (>= 0.2.8-~~), + librust-ppv-lite86-0.2+std-dev (>= 0.2.8-~~), + librust-rand-core-0.6+default-dev, + librust-serde-1+default-dev, + librust-serde-1+derive-dev Provides: + librust-rand-chacha+default-dev (= ${binary:Version}), + librust-rand-chacha+serde-dev (= ${binary:Version}), + librust-rand-chacha+serde1-dev (= ${binary:Version}), librust-rand-chacha+simd-dev (= ${binary:Version}), + librust-rand-chacha+std-dev (= ${binary:Version}), librust-rand-chacha-0-dev (= ${binary:Version}), + librust-rand-chacha-0+default-dev (= ${binary:Version}), + librust-rand-chacha-0+serde-dev (= ${binary:Version}), + librust-rand-chacha-0+serde1-dev (= ${binary:Version}), librust-rand-chacha-0+simd-dev (= ${binary:Version}), - librust-rand-chacha-0.2-dev (= ${binary:Version}), - librust-rand-chacha-0.2+simd-dev (= ${binary:Version}), - librust-rand-chacha-0.2.2-dev (= ${binary:Version}), - librust-rand-chacha-0.2.2+simd-dev (= ${binary:Version}) + librust-rand-chacha-0+std-dev (= ${binary:Version}), + librust-rand-chacha-0.3-dev (= ${binary:Version}), + librust-rand-chacha-0.3+default-dev (= ${binary:Version}), + librust-rand-chacha-0.3+serde-dev (= ${binary:Version}), + librust-rand-chacha-0.3+serde1-dev (= ${binary:Version}), + librust-rand-chacha-0.3+simd-dev (= ${binary:Version}), + librust-rand-chacha-0.3+std-dev (= ${binary:Version}), + librust-rand-chacha-0.3.1-dev (= ${binary:Version}), + librust-rand-chacha-0.3.1+default-dev (= ${binary:Version}), + librust-rand-chacha-0.3.1+serde-dev (= ${binary:Version}), + librust-rand-chacha-0.3.1+serde1-dev (= ${binary:Version}), + librust-rand-chacha-0.3.1+simd-dev (= ${binary:Version}), + librust-rand-chacha-0.3.1+std-dev (= ${binary:Version}) Description: ChaCha random number generator - Rust source code This package contains the source for the Rust rand_chacha crate, packaged by debcargo for use with cargo and dh-cargo. - -Package: librust-rand-chacha+default-dev -Architecture: any -Multi-Arch: same -Depends: - ${misc:Depends}, - librust-rand-chacha-dev (= ${binary:Version}), - librust-rand-chacha+std-dev (= ${binary:Version}), - librust-rand-chacha+simd-dev (= ${binary:Version}) -Provides: - librust-rand-chacha-0+default-dev (= ${binary:Version}), - librust-rand-chacha-0.2+default-dev (= ${binary:Version}), - librust-rand-chacha-0.2.2+default-dev (= ${binary:Version}) -Description: ChaCha random number generator - feature "default" - This metapackage enables feature "default" for the Rust rand_chacha crate, by - pulling in any additional dependencies needed by that feature. - -Package: librust-rand-chacha+std-dev -Architecture: any -Multi-Arch: same -Depends: - ${misc:Depends}, - librust-rand-chacha-dev (= ${binary:Version}), - librust-ppv-lite86-0.2+std-dev (>= 0.2.6-~~) -Provides: - librust-rand-chacha-0+std-dev (= ${binary:Version}), - librust-rand-chacha-0.2+std-dev (= ${binary:Version}), - librust-rand-chacha-0.2.2+std-dev (= ${binary:Version}) -Description: ChaCha random number generator - feature "std" - This metapackage enables feature "std" for the Rust rand_chacha crate, by - pulling in any additional dependencies needed by that feature. diff -Nru rust-rand-chacha-0.2.2/debian/copyright rust-rand-chacha-0.3.1/debian/copyright --- rust-rand-chacha-0.2.2/debian/copyright 2020-05-05 08:46:10.000000000 +0000 +++ rust-rand-chacha-0.3.1/debian/copyright 2022-02-05 09:04:53.000000000 +0000 @@ -9,13 +9,13 @@ Files: * Copyright: 2018-2019 The CryptoCorrosion Contributors - 2018-2020 The Rand Project Developers + 2018-2021 The Rand Project Developers 2013-2018 The Rust Project Developers License: MIT or Apache-2.0 Files: debian/* Copyright: - 2018-2020 Debian Rust Maintainers + 2018-2022 Debian Rust Maintainers 2018-2020 Wolfgang Silbermayr License: MIT or Apache-2.0 diff -Nru rust-rand-chacha-0.2.2/debian/copyright.debcargo.hint rust-rand-chacha-0.3.1/debian/copyright.debcargo.hint --- rust-rand-chacha-0.2.2/debian/copyright.debcargo.hint 2020-05-05 08:46:10.000000000 +0000 +++ rust-rand-chacha-0.3.1/debian/copyright.debcargo.hint 2022-02-05 09:04:53.000000000 +0000 @@ -52,8 +52,8 @@ Files: debian/* Copyright: - 2019-2020 Debian Rust Maintainers - 2019-2020 Wolfgang Silbermayr + 2019-2022 Debian Rust Maintainers + 2019-2022 Wolfgang Silbermayr License: MIT or Apache-2.0 License: Apache-2.0 diff -Nru rust-rand-chacha-0.2.2/debian/debcargo.toml rust-rand-chacha-0.3.1/debian/debcargo.toml --- rust-rand-chacha-0.2.2/debian/debcargo.toml 2020-05-05 08:46:10.000000000 +0000 +++ rust-rand-chacha-0.3.1/debian/debcargo.toml 2022-02-05 09:04:53.000000000 +0000 @@ -1,2 +1,3 @@ overlay = "." uploaders = ["Wolfgang Silbermayr "] +collapse_features = true diff -Nru rust-rand-chacha-0.2.2/debian/rules rust-rand-chacha-0.3.1/debian/rules --- rust-rand-chacha-0.2.2/debian/rules 2020-05-05 08:46:10.000000000 +0000 +++ rust-rand-chacha-0.3.1/debian/rules 2022-02-05 09:04:53.000000000 +0000 @@ -1,6 +1,3 @@ #!/usr/bin/make -f %: dh $@ --buildsystem cargo - -override_dh_auto_test: - dh_auto_test -- test --all diff -Nru rust-rand-chacha-0.2.2/debian/tests/control rust-rand-chacha-0.3.1/debian/tests/control --- rust-rand-chacha-0.2.2/debian/tests/control 2020-05-05 08:46:10.000000000 +0000 +++ rust-rand-chacha-0.3.1/debian/tests/control 2022-02-05 09:04:53.000000000 +0000 @@ -1,19 +1,34 @@ -Test-Command: /usr/share/cargo/bin/cargo-auto-test rand_chacha 0.2.2 --all-targets --all-features -Features: test-name=@ -Depends: dh-cargo (>= 18), @ +Test-Command: /usr/share/cargo/bin/cargo-auto-test rand_chacha 0.3.1 --all-targets --all-features +Features: test-name=rust-rand-chacha:@ +Depends: dh-cargo (>= 18), librust-serde-json-1+default-dev, @ Restrictions: allow-stderr, skip-not-installable -Test-Command: /usr/share/cargo/bin/cargo-auto-test rand_chacha 0.2.2 --all-targets --no-default-features -Features: test-name=librust-rand-chacha-dev -Depends: dh-cargo (>= 18), @ +Test-Command: /usr/share/cargo/bin/cargo-auto-test rand_chacha 0.3.1 --all-targets +Features: test-name=librust-rand-chacha-dev:default +Depends: dh-cargo (>= 18), librust-serde-json-1+default-dev, @ Restrictions: allow-stderr, skip-not-installable -Test-Command: /usr/share/cargo/bin/cargo-auto-test rand_chacha 0.2.2 --all-targets --features default -Features: test-name=librust-rand-chacha+default-dev -Depends: dh-cargo (>= 18), @ +Test-Command: /usr/share/cargo/bin/cargo-auto-test rand_chacha 0.3.1 --all-targets --no-default-features --features serde +Features: test-name=librust-rand-chacha-dev:serde +Depends: dh-cargo (>= 18), librust-serde-json-1+default-dev, @ Restrictions: allow-stderr, skip-not-installable -Test-Command: /usr/share/cargo/bin/cargo-auto-test rand_chacha 0.2.2 --all-targets --features std -Features: test-name=librust-rand-chacha+std-dev -Depends: dh-cargo (>= 18), @ +Test-Command: /usr/share/cargo/bin/cargo-auto-test rand_chacha 0.3.1 --all-targets --no-default-features --features serde1 +Features: test-name=librust-rand-chacha-dev:serde1 +Depends: dh-cargo (>= 18), librust-serde-json-1+default-dev, @ +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test rand_chacha 0.3.1 --all-targets --no-default-features --features simd +Features: test-name=librust-rand-chacha-dev:simd +Depends: dh-cargo (>= 18), librust-serde-json-1+default-dev, @ +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test rand_chacha 0.3.1 --all-targets --no-default-features --features std +Features: test-name=librust-rand-chacha-dev:std +Depends: dh-cargo (>= 18), librust-serde-json-1+default-dev, @ +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test rand_chacha 0.3.1 --all-targets --no-default-features +Features: test-name=librust-rand-chacha-dev: +Depends: dh-cargo (>= 18), librust-serde-json-1+default-dev, @ Restrictions: allow-stderr, skip-not-installable diff -Nru rust-rand-chacha-0.2.2/README.md rust-rand-chacha-0.3.1/README.md --- rust-rand-chacha-0.2.2/README.md 2019-10-12 09:26:57.000000000 +0000 +++ rust-rand-chacha-0.3.1/README.md 1970-01-01 00:00:00.000000000 +0000 @@ -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 -Nru rust-rand-chacha-0.2.2/src/chacha.rs rust-rand-chacha-0.3.1/src/chacha.rs --- rust-rand-chacha-0.2.2/src/chacha.rs 2020-03-10 10:38:58.000000000 +0000 +++ rust-rand-chacha-0.3.1/src/chacha.rs 1970-01-01 00:00:00.000000000 +0000 @@ -16,9 +16,14 @@ use rand_core::block::{BlockRng, BlockRngCore}; use rand_core::{CryptoRng, Error, RngCore, SeedableRng}; -const STREAM_PARAM_NONCE: u32 = 1; -const STREAM_PARAM_BLOCK: u32 = 0; +#[cfg(feature = "serde1")] use serde::{Serialize, Deserialize, Serializer, Deserializer}; +// 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; + +#[repr(transparent)] pub struct Array64([T; 64]); impl Default for Array64 where T: Default @@ -63,9 +68,9 @@ } macro_rules! chacha_impl { - ($ChaChaXCore:ident, $ChaChaXRng:ident, $rounds:expr, $doc:expr) => { + ($ChaChaXCore:ident, $ChaChaXRng:ident, $rounds:expr, $doc:expr, $abst:ident) => { #[doc=$doc] - #[derive(Clone)] + #[derive(Clone, PartialEq, Eq)] pub struct $ChaChaXCore { state: ChaCha, } @@ -187,10 +192,19 @@ /// 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_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 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 @@ /// 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); + .set_block_pos(block); + self.rng.generate_and_set((word_offset % u128::from(BLOCK_WORDS)) as usize); } /// Set the stream number. @@ -224,12 +238,30 @@ self.rng .core .state - .set_stream_param(STREAM_PARAM_NONCE, stream); + .set_nonce(stream); if self.rng.index() != 64 { let wp = self.get_word_pos(); self.set_word_pos(wp); } } + + /// Get the stream number. + #[inline] + pub fn get_stream(&self) -> u64 { + self.rng + .core + .state + .get_nonce() + } + + /// Get the seed. + #[inline] + pub fn get_seed(&self) -> [u8; 32] { + self.rng + .core + .state + .get_seed() + } } impl CryptoRng for $ChaChaXRng {} @@ -241,19 +273,132 @@ } } } + + impl PartialEq<$ChaChaXRng> for $ChaChaXRng { + fn eq(&self, rhs: &$ChaChaXRng) -> bool { + let a: $abst::$ChaChaXRng = self.into(); + let b: $abst::$ChaChaXRng = rhs.into(); + a == b + } + } + impl Eq for $ChaChaXRng {} + + #[cfg(feature = "serde1")] + impl Serialize for $ChaChaXRng { + fn serialize(&self, s: S) -> Result + where S: Serializer { + $abst::$ChaChaXRng::from(self).serialize(s) + } + } + #[cfg(feature = "serde1")] + impl<'de> Deserialize<'de> for $ChaChaXRng { + fn deserialize(d: D) -> Result where D: Deserializer<'de> { + $abst::$ChaChaXRng::deserialize(d).map(|x| Self::from(&x)) + } + } + + mod $abst { + #[cfg(feature = "serde1")] use serde::{Serialize, Deserialize}; + + // The abstract state of a ChaCha stream, independent of implementation choices. The + // comparison and serialization of this object is considered a semver-covered part of + // the API. + #[derive(Debug, PartialEq, Eq)] + #[cfg_attr( + feature = "serde1", + derive(Serialize, Deserialize), + )] + pub(crate) struct $ChaChaXRng { + seed: [u8; 32], + stream: u64, + word_pos: u128, + } + + impl From<&super::$ChaChaXRng> for $ChaChaXRng { + // Forget all information about the input except what is necessary to determine the + // outputs of any sequence of pub API calls. + fn from(r: &super::$ChaChaXRng) -> Self { + Self { + seed: r.get_seed(), + stream: r.get_stream(), + word_pos: r.get_word_pos(), + } + } + } + + impl From<&$ChaChaXRng> for super::$ChaChaXRng { + // Construct one of the possible concrete RNGs realizing an abstract state. + fn from(a: &$ChaChaXRng) -> Self { + use rand_core::SeedableRng; + let mut r = Self::from_seed(a.seed); + r.set_stream(a.stream); + r.set_word_pos(a.word_pos); + r + } + } + } } } -chacha_impl!(ChaCha20Core, ChaCha20Rng, 10, "ChaCha with 20 rounds"); -chacha_impl!(ChaCha12Core, ChaCha12Rng, 6, "ChaCha with 12 rounds"); -chacha_impl!(ChaCha8Core, ChaCha8Rng, 4, "ChaCha with 8 rounds"); +chacha_impl!(ChaCha20Core, ChaCha20Rng, 10, "ChaCha with 20 rounds", abstract20); +chacha_impl!(ChaCha12Core, ChaCha12Rng, 6, "ChaCha with 12 rounds", abstract12); +chacha_impl!(ChaCha8Core, ChaCha8Rng, 4, "ChaCha with 8 rounds", abstract8); #[cfg(test)] mod test { use rand_core::{RngCore, SeedableRng}; + #[cfg(feature = "serde1")] use super::{ChaCha20Rng, ChaCha12Rng, ChaCha8Rng}; + type ChaChaRng = super::ChaCha20Rng; + #[cfg(feature = "serde1")] + #[test] + fn test_chacha_serde_roundtrip() { + let seed = [ + 1, 0, 52, 0, 0, 0, 0, 0, 1, 0, 10, 0, 22, 32, 0, 0, 2, 0, 55, 49, 0, 11, 0, 0, 3, 0, 0, 0, 0, + 0, 2, 92, + ]; + let mut rng1 = ChaCha20Rng::from_seed(seed); + let mut rng2 = ChaCha12Rng::from_seed(seed); + let mut rng3 = ChaCha8Rng::from_seed(seed); + + let encoded1 = serde_json::to_string(&rng1).unwrap(); + let encoded2 = serde_json::to_string(&rng2).unwrap(); + let encoded3 = serde_json::to_string(&rng3).unwrap(); + + let mut decoded1: ChaCha20Rng = serde_json::from_str(&encoded1).unwrap(); + let mut decoded2: ChaCha12Rng = serde_json::from_str(&encoded2).unwrap(); + let mut decoded3: ChaCha8Rng = serde_json::from_str(&encoded3).unwrap(); + + assert_eq!(rng1, decoded1); + assert_eq!(rng2, decoded2); + assert_eq!(rng3, decoded3); + + assert_eq!(rng1.next_u32(), decoded1.next_u32()); + assert_eq!(rng2.next_u32(), decoded2.next_u32()); + assert_eq!(rng3.next_u32(), decoded3.next_u32()); + } + + // This test validates that: + // 1. a hard-coded serialization demonstrating the format at time of initial release can still + // be deserialized to a ChaChaRng + // 2. re-serializing the resultant object produces exactly the original string + // + // Condition 2 is stronger than necessary: an equivalent serialization (e.g. with field order + // permuted, or whitespace differences) would also be admissible, but would fail this test. + // However testing for equivalence of serialized data is difficult, and there shouldn't be any + // reason we need to violate the stronger-than-needed condition, e.g. by changing the field + // definition order. + #[cfg(feature = "serde1")] + #[test] + fn test_chacha_serde_format_stability() { + let j = r#"{"seed":[4,8,15,16,23,42,4,8,15,16,23,42,4,8,15,16,23,42,4,8,15,16,23,42,4,8,15,16,23,42,4,8],"stream":27182818284,"word_pos":314159265359}"#; + let r: ChaChaRng = serde_json::from_str(&j).unwrap(); + let j1 = serde_json::to_string(&r).unwrap(); + assert_eq!(j, j1); + } + #[test] fn test_chacha_construction() { let seed = [ @@ -456,4 +601,32 @@ 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 -Nru rust-rand-chacha-0.2.2/src/guts.rs rust-rand-chacha-0.3.1/src/guts.rs --- rust-rand-chacha-0.2.2/src/guts.rs 2020-02-28 14:36:58.000000000 +0000 +++ rust-rand-chacha-0.3.1/src/guts.rs 1970-01-01 00:00:00.000000000 +0000 @@ -21,7 +21,10 @@ pub(crate) const BUFSZ64: u64 = BLOCK64 * BUFBLOCKS; pub(crate) const BUFSZ: usize = BUFSZ64 as usize; -#[derive(Clone)] +const STREAM_PARAM_NONCE: u32 = 1; +const STREAM_PARAM_BLOCK: u32 = 0; + +#[derive(Clone, PartialEq, Eq)] pub struct ChaCha { pub(crate) b: vec128_storage, pub(crate) c: vec128_storage, @@ -83,16 +86,32 @@ } #[inline(always)] - pub fn set_stream_param(&mut self, param: u32, value: u64) { - set_stream_param(self, param, value) + pub fn set_block_pos(&mut self, value: u64) { + set_stream_param(self, STREAM_PARAM_BLOCK, value) + } + + #[inline(always)] + pub fn get_block_pos(&self) -> u64 { + get_stream_param(self, STREAM_PARAM_BLOCK) + } + + #[inline(always)] + pub fn set_nonce(&mut self, value: u64) { + set_stream_param(self, STREAM_PARAM_NONCE, value) } #[inline(always)] - pub fn get_stream_param(&self, param: u32) -> u64 { - get_stream_param(self, param) + pub fn get_nonce(&self) -> u64 { + get_stream_param(self, STREAM_PARAM_NONCE) + } + + #[inline(always)] + pub fn get_seed(&self) -> [u8; 32] { + get_seed(self) } } +#[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 +119,11 @@ 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 +140,13 @@ } 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) = ( @@ -196,6 +215,17 @@ } }); +dispatch_light128!(m, Mach, { + fn get_seed(state: &ChaCha) -> [u8; 32] { + let b: Mach::u32x4 = m.unpack(state.b); + let c: Mach::u32x4 = m.unpack(state.c); + let mut key = [0u8; 32]; + b.write_le(&mut key[..16]); + c.write_le(&mut key[16..]); + key + } +}); + fn read_u32le(xs: &[u8]) -> u32 { assert_eq!(xs.len(), 4); u32::from(xs[0]) | (u32::from(xs[1]) << 8) | (u32::from(xs[2]) << 16) | (u32::from(xs[3]) << 24)