Package: rust-prio Once rust-getrandom, rust-rand, rust-rand-core and rust-rand-chacha migrate to testing, I hope to update the remainder of the rand stack.
Rust-prio has dependencies on rust-rand, rust-rand-core and rust-rand-distr. Upstream uses versions 0.9, 0.9 and 0.5 respectively. Debian is currently patching this down to versions 0.8, 0.6 and 0.4 respectively. I have removed the 0.8 related changes, and prepared a new patch for versions 0.10, 0.10 and 0.6 respectively. I have not investigated the impact of these changes in the API presented by the package, but rust-prio doesn't appear to have any current reverse dependencies in Debian, and the rand version currently used is already a deviation from upstream. The autopkgtest results are the same as with the version in sid (all tests except all-features fail).
diff -Nru rust-prio-0.17.0+ds/debian/changelog rust-prio-0.17.0+ds/debian/changelog --- rust-prio-0.17.0+ds/debian/changelog 2026-03-09 06:55:51.000000000 +0000 +++ rust-prio-0.17.0+ds/debian/changelog 2026-03-26 05:37:56.000000000 +0000 @@ -1,3 +1,11 @@ +rust-prio (0.17.0+ds-3.1) UNRELEASED; urgency=medium + + * Non-maintainer upload. + * Replace patch for rand 0.8 etc with patch for rand 0.10 etc. + + Tighten (build-)depends accordingly. + + -- Peter Michael Green <[email protected]> Thu, 26 Mar 2026 05:37:56 +0000 + rust-prio (0.17.0+ds-3) unstable; urgency=medium * fix patch 2001_no_bench diff -Nru rust-prio-0.17.0+ds/debian/control rust-prio-0.17.0+ds/debian/control --- rust-prio-0.17.0+ds/debian/control 2026-03-07 19:56:11.000000000 +0000 +++ rust-prio-0.17.0+ds/debian/control 2026-03-26 05:37:56.000000000 +0000 @@ -21,9 +21,9 @@ librust-num-rational-dev, librust-num-traits-dev, librust-once-cell-dev, - librust-rand-core-dev, - librust-rand-dev, - librust-rand-distr-dev, + librust-rand-core-0.10-dev, + librust-rand-0.10-dev, + librust-rand-distr-0.6-dev, librust-rayon-dev, librust-serde-dev, librust-serde-json-dev, @@ -55,9 +55,9 @@ librust-num-iter-dev, librust-num-rational-dev, librust-num-traits-dev, - librust-rand-core-dev, - librust-rand-dev, - librust-rand-distr-dev, + librust-rand-core-0.10-dev, + librust-rand-0.10-dev, + librust-rand-distr-0.6-dev, librust-rayon-dev, librust-serde-dev, librust-serde-json-dev, diff -Nru rust-prio-0.17.0+ds/debian/patches/2002_rand.patch rust-prio-0.17.0+ds/debian/patches/2002_rand.patch --- rust-prio-0.17.0+ds/debian/patches/2002_rand.patch 2026-03-07 20:00:06.000000000 +0000 +++ rust-prio-0.17.0+ds/debian/patches/2002_rand.patch 2026-03-26 05:37:23.000000000 +0000 @@ -1,1269 +1,675 @@ -Description: use older minor versions of crates rand rand_core rand_distr - This essentially reverts upstream git comit e6983b5. -Author: Jonas Smedegaard <[email protected]> -Forwarded: not-needed -Last-Update: 2026-03-07 +Description: use newer minor versions of crates rand rand_core rand_distr +Author: Peter Michael Green <[email protected]> +Forwarded: no +Last-Update: 2026-03-26 --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ ---- a/Cargo.toml -+++ b/Cargo.toml -@@ -20,14 +20,14 @@ - fixed = { version = "1.27", optional = true } - hex = { version = "0.4.3", features = ["serde"], optional = true } - hmac = { version = "0.12.1", optional = true } --num-bigint = { version = "0.4.6", optional = true, features = ["serde"] } -+num-bigint = { version = "0.4.6", optional = true, features = ["rand", "serde"] } - num-integer = { version = "0.1.46", optional = true } +Index: rust-prio-0.17.0+ds/Cargo.toml +=================================================================== +--- rust-prio-0.17.0+ds.orig/Cargo.toml ++++ rust-prio-0.17.0+ds/Cargo.toml +@@ -25,9 +25,9 @@ num-integer = { version = "0.1.46", opti num-iter = { version = "0.1.45", optional = true } num-rational = { version = "0.4.2", optional = true, features = ["serde"] } num-traits = "0.2.19" -rand = "0.9" -rand_core = { version = "0.9", features = ["os_rng"] } -rand_distr = { version = "0.5", optional = true } -+rand = "0.8" -+rand_core = "0.6.4" -+rand_distr = { version = "0.4.3", optional = true } ++rand = "0.10" ++rand_core = "0.10" ++rand_distr = { version = "0.6", optional = true } rayon = { version = "1.10.0", optional = true } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0", optional = true } -@@ -43,7 +43,6 @@ +@@ -43,7 +43,7 @@ hex-literal = "0.4.1" num-bigint = "0.4.6" once_cell = "1.21.3" prio = { path = ".", features = ["crypto-dependencies", "test-util"] } -rand = { version = "0.9", features = ["std_rng"] } ++rand = { version = "0.10", features = ["std_rng"] } statrs = "0.18.0" [features] ---- a/benches/speed_tests.rs -+++ b/benches/speed_tests.rs -@@ -33,7 +33,7 @@ - vdaf::poplar1::{Poplar1, Poplar1AggregationParam, Poplar1IdpfValue}, - }; - #[cfg(feature = "experimental")] --use rand::{distr::Distribution, random, rngs::StdRng, Rng, SeedableRng}; -+use rand::prelude::*; - #[cfg(feature = "experimental")] - use std::iter; - use std::{hint::black_box, time::Duration}; -@@ -784,8 +784,8 @@ - group.bench_with_input(BenchmarkId::from_parameter(size), size, |b, &size| { - let vdaf = Poplar1::new_turboshake128(size); - let mut rng = StdRng::seed_from_u64(RNG_SEED); -- let nonce = rng.random::<[u8; 16]>(); -- let bits = iter::repeat_with(|| rng.random()) -+ let nonce = rng.gen::<[u8; 16]>(); -+ let bits = iter::repeat_with(|| rng.gen()) - .take(size) - .collect::<Vec<bool>>(); - let measurement = IdpfInput::from_bools(&bits); -@@ -803,8 +803,8 @@ - group.bench_with_input(BenchmarkId::from_parameter(size), size, |b, &size| { - let vdaf = Poplar1::new_turboshake128(size); - let mut rng = StdRng::seed_from_u64(RNG_SEED); -- let verify_key: [u8; 32] = rng.random(); -- let nonce: [u8; 16] = rng.random(); -+ let verify_key: [u8; 32] = rng.gen(); -+ let nonce: [u8; 16] = rng.gen(); - - // Parameters are chosen to match Chris Wood's experimental setup: - // https://github.com/chris-wood/heavy-hitter-comparison ---- a/binaries/Cargo.toml -+++ b/binaries/Cargo.toml -@@ -9,5 +9,5 @@ - [dependencies] - base64 = "0.22.1" - fixed = "1.27" --rand = "0.9" -+rand = "0.8" - prio = { path = "..", features = ["experimental", "test-util"] } ---- a/binaries/src/bin/idpf_agg_param_size.rs -+++ b/binaries/src/bin/idpf_agg_param_size.rs -@@ -4,7 +4,7 @@ - codec::Encode, idpf::test_utils::generate_zipf_distributed_batch, - vdaf::poplar1::Poplar1AggregationParam, +Index: rust-prio-0.17.0+ds/src/vdaf/xof.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/vdaf/xof.rs ++++ rust-prio-0.17.0+ds/src/vdaf/xof.rs +@@ -30,8 +30,8 @@ use ctr::Ctr64BE; + #[cfg(feature = "crypto-dependencies")] + use hmac::{Hmac, Mac}; + use rand_core::{ +- impls::{next_u32_via_fill, next_u64_via_fill}, +- RngCore, SeedableRng, ++ utils::next_word_via_fill, ++ Rng, SeedableRng, }; --use rand::rng; -+use rand::prelude::*; - - fn main() { - let bits = 256; -@@ -16,7 +16,7 @@ - println!("Generating inputs and computing the prefix tree. This may take some time..."); - let start = Instant::now(); - let (_measurements, prefix_tree) = generate_zipf_distributed_batch( -- &mut rng(), -+ &mut thread_rng(), - bits, - threshold, - measurement_count, ---- a/src/dp.rs -+++ b/src/dp.rs -@@ -174,7 +174,6 @@ - } - pub mod distributions; --mod rand_bigint; + use rand::distr::{Distribution, StandardUniform}; +@@ -54,7 +54,7 @@ use subtle::{Choice, ConstantTimeEq}; + pub struct Seed<const SEED_SIZE: usize>(pub(crate) [u8; SEED_SIZE]); - #[cfg(test)] - mod tests { ---- a/src/dp/distributions.rs -+++ b/src/dp/distributions.rs -@@ -50,19 +50,18 @@ - //! Clément Canonne, Gautam Kamath, Thomas Steinke. The Discrete Gaussian for Differential Privacy. 2020. - //! <https://arxiv.org/pdf/2004.00010.pdf> + impl<const SEED_SIZE: usize> Distribution<Seed<SEED_SIZE>> for StandardUniform { +- fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Seed<SEED_SIZE> { ++ fn sample<R: rand::RngExt + ?Sized>(&self, rng: &mut R) -> Seed<SEED_SIZE> { + let mut seed_bytes = [0; SEED_SIZE]; + rng.fill(&mut seed_bytes[..]); + Seed(seed_bytes) +@@ -108,12 +108,12 @@ impl<const SEED_SIZE: usize> Decode for + } --use num_bigint::{BigInt, BigUint}; -+use num_bigint::{BigInt, BigUint, UniformBigUint}; - use num_integer::Integer; - use num_iter::range_inclusive; - use num_rational::Ratio; - use num_traits::{One, Zero}; --use rand::{distr::Distribution, Rng}; -+use rand::{distributions::uniform::UniformSampler, distributions::Distribution, Rng}; - use serde::{Deserialize, Serialize}; + /// Trait for deriving a vector of field elements. +-pub trait IntoFieldVec: RngCore + Sized { ++pub trait IntoFieldVec: Rng + Sized { + /// Generate a finite field vector from the seed stream. + fn into_field_vec<F: FieldElement>(self, length: usize) -> Vec<F>; + } - use super::{ - DifferentialPrivacyBudget, DifferentialPrivacyDistribution, DifferentialPrivacyStrategy, - DpError, PureDpBudget, ZCdpBudget, - }; --use crate::dp::rand_bigint::UniformBigUint; +-impl<S: RngCore> IntoFieldVec for S { ++impl<S: Rng> IntoFieldVec for S { + fn into_field_vec<F: FieldElement>(self, length: usize) -> Vec<F> { + Prng::from_seed_stream(self).take(length).collect() + } +@@ -124,7 +124,7 @@ impl<S: RngCore> IntoFieldVec for S { + /// [draft-irtf-cfrg-vdaf-08]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/08/ + pub trait Xof<const SEED_SIZE: usize>: Clone + Debug { + /// The type of stream produced by this XOF. +- type SeedStream: RngCore + Sized; ++ type SeedStream: Rng + Sized; + + /// Construct an instance of [`Xof`] with the given seed. + fn init(seed_bytes: &[u8; SEED_SIZE], dst_parts: &[&[u8]]) -> Self; +@@ -178,17 +178,19 @@ impl SeedStreamAes128 { + } - /// Sample from the Bernoulli(gamma) distribution, where $gamma /leq 1$. - /// -@@ -76,12 +75,9 @@ - assert!(!d.is_zero()); - assert!(gamma <= &Ratio::<BigUint>::one()); + #[cfg(feature = "crypto-dependencies")] +-impl RngCore for SeedStreamAes128 { +- fn fill_bytes(&mut self, dest: &mut [u8]) { ++impl rand_core::TryRng for SeedStreamAes128 { ++ type Error = core::convert::Infallible; ++ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> { + self.fill(dest); ++ Ok(()) + } -- // Sample uniform biguint in {1,...,d}. -- // Unwrap safety: this cannot fail because the denominator cannot be zero, and therefore the -- // range [1, d] is well-formed. -- let s = UniformBigUint::new_inclusive(&BigUint::one(), d) -- .unwrap() -- .sample(rng); -+ // sample uniform biguint in {1,...,d} -+ // uses the implementation of rand::Uniform for num_bigint::BigUint -+ let s = UniformBigUint::sample_single_inclusive(BigUint::one(), d, rng); +- fn next_u32(&mut self) -> u32 { +- next_u32_via_fill(self) ++ fn try_next_u32(&mut self) -> Result<u32, Self::Error> { ++ next_word_via_fill(self) + } - s <= *gamma.numer() +- fn next_u64(&mut self) -> u64 { +- next_u64_via_fill(self) ++ fn try_next_u64(&mut self) -> Result<u64, Self::Error>{ ++ next_word_via_fill(self) + } } -@@ -138,9 +134,9 @@ - return BigUint::zero(); + +@@ -263,17 +265,19 @@ impl SeedStreamTurboShake128 { } + } -- // Sampler for uniform biguint in {0...t-1}. -- // Unwrap safety: this range is always valid because the denominator of `gamma` must be nonzero. -- let usampler = UniformBigUint::new(&BigUint::zero(), t).unwrap(); -+ // sampler for uniform biguint in {0...t-1} -+ // uses the implementation of rand::Uniform for num_bigint::BigUint -+ let usampler = UniformBigUint::new(BigUint::zero(), t); - let mut u = usampler.sample(rng); - - while !sample_bernoulli_exp1(&Ratio::<BigUint>::new(u.clone(), t.clone()), rng) { -@@ -385,7 +381,7 @@ - - use num_bigint::{BigUint, Sign, ToBigInt, ToBigUint}; - use num_traits::{One, Signed, ToPrimitive}; -- use rand::{distr::Distribution, SeedableRng}; -+ use rand::{distributions::Distribution, SeedableRng}; - use statrs::distribution::{ChiSquared, ContinuousCDF, Normal}; - use std::collections::HashMap; - ---- a/src/dp/rand_bigint.rs -+++ /dev/null -@@ -1,115 +0,0 @@ --// Copyright (c) 2025 ISRG --// SPDX-License-Identifier: MPL-2.0 AND Apache-2.0 --// --// Portions of this file are derived from the num-bigint crate --// (https://docs.rs/num-bigint/0.4.6/) --// Copyright 2013-2014 The Rust Project Developers --// Licensed under the Apache 2.0 license --// --// This file contains code covered by the following copyright and permission notice --// and has been modified by ISRG and collaborators. --// --// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT --// file at the top-level directory of this distribution and at --// http://rust-lang.org/COPYRIGHT. --// --// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or --// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license --// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your --// option. This file may not be copied, modified, or distributed --// except according to those terms. -- --//! Helper functions to randomly generate big integers, sampled from uniform distributions. --//! --//! These were vendored from num-bigint. Unused functionality has been deleted, trait --//! implementations have been transformed into free functions, use of the private --//! `biguint_from_vec()` function has been replaced, use of the `SampleBorrow` trait has been --//! removed, method names and signatures have been updated to align with rand 0.9, and documentation --//! has been updated. -- --use num_bigint::BigUint; --use num_integer::Integer; --use num_traits::{ToPrimitive, Zero}; --use rand::distr::uniform::Error; --use rand::Rng; -- --/// Use [`Rng::fill`] to generate random bits. --/// --/// If `rem` is greater than zero, than only the lowest `rem` bits of the last u32 are filled with --/// random data. --/// --/// # Panics --/// --/// Panics if `rem` is greater than 32. --fn random_bits<R>(rng: &mut R, data: &mut [u32], rem: u64) --where -- R: Rng + ?Sized, --{ -- // `fill` is faster than many `random::<u32>` calls -- rng.fill(data); -- if rem > 0 { -- let last = data.len() - 1; -- data[last] >>= 32 - rem; -- } --} -- --/// Uniformly generate a random [`BigUint`] in the range \[0, 2^`bits`). --fn random_biguint<R>(rng: &mut R, bit_size: u64) -> BigUint --where -- R: Rng + ?Sized, --{ -- let (digits, rem) = bit_size.div_rem(&32); -- let len = (digits + (rem > 0) as u64) -- .to_usize() -- .expect("capacity overflow"); -- let mut data = vec![0u32; len]; -- random_bits(rng, &mut data, rem); -- BigUint::new(data) --} -- --/// Uniformly generate a random [`BigUint`] in the range \[0, `bound`). --fn random_biguint_below<R>(rng: &mut R, bound: &BigUint) -> BigUint --where -- R: Rng + ?Sized, --{ -- assert!(!bound.is_zero()); -- let bits = bound.bits(); -- loop { -- let n = random_biguint(rng, bits); -- if n < *bound { -- return n; -- } -- } --} -- --/// Uniform distribution producing [`BigUint`]. --pub(super) struct UniformBigUint { -- base: BigUint, -- len: BigUint, --} -- --impl UniformBigUint { -- pub(super) fn new(low: &BigUint, high: &BigUint) -> Result<Self, Error> { -- if low >= high { -- return Err(Error::EmptyRange); -- } -- Ok(UniformBigUint { -- len: high - low, -- base: low.clone(), -- }) -- } -- -- pub(super) fn new_inclusive(low: &BigUint, high: &BigUint) -> Result<Self, Error> { -- if low > high { -- return Err(Error::EmptyRange); -- } -- Self::new(low, &(high + 1u32)) -- } -- -- pub(super) fn sample<R>(&self, rng: &mut R) -> BigUint -- where -- R: Rng + ?Sized, -- { -- &self.base + random_biguint_below(rng, &self.len) -- } --} ---- a/src/field.rs -+++ b/src/field.rs -@@ -13,7 +13,7 @@ - prng::Prng, - }; - use rand::{ -- distr::{Distribution, StandardUniform}, -+ distributions::{Distribution, Standard}, - Rng, - }; - use rand_core::RngCore; -@@ -774,7 +774,7 @@ - } - } +-impl RngCore for SeedStreamTurboShake128 { +- fn fill_bytes(&mut self, dest: &mut [u8]) { ++impl rand_core::TryRng for SeedStreamTurboShake128 { ++ type Error = core::convert::Infallible; ++ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> { + XofReader::read(&mut self.0, dest); ++ Ok(()) + } -- impl Distribution<$elem> for StandardUniform { -+ impl Distribution<$elem> for Standard { - fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $elem { - $elem::generate_random(rng) - } ---- a/src/flp/types/dp.rs -+++ b/src/flp/types/dp.rs -@@ -9,7 +9,7 @@ - use crate::vdaf::xof::SeedStreamTurboShake128; - use num_bigint::{BigInt, BigUint, TryFromBigIntError}; - use num_integer::Integer; --use rand::{distr::Distribution, Rng, SeedableRng}; -+use rand::{distributions::Distribution, Rng, SeedableRng}; +- fn next_u32(&mut self) -> u32 { +- next_u32_via_fill(self) ++ fn try_next_u32(&mut self) -> Result<u32, Self::Error> { ++ next_word_via_fill(self) + } - // TODO(#1071): This is implemented for the concrete fields `Field64` and `Field128` in order to - // avoid imposing the `BigInt: From<F::Integer>` bound on all callers. In the future, we may want to -@@ -28,7 +28,7 @@ - self.add_noise( - dp_strategy, - agg_result, -- &mut SeedStreamTurboShake128::from_os_rng(), -+ &mut SeedStreamTurboShake128::from_entropy(), - ) +- fn next_u64(&mut self) -> u64 { +- next_u64_via_fill(self) ++ fn try_next_u64(&mut self) -> Result<u64, Self::Error>{ ++ next_word_via_fill(self) } } -@@ -46,7 +46,7 @@ - self.add_noise( - dp_strategy, - agg_result, -- &mut SeedStreamTurboShake128::from_os_rng(), -+ &mut SeedStreamTurboShake128::from_entropy(), - ) - } + +@@ -481,17 +485,19 @@ impl SeedStreamFixedKeyAes128 { } -@@ -102,7 +102,7 @@ - self.add_noise( - dp_strategy, - agg_result, -- &mut SeedStreamTurboShake128::from_os_rng(), -+ &mut SeedStreamTurboShake128::from_entropy(), - ) + + #[cfg(all(feature = "crypto-dependencies", feature = "experimental"))] +-impl RngCore for SeedStreamFixedKeyAes128 { +- fn fill_bytes(&mut self, dest: &mut [u8]) { ++impl rand_core::TryRng for SeedStreamFixedKeyAes128 { ++ type Error = core::convert::Infallible; ++ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> { + self.fill(dest); ++ Ok(()) } - } -@@ -120,7 +120,7 @@ - self.add_noise( - dp_strategy, - agg_result, -- &mut SeedStreamTurboShake128::from_os_rng(), -+ &mut SeedStreamTurboShake128::from_entropy(), - ) + +- fn next_u32(&mut self) -> u32 { +- next_u32_via_fill(self) ++ fn try_next_u32(&mut self) -> Result<u32, Self::Error> { ++ next_word_via_fill(self) } - } ---- a/src/flp/types/fixedpoint_l2.rs -+++ b/src/flp/types/fixedpoint_l2.rs -@@ -635,7 +635,7 @@ - self.add_noise( - dp_strategy, - agg_result, -- &mut SeedStreamTurboShake128::from_os_rng(), -+ &mut SeedStreamTurboShake128::from_entropy(), - ) + +- fn next_u64(&mut self) -> u64 { +- next_u64_via_fill(self) ++ fn try_next_u64(&mut self) -> Result<u64, Self::Error>{ ++ next_word_via_fill(self) } } ---- a/src/fp.rs -+++ b/src/fp.rs -@@ -132,7 +132,7 @@ + +@@ -536,7 +542,7 @@ impl Xof<32> for XofHmacSha256Aes128 { + mod tests { + use super::*; + use crate::{field::Field128, vdaf::equality_comparison_test}; +- use rand::{rng, Rng, RngCore}; ++ use rand::{rng, RngExt, Rng}; + use serde::{Deserialize, Serialize}; + use std::{convert::TryInto, io::Cursor}; + +Index: rust-prio-0.17.0+ds/src/field.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/field.rs ++++ rust-prio-0.17.0+ds/src/field.rs +@@ -14,9 +14,9 @@ use crate::{ + }; + use rand::{ + distr::{Distribution, StandardUniform}, +- Rng, ++ RngExt, + }; +-use rand_core::RngCore; ++use rand_core::Rng; + use serde::{ + de::{DeserializeOwned, Visitor}, + Deserialize, Deserializer, Serialize, Serializer, +@@ -355,7 +355,7 @@ pub(crate) trait FieldElementExt: FieldE + + /// Generate a uniformly random field element from the provided source of random bytes using + /// rejection sampling. +- fn generate_random<S: RngCore + ?Sized>(seed_stream: &mut S) -> Self { ++ fn generate_random<S: Rng + ?Sized>(seed_stream: &mut S) -> Self { + // This is analogous to `Prng::get()`, but does not make use of a persistent buffer of + // output. + let mut buffer = [0u8; 64]; +@@ -775,7 +775,7 @@ macro_rules! make_field { + } + + impl Distribution<$elem> for StandardUniform { +- fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $elem { ++ fn sample<R: RngExt + ?Sized>(&self, rng: &mut R) -> $elem { + $elem::generate_random(rng) + } + } +Index: rust-prio-0.17.0+ds/src/fp.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/fp.rs ++++ rust-prio-0.17.0+ds/src/fp.rs +@@ -132,7 +132,7 @@ pub(crate) mod tests { // use modinverse::modinverse; use num_bigint::{BigInt, ToBigInt}; use num_traits::AsPrimitive; - use rand::{distr::Distribution, rng, Rng}; -+ use rand::{distributions::Distribution, thread_rng, Rng}; ++ use rand::{distr::Distribution, rng, RngExt}; use super::ops::Word; use crate::fp::{log2, FieldOps, FP128, FP32, FP64, MAX_ROOTS}; -@@ -241,8 +241,8 @@ - let u128_p = T::PRIME.as_(); - let big_p = &u128_p.to_bigint().unwrap(); - let big_zero = &BigInt::from(0); -- let uniform = rand::distr::Uniform::try_from(0..u128_p).unwrap(); -- let mut rng = rng(); -+ let uniform = rand::distributions::Uniform::from(0..u128_p); -+ let mut rng = thread_rng(); - - let mut weird_ints = Vec::from([ - 0, -@@ -263,8 +263,8 @@ - - let mut generate_random = || -> (W, BigInt) { - // Add bias to random element generation, to explore "interesting" inputs. -- let intu128 = if rng.random_ratio(1, 4) { -- weird_ints[rng.random_range(0..weird_ints.len())] -+ let intu128 = if rng.gen_ratio(1, 4) { -+ weird_ints[rng.gen_range(0..weird_ints.len())] - } else { - uniform.sample(&mut rng) - }; ---- a/src/idpf.rs -+++ b/src/idpf.rs -@@ -19,7 +19,7 @@ +Index: rust-prio-0.17.0+ds/src/idpf.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/idpf.rs ++++ rust-prio-0.17.0+ds/src/idpf.rs +@@ -19,7 +19,7 @@ use bitvec::{ vec::BitVec, view::BitView, }; -use rand::{rng, Rng, RngCore}; -+use rand::prelude::*; ++use rand::{rng, RngExt, Rng}; use std::{ collections::{HashMap, VecDeque}, fmt::Debug, -@@ -493,7 +493,7 @@ +@@ -175,7 +175,7 @@ pub trait IdpfValue: + /// Generate a pseudorandom value from a seed stream. + fn generate<S>(seed_stream: &mut S, parameter: &Self::ValueParameter) -> Self where - M: IntoIterator<Item = VI>, - { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - if input.is_empty() { - return Err( - IdpfError::InvalidParameter("invalid number of bits: 0".to_string()).into(), -@@ -1036,7 +1036,6 @@ - pub mod test_utils { - use super::*; +- S: RngCore; ++ S: Rng; -- use rand::distr::Distribution; - use rand_distr::Zipf; + /// Returns the additive identity. + fn zero(parameter: &Self::ValueParameter) -> Self; +@@ -195,7 +195,7 @@ where - /// Generate a set of IDPF inputs with the given bit length `bits`. They are sampled according -@@ -1059,13 +1058,13 @@ - // Generate random inputs. - let mut inputs = Vec::with_capacity(zipf_support); - for _ in 0..zipf_support { -- let bools: Vec<bool> = (0..bits).map(|_| rng.random()).collect(); -+ let bools: Vec<bool> = (0..bits).map(|_| rng.gen()).collect(); - inputs.push(IdpfInput::from_bools(&bools)); - } + fn generate<S>(seed_stream: &mut S, _: &()) -> Self + where +- S: RngCore, ++ S: Rng, + { + F::generate_random(seed_stream) + } +@@ -1049,7 +1049,7 @@ pub mod test_utils { + /// For any prefix `p` whose hit count is at least the desired threshold, add `p || 0` and `p || 1` + /// to the list. + pub fn generate_zipf_distributed_batch( +- rng: &mut impl Rng, ++ rng: &mut impl RngExt, + bits: usize, + threshold: usize, + measurement_count: usize, +@@ -2148,7 +2148,7 @@ mod tests { + + fn generate<S>(_: &mut S, _: &Self::ValueParameter) -> Self + where +- S: rand_core::RngCore, ++ S: rand_core::Rng, + { + MyUnit + } +@@ -2215,7 +2215,7 @@ mod tests { - // Sample a number of inputs according to the Zipf distribution. - let mut samples = Vec::with_capacity(measurement_count); -- let zipf = Zipf::new(zipf_support as f64, zipf_exponent).unwrap(); -+ let zipf = Zipf::new(zipf_support as u64, zipf_exponent).unwrap(); - for _ in 0..measurement_count { - samples.push(inputs[zipf.sample(rng).round() as usize - 1].clone()); - } ---- a/src/polynomial.rs -+++ b/src/polynomial.rs -@@ -235,7 +235,7 @@ - TestPolyAuxMemory, - }, - }; -- use rand::random; -+ use rand::prelude::*; - use std::convert::TryFrom; - - #[test] ---- a/src/prng.rs -+++ b/src/prng.rs -@@ -9,7 +9,7 @@ + fn generate<S>(seed_stream: &mut S, length: &Self::ValueParameter) -> Self + where +- S: rand_core::RngCore, ++ S: rand_core::Rng, + { + let mut output = vec![<Field128 as FieldElement>::zero(); *length]; + for element in output.iter_mut() { +Index: rust-prio-0.17.0+ds/src/prng.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/prng.rs ++++ rust-prio-0.17.0+ds/src/prng.rs +@@ -9,7 +9,7 @@ use crate::field::{FieldElement, FieldEl #[cfg(all(feature = "crypto-dependencies", feature = "experimental"))] use crate::vdaf::xof::SeedStreamAes128; use crate::vdaf::xof::{Seed, SeedStreamTurboShake128, Xof, XofTurboShake128}; -use rand::{rng, Rng, RngCore}; -+use rand::prelude::*; ++use rand::{rng, RngExt, Rng}; use std::marker::PhantomData; use std::ops::ControlFlow; -@@ -40,7 +40,7 @@ - impl<F: FieldElement> Prng<F, SeedStreamTurboShake128> { - /// Create a [`Prng`] from a randomly generated seed. - pub(crate) fn new() -> Self { -- let seed = rng().random::<Seed<32>>(); -+ let seed = thread_rng().gen::<Seed<32>>(); - Prng::from_seed_stream(XofTurboShake128::seed_stream(seed.as_ref(), &[], &[])) - } - } -@@ -241,7 +241,7 @@ - // once it reaches the end. - #[test] - fn left_over_buffer_back_fill() { -- let seed = rng().random::<Seed<32>>(); -+ let seed = thread_rng().gen::<Seed<32>>(); - - let mut prng: Prng<Field64, SeedStreamTurboShake128> = - Prng::from_seed_stream(XofTurboShake128::seed_stream(seed.as_ref(), &[], &[])); -@@ -263,7 +263,7 @@ - #[cfg(feature = "experimental")] - #[test] - fn into_different_field() { -- let seed = rng().random::<Seed<32>>(); -+ let seed = thread_rng().gen::<Seed<32>>(); - let want: Prng<Field64, SeedStreamTurboShake128> = - Prng::from_seed_stream(XofTurboShake128::seed_stream(seed.as_ref(), &[], &[])); - let want_buffer = want.buffer.clone(); ---- a/src/vdaf.rs -+++ b/src/vdaf.rs -@@ -479,7 +479,7 @@ +@@ -48,7 +48,7 @@ impl<F: FieldElement> Prng<F, SeedStream + impl<F, S> Prng<F, S> + where + F: FieldElement, +- S: RngCore, ++ S: Rng, + { + pub(crate) fn from_seed_stream(mut seed_stream: S) -> Self { + let mut buffer = vec![0; BUFFER_SIZE_IN_ELEMENTS * F::ENCODED_SIZE]; +@@ -105,7 +105,7 @@ where + impl<F, S> Iterator for Prng<F, S> + where + F: FieldElement, +- S: RngCore, ++ S: Rng, + { + type Item = F; + +Index: rust-prio-0.17.0+ds/src/vdaf.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/vdaf.rs ++++ rust-prio-0.17.0+ds/src/vdaf.rs +@@ -479,7 +479,7 @@ impl<F: FieldElement> Encode for Aggrega pub mod test_utils { use super::{Aggregatable, Aggregator, Client, Collector, PrepareTransition, VdafError}; use crate::codec::{Encode, ParameterizedDecode}; - use rand::{random, rng, Rng}; -+ use rand::prelude::*; ++ use rand::{random, rng, RngExt}; /// Execute the VDAF end-to-end and return the aggregate result. pub fn run_vdaf<V, M, const SEED_SIZE: usize>( -@@ -515,7 +515,7 @@ - M: IntoIterator<Item = (V::PublicShare, [u8; 16], I)>, - I: IntoIterator<Item = V::InputShare>, - { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let mut verify_key = [0; SEED_SIZE]; - rng.fill(&mut verify_key[..]); - ---- a/src/vdaf/dummy.rs -+++ b/src/vdaf/dummy.rs -@@ -346,17 +346,17 @@ +Index: rust-prio-0.17.0+ds/src/vidpf.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/vidpf.rs ++++ rust-prio-0.17.0+ds/src/vidpf.rs +@@ -15,7 +15,7 @@ use core::{ + }; + + use bitvec::prelude::{BitVec, Lsb0}; +-use rand::{rng, Rng, RngCore}; ++use rand::{rng, RngExt, Rng}; + use std::fmt::Debug; + use std::io::{Cursor, Read}; + use subtle::{Choice, ConditionallyNegatable, ConditionallySelectable, ConstantTimeEq}; +@@ -668,7 +668,7 @@ impl<F: FieldElement> IdpfValue for Vidp + /// The parameter determines the number of field elements in the vector. + type ValueParameter = usize; + +- fn generate<S: RngCore>(seed_stream: &mut S, length: &Self::ValueParameter) -> Self { ++ fn generate<S: Rng>(seed_stream: &mut S, length: &Self::ValueParameter) -> Self { + Self( + (0..*length) + .map(|_| <F as IdpfValue>::generate(seed_stream, &())) +Index: rust-prio-0.17.0+ds/src/vdaf/dummy.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/vdaf/dummy.rs ++++ rust-prio-0.17.0+ds/src/vdaf/dummy.rs +@@ -346,7 +346,7 @@ where mod tests { use super::*; use crate::vdaf::{test_utils::run_vdaf_sharded, Client}; - use rand::{rng, Rng}; -+ use rand::prelude::*; ++ use rand::{rng, RngExt}; fn run_test(rounds: u32, aggregation_parameter: u8) { let vdaf = Vdaf::new(rounds); - let mut verify_key = [0; 0]; -- rng().fill(&mut verify_key[..]); -+ thread_rng().fill(&mut verify_key[..]); - let measurements = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]; - - let mut sharded_measurements = Vec::new(); - for measurement in measurements { -- let nonce = rng().random(); -+ let nonce = thread_rng().gen(); - let (public_share, input_shares) = - vdaf.shard(b"dummy ctx", &measurement, &nonce).unwrap(); - ---- a/src/vdaf/mastic.rs -+++ b/src/vdaf/mastic.rs -@@ -23,7 +23,7 @@ +Index: rust-prio-0.17.0+ds/src/vdaf/mastic.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/vdaf/mastic.rs ++++ rust-prio-0.17.0+ds/src/vdaf/mastic.rs +@@ -23,7 +23,7 @@ use crate::{ use szk::{Szk, SzkJointShare, SzkProofShare, SzkQueryShare, SzkQueryState}; -use rand::{rng, Rng}; -+use rand::prelude::*; ++use rand::{rng, RngExt}; use std::io::{Cursor, Read}; use std::ops::BitAnd; use std::slice::from_ref; -@@ -345,14 +345,14 @@ - measurement: &(VidpfInput, T::Measurement), - nonce: &[u8; 16], - ) -> Result<(Self::PublicShare, Vec<Self::InputShare>), VdafError> { -- let mut rng = rng(); -- let vidpf_keys = rng.random(); -+ let mut rng = thread_rng(); -+ let vidpf_keys = rng.gen(); - let joint_random_opt = if self.szk.requires_joint_rand() { -- Some(rng.random()) -+ Some(rng.gen()) - } else { - None - }; -- let szk_random = rng.random(); -+ let szk_random = rng.gen(); - - self.shard_with_random( - ctx, -@@ -797,7 +797,7 @@ +@@ -797,7 +797,7 @@ mod tests { use crate::flp::gadgets::{Mul, ParallelSum}; use crate::flp::types::{Count, Histogram, Sum, SumVec}; use crate::vdaf::test_utils::run_vdaf; - use rand::{rng, Rng}; -+ use rand::{thread_rng, Rng}; ++ use rand::{rng, RngExt}; const CTX_STR: &[u8] = b"mastic ctx"; -@@ -809,7 +809,7 @@ - let mastic = Mastic::new(algorithm_id, sum_typ, 32).unwrap(); - - let mut nonce = [0u8; 16]; -- rng().fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - - let inputs = [ - VidpfInput::from_bytes(&[240u8, 0u8, 1u8, 4u8][..]), -@@ -888,7 +888,7 @@ - let mastic = Mastic::new(algorithm_id, sum_typ, 32).unwrap(); - - let mut nonce = [0u8; 16]; -- rng().fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - - let first_input = VidpfInput::from_bytes(&[15u8, 0u8, 1u8, 4u8][..]); - -@@ -939,7 +939,7 @@ - let mastic = Mastic::new(algorithm_id, sum_typ, 32).unwrap(); - - let mut nonce = [0u8; 16]; -- rng().fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - - let first_input = VidpfInput::from_bytes(&[15u8, 0u8, 1u8, 4u8][..]); - -@@ -960,7 +960,7 @@ - let mastic = Mastic::new(algorithm_id, count, 32).unwrap(); - - let mut nonce = [0u8; 16]; -- rng().fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - - let inputs = [ - VidpfInput::from_bytes(&[240u8, 0u8, 1u8, 4u8][..]), -@@ -1037,7 +1037,7 @@ - let mastic = Mastic::new(algorithm_id, count, 32).unwrap(); - - let mut nonce = [0u8; 16]; -- rng().fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - let first_input = VidpfInput::from_bytes(&[15u8, 0u8, 1u8, 4u8][..]); - - let (public, _) = mastic.shard(CTX_STR, &(first_input, true), &nonce).unwrap(); -@@ -1055,7 +1055,7 @@ - let mastic = Mastic::new(algorithm_id, count, 32).unwrap(); - - let mut nonce = [0u8; 16]; -- rng().fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - - let first_input = VidpfInput::from_bytes(&[15u8, 0u8, 1u8, 4u8][..]); - -@@ -1075,7 +1075,7 @@ - let mastic = Mastic::new(algorithm_id, sumvec, 32).unwrap(); - - let mut nonce = [0u8; 16]; -- rng().fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - - let inputs = [ - VidpfInput::from_bytes(&[240u8, 0u8, 1u8, 4u8][..]), -@@ -1163,7 +1163,7 @@ - let mastic = Mastic::new(algorithm_id, sumvec, 32).unwrap(); - - let mut nonce = [0u8; 16]; -- rng().fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - - let first_input = VidpfInput::from_bytes(&[15u8, 0u8, 1u8, 4u8][..]); - -@@ -1192,7 +1192,7 @@ - let mastic = Mastic::new(algorithm_id, sumvec, 32).unwrap(); - - let mut nonce = [0u8; 16]; -- rng().fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - - let first_input = VidpfInput::from_bytes(&[15u8, 0u8, 1u8, 4u8][..]); - -@@ -1223,7 +1223,7 @@ - let mastic = Mastic::new(algorithm_id, sumvec, 32).unwrap(); - - let mut nonce = [0u8; 16]; -- rng().fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - - let first_input = VidpfInput::from_bytes(&[15u8, 0u8, 1u8, 4u8][..]); - -@@ -1246,7 +1246,7 @@ - let mastic = Mastic::new(algorithm_id, sumvec, 32).unwrap(); - - let mut nonce = [0u8; 16]; -- rng().fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - - let first_input = VidpfInput::from_bytes(&[15u8, 0u8, 1u8, 4u8][..]); - ---- a/src/vdaf/mastic/szk.rs -+++ b/src/vdaf/mastic/szk.rs -@@ -664,19 +664,19 @@ - Flp, Type, - }, - }; -- use rand::{rng, Rng}; -+ use rand::{thread_rng, Rng}; - - fn generic_szk_test<T: Type>(typ: T, encoded_measurement: &[T::Field], valid: bool) { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let ctx = b"some application context"; - let mut nonce = [0u8; 16]; - let mut verify_key = [0u8; 32]; - let szk_typ = Szk::new(typ.clone(), 0); -- rng.fill(&mut verify_key[..]); -- rng.fill(&mut nonce[..]); -- let prove_rand_seed = rng.random(); -- let helper_seed = rng.random(); -- let leader_seed_opt = szk_typ.requires_joint_rand().then(|| rng.random()); -+ thread_rng().fill(&mut verify_key[..]); -+ thread_rng().fill(&mut nonce[..]); -+ let prove_rand_seed = rng.gen(); -+ let helper_seed = rng.gen(); -+ let leader_seed_opt = szk_typ.requires_joint_rand().then(|| rng.gen()); - let helper_input_share = T::Field::random_vector(szk_typ.typ.input_len()); - let mut leader_input_share = encoded_measurement.to_owned(); - sub_assign_vector(&mut leader_input_share, helper_input_share.iter().copied()); -@@ -741,7 +741,7 @@ - - //test mutated jr seed - if szk_typ.requires_joint_rand() { -- let joint_rand_seed_opt = Some(rng.random()); -+ let joint_rand_seed_opt = Some(rng.gen()); - if let Ok(()) = szk_typ.decide(joint_rand_seed_opt.clone(), joint_share) { - panic!("Leader accepted wrong jr seed"); - }; -@@ -831,16 +831,16 @@ - - #[test] - fn test_sum_proof_share_encode() { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let mut nonce = [0u8; 16]; - let max_measurement = 13; -- rng.fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - let sum = Sum::<Field128>::new(max_measurement).unwrap(); - let encoded_measurement = sum.encode_measurement(&9).unwrap(); - let szk_typ = Szk::new(sum, 0); -- let prove_rand_seed = rng.random(); -- let helper_seed = rng.random(); -- let leader_seed_opt = Some(rng.random()); -+ let prove_rand_seed = rng.gen(); -+ let helper_seed = rng.gen(); -+ let leader_seed_opt = Some(rng.gen()); - let helper_input_share = Field128::random_vector(szk_typ.typ.input_len()); - let mut leader_input_share = encoded_measurement.clone().to_owned(); - sub_assign_vector(&mut leader_input_share, helper_input_share.iter().copied()); -@@ -865,16 +865,16 @@ - - #[test] - fn test_sumvec_proof_share_encode() { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let mut nonce = [0u8; 16]; -- rng.fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - let sumvec = - SumVec::<Field128, ParallelSum<Field128, Mul<Field128>>>::new(5, 3, 3).unwrap(); - let encoded_measurement = sumvec.encode_measurement(&vec![1, 16, 0]).unwrap(); - let szk_typ = Szk::new(sumvec, 0); -- let prove_rand_seed = rng.random(); -- let helper_seed = rng.random(); -- let leader_seed_opt = Some(rng.random()); -+ let prove_rand_seed = rng.gen(); -+ let helper_seed = rng.gen(); -+ let leader_seed_opt = Some(rng.gen()); - let helper_input_share = Field128::random_vector(szk_typ.typ.input_len()); - let mut leader_input_share = encoded_measurement.clone().to_owned(); - sub_assign_vector(&mut leader_input_share, helper_input_share.iter().copied()); -@@ -899,15 +899,15 @@ - - #[test] - fn test_count_proof_share_encode() { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let mut nonce = [0u8; 16]; -- rng.fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - let count = Count::<Field128>::new(); - let encoded_measurement = count.encode_measurement(&true).unwrap(); - let szk_typ = Szk::new(count, 0); -- let prove_rand_seed = rng.random(); -- let helper_seed = rng.random(); -- let leader_seed_opt = Some(rng.random()); -+ let prove_rand_seed = rng.gen(); -+ let helper_seed = rng.gen(); -+ let leader_seed_opt = Some(rng.gen()); - let helper_input_share = Field128::random_vector(szk_typ.typ.input_len()); - let mut leader_input_share = encoded_measurement.clone().to_owned(); - sub_assign_vector(&mut leader_input_share, helper_input_share.iter().copied()); -@@ -932,15 +932,15 @@ - - #[test] - fn test_sum_leader_proof_share_roundtrip() { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let max_measurement = 13; - let mut nonce = [0u8; 16]; -- rng.fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - let sum = Sum::<Field128>::new(max_measurement).unwrap(); - let encoded_measurement = sum.encode_measurement(&9).unwrap(); - let szk_typ = Szk::new(sum, 0); -- let prove_rand_seed = rng.random(); -- let helper_seed = rng.random(); -+ let prove_rand_seed = rng.gen(); -+ let helper_seed = rng.gen(); - let leader_seed_opt = None; - let helper_input_share = Field128::random_vector(szk_typ.typ.input_len()); - let mut leader_input_share = encoded_measurement.clone().to_owned(); -@@ -972,15 +972,15 @@ - - #[test] - fn test_sum_helper_proof_share_roundtrip() { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let max_measurement = 13; - let mut nonce = [0u8; 16]; -- rng.fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - let sum = Sum::<Field128>::new(max_measurement).unwrap(); - let encoded_measurement = sum.encode_measurement(&9).unwrap(); - let szk_typ = Szk::new(sum, 0); -- let prove_rand_seed = rng.random(); -- let helper_seed = rng.random(); -+ let prove_rand_seed = rng.gen(); -+ let helper_seed = rng.gen(); - let leader_seed_opt = None; - let helper_input_share = Field128::random_vector(szk_typ.typ.input_len()); - let mut leader_input_share = encoded_measurement.clone().to_owned(); -@@ -1012,14 +1012,14 @@ - - #[test] - fn test_count_leader_proof_share_roundtrip() { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let mut nonce = [0u8; 16]; -- rng.fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - let count = Count::<Field128>::new(); - let encoded_measurement = count.encode_measurement(&true).unwrap(); - let szk_typ = Szk::new(count, 0); -- let prove_rand_seed = rng.random(); -- let helper_seed = rng.random(); -+ let prove_rand_seed = rng.gen(); -+ let helper_seed = rng.gen(); - let leader_seed_opt = None; - let helper_input_share = Field128::random_vector(szk_typ.typ.input_len()); - let mut leader_input_share = encoded_measurement.clone().to_owned(); -@@ -1051,14 +1051,14 @@ - - #[test] - fn test_count_helper_proof_share_roundtrip() { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let mut nonce = [0u8; 16]; -- rng.fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - let count = Count::<Field128>::new(); - let encoded_measurement = count.encode_measurement(&true).unwrap(); - let szk_typ = Szk::new(count, 0); -- let prove_rand_seed = rng.random(); -- let helper_seed = rng.random(); -+ let prove_rand_seed = rng.gen(); -+ let helper_seed = rng.gen(); - let leader_seed_opt = None; - let helper_input_share = Field128::random_vector(szk_typ.typ.input_len()); - let mut leader_input_share = encoded_measurement.clone().to_owned(); -@@ -1090,16 +1090,16 @@ - - #[test] - fn test_sumvec_leader_proof_share_roundtrip() { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let mut nonce = [0u8; 16]; -- rng.fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - let sumvec = - SumVec::<Field128, ParallelSum<Field128, Mul<Field128>>>::new(5, 3, 3).unwrap(); - let encoded_measurement = sumvec.encode_measurement(&vec![1, 16, 0]).unwrap(); - let szk_typ = Szk::new(sumvec, 0); -- let prove_rand_seed = rng.random(); -- let helper_seed = rng.random(); -- let leader_seed_opt = Some(rng.random()); -+ let prove_rand_seed = rng.gen(); -+ let helper_seed = rng.gen(); -+ let leader_seed_opt = Some(rng.gen()); - let helper_input_share = Field128::random_vector(szk_typ.typ.input_len()); - let mut leader_input_share = encoded_measurement.clone().to_owned(); - sub_assign_vector(&mut leader_input_share, helper_input_share.iter().copied()); -@@ -1130,16 +1130,16 @@ - - #[test] - fn test_sumvec_helper_proof_share_roundtrip() { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let mut nonce = [0u8; 16]; -- rng.fill(&mut nonce[..]); -+ thread_rng().fill(&mut nonce[..]); - let sumvec = - SumVec::<Field128, ParallelSum<Field128, Mul<Field128>>>::new(5, 3, 3).unwrap(); - let encoded_measurement = sumvec.encode_measurement(&vec![1, 16, 0]).unwrap(); - let szk_typ = Szk::new(sumvec, 0); -- let prove_rand_seed = rng.random(); -- let helper_seed = rng.random(); -- let leader_seed_opt = Some(rng.random()); -+ let prove_rand_seed = rng.gen(); -+ let helper_seed = rng.gen(); -+ let leader_seed_opt = Some(rng.gen()); - let helper_input_share = Field128::random_vector(szk_typ.typ.input_len()); - let mut leader_input_share = encoded_measurement.clone().to_owned(); - sub_assign_vector(&mut leader_input_share, helper_input_share.iter().copied()); ---- a/src/vdaf/poplar1.rs -+++ b/src/vdaf/poplar1.rs -@@ -14,7 +14,7 @@ +Index: rust-prio-0.17.0+ds/src/vdaf/poplar1.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/vdaf/poplar1.rs ++++ rust-prio-0.17.0+ds/src/vdaf/poplar1.rs +@@ -14,7 +14,7 @@ use crate::{ Aggregatable, Aggregator, Client, Collector, PrepareTransition, Vdaf, VdafError, VERSION, }, }; -use rand::{rng, Rng, RngCore}; -+use rand::prelude::*; ++use rand::{rng, RngExt, Rng}; use std::{ collections::BTreeSet, convert::TryFrom, -@@ -1044,7 +1044,7 @@ - input: &IdpfInput, - nonce: &[u8; 16], - ) -> Result<(Self::PublicShare, Vec<Poplar1InputShare<SEED_SIZE>>), VdafError> { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let mut idpf_random = [[0u8; 16]; 2]; - let mut poplar_random = [[0u8; SEED_SIZE]; 3]; - for random_seed in idpf_random.iter_mut() { -@@ -1605,7 +1605,7 @@ - measurements: impl IntoIterator<Item = B>, - expected_result: impl IntoIterator<Item = B>, - ) { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - - // Sharding step - let reports: Vec<( -@@ -1615,7 +1615,7 @@ - )> = measurements - .into_iter() - .map(|measurement| { -- let nonce = rng.random(); -+ let nonce = rng.gen(); - let (public_share, input_shares) = vdaf - .shard( - CTX_STR, -@@ -1701,11 +1701,11 @@ - - #[test] - fn shard_prepare() { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let vdaf = Poplar1::new_turboshake128(64); -- let verify_key = rng.random(); -+ let verify_key = rng.gen(); - let input = IdpfInput::from_bytes(b"12341324"); -- let nonce = rng.random(); -+ let nonce = rng.gen(); - let (public_share, input_shares) = vdaf.shard(CTX_STR, &input, &nonce).unwrap(); - - test_prepare( -@@ -1744,8 +1744,8 @@ - - #[test] - fn heavy_hitters() { -- let mut rng = rng(); -- let verify_key = rng.random(); -+ let mut rng = thread_rng(); -+ let verify_key = rng.gen(); - let vdaf = Poplar1::new_turboshake128(8); - - run_heavy_hitters( -@@ -1761,12 +1761,12 @@ - - #[test] - fn encoded_len() { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - - // Input share - let input_share = Poplar1InputShare { -- idpf_key: rng.random::<Seed<16>>(), -- corr_seed: rng.random::<Seed<16>>(), -+ idpf_key: rng.gen::<Seed<16>>(), -+ corr_seed: rng.gen::<Seed<16>>(), - corr_inner: vec![ - [Field64::one(), <Field64 as FieldElement>::zero()], - [Field64::one(), <Field64 as FieldElement>::zero()], ---- a/src/vdaf/prio2.rs -+++ b/src/vdaf/prio2.rs -@@ -19,7 +19,7 @@ +@@ -1360,7 +1360,7 @@ impl From<IdpfOutputShare<Poplar1IdpfVal + // seed, rather than iteratively, as we do in Doplar. This would be more efficient for the + // Aggregators. As long as the Client isn't significantly slower, this should be a win. + #[allow(non_snake_case)] +-fn compute_next_corr_shares<F: FieldElement + From<u64>, S: RngCore>( ++fn compute_next_corr_shares<F: FieldElement + From<u64>, S: Rng>( + prng: &mut Prng<F, S>, + corr_prng_0: &mut Prng<F, S>, + corr_prng_1: &mut Prng<F, S>, +@@ -1451,7 +1451,7 @@ where + Self([F::zero(); 2]) + } + +- fn generate<S: RngCore>(seed_stream: &mut S, _: &()) -> Self { ++ fn generate<S: Rng>(seed_stream: &mut S, _: &()) -> Self { + Self([F::generate(seed_stream, &()), F::generate(seed_stream, &())]) + } + +Index: rust-prio-0.17.0+ds/src/vdaf/prio2.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/vdaf/prio2.rs ++++ rust-prio-0.17.0+ds/src/vdaf/prio2.rs +@@ -19,7 +19,7 @@ use crate::{ }, }; use hmac::{Hmac, Mac}; -use rand::{rng, Rng, RngCore}; -+use rand::prelude::*; ++use rand::{rng, RngExt, Rng}; use sha2::Sha256; use std::{convert::TryFrom, io::Cursor}; use subtle::{Choice, ConstantTimeEq}; -@@ -147,7 +147,7 @@ - measurement: &Vec<u32>, - _nonce: &[u8; 16], - ) -> Result<(Self::PublicShare, Vec<Share<FieldPrio2, 32>>), VdafError> { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - if measurement.len() != self.input_len { - return Err(VdafError::Uncategorized("incorrect input length".into())); - } -@@ -162,7 +162,7 @@ - }; - let mut leader_data = mem.prove_with(self.input_len, copy_data); - -- let helper_seed = rng.random(); -+ let helper_seed = rng.gen(); - let helper_prng = Prng::from_prio2_seed(&helper_seed); - for (s1, d) in leader_data.iter_mut().zip(helper_prng.into_iter()) { - *s1 -= d; -@@ -429,9 +429,9 @@ - - #[test] - fn prepare_state_serialization() { -- let mut rng = rng(); -- let verify_key = rng.random::<[u8; 32]>(); -- let nonce = rng.random::<[u8; 16]>(); -+ let mut rng = thread_rng(); -+ let verify_key = rng.gen::<[u8; 32]>(); -+ let nonce = rng.gen::<[u8; 16]>(); - let data = vec![0, 0, 1, 1, 0]; - let prio2 = Prio2::new(data.len()).unwrap(); - let (public_share, input_shares) = prio2.shard(CTX_STR, &data, &nonce).unwrap(); ---- a/src/vdaf/prio2/client.rs -+++ b/src/vdaf/prio2/client.rs -@@ -11,7 +11,7 @@ - vdaf::{xof::SeedStreamAes128, VdafError}, - }; - --use rand::{rng, Rng}; -+use rand::prelude::*; - use std::convert::TryFrom; - - /// Serialization errors -@@ -40,7 +40,7 @@ - - impl<F: NttFriendlyFieldElement> ClientMemory<F> { - pub(crate) fn new(dimension: usize) -> Result<Self, VdafError> { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let n = (dimension + 1).next_power_of_two(); - if let Ok(size) = F::Integer::try_from(2 * n) { - if size > F::generator_order() { -@@ -55,7 +55,7 @@ - } - - Ok(Self { -- prng: Prng::from_prio2_seed(&rng.random()), -+ prng: Prng::from_prio2_seed(&rng.gen()), - points_f: vec![F::zero(); n], - points_g: vec![F::zero(); n], - evals_f: vec![F::zero(); 2 * n], ---- a/src/vdaf/prio3.rs -+++ b/src/vdaf/prio3.rs -@@ -61,7 +61,7 @@ +@@ -104,7 +104,7 @@ impl Prio2 { + /// The point returned is not one of the roots used for polynomial interpolation. + pub(crate) fn choose_eval_at<S>(&self, prng: &mut Prng<FieldPrio2, S>) -> FieldPrio2 + where +- S: RngCore, ++ S: Rng, + { + // Make sure the query randomness isn't a root of unity. Evaluating the proof at any of + // these points would be a privacy violation, since these points were used by the prover to +Index: rust-prio-0.17.0+ds/src/vdaf/prio3.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/vdaf/prio3.rs ++++ rust-prio-0.17.0+ds/src/vdaf/prio3.rs +@@ -61,7 +61,7 @@ use crate::vdaf::{ }; #[cfg(feature = "experimental")] use fixed::traits::Fixed; -use rand::{rng, Rng}; -+use rand::prelude::*; ++use rand::{rng, RngExt}; use std::borrow::Cow; use std::convert::TryFrom; use std::fmt::Debug; -@@ -376,19 +376,19 @@ +@@ -376,7 +376,7 @@ impl Prio3Average { /// Aggregator, Client, Collector, PrepareTransition, /// prio3::Prio3, /// }; -/// use rand::{rng, Rng, RngCore}; -+/// use rand::prelude::*; ++/// use rand::{rng, RngExt, Rng}; /// /// let num_shares = 2; /// let ctx = b"my context str"; - /// let vdaf = Prio3::new_count(num_shares).unwrap(); +Index: rust-prio-0.17.0+ds/src/dp/distributions.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/dp/distributions.rs ++++ rust-prio-0.17.0+ds/src/dp/distributions.rs +@@ -55,7 +55,7 @@ use num_integer::Integer; + use num_iter::range_inclusive; + use num_rational::Ratio; + use num_traits::{One, Zero}; +-use rand::{distr::Distribution, Rng}; ++use rand::{distr::Distribution, RngExt}; + use serde::{Deserialize, Serialize}; + + use super::{ +@@ -71,7 +71,7 @@ use crate::dp::rand_bigint::UniformBigUi + /// on page 30 of [[CKS20]]. + /// + /// [CKS20]: https://arxiv.org/pdf/2004.00010.pdf +-fn sample_bernoulli<R: Rng + ?Sized>(gamma: &Ratio<BigUint>, rng: &mut R) -> bool { ++fn sample_bernoulli<R: RngExt + ?Sized>(gamma: &Ratio<BigUint>, rng: &mut R) -> bool { + let d = gamma.denom(); + assert!(!d.is_zero()); + assert!(gamma <= &Ratio::<BigUint>::one()); +@@ -93,7 +93,7 @@ fn sample_bernoulli<R: Rng + ?Sized>(gam + /// splitting the branches into two non-recursive functions. This is the `gamma in [0,1]` branch. + /// + /// [CKS20]: https://arxiv.org/pdf/2004.00010.pdf +-fn sample_bernoulli_exp1<R: Rng + ?Sized>(gamma: &Ratio<BigUint>, rng: &mut R) -> bool { ++fn sample_bernoulli_exp1<R: RngExt + ?Sized>(gamma: &Ratio<BigUint>, rng: &mut R) -> bool { + assert!(!gamma.denom().is_zero()); + assert!(gamma <= &Ratio::<BigUint>::one()); + +@@ -114,7 +114,7 @@ fn sample_bernoulli_exp1<R: Rng + ?Sized + /// splitting the branches into two non-recursive functions. This is the `gamma > 1` branch. + /// + /// [CKS20]: https://arxiv.org/pdf/2004.00010.pdf +-fn sample_bernoulli_exp<R: Rng + ?Sized>(gamma: &Ratio<BigUint>, rng: &mut R) -> bool { ++fn sample_bernoulli_exp<R: RngExt + ?Sized>(gamma: &Ratio<BigUint>, rng: &mut R) -> bool { + assert!(!gamma.denom().is_zero()); + for _ in range_inclusive(BigUint::one(), gamma.floor().to_integer()) { + if !sample_bernoulli_exp1(&Ratio::<BigUint>::one(), rng) { +@@ -131,7 +131,7 @@ fn sample_bernoulli_exp<R: Rng + ?Sized> + /// The code follows all but the last three lines of Algorithm 2 in [[CKS20]]. /// - /// let mut out_shares = vec![vec![]; num_shares.into()]; --/// let mut rng = rng(); --/// let verify_key = rng.random(); -+/// let mut rng = thread_rng(); -+/// let verify_key = rng.gen(); - /// let measurements = [false, true, true, true, false]; - /// for measurement in measurements { - /// // Shard --/// let nonce = rng.random::<[u8; 16]>(); -+/// let nonce = rng.gen::<[u8; 16]>(); - /// let (public_share, input_shares) = vdaf.shard(ctx, &measurement, &nonce).unwrap(); + /// [CKS20]: https://arxiv.org/pdf/2004.00010.pdf +-fn sample_geometric_exp<R: Rng + ?Sized>(gamma: &Ratio<BigUint>, rng: &mut R) -> BigUint { ++fn sample_geometric_exp<R: RngExt + ?Sized>(gamma: &Ratio<BigUint>, rng: &mut R) -> BigUint { + let (s, t) = (gamma.numer(), gamma.denom()); + assert!(!t.is_zero()); + if gamma.is_zero() { +@@ -167,7 +167,7 @@ fn sample_geometric_exp<R: Rng + ?Sized> + /// This follows Algorithm 2 of [[CKS20]], using a subfunction for geometric sampling. /// - /// // Prepare -@@ -1217,7 +1217,7 @@ - nonce: &[u8; 16], - ) -> Result<(Self::PublicShare, Vec<Prio3InputShare<T::Field, SEED_SIZE>>), VdafError> { - let mut random = vec![0u8; self.random_size()]; -- rng().fill(&mut random[..]); -+ thread_rng().fill(&mut random[..]); - self.shard_with_random(ctx, measurement, nonce, &random) + /// [CKS20]: https://arxiv.org/pdf/2004.00010.pdf +-fn sample_discrete_laplace<R: Rng + ?Sized>(scale: &Ratio<BigUint>, rng: &mut R) -> BigInt { ++fn sample_discrete_laplace<R: RngExt + ?Sized>(scale: &Ratio<BigUint>, rng: &mut R) -> BigInt { + let (s, t) = (scale.numer(), scale.denom()); + assert!(!t.is_zero()); + if s.is_zero() { +@@ -192,7 +192,7 @@ fn sample_discrete_laplace<R: Rng + ?Siz + /// randomness. Follows Algorithm 3 from [[CKS20]]. + /// + /// [CKS20]: https://arxiv.org/pdf/2004.00010.pdf +-fn sample_discrete_gaussian<R: Rng + ?Sized>(sigma: &Ratio<BigUint>, rng: &mut R) -> BigInt { ++fn sample_discrete_gaussian<R: RngExt + ?Sized>(sigma: &Ratio<BigUint>, rng: &mut R) -> BigInt { + assert!(!sigma.denom().is_zero()); + if sigma.is_zero() { + return 0.into(); +@@ -248,7 +248,7 @@ impl DiscreteGaussian { + impl Distribution<BigInt> for DiscreteGaussian { + fn sample<R>(&self, rng: &mut R) -> BigInt + where +- R: Rng + ?Sized, ++ R: RngExt + ?Sized, + { + sample_discrete_gaussian(&self.std, rng) } +@@ -320,7 +320,7 @@ impl DiscreteLaplace { } -@@ -1783,8 +1783,8 @@ - let mut nonce = [0; 16]; - let mut verify_key = [0; 32]; -- rng().fill(&mut verify_key[..]); -- rng().fill(&mut nonce[..]); -+ thread_rng().fill(&mut verify_key[..]); -+ thread_rng().fill(&mut nonce[..]); - - let (public_share, input_shares) = prio3.shard(CTX_STR, &false, &nonce).unwrap(); - run_vdaf_prepare( -@@ -1837,7 +1837,7 @@ - ); - - let mut verify_key = [0; 32]; -- rng().fill(&mut verify_key[..]); -+ thread_rng().fill(&mut verify_key[..]); - let nonce = [0; 16]; - - let (public_share, mut input_shares) = prio3.shard(CTX_STR, &1, &nonce).unwrap(); -@@ -2104,8 +2104,8 @@ - - let mut verify_key = [0; 32]; - let mut nonce = [0; 16]; -- rng().fill(&mut verify_key); -- rng().fill(&mut nonce); -+ thread_rng().fill(&mut verify_key); -+ thread_rng().fill(&mut nonce); - - let (public_share, mut input_shares) = prio3 - .shard(CTX_STR, &vec![fp_4_inv, fp_8_inv, fp_16_inv], &nonce) -@@ -2274,7 +2274,7 @@ - P: Xof<SEED_SIZE>, - { - let mut verify_key = [0; SEED_SIZE]; -- rng().fill(&mut verify_key[..]); -+ thread_rng().fill(&mut verify_key[..]); - let (public_share, input_shares) = prio3.shard(CTX_STR, measurement, nonce)?; - - let encoded_public_share = public_share.get_encoded().unwrap(); ---- a/src/vdaf/xof.rs -+++ b/src/vdaf/xof.rs -@@ -34,7 +34,7 @@ - RngCore, SeedableRng, - }; + impl Distribution<BigInt> for DiscreteLaplace { +- fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> BigInt { ++ fn sample<R: RngExt + ?Sized>(&self, rng: &mut R) -> BigInt { + sample_discrete_laplace(&self.scale, rng) + } + } +Index: rust-prio-0.17.0+ds/src/dp/rand_bigint.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/dp/rand_bigint.rs ++++ rust-prio-0.17.0+ds/src/dp/rand_bigint.rs +@@ -31,9 +31,9 @@ use num_bigint::BigUint; + use num_integer::Integer; + use num_traits::{ToPrimitive, Zero}; + use rand::distr::uniform::Error; +-use rand::Rng; ++use rand::RngExt; --use rand::distr::{Distribution, StandardUniform}; -+use rand::distributions::{Distribution, Standard}; - #[cfg(feature = "crypto-dependencies")] - use sha2::Sha256; - use sha3::{ -@@ -53,7 +53,7 @@ - #[derive(Clone, Debug)] - pub struct Seed<const SEED_SIZE: usize>(pub(crate) [u8; SEED_SIZE]); +-/// Use [`Rng::fill`] to generate random bits. ++/// Use [`RngExt::fill`] to generate random bits. + /// + /// If `rem` is greater than zero, than only the lowest `rem` bits of the last u32 are filled with + /// random data. +@@ -43,7 +43,7 @@ use rand::Rng; + /// Panics if `rem` is greater than 32. + fn random_bits<R>(rng: &mut R, data: &mut [u32], rem: u64) + where +- R: Rng + ?Sized, ++ R: RngExt + ?Sized, + { + // `fill` is faster than many `random::<u32>` calls + rng.fill(data); +@@ -56,7 +56,7 @@ where + /// Uniformly generate a random [`BigUint`] in the range \[0, 2^`bits`). + fn random_biguint<R>(rng: &mut R, bit_size: u64) -> BigUint + where +- R: Rng + ?Sized, ++ R: RngExt + ?Sized, + { + let (digits, rem) = bit_size.div_rem(&32); + let len = (digits + (rem > 0) as u64) +@@ -70,7 +70,7 @@ where + /// Uniformly generate a random [`BigUint`] in the range \[0, `bound`). + fn random_biguint_below<R>(rng: &mut R, bound: &BigUint) -> BigUint + where +- R: Rng + ?Sized, ++ R: RngExt + ?Sized, + { + assert!(!bound.is_zero()); + let bits = bound.bits(); +@@ -108,7 +108,7 @@ impl UniformBigUint { --impl<const SEED_SIZE: usize> Distribution<Seed<SEED_SIZE>> for StandardUniform { -+impl<const SEED_SIZE: usize> Distribution<Seed<SEED_SIZE>> for Standard { - fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Seed<SEED_SIZE> { - let mut seed_bytes = [0; SEED_SIZE]; - rng.fill(&mut seed_bytes[..]); -@@ -183,6 +183,11 @@ - self.fill(dest); + pub(super) fn sample<R>(&self, rng: &mut R) -> BigUint + where +- R: Rng + ?Sized, ++ R: RngExt + ?Sized, + { + &self.base + random_biguint_below(rng, &self.len) } - -+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { -+ self.fill(dest); -+ Ok(()) -+ } -+ - fn next_u32(&mut self) -> u32 { - next_u32_via_fill(self) +Index: rust-prio-0.17.0+ds/src/flp/types/dp.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/flp/types/dp.rs ++++ rust-prio-0.17.0+ds/src/flp/types/dp.rs +@@ -28,7 +28,7 @@ where + self.add_noise( + dp_strategy, + agg_result, +- &mut SeedStreamTurboShake128::from_os_rng(), ++ &mut SeedStreamTurboShake128::from_rng(&mut rand::rand_core::UnwrapErr(rand::rngs::SysRng)), + ) } -@@ -268,6 +273,11 @@ - XofReader::read(&mut self.0, dest); + } +@@ -46,7 +46,7 @@ where + self.add_noise( + dp_strategy, + agg_result, +- &mut SeedStreamTurboShake128::from_os_rng(), ++ &mut SeedStreamTurboShake128::from_rng(&mut rand::rand_core::UnwrapErr(rand::rngs::SysRng)), + ) } - -+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { -+ XofReader::read(&mut self.0, dest); -+ Ok(()) -+ } -+ - fn next_u32(&mut self) -> u32 { - next_u32_via_fill(self) + } +@@ -102,7 +102,7 @@ where + self.add_noise( + dp_strategy, + agg_result, +- &mut SeedStreamTurboShake128::from_os_rng(), ++ &mut SeedStreamTurboShake128::from_rng(&mut rand::rand_core::UnwrapErr(rand::rngs::SysRng)), + ) } -@@ -486,6 +496,11 @@ - self.fill(dest); + } +@@ -120,7 +120,7 @@ where + self.add_noise( + dp_strategy, + agg_result, +- &mut SeedStreamTurboShake128::from_os_rng(), ++ &mut SeedStreamTurboShake128::from_rng(&mut rand::rand_core::UnwrapErr(rand::rngs::SysRng)), + ) } - -+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { -+ self.fill(dest); -+ Ok(()) -+ } -+ - fn next_u32(&mut self) -> u32 { - next_u32_via_fill(self) + } +Index: rust-prio-0.17.0+ds/src/flp/types/fixedpoint_l2.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/flp/types/fixedpoint_l2.rs ++++ rust-prio-0.17.0+ds/src/flp/types/fixedpoint_l2.rs +@@ -635,7 +635,7 @@ where + self.add_noise( + dp_strategy, + agg_result, +- &mut SeedStreamTurboShake128::from_os_rng(), ++ &mut SeedStreamTurboShake128::from_rng(&mut rand::rand_core::UnwrapErr(rand::rngs::SysRng)), + ) } -@@ -536,7 +551,7 @@ - mod tests { - use super::*; - use crate::{field::Field128, vdaf::equality_comparison_test}; -- use rand::{rng, Rng, RngCore}; -+ use rand::prelude::*; - use serde::{Deserialize, Serialize}; - use std::{convert::TryInto, io::Cursor}; - -@@ -560,8 +575,8 @@ - where - P: Xof<SEED_SIZE>, - { -- let mut rng = rng(); -- let seed = rng.random::<Seed<SEED_SIZE>>(); -+ let mut rng = thread_rng(); -+ let seed = rng.gen::<Seed<SEED_SIZE>>(); - let dst = b"algorithm and usage"; - let binder = b"bind to artifact"; - -@@ -654,8 +669,8 @@ - #[cfg(feature = "experimental")] - #[test] - fn xof_fixed_key_aes128_incomplete_block() { -- let mut rng = rng(); -- let seed = rng.random::<Seed<16>>(); -+ let mut rng = thread_rng(); -+ let seed = rng.gen::<Seed<16>>(); - let mut expected = [0; 32]; - XofFixedKeyAes128::seed_stream(seed.as_ref(), &[b"dst"], &[b"binder"]).fill(&mut expected); - -@@ -669,12 +684,12 @@ - #[cfg(feature = "experimental")] - #[test] - fn xof_fixed_key_aes128_alternate_apis() { -- let mut rng = rng(); -+ let mut rng = thread_rng(); - let fixed_dst = b"domain separation tag"; - let ctx = b"context string"; - let binder = b"AAAAAAAAAAAAAAAAAAAAAAAA"; -- let seed_1 = rng.random::<Seed<16>>(); -- let seed_2 = rng.random::<Seed<16>>(); -+ let seed_1 = rng.gen::<Seed<16>>(); -+ let seed_2 = rng.gen::<Seed<16>>(); - - let mut stream_1_trait_api = - XofFixedKeyAes128::seed_stream(seed_1.as_ref(), &[fixed_dst, ctx], &[binder]); ---- a/src/vidpf.rs -+++ b/src/vidpf.rs -@@ -15,7 +15,7 @@ + } +Index: rust-prio-0.17.0+ds/src/vdaf/prio2/client.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/vdaf/prio2/client.rs ++++ rust-prio-0.17.0+ds/src/vdaf/prio2/client.rs +@@ -11,7 +11,7 @@ use crate::{ + vdaf::{xof::SeedStreamAes128, VdafError}, }; - use bitvec::prelude::{BitVec, Lsb0}; --use rand::{rng, Rng, RngCore}; -+use rand::prelude::*; - use std::fmt::Debug; - use std::io::{Cursor, Read}; - use subtle::{Choice, ConditionallyNegatable, ConditionallySelectable, ConstantTimeEq}; -@@ -98,8 +98,8 @@ - weight: &W, - nonce: &[u8], - ) -> Result<(VidpfPublicShare<W>, [VidpfKey; 2]), VidpfError> { -- let mut rng = rng(); -- let keys = rng.random(); -+ let mut rng = thread_rng(); -+ let keys = rng.gen(); - let public = self.gen_with_keys(ctx, &keys, input, weight, nonce)?; - Ok((public, keys)) - } ---- a/tests/discrete_gauss.rs -+++ b/tests/discrete_gauss.rs -@@ -5,7 +5,7 @@ - use num_traits::FromPrimitive; - use prio::dp::distributions::DiscreteGaussian; - use prio::vdaf::xof::SeedStreamTurboShake128; --use rand::distr::Distribution; -+use rand::distributions::Distribution; - use rand::SeedableRng; - use serde::Deserialize; +-use rand::{rng, Rng}; ++use rand::{rng, RngExt}; + use std::convert::TryFrom; + /// Serialization errors +Index: rust-prio-0.17.0+ds/binaries/Cargo.toml +=================================================================== +--- rust-prio-0.17.0+ds.orig/binaries/Cargo.toml ++++ rust-prio-0.17.0+ds/binaries/Cargo.toml +@@ -9,5 +9,5 @@ repository = "https://github.com/divviup + [dependencies] + base64 = "0.22.1" + fixed = "1.27" +-rand = "0.9" ++rand = "0.10" + prio = { path = "..", features = ["experimental", "test-util"] } +Index: rust-prio-0.17.0+ds/src/vdaf/mastic/szk.rs +=================================================================== +--- rust-prio-0.17.0+ds.orig/src/vdaf/mastic/szk.rs ++++ rust-prio-0.17.0+ds/src/vdaf/mastic/szk.rs +@@ -664,7 +664,7 @@ mod tests { + Flp, Type, + }, + }; +- use rand::{rng, Rng}; ++ use rand::{rng, RngExt}; + + fn generic_szk_test<T: Type>(typ: T, encoded_measurement: &[T::Field], valid: bool) { + let mut rng = rng();

