labrador/core/
challenge_set.rs1use crate::ring::poly::PolyRing;
2use crate::ring::zq::Zq;
3use rand::prelude::*;
4use rand::seq::SliceRandom;
5
6pub struct ChallengeSet {
7 challenges: PolyRing,
8 norm: f64,
9}
10
11impl ChallengeSet {
13 pub fn new(deg_bound_d: usize) -> Self {
14 let op_norm = 15.0;
16 let challenges: PolyRing = sample_challenge_with_norm(deg_bound_d, op_norm);
18 let norm = PolyRing::operator_norm(&challenges);
19 ChallengeSet { challenges, norm }
20 }
21
22 pub fn get_challenges(&self) -> &PolyRing {
24 &self.challenges
25 }
26
27 pub fn get_norm(&self) -> f64 {
29 self.norm
30 }
31}
32
33fn sample_challenge(deg_bound_d: usize) -> PolyRing {
40 let mut rng = rand::rng();
41 let mut challenge: Vec<Zq> = Vec::with_capacity(deg_bound_d);
42
43 for _ in 0..23 {
45 challenge.push(Zq::ZERO);
46 }
47 for _ in 0..31 {
49 let value = if rng.random_bool(0.5) {
50 Zq::ONE
51 } else {
52 -Zq::ONE
53 };
54 challenge.push(value);
55 }
56 for _ in 0..10 {
58 let value = if rng.random_bool(0.5) {
59 Zq::new(2)
60 } else {
61 -Zq::new(2)
62 };
63 challenge.push(value);
64 }
65
66 challenge.shuffle(&mut rng);
68 PolyRing::new(challenge)
69}
70
71fn sample_challenge_with_norm(deg_bound_d: usize, threshold: f64) -> PolyRing {
74 loop {
75 let candidate = sample_challenge(deg_bound_d);
76 let norm = PolyRing::operator_norm(&candidate);
77 if norm < threshold {
78 return candidate;
79 }
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
92 fn test_challenge_set() {
93 let op_norm = 15.0;
94 let deg_bound_d: usize = 8;
95 let cs_1: ChallengeSet = ChallengeSet::new(deg_bound_d);
96 let norm = cs_1.get_norm();
97 let challenges_1 = cs_1.get_challenges();
98
99 let cs_2: ChallengeSet = ChallengeSet::new(deg_bound_d);
100 let challenges_2 = cs_2.get_challenges();
101
102 assert_eq!(challenges_1.inner_product(challenges_1), Zq::new(71));
104 assert!(norm <= op_norm);
105
106 assert_ne!(challenges_1, challenges_2);
107 }
108}