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 use crate::utils::vec::tests::{to_F_matrix, to_F_vec};
23
24 pub fn get_test_r1cs<F: PrimeField>() -> R1CS<F> {
25 // R1CS for: x^3 + x + 5 = y (example from article
26 // https://www.vitalik.ca/general/2016/12/10/qap.html )
27 let A = dense_matrix_to_sparse(to_F_matrix::<F>(vec![
28 vec![0, 1, 0, 0, 0, 0],
29 vec![0, 0, 0, 1, 0, 0],
30 vec![0, 1, 0, 0, 1, 0],
31 vec![5, 0, 0, 0, 0, 1],
32 ]));
33 let B = dense_matrix_to_sparse(to_F_matrix::<F>(vec![
34 vec![0, 1, 0, 0, 0, 0],
35 vec![0, 1, 0, 0, 0, 0],
36 vec![1, 0, 0, 0, 0, 0],
37 vec![1, 0, 0, 0, 0, 0],
38 ]));
39 let C = dense_matrix_to_sparse(to_F_matrix::<F>(vec![
40 vec![0, 0, 0, 1, 0, 0],
41 vec![0, 0, 0, 0, 1, 0],
42 vec![0, 0, 0, 0, 0, 1],
43 vec![0, 0, 1, 0, 0, 0],
44 ]));
45
46 R1CS::<F> { l: 1, A, B, C }
47 }
48
49 pub fn get_test_z<F: PrimeField>(input: usize) -> Vec<F> {
50 // z = (1, io, w)
51 to_F_vec(vec![
52 1,
53 input, // io
54 input * input * input + input + 5, // x^3 + x + 5
55 input * input, // x^2
56 input * input * input, // x^2 * x
57 input * input * input + input, // x^3 + x
58 ])
59 }
60}