arnaucube
arnaucube/NovaPublic Self-hosted repository
Nova/src/spartan/spark/mod.rs
src/spartan/spark/mod.rsRaw
  1//! This module implements `CompCommitmentEngineTrait` using Spartan's SPARK compiler
  2//! We also provide a trivial implementation that has the verifier evaluate the sparse polynomials
  3use crate::{
  4  errors::NovaError,
  5  r1cs::R1CSShape,
  6  spartan::{math::Math, CompCommitmentEngineTrait, PolyEvalInstance, PolyEvalWitness},
  7  traits::{evaluation::EvaluationEngineTrait, Group, TranscriptReprTrait},
  8  CommitmentKey,
  9};
 10use core::marker::PhantomData;
 11use serde::{Deserialize, Serialize};
 12
 13/// A trivial implementation of `ComputationCommitmentEngineTrait`
 14pub struct TrivialCompComputationEngine<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> {
 15  _p: PhantomData<G>,
 16  _p2: PhantomData<EE>,
 17}
 18
 19/// Provides an implementation of a trivial commitment
 20#[derive(Clone, Debug, Serialize, Deserialize)]
 21#[serde(bound = "")]
 22pub struct TrivialCommitment<G: Group> {
 23  S: R1CSShape<G>,
 24}
 25
 26/// Provides an implementation of a trivial decommitment
 27#[derive(Clone, Debug, Serialize, Deserialize)]
 28#[serde(bound = "")]
 29pub struct TrivialDecommitment<G: Group> {
 30  _p: PhantomData<G>,
 31}
 32
 33/// Provides an implementation of a trivial evaluation argument
 34#[derive(Clone, Debug, Serialize, Deserialize)]
 35#[serde(bound = "")]
 36pub struct TrivialEvaluationArgument<G: Group> {
 37  _p: PhantomData<G>,
 38}
 39
 40impl<G: Group> TranscriptReprTrait<G> for TrivialCommitment<G> {
 41  fn to_transcript_bytes(&self) -> Vec<u8> {
 42    self.S.to_transcript_bytes()
 43  }
 44}
 45
 46impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> CompCommitmentEngineTrait<G>
 47  for TrivialCompComputationEngine<G, EE>
 48{
 49  type Decommitment = TrivialDecommitment<G>;
 50  type Commitment = TrivialCommitment<G>;
 51  type EvaluationArgument = TrivialEvaluationArgument<G>;
 52
 53  /// commits to R1CS matrices
 54  fn commit(
 55    _ck: &CommitmentKey<G>,
 56    S: &R1CSShape<G>,
 57  ) -> Result<(Self::Commitment, Self::Decommitment), NovaError> {
 58    Ok((
 59      TrivialCommitment { S: S.clone() },
 60      TrivialDecommitment {
 61        _p: Default::default(),
 62      },
 63    ))
 64  }
 65
 66  /// proves an evaluation of R1CS matrices viewed as polynomials
 67  fn prove(
 68    _ck: &CommitmentKey<G>,
 69    _S: &R1CSShape<G>,
 70    _decomm: &Self::Decommitment,
 71    _comm: &Self::Commitment,
 72    _r: &(&[G::Scalar], &[G::Scalar]),
 73    _transcript: &mut G::TE,
 74  ) -> Result<
 75    (
 76      Self::EvaluationArgument,
 77      Vec<(PolyEvalWitness<G>, PolyEvalInstance<G>)>,
 78    ),
 79    NovaError,
 80  > {
 81    Ok((
 82      TrivialEvaluationArgument {
 83        _p: Default::default(),
 84      },
 85      Vec::new(),
 86    ))
 87  }
 88
 89  /// verifies an evaluation of R1CS matrices viewed as polynomials
 90  fn verify(
 91    comm: &Self::Commitment,
 92    r: &(&[G::Scalar], &[G::Scalar]),
 93    _arg: &Self::EvaluationArgument,
 94    _transcript: &mut G::TE,
 95  ) -> Result<(G::Scalar, G::Scalar, G::Scalar, Vec<PolyEvalInstance<G>>), NovaError> {
 96    let (r_x, r_y) = r;
 97    let evals = SparsePolynomial::<G>::multi_evaluate(&[&comm.S.A, &comm.S.B, &comm.S.C], r_x, r_y);
 98    Ok((evals[0], evals[1], evals[2], Vec::new()))
 99  }
100}
101
102mod product;
103mod sparse;
104
105use sparse::{SparseEvaluationArgument, SparsePolynomial, SparsePolynomialCommitment};
106
107/// A non-trivial implementation of `CompCommitmentEngineTrait` using Spartan's SPARK compiler
108pub struct SparkEngine<G: Group> {
109  _p: PhantomData<G>,
110}
111
112/// An implementation of Spark decommitment
113#[derive(Clone, Serialize, Deserialize)]
114#[serde(bound = "")]
115pub struct SparkDecommitment<G: Group> {
116  A: SparsePolynomial<G>,
117  B: SparsePolynomial<G>,
118  C: SparsePolynomial<G>,
119}
120
121impl<G: Group> SparkDecommitment<G> {
122  fn new(S: &R1CSShape<G>) -> Self {
123    let ell = (S.num_cons.log_2(), S.num_vars.log_2() + 1);
124    let A = SparsePolynomial::new(ell, &S.A);
125    let B = SparsePolynomial::new(ell, &S.B);
126    let C = SparsePolynomial::new(ell, &S.C);
127
128    Self { A, B, C }
129  }
130
131  fn commit(&self, ck: &CommitmentKey<G>) -> SparkCommitment<G> {
132    let comm_A = self.A.commit(ck);
133    let comm_B = self.B.commit(ck);
134    let comm_C = self.C.commit(ck);
135
136    SparkCommitment {
137      comm_A,
138      comm_B,
139      comm_C,
140    }
141  }
142}
143
144/// An implementation of Spark commitment
145#[derive(Clone, Serialize, Deserialize)]
146#[serde(bound = "")]
147pub struct SparkCommitment<G: Group> {
148  comm_A: SparsePolynomialCommitment<G>,
149  comm_B: SparsePolynomialCommitment<G>,
150  comm_C: SparsePolynomialCommitment<G>,
151}
152
153impl<G: Group> TranscriptReprTrait<G> for SparkCommitment<G> {
154  fn to_transcript_bytes(&self) -> Vec<u8> {
155    let mut bytes = self.comm_A.to_transcript_bytes();
156    bytes.extend(self.comm_B.to_transcript_bytes());
157    bytes.extend(self.comm_C.to_transcript_bytes());
158    bytes
159  }
160}
161
162/// Provides an implementation of a trivial evaluation argument
163#[derive(Clone, Serialize, Deserialize)]
164#[serde(bound = "")]
165pub struct SparkEvaluationArgument<G: Group> {
166  arg_A: SparseEvaluationArgument<G>,
167  arg_B: SparseEvaluationArgument<G>,
168  arg_C: SparseEvaluationArgument<G>,
169}
170
171impl<G: Group> CompCommitmentEngineTrait<G> for SparkEngine<G> {
172  type Decommitment = SparkDecommitment<G>;
173  type Commitment = SparkCommitment<G>;
174  type EvaluationArgument = SparkEvaluationArgument<G>;
175
176  /// commits to R1CS matrices
177  fn commit(
178    ck: &CommitmentKey<G>,
179    S: &R1CSShape<G>,
180  ) -> Result<(Self::Commitment, Self::Decommitment), NovaError> {
181    let sparse = SparkDecommitment::new(S);
182    let comm = sparse.commit(ck);
183    Ok((comm, sparse))
184  }
185
186  /// proves an evaluation of R1CS matrices viewed as polynomials
187  fn prove(
188    ck: &CommitmentKey<G>,
189    S: &R1CSShape<G>,
190    decomm: &Self::Decommitment,
191    comm: &Self::Commitment,
192    r: &(&[G::Scalar], &[G::Scalar]),
193    transcript: &mut G::TE,
194  ) -> Result<
195    (
196      Self::EvaluationArgument,
197      Vec<(PolyEvalWitness<G>, PolyEvalInstance<G>)>,
198    ),
199    NovaError,
200  > {
201    let (arg_A, u_w_vec_A) =
202      SparseEvaluationArgument::prove(ck, &decomm.A, &S.A, &comm.comm_A, r, transcript)?;
203    let (arg_B, u_w_vec_B) =
204      SparseEvaluationArgument::prove(ck, &decomm.B, &S.B, &comm.comm_B, r, transcript)?;
205    let (arg_C, u_w_vec_C) =
206      SparseEvaluationArgument::prove(ck, &decomm.C, &S.C, &comm.comm_C, r, transcript)?;
207
208    let u_w_vec = {
209      let mut u_w_vec = u_w_vec_A;
210      u_w_vec.extend(u_w_vec_B);
211      u_w_vec.extend(u_w_vec_C);
212      u_w_vec
213    };
214
215    Ok((
216      SparkEvaluationArgument {
217        arg_A,
218        arg_B,
219        arg_C,
220      },
221      u_w_vec,
222    ))
223  }
224
225  /// verifies an evaluation of R1CS matrices viewed as polynomials
226  fn verify(
227    comm: &Self::Commitment,
228    r: &(&[G::Scalar], &[G::Scalar]),
229    arg: &Self::EvaluationArgument,
230    transcript: &mut G::TE,
231  ) -> Result<(G::Scalar, G::Scalar, G::Scalar, Vec<PolyEvalInstance<G>>), NovaError> {
232    let (eval_A, u_vec_A) = arg.arg_A.verify(&comm.comm_A, r, transcript)?;
233    let (eval_B, u_vec_B) = arg.arg_B.verify(&comm.comm_B, r, transcript)?;
234    let (eval_C, u_vec_C) = arg.arg_C.verify(&comm.comm_C, r, transcript)?;
235
236    let u_vec = {
237      let mut u_vec = u_vec_A;
238      u_vec.extend(u_vec_B);
239      u_vec.extend(u_vec_C);
240      u_vec
241    };
242
243    Ok((eval_A, eval_B, eval_C, u_vec))
244  }
245}