summaryrefslogtreecommitdiffstats
path: root/vendor/rand_chacha
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/rand_chacha
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/rand_chacha')
-rw-r--r--vendor/rand_chacha/.cargo-checksum.json2
-rw-r--r--vendor/rand_chacha/CHANGELOG.md5
-rw-r--r--vendor/rand_chacha/Cargo.toml14
-rw-r--r--vendor/rand_chacha/src/chacha.rs145
-rw-r--r--vendor/rand_chacha/src/guts.rs41
5 files changed, 182 insertions, 25 deletions
diff --git a/vendor/rand_chacha/.cargo-checksum.json b/vendor/rand_chacha/.cargo-checksum.json
index 293de38d6..a7100e9bc 100644
--- a/vendor/rand_chacha/.cargo-checksum.json
+++ b/vendor/rand_chacha/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"ad5ed93d0f6e7c9adad7ce346b05ba5585275f689a1ae1aa176baab5f95266c7","COPYRIGHT":"90eb64f0279b0d9432accfa6023ff803bc4965212383697eee27a0f426d5f8d5","Cargo.toml":"1ea33201f9d2687c4a7201073efe3ddd9c7fe4ffef1307b22ccbf8e4a7537488","LICENSE-APACHE":"aaff376532ea30a0cd5330b9502ad4a4c8bf769c539c87ffe78819d188a18ebf","LICENSE-MIT":"209fbbe0ad52d9235e37badf9cadfe4dbdc87203179c0899e738b39ade42177b","README.md":"f4221f35b7086649fa77807e826af020b57eb65b19cb693482d4a7e1e4d80537","src/chacha.rs":"c48699c02df8e8fb654e9cb9feddaf432e367539da40bbfe2b8a0f4189797dee","src/guts.rs":"b378faf7648a510653cec160bd4a01dca65790e530a8a9bdebc6e5c9e1faf70a","src/lib.rs":"a27fe2bff676a764d43d604a20cf30a41dc1c5ef4053eb41129d2479f5ae83fe"},"package":"e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"deb20cd6e8be14e767b7fdea0e503ddd8226afd1253a5221aacc28a23d45db20","COPYRIGHT":"90eb64f0279b0d9432accfa6023ff803bc4965212383697eee27a0f426d5f8d5","Cargo.toml":"e2ef45f3c9d6f013da266b76ca1e1f664ad5fa1d526b46580a77fb311c659fd8","LICENSE-APACHE":"aaff376532ea30a0cd5330b9502ad4a4c8bf769c539c87ffe78819d188a18ebf","LICENSE-MIT":"209fbbe0ad52d9235e37badf9cadfe4dbdc87203179c0899e738b39ade42177b","README.md":"f4221f35b7086649fa77807e826af020b57eb65b19cb693482d4a7e1e4d80537","src/chacha.rs":"dfd79ed4762e8267148d1776381c71b898808014a4069cfafbc78177247d5fe9","src/guts.rs":"898fd129897fb44d15053044227307ee2bf416970adb8e63b4f5eabb7431aa1e","src/lib.rs":"a27fe2bff676a764d43d604a20cf30a41dc1c5ef4053eb41129d2479f5ae83fe"},"package":"e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"} \ No newline at end of file
diff --git a/vendor/rand_chacha/CHANGELOG.md b/vendor/rand_chacha/CHANGELOG.md
index 8a0739007..a598bb7ee 100644
--- a/vendor/rand_chacha/CHANGELOG.md
+++ b/vendor/rand_chacha/CHANGELOG.md
@@ -4,6 +4,11 @@ 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.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)
diff --git a/vendor/rand_chacha/Cargo.toml b/vendor/rand_chacha/Cargo.toml
index 0f371b3c3..c907ae974 100644
--- a/vendor/rand_chacha/Cargo.toml
+++ b/vendor/rand_chacha/Cargo.toml
@@ -13,11 +13,11 @@
[package]
edition = "2018"
name = "rand_chacha"
-version = "0.3.0"
+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"]
@@ -31,7 +31,15 @@ default-features = false
[dependencies.rand_core]
version = "0.6.0"
+[dependencies.serde]
+version = "1.0"
+features = ["derive"]
+optional = true
+[dev-dependencies.serde_json]
+version = "1.0"
+
[features]
default = ["std"]
+serde1 = ["serde"]
simd = []
std = ["ppv-lite86/std"]
diff --git a/vendor/rand_chacha/src/chacha.rs b/vendor/rand_chacha/src/chacha.rs
index 17bcc5528..50da81bfa 100644
--- a/vendor/rand_chacha/src/chacha.rs
+++ b/vendor/rand_chacha/src/chacha.rs
@@ -16,14 +16,14 @@ use crate::guts::ChaCha;
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>([T; 64]);
impl<T> Default for Array64<T>
where T: Default
@@ -68,7 +68,7 @@ impl<T> fmt::Debug for Array64<T> {
}
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, PartialEq, Eq)]
pub struct $ChaChaXCore {
@@ -193,7 +193,7 @@ 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_stream_param(STREAM_PARAM_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) = {
@@ -218,7 +218,7 @@ macro_rules! chacha_impl {
self.rng
.core
.state
- .set_stream_param(STREAM_PARAM_BLOCK, block);
+ .set_block_pos(block);
self.rng.generate_and_set((word_offset % u128::from(BLOCK_WORDS)) as usize);
}
@@ -238,12 +238,30 @@ macro_rules! chacha_impl {
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 {}
@@ -258,24 +276,129 @@ 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()
+ 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<S>(&self, s: S) -> Result<S::Ok, S::Error>
+ where S: Serializer {
+ $abst::$ChaChaXRng::from(self).serialize(s)
+ }
+ }
+ #[cfg(feature = "serde1")]
+ impl<'de> Deserialize<'de> for $ChaChaXRng {
+ fn deserialize<D>(d: D) -> Result<Self, D::Error> 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 = [
diff --git a/vendor/rand_chacha/src/guts.rs b/vendor/rand_chacha/src/guts.rs
index 27ff957a9..cee8cf75d 100644
--- a/vendor/rand_chacha/src/guts.rs
+++ b/vendor/rand_chacha/src/guts.rs
@@ -21,6 +21,9 @@ const BUFBLOCKS: u64 = 1 << LOG2_BUFBLOCKS;
pub(crate) const BUFSZ64: u64 = BLOCK64 * BUFBLOCKS;
pub(crate) const BUFSZ: usize = BUFSZ64 as usize;
+const STREAM_PARAM_NONCE: u32 = 1;
+const STREAM_PARAM_BLOCK: u32 = 0;
+
#[derive(Clone, PartialEq, Eq)]
pub struct ChaCha {
pub(crate) b: vec128_storage,
@@ -83,21 +86,28 @@ impl ChaCha {
}
#[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)
}
- /// 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]
+ #[inline(always)]
+ pub fn get_seed(&self) -> [u8; 32] {
+ get_seed(self)
}
}
@@ -205,6 +215,17 @@ dispatch_light128!(m, Mach, {
}
});
+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)