arnaucube
arnaucube/sonobePublic Self-hosted repository
sonobe/src/ccs/r1cs.rs
src/ccs/r1cs.rsRaw
 1use ark_ff::PrimeField;
 2
 3use crate::utils::vec::*;
 4
 5#[derive(Debug, Clone, Eq, PartialEq)]
 6pub struct R1CS<F: PrimeField> {
 7    pub l: usize, // io len
 8    pub A: SparseMatrix<F>,
 9    pub B: SparseMatrix<F>,
10    pub C: SparseMatrix<F>,
11}
12impl<F: PrimeField> R1CS<F> {
13    /// returns a tuple containing (w, x) (witness and public inputs respectively)
14    pub fn split_z(&self, z: &[F]) -> (Vec<F>, Vec<F>) {
15        (z[self.l + 1..].to_vec(), z[1..self.l + 1].to_vec())
16    }
17}
18
19#[cfg(test)]
20pub mod tests {
21    use super::*;
22
23    pub fn to_F_matrix<F: PrimeField>(M: Vec<Vec<usize>>) -> Vec<Vec<F>> {
24        let mut R: Vec<Vec<F>> = vec![Vec::new(); M.len()];
25        for i in 0..M.len() {
26            R[i] = vec![F::zero(); M[i].len()];
27            for j in 0..M[i].len() {
28                R[i][j] = F::from(M[i][j] as u64);
29            }
30        }
31        R
32    }
33    pub fn to_F_vec<F: PrimeField>(z: Vec<usize>) -> Vec<F> {
34        let mut r: Vec<F> = vec![F::zero(); z.len()];
35        for i in 0..z.len() {
36            r[i] = F::from(z[i] as u64);
37        }
38        r
39    }
40
41    pub fn get_test_r1cs<F: PrimeField>() -> R1CS<F> {
42        // R1CS for: x^3 + x + 5 = y (example from article
43        // https://www.vitalik.ca/general/2016/12/10/qap.html )
44        let A = dense_matrix_to_sparse(to_F_matrix::<F>(vec![
45            vec![0, 1, 0, 0, 0, 0],
46            vec![0, 0, 0, 1, 0, 0],
47            vec![0, 1, 0, 0, 1, 0],
48            vec![5, 0, 0, 0, 0, 1],
49        ]));
50        let B = dense_matrix_to_sparse(to_F_matrix::<F>(vec![
51            vec![0, 1, 0, 0, 0, 0],
52            vec![0, 1, 0, 0, 0, 0],
53            vec![1, 0, 0, 0, 0, 0],
54            vec![1, 0, 0, 0, 0, 0],
55        ]));
56        let C = dense_matrix_to_sparse(to_F_matrix::<F>(vec![
57            vec![0, 0, 0, 1, 0, 0],
58            vec![0, 0, 0, 0, 1, 0],
59            vec![0, 0, 0, 0, 0, 1],
60            vec![0, 0, 1, 0, 0, 0],
61        ]));
62
63        R1CS::<F> { l: 1, A, B, C }
64    }
65
66    pub fn get_test_z<F: PrimeField>(input: usize) -> Vec<F> {
67        // z = (1, io, w)
68        to_F_vec(vec![
69            1,
70            input,                             // io
71            input * input * input + input + 5, // x^3 + x + 5
72            input * input,                     // x^2
73            input * input * input,             // x^2 * x
74            input * input * input + input,     // x^3 + x
75            0,                                 // pad to pow of 2
76            0,
77        ])
78    }
79}