Skip to main content

binius_transcript/fiat_shamir/
sampling.rs

1// Copyright 2024-2025 Irreducible Inc.
2// Copyright (c) 2024 The Plonky3 authors
3
4//! Traits used to sample random values in a public-coin interactive protocol.
5//!
6//! These interfaces are taken from [p3_challenger](https://github.com/Plonky3/Plonky3/blob/main/challenger/src/lib.rs) in [Plonky3].
7//!
8//! Plonky3 is dual-licensed under MIT OR Apache 2.0. We use it under Apache 2.0.
9//!
10//! [Plonky3]: <https://github.com/plonky3/plonky3>
11
12use std::array;
13
14use bytes::Buf;
15
16#[auto_impl::auto_impl(&mut)]
17pub trait CanSample<T> {
18	fn sample(&mut self) -> T;
19
20	fn sample_array<const N: usize>(&mut self) -> [T; N] {
21		array::from_fn(|_| self.sample())
22	}
23
24	fn sample_vec(&mut self, n: usize) -> Vec<T> {
25		(0..n).map(|_| self.sample()).collect()
26	}
27}
28
29#[auto_impl::auto_impl(&mut)]
30pub trait CanSampleBits<T> {
31	fn sample_bits(&mut self, bits: usize) -> T;
32}
33
34pub fn sample_bits_reader<Reader: Buf>(mut reader: Reader, bits: usize) -> u32 {
35	let bits = bits.min(u32::BITS as usize);
36
37	let bytes_to_sample = size_of::<u32>();
38
39	let mut bytes = [0u8; size_of::<u32>()];
40
41	reader.copy_to_slice(&mut bytes[..bytes_to_sample]);
42
43	let unmasked = u32::from_le_bytes(bytes);
44	let mask = 1u32.checked_shl(bits as u32).map_or(u32::MAX, |x| x - 1);
45	mask & unmasked
46}