arnaucube
arnaucube/nova-studyPublic Self-hosted repository
nova-study/src/hypernova/ccs.rs
src/hypernova/ccs.rsRaw
 1use ark_ff::fields::PrimeField;
 2
 3use crate::nifs::R1CS;
 4use crate::utils::{hadamard_product, matrix_vector_product, vec_add, vector_elem_product};
 5
 6pub struct CCS<F: PrimeField> {
 7    m: usize,
 8    n: usize,
 9    t: usize,
10    q: usize,
11    d: usize,
12    S: Vec<Vec<usize>>,
13    c: Vec<F>,
14    M: Vec<Vec<Vec<F>>>,
15}
16
17impl<F: PrimeField> R1CS<F> {
18    pub fn to_ccs(self) -> CCS<F> {
19        CCS::<F> {
20            m: self.A.len(),
21            n: self.A[0].len(),
22            t: 3,
23            q: 2,
24            d: 2,
25            S: vec![vec![0, 1], vec![2]],
26            c: vec![F::one(), F::one().neg()],
27            M: vec![self.A, self.B, self.C],
28        }
29    }
30}
31
32impl<F: PrimeField> CCS<F> {
33    pub fn check_relation(self, z: Vec<F>) -> bool {
34        let mut r: Vec<F> = vec![F::zero(); self.m];
35        for i in 0..self.q {
36            let mut hadamard_output = vec![F::one(); self.m];
37            for j in self.S[i].clone() {
38                hadamard_output =
39                    hadamard_product(hadamard_output, matrix_vector_product(&self.M[j], &z));
40            }
41            r = vec_add(&r, &vector_elem_product(&hadamard_output, &self.c[i]));
42        }
43
44        let zero: Vec<F> = vec![F::zero(); self.m];
45
46        r == zero
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53    use crate::transcript::poseidon_test_config;
54    use ark_mnt4_298::{Fr, G1Projective};
55    use ark_std::One;
56    use ark_std::UniformRand;
57
58    use crate::nifs::gen_test_values;
59
60    #[test]
61    fn test_r1cs_to_ccs() {
62        let (r1cs, ws, _) = gen_test_values(2);
63        let w: Vec<Fr> = ws[0].clone();
64
65        let ccs = r1cs.to_ccs();
66
67        assert!(ccs.check_relation(w));
68    }
69}