labrador/core/
statement.rs1use crate::core::env_params::EnvironmentParameters;
2use crate::prover::Witness;
3use crate::ring::poly::{PolyRing, PolyVector, ZqVector};
4
5pub struct Statement {
8 pub a_constraint: Vec<Vec<PolyVector>>,
10 pub phi_constraint: Vec<Vec<PolyVector>>,
12 pub b_constraint: PolyVector,
14 pub a_ct: Vec<Vec<PolyVector>>,
16 pub phi_ct: Vec<Vec<PolyVector>>,
18 pub b_0_ct: ZqVector,
20}
21
22impl Statement {
23 pub fn new(witness: &Witness, ep: &EnvironmentParameters) -> Self {
24 let a_constraint: Vec<Vec<PolyVector>> = (0..ep.constraint_k)
26 .map(|_| {
27 (0..ep.r)
28 .map(|_| PolyVector::random(ep.n, ep.deg_bound_d))
29 .collect()
30 })
31 .collect();
32
33 let phi_constraint: Vec<Vec<PolyVector>> = (0..ep.constraint_k)
35 .map(|_| {
36 (0..ep.r)
37 .map(|_| PolyVector::random(ep.n, ep.deg_bound_d))
38 .collect()
39 })
40 .collect();
41
42 let b_constraint: PolyVector = (0..ep.constraint_k)
44 .map(|k| calculate_b_constraint(&witness.s, &a_constraint[k], &phi_constraint[k]))
45 .collect();
46
47 let a_ct: Vec<Vec<PolyVector>> = (0..ep.constraint_l)
49 .map(|_| {
50 (0..ep.r)
51 .map(|_| PolyVector::random(ep.n, ep.deg_bound_d))
52 .collect()
53 })
54 .collect();
55
56 let phi_ct: Vec<Vec<PolyVector>> = (0..ep.constraint_k)
59 .map(|_| {
60 (0..ep.r)
61 .map(|_| PolyVector::random(ep.n, ep.deg_bound_d))
62 .collect()
63 })
64 .collect();
65
66 let b_constraint_l: PolyVector = (0..ep.constraint_l)
68 .map(|l| calculate_b_constraint(&witness.s, &a_ct[l], &phi_ct[l]))
69 .collect();
70
71 let b_0_ct: ZqVector = (0..ep.constraint_l)
73 .map(|l| b_constraint_l.get_elements()[l].get_coeffs()[0])
74 .collect();
75
76 Self {
77 a_constraint,
78 phi_constraint,
79 b_constraint,
80 a_ct,
81 phi_ct,
82 b_0_ct,
83 }
84 }
85}
86
87#[rustfmt::skip]
96pub fn calculate_b_constraint(
97 s: &[PolyVector],
98 a_constraint: &[PolyVector],
99 phi_constraint: &[PolyVector],
100) -> PolyRing {
101 let size_s = s.len();
102 let left_side = (0..size_s).map(|i| {
104 (0..size_s).map(|j| {
105 &a_constraint[i].get_elements()[j]
106 * &s[i].inner_product_poly_vector(&s[j])
107 })
108 .fold(PolyRing::zero_poly(), |acc, val| &acc + &val )
109 })
110 .fold(PolyRing::zero_poly(), |acc, val| &acc + &val );
111
112 let right_side = (0..size_s).fold(PolyRing::zero_poly(), |acc, i| {
114 &acc + &phi_constraint[i].inner_product_poly_vector(&s[i])
115 });
116
117 &left_side + &right_side
118}