arnaucube
arnaucube/NovaPublic Self-hosted repository
Nova/src/bellperson/r1cs.rs
src/bellperson/r1cs.rsRaw
  1//! Support for generating R1CS using bellperson.
  2
  3#![allow(non_snake_case)]
  4
  5use super::{shape_cs::ShapeCS, solver::SatisfyingAssignment};
  6use crate::{
  7  errors::NovaError,
  8  r1cs::{R1CSInstance, R1CSShape, R1CSWitness, R1CS},
  9  traits::Group,
 10  CommitmentKey,
 11};
 12use bellperson::{Index, LinearCombination};
 13use ff::PrimeField;
 14
 15/// `NovaWitness` provide a method for acquiring an `R1CSInstance` and `R1CSWitness` from implementers.
 16pub trait NovaWitness<G: Group> {
 17  /// Return an instance and witness, given a shape and ck.
 18  fn r1cs_instance_and_witness(
 19    &self,
 20    shape: &R1CSShape<G>,
 21    ck: &CommitmentKey<G>,
 22  ) -> Result<(R1CSInstance<G>, R1CSWitness<G>), NovaError>;
 23}
 24
 25/// `NovaShape` provides methods for acquiring `R1CSShape` and `R1CSGens` from implementers.
 26pub trait NovaShape<G: Group> {
 27  /// Return an appropriate `R1CSShape` struct.
 28  fn r1cs_shape(&self) -> R1CSShape<G>;
 29  /// Return an appropriate `CommitmentKey` struct.
 30  fn commitment_key(&self) -> CommitmentKey<G>;
 31}
 32
 33impl<G: Group> NovaWitness<G> for SatisfyingAssignment<G>
 34where
 35  G::Scalar: PrimeField,
 36{
 37  fn r1cs_instance_and_witness(
 38    &self,
 39    shape: &R1CSShape<G>,
 40    ck: &CommitmentKey<G>,
 41  ) -> Result<(R1CSInstance<G>, R1CSWitness<G>), NovaError> {
 42    let W = R1CSWitness::<G>::new(shape, &self.aux_assignment)?;
 43    let X = &self.input_assignment[1..];
 44
 45    let comm_W = W.commit(ck);
 46
 47    let instance = R1CSInstance::<G>::new(shape, &comm_W, X)?;
 48
 49    Ok((instance, W))
 50  }
 51}
 52
 53impl<G: Group> NovaShape<G> for ShapeCS<G>
 54where
 55  G::Scalar: PrimeField,
 56{
 57  fn r1cs_shape(&self) -> R1CSShape<G> {
 58    let mut A: Vec<(usize, usize, G::Scalar)> = Vec::new();
 59    let mut B: Vec<(usize, usize, G::Scalar)> = Vec::new();
 60    let mut C: Vec<(usize, usize, G::Scalar)> = Vec::new();
 61
 62    let mut num_cons_added = 0;
 63    let mut X = (&mut A, &mut B, &mut C, &mut num_cons_added);
 64
 65    let num_inputs = self.num_inputs();
 66    let num_constraints = self.num_constraints();
 67    let num_vars = self.num_aux();
 68
 69    for constraint in self.constraints.iter() {
 70      add_constraint(
 71        &mut X,
 72        num_vars,
 73        &constraint.0,
 74        &constraint.1,
 75        &constraint.2,
 76      );
 77    }
 78
 79    assert_eq!(num_cons_added, num_constraints);
 80
 81    let S: R1CSShape<G> = {
 82      // Don't count One as an input for shape's purposes.
 83      let res = R1CSShape::new(num_constraints, num_vars, num_inputs - 1, &A, &B, &C);
 84      res.unwrap()
 85    };
 86
 87    S
 88  }
 89
 90  fn commitment_key(&self) -> CommitmentKey<G> {
 91    R1CS::<G>::commitment_key(self.num_constraints(), self.num_aux())
 92  }
 93}
 94
 95fn add_constraint<S: PrimeField>(
 96  X: &mut (
 97    &mut Vec<(usize, usize, S)>,
 98    &mut Vec<(usize, usize, S)>,
 99    &mut Vec<(usize, usize, S)>,
100    &mut usize,
101  ),
102  num_vars: usize,
103  a_lc: &LinearCombination<S>,
104  b_lc: &LinearCombination<S>,
105  c_lc: &LinearCombination<S>,
106) {
107  let (A, B, C, nn) = X;
108  let n = **nn;
109  let one = S::one();
110
111  let add_constraint_component = |index: Index, coeff, V: &mut Vec<_>| {
112    match index {
113      Index::Input(idx) => {
114        // Inputs come last, with input 0, reprsenting 'one',
115        // at position num_vars within the witness vector.
116        let i = idx + num_vars;
117        V.push((n, i, one * coeff))
118      }
119      Index::Aux(idx) => V.push((n, idx, one * coeff)),
120    }
121  };
122
123  for (index, coeff) in a_lc.iter() {
124    add_constraint_component(index.0, coeff, A);
125  }
126  for (index, coeff) in b_lc.iter() {
127    add_constraint_component(index.0, coeff, B)
128  }
129  for (index, coeff) in c_lc.iter() {
130    add_constraint_component(index.0, coeff, C)
131  }
132
133  **nn += 1;
134}