labrador/relation/
statement.rs1use super::env_params::EnvironmentParameters;
2use crate::relation::witness::Witness;
3use crate::ring::rq::Rq;
4use crate::ring::rq_matrix::RqMatrix;
5use crate::ring::rq_vector::RqVector;
6use crate::ring::zq::Zq;
7
8use crate::core::inner_product;
9
10pub struct Statement {
13 pub a_constraint: Vec<RqMatrix>,
15 pub phi_constraint: Vec<Vec<RqVector>>,
17 pub b_constraint: RqVector,
19 pub a_ct: Vec<RqMatrix>,
21 pub phi_ct: Vec<Vec<RqVector>>,
23 pub b_0_ct: Vec<Zq>,
25}
26
27impl Statement {
28 pub fn new(witness: &Witness, ep: &EnvironmentParameters) -> Self {
29 let a_constraint: Vec<RqMatrix> = (0..ep.constraint_k)
31 .map(|_| RqMatrix::symmetric_random(&mut rand::rng(), ep.multiplicity))
32 .collect();
33
34 let phi_constraint: Vec<Vec<RqVector>> = (0..ep.constraint_k)
36 .map(|_| {
37 (0..ep.multiplicity)
38 .map(|_| RqVector::random(&mut rand::rng(), ep.rank))
39 .collect()
40 })
41 .collect();
42
43 let b_constraint: RqVector = (0..ep.constraint_k)
45 .map(|k| calculate_b_constraint(&witness.s, &a_constraint[k], &phi_constraint[k]))
46 .collect();
47
48 let a_ct: Vec<RqMatrix> = (0..ep.constraint_l)
50 .map(|_| RqMatrix::symmetric_random(&mut rand::rng(), ep.multiplicity))
51 .collect();
52
53 let phi_ct: Vec<Vec<RqVector>> = (0..ep.constraint_l)
56 .map(|_| {
57 (0..ep.multiplicity)
58 .map(|_| RqVector::random(&mut rand::rng(), ep.rank))
59 .collect()
60 })
61 .collect();
62
63 let b_constraint_l: RqVector = (0..ep.constraint_l)
65 .map(|l| calculate_b_constraint(&witness.s, &a_ct[l], &phi_ct[l]))
66 .collect();
67
68 let b_0_ct: Vec<Zq> = (0..ep.constraint_l)
70 .map(|l| b_constraint_l.get_elements()[l].get_coefficients()[0])
71 .collect();
72
73 Self {
74 a_constraint,
75 phi_constraint,
76 b_constraint,
77 a_ct,
78 phi_ct,
79 b_0_ct,
80 }
81 }
82}
83
84#[rustfmt::skip]
93pub fn calculate_b_constraint(
94 s: &[RqVector],
95 a_constraint: &RqMatrix,
96 phi_constraint: &[RqVector],
97) -> Rq {
98 let size_s = s.len();
99 let left_side = (0..size_s).map(|i| {
101 (0..size_s).map(|j: usize| {
102 a_constraint.get_cell(i, j)
103 * &inner_product::compute_linear_combination(s[i].get_elements(), s[j].get_elements())
104 })
105 .fold(Rq::zero(), |acc, val| &acc + &val )
106 })
107 .fold(Rq::zero(), |acc, val| &acc + &val );
108
109 let right_side = (0..size_s).fold(Rq::zero(), |acc, i| {
111 &acc + &inner_product::compute_linear_combination(phi_constraint[i].get_elements(), s[i].get_elements())
112 });
113
114 &left_side + &right_side
115}