summaryrefslogtreecommitdiffstats
path: root/third_party/rust/prio/src/prng.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:43:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:43:14 +0000
commit8dd16259287f58f9273002717ec4d27e97127719 (patch)
tree3863e62a53829a84037444beab3abd4ed9dfc7d0 /third_party/rust/prio/src/prng.rs
parentReleasing progress-linux version 126.0.1-1~progress7.99u1. (diff)
downloadfirefox-8dd16259287f58f9273002717ec4d27e97127719.tar.xz
firefox-8dd16259287f58f9273002717ec4d27e97127719.zip
Merging upstream version 127.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/prio/src/prng.rs')
-rw-r--r--third_party/rust/prio/src/prng.rs71
1 files changed, 40 insertions, 31 deletions
diff --git a/third_party/rust/prio/src/prng.rs b/third_party/rust/prio/src/prng.rs
index cb7d3a54c8..2c3f5b6640 100644
--- a/third_party/rust/prio/src/prng.rs
+++ b/third_party/rust/prio/src/prng.rs
@@ -6,10 +6,9 @@
//! NOTE: The public API for this module is a work in progress.
use crate::field::{FieldElement, FieldElementExt};
-#[cfg(feature = "crypto-dependencies")]
+#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
use crate::vdaf::xof::SeedStreamAes128;
-#[cfg(feature = "crypto-dependencies")]
-use getrandom::getrandom;
+use crate::vdaf::xof::{Seed, SeedStreamTurboShake128, Xof, XofTurboShake128};
use rand_core::RngCore;
use std::marker::PhantomData;
@@ -19,6 +18,7 @@ const BUFFER_SIZE_IN_ELEMENTS: usize = 32;
/// Errors propagated by methods in this module.
#[derive(Debug, thiserror::Error)]
+#[non_exhaustive]
pub enum PrngError {
/// Failure when calling getrandom().
#[error("getrandom: {0}")]
@@ -35,7 +35,7 @@ pub(crate) struct Prng<F, S> {
buffer_index: usize,
}
-#[cfg(feature = "crypto-dependencies")]
+#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
impl<F: FieldElement> Prng<F, SeedStreamAes128> {
/// Create a [`Prng`] from a seed for Prio 2. The first 16 bytes of the seed and the last 16
/// bytes of the seed are used, respectively, for the key and initialization vector for AES128
@@ -44,12 +44,17 @@ impl<F: FieldElement> Prng<F, SeedStreamAes128> {
let seed_stream = SeedStreamAes128::new(&seed[..16], &seed[16..]);
Self::from_seed_stream(seed_stream)
}
+}
+impl<F: FieldElement> Prng<F, SeedStreamTurboShake128> {
/// Create a [`Prng`] from a randomly generated seed.
pub(crate) fn new() -> Result<Self, PrngError> {
- let mut seed = [0; 32];
- getrandom(&mut seed)?;
- Ok(Self::from_prio2_seed(&seed))
+ let seed = Seed::generate()?;
+ Ok(Prng::from_seed_stream(XofTurboShake128::seed_stream(
+ &seed,
+ &[],
+ &[],
+ )))
}
}
@@ -125,18 +130,20 @@ where
#[cfg(test)]
mod tests {
use super::*;
+ #[cfg(feature = "experimental")]
+ use crate::field::{encode_fieldvec, Field128, FieldPrio2};
use crate::{
codec::Decode,
- field::{Field64, FieldPrio2},
- vdaf::xof::{Seed, SeedStreamSha3, Xof, XofShake128},
+ field::Field64,
+ vdaf::xof::{Seed, SeedStreamTurboShake128, Xof, XofTurboShake128},
};
- #[cfg(feature = "prio2")]
+ #[cfg(feature = "experimental")]
use base64::{engine::Engine, prelude::BASE64_STANDARD};
- #[cfg(feature = "prio2")]
+ #[cfg(feature = "experimental")]
use sha2::{Digest, Sha256};
- use std::convert::TryInto;
#[test]
+ #[cfg(feature = "experimental")]
fn secret_sharing_interop() {
let seed = [
0xcd, 0x85, 0x5b, 0xd4, 0x86, 0x48, 0xa4, 0xce, 0x52, 0x5c, 0x36, 0xee, 0x5a, 0x71,
@@ -158,21 +165,22 @@ mod tests {
}
/// takes a seed and hash as base64 encoded strings
- #[cfg(feature = "prio2")]
+ #[cfg(feature = "experimental")]
fn random_data_interop(seed_base64: &str, hash_base64: &str, len: usize) {
let seed = BASE64_STANDARD.decode(seed_base64).unwrap();
let random_data = extract_share_from_seed::<FieldPrio2>(len, &seed);
- let random_bytes = FieldPrio2::slice_into_byte_vec(&random_data);
+ let mut random_bytes = Vec::new();
+ encode_fieldvec(&random_data, &mut random_bytes).unwrap();
- let mut hasher = Sha256::new();
+ let mut hasher = <Sha256 as Digest>::new();
hasher.update(&random_bytes);
let digest = hasher.finalize();
assert_eq!(BASE64_STANDARD.encode(digest), hash_base64);
}
#[test]
- #[cfg(feature = "prio2")]
+ #[cfg(feature = "experimental")]
fn test_hash_interop() {
random_data_interop(
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
@@ -206,6 +214,7 @@ mod tests {
);
}
+ #[cfg(feature = "experimental")]
fn extract_share_from_seed<F: FieldElement>(length: usize, seed: &[u8]) -> Vec<F> {
assert_eq!(seed.len(), 32);
Prng::from_prio2_seed(seed.try_into().unwrap())
@@ -218,22 +227,22 @@ mod tests {
// These constants were found in a brute-force search, and they test that the XOF performs
// rejection sampling correctly when the raw output exceeds the prime modulus.
let seed = Seed::get_decoded(&[
- 0x29, 0xb2, 0x98, 0x64, 0xb4, 0xaa, 0x4e, 0x07, 0x2a, 0x44, 0x49, 0x24, 0xf6, 0x74,
- 0x0a, 0x3d,
+ 0xd5, 0x3f, 0xff, 0x5d, 0x88, 0x8c, 0x60, 0x4e, 0x9f, 0x24, 0x16, 0xe1, 0xa2, 0x0a,
+ 0x62, 0x34,
])
.unwrap();
- let expected = Field64::from(2035552711764301796);
+ let expected = Field64::from(3401316594827516850);
- let seed_stream = XofShake128::seed_stream(&seed, b"", b"");
+ let seed_stream = XofTurboShake128::seed_stream(&seed, b"", b"");
let mut prng = Prng::<Field64, _>::from_seed_stream(seed_stream);
- let actual = prng.nth(33236).unwrap();
+ let actual = prng.nth(662).unwrap();
assert_eq!(actual, expected);
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
{
- let mut seed_stream = XofShake128::seed_stream(&seed, b"", b"");
+ let mut seed_stream = XofTurboShake128::seed_stream(&seed, b"", b"");
let mut actual = <Field64 as FieldElement>::zero();
- for _ in 0..=33236 {
+ for _ in 0..=662 {
actual = <Field64 as crate::idpf::IdpfValue>::generate(&mut seed_stream, &());
}
assert_eq!(actual, expected);
@@ -246,12 +255,12 @@ mod tests {
fn left_over_buffer_back_fill() {
let seed = Seed::generate().unwrap();
- let mut prng: Prng<Field64, SeedStreamSha3> =
- Prng::from_seed_stream(XofShake128::seed_stream(&seed, b"", b""));
+ let mut prng: Prng<Field64, SeedStreamTurboShake128> =
+ Prng::from_seed_stream(XofTurboShake128::seed_stream(&seed, b"", b""));
// Construct a `Prng` with a longer-than-usual buffer.
- let mut prng_weird_buffer_size: Prng<Field64, SeedStreamSha3> =
- Prng::from_seed_stream(XofShake128::seed_stream(&seed, b"", b""));
+ let mut prng_weird_buffer_size: Prng<Field64, SeedStreamTurboShake128> =
+ Prng::from_seed_stream(XofTurboShake128::seed_stream(&seed, b"", b""));
let mut extra = [0; 7];
prng_weird_buffer_size.seed_stream.fill_bytes(&mut extra);
prng_weird_buffer_size.buffer.extend_from_slice(&extra);
@@ -265,13 +274,13 @@ mod tests {
#[cfg(feature = "experimental")]
#[test]
- fn into_new_field() {
+ fn into_different_field() {
let seed = Seed::generate().unwrap();
- let want: Prng<Field64, SeedStreamSha3> =
- Prng::from_seed_stream(XofShake128::seed_stream(&seed, b"", b""));
+ let want: Prng<Field64, SeedStreamTurboShake128> =
+ Prng::from_seed_stream(XofTurboShake128::seed_stream(&seed, b"", b""));
let want_buffer = want.buffer.clone();
- let got: Prng<FieldPrio2, _> = want.into_new_field();
+ let got: Prng<Field128, _> = want.into_new_field();
assert_eq!(got.buffer_index, 0);
assert_eq!(got.buffer, want_buffer);
}