use crate::{
error::MathError,
integer::Z,
integer_mod_q::{Modulus, Zq},
macros::seeded::seedable_function,
rational::Q,
utils::sample::binomial::BinomialSampler,
};
impl Zq {
seedable_function!(
#[seeded]
#[optionally_seeded]
#[optionally_seeded]
#[unseeded]
#[seeded]
pub(crate) fn sample_binomial(
modulus: impl Into<Modulus>,
n: impl Into<Z>,
p: impl Into<Q>,
seed: Option<[u8; 32]>,
) -> Result<Self, MathError> {
let modulus: Modulus = modulus.into();
let mut bin_sampler = BinomialSampler::init(n, p, seed)?;
let sample = bin_sampler.sample();
Ok(Zq::from((sample, modulus)))
}
);
}
#[cfg(test)]
mod test_sample_binomial {
use super::{Q, Z, Zq};
use crate::utils::sample::test_seed;
#[test]
fn availability() {
for seeded in [false, true] {
let _ = Zq::sample_binomial_optionally_seeded(7u8, 1u16, 7u8, seeded.then(test_seed));
let _ = Zq::sample_binomial_optionally_seeded(7u16, 1u32, 7u16, seeded.then(test_seed));
let _ = Zq::sample_binomial_optionally_seeded(7u32, 1u64, 7u32, seeded.then(test_seed));
let _ = Zq::sample_binomial_optionally_seeded(7u64, 1i8, 7u64, seeded.then(test_seed));
let _ = Zq::sample_binomial_optionally_seeded(7i8, 1i16, 7i8, seeded.then(test_seed));
let _ = Zq::sample_binomial_optionally_seeded(7i16, 1i32, 7i16, seeded.then(test_seed));
let _ = Zq::sample_binomial_optionally_seeded(7i32, 1i64, 7i32, seeded.then(test_seed));
let _ =
Zq::sample_binomial_optionally_seeded(7i64, Z::ONE, 7i64, seeded.then(test_seed));
let _ = Zq::sample_binomial_optionally_seeded(7, 1u8, 0.5f32, seeded.then(test_seed));
let _ = Zq::sample_binomial_optionally_seeded(7, 1u8, 0.5f64, seeded.then(test_seed));
let _ = Zq::sample_binomial_optionally_seeded(
7,
1,
Q::from((1, 2)),
seeded.then(test_seed),
);
if seeded {
let _ = Zq::sample_binomial_seeded(7u8, 1u16, 7u8, test_seed());
} else {
let _ = Zq::sample_binomial(7u8, 1u16, 7u8);
}
}
}
#[test]
fn same_seed_same_sample() {
use crate::integer_mod_q::Zq;
let sample_0 = Zq::sample_binomial_seeded(7, 2, 0.5, [42; 32]).unwrap();
let sample_1 = Zq::sample_binomial_seeded(7, 2, 0.5, [42; 32]).unwrap();
assert_eq!(sample_0, sample_1);
}
#[test]
fn known_answer() {
use crate::integer_mod_q::Zq;
let sample = Zq::sample_binomial_seeded(7, 2, 0.5, [42; 32]).unwrap();
assert_eq!("0 mod 7", sample.to_string());
}
}