labrador/core/
statement.rs1use crate::core::env_params::EnvironmentParameters;
2use crate::prover::Witness;
3use crate::ring::rq::Rq;
4use crate::ring::rq_vector::RqVector;
5use crate::ring::zq::Zq;
6
7pub struct Statement {
10 pub a_constraint: Vec<Vec<RqVector>>,
12 pub phi_constraint: Vec<Vec<RqVector>>,
14 pub b_constraint: RqVector,
16 pub a_ct: Vec<Vec<RqVector>>,
18 pub phi_ct: Vec<Vec<RqVector>>,
20 pub b_0_ct: Vec<Zq>,
22}
23
24impl Statement {
25 pub fn new(witness: &Witness, ep: &EnvironmentParameters) -> Self {
26 let a_constraint: Vec<Vec<RqVector>> = (0..ep.constraint_k)
28 .map(|_| {
29 (0..ep.r)
30 .map(|_| RqVector::random(&mut rand::rng(), ep.n))
31 .collect()
32 })
33 .collect();
34
35 let phi_constraint: Vec<Vec<RqVector>> = (0..ep.constraint_k)
37 .map(|_| {
38 (0..ep.r)
39 .map(|_| RqVector::random(&mut rand::rng(), ep.n))
40 .collect()
41 })
42 .collect();
43
44 let b_constraint: RqVector = (0..ep.constraint_k)
46 .map(|k| calculate_b_constraint(&witness.s, &a_constraint[k], &phi_constraint[k]))
47 .collect();
48
49 let a_ct: Vec<Vec<RqVector>> = (0..ep.constraint_l)
51 .map(|_| {
52 (0..ep.r)
53 .map(|_| RqVector::random(&mut rand::rng(), ep.n))
54 .collect()
55 })
56 .collect();
57
58 let phi_ct: Vec<Vec<RqVector>> = (0..ep.constraint_k)
61 .map(|_| {
62 (0..ep.r)
63 .map(|_| RqVector::random(&mut rand::rng(), ep.n))
64 .collect()
65 })
66 .collect();
67
68 let b_constraint_l: RqVector = (0..ep.constraint_l)
70 .map(|l| calculate_b_constraint(&witness.s, &a_ct[l], &phi_ct[l]))
71 .collect();
72
73 let b_0_ct: Vec<Zq> = (0..ep.constraint_l)
75 .map(|l| b_constraint_l.get_elements()[l].get_coefficients()[0])
76 .collect();
77
78 Self {
79 a_constraint,
80 phi_constraint,
81 b_constraint,
82 a_ct,
83 phi_ct,
84 b_0_ct,
85 }
86 }
87}
88
89#[rustfmt::skip]
98pub fn calculate_b_constraint(
99 s: &[RqVector],
100 a_constraint: &[RqVector],
101 phi_constraint: &[RqVector],
102) -> Rq {
103 let size_s = s.len();
104 let left_side = (0..size_s).map(|i| {
106 (0..size_s).map(|j| {
107 a_constraint[i].get_elements()[j].clone()
108 * s[i].inner_product_poly_vector(&s[j])
109 })
110 .fold(Rq::zero(), |acc, val| acc + val )
111 })
112 .fold(Rq::zero(), |acc, val| acc + val );
113
114 let right_side = (0..size_s).fold(Rq::zero(), |acc, i| {
116 acc + phi_constraint[i].inner_product_poly_vector(&s[i])
117 });
118
119 left_side + right_side
120}