arnaucube
arnaucube/sonobePublic Self-hosted repository
sonobe/folding-schemes/src/folding/nova/traits.rs
folding-schemes/src/folding/nova/traits.rsRaw
 1use ark_crypto_primitives::sponge::Absorb;
 2use ark_ec::{CurveGroup, Group};
 3use ark_std::{One, Zero};
 4
 5use super::{CommittedInstance, Witness};
 6use crate::ccs::r1cs::R1CS;
 7use crate::Error;
 8
 9/// NovaR1CS extends R1CS methods with Nova specific methods
10pub trait NovaR1CS<C: CurveGroup> {
11    /// returns a dummy instance (Witness and CommittedInstance) for the current R1CS structure
12    fn dummy_instance(&self) -> (Witness<C>, CommittedInstance<C>);
13
14    /// checks the R1CS relation (un-relaxed) for the given Witness and CommittedInstance.
15    fn check_instance_relation(
16        &self,
17        W: &Witness<C>,
18        U: &CommittedInstance<C>,
19    ) -> Result<(), Error>;
20
21    /// checks the Relaxed R1CS relation (corresponding to the current R1CS) for the given Witness
22    /// and CommittedInstance.
23    fn check_relaxed_instance_relation(
24        &self,
25        W: &Witness<C>,
26        U: &CommittedInstance<C>,
27    ) -> Result<(), Error>;
28}
29
30impl<C: CurveGroup> NovaR1CS<C> for R1CS<C::ScalarField>
31where
32    <C as Group>::ScalarField: Absorb,
33    <C as ark_ec::CurveGroup>::BaseField: ark_ff::PrimeField,
34{
35    fn dummy_instance(&self) -> (Witness<C>, CommittedInstance<C>) {
36        let w_len = self.A.n_cols - 1 - self.l;
37        let w_dummy = Witness::<C>::new(vec![C::ScalarField::zero(); w_len], self.A.n_rows);
38        let u_dummy = CommittedInstance::<C>::dummy(self.l);
39        (w_dummy, u_dummy)
40    }
41
42    // notice that this method does not check the commitment correctness
43    fn check_instance_relation(
44        &self,
45        W: &Witness<C>,
46        U: &CommittedInstance<C>,
47    ) -> Result<(), Error> {
48        if U.cmE != C::zero() || U.u != C::ScalarField::one() {
49            return Err(Error::R1CSUnrelaxedFail);
50        }
51
52        let Z: Vec<C::ScalarField> = [vec![U.u], U.x.to_vec(), W.W.to_vec()].concat();
53        self.check_relation(&Z)
54    }
55
56    // notice that this method does not check the commitment correctness
57    fn check_relaxed_instance_relation(
58        &self,
59        W: &Witness<C>,
60        U: &CommittedInstance<C>,
61    ) -> Result<(), Error> {
62        let mut rel_r1cs = self.clone().relax();
63        rel_r1cs.u = U.u;
64        rel_r1cs.E = W.E.clone();
65
66        let Z: Vec<C::ScalarField> = [vec![U.u], U.x.to_vec(), W.W.to_vec()].concat();
67        rel_r1cs.check_relation(&Z)
68    }
69}