Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ neptune = "6.1"
generic-array = "0.14.4"
bellperson-nonnative = { version = "0.2.1", default-features = false, features = ["wasm"] }
rug = { version = "1.10", default-features = false, features = ["integer", "serde", "rand"] }
serde = { version = "1.0", features = ["derive"] }
bincode = "1.2.1"
flate2 = "1.0"

[features]
default = [ "bellperson/default", "bellperson-nonnative/default" ]
Expand Down
6 changes: 1 addition & 5 deletions src/commitments.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{
errors::NovaError,
traits::{CompressedGroup, Group},
traits::{AppendToTranscriptTrait, CompressedGroup, Group},
};
use core::{
fmt::Debug,
Expand Down Expand Up @@ -80,10 +80,6 @@ impl<G: Group> CommitTrait<G> for [G::Scalar] {
}
}

pub trait AppendToTranscriptTrait {
fn append_to_transcript(&self, label: &'static [u8], transcript: &mut Transcript);
}

impl<G: Group> AppendToTranscriptTrait for Commitment<G> {
fn append_to_transcript(&self, label: &'static [u8], transcript: &mut Transcript) {
transcript.append_message(label, self.comm.compress().as_bytes());
Expand Down
23 changes: 19 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ pub mod traits;

use std::marker::PhantomData;

use commitments::{AppendToTranscriptTrait, CompressedCommitment};
use commitments::CompressedCommitment;
use errors::NovaError;
use merlin::Transcript;
use r1cs::{
R1CSGens, R1CSInstance, R1CSShape, R1CSWitness, RelaxedR1CSInstance, RelaxedR1CSWitness,
};
use traits::{ChallengeTrait, Group};
use traits::{AppendToTranscriptTrait, ChallengeTrait, Group};

/// A SNARK that holds the proof of a step of an incremental computation
pub struct StepSNARK<G: Group> {
Expand Down Expand Up @@ -59,6 +59,13 @@ impl<G: Group> StepSNARK<G> {
// append the protocol name to the transcript
transcript.append_message(b"protocol-name", StepSNARK::<G>::protocol_name());

// append S to the transcript
S.append_to_transcript(b"S", transcript);

// append U1 and U2 to transcript
U1.append_to_transcript(b"U1", transcript);
U2.append_to_transcript(b"U2", transcript);

// compute a commitment to the cross-term
let (T, comm_T) = S.commit_T(gens, U1, W1, U2, W2)?;

Expand Down Expand Up @@ -91,13 +98,21 @@ impl<G: Group> StepSNARK<G> {
/// if and only if `U1` and `U2` are satisfiable.
pub fn verify(
&self,
S: &R1CSShape<G>,
U1: &RelaxedR1CSInstance<G>,
U2: &R1CSInstance<G>,
transcript: &mut Transcript,
) -> Result<RelaxedR1CSInstance<G>, NovaError> {
// append the protocol name to the transcript
transcript.append_message(b"protocol-name", StepSNARK::<G>::protocol_name());

// append S to the transcript
S.append_to_transcript(b"S", transcript);

// append U1 and U2 to transcript
U1.append_to_transcript(b"U1", transcript);
U2.append_to_transcript(b"U2", transcript);

// append `comm_T` to the transcript and obtain a challenge
self.comm_T.append_to_transcript(b"comm_T", transcript);

Expand Down Expand Up @@ -232,7 +247,7 @@ mod tests {

// verify the step SNARK with U1 as the first incoming instance
let mut verifier_transcript = Transcript::new(b"StepSNARKExample");
let res = step_snark.verify(&r_U, U1, &mut verifier_transcript);
let res = step_snark.verify(shape, &r_U, U1, &mut verifier_transcript);
assert!(res.is_ok());
let U = res.unwrap();

Expand All @@ -248,7 +263,7 @@ mod tests {
let (step_snark, (_U, W)) = res.unwrap();

// verify the step SNARK with U1 as the first incoming instance
let res = step_snark.verify(&r_U, U2, &mut verifier_transcript);
let res = step_snark.verify(shape, &r_U, U2, &mut verifier_transcript);
assert!(res.is_ok());
let U = res.unwrap();

Expand Down
63 changes: 61 additions & 2 deletions src/r1cs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
use super::{
commitments::{CommitGens, CommitTrait, Commitment, CompressedCommitment},
errors::NovaError,
traits::Group,
traits::{AppendToTranscriptTrait, Group},
};
use ff::Field;
use ff::{Field, PrimeField};
use flate2::{write::ZlibEncoder, Compression};
use itertools::concat;
use merlin::Transcript;
use rayon::prelude::*;
use serde::{Deserialize, Serialize};

/// Public parameters for a given R1CS
pub struct R1CSGens<G: Group> {
Expand Down Expand Up @@ -292,6 +295,46 @@ impl<G: Group> R1CSShape<G> {
}
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
struct R1CSShapeSerialized {
num_cons: usize,
num_vars: usize,
num_io: usize,
A: Vec<(usize, usize, Vec<u8>)>,
B: Vec<(usize, usize, Vec<u8>)>,
C: Vec<(usize, usize, Vec<u8>)>,
}

impl<G: Group> AppendToTranscriptTrait for R1CSShape<G> {
fn append_to_transcript(&self, _label: &'static [u8], transcript: &mut Transcript) {
let shape_serialized = R1CSShapeSerialized {
num_cons: self.num_cons,
num_vars: self.num_vars,
num_io: self.num_io,
A: self
.A
.iter()
.map(|(i, j, v)| (*i, *j, v.to_repr().as_ref().to_vec()))
.collect(),
B: self
.B
.iter()
.map(|(i, j, v)| (*i, *j, v.to_repr().as_ref().to_vec()))
.collect(),
C: self
.C
.iter()
.map(|(i, j, v)| (*i, *j, v.to_repr().as_ref().to_vec()))
.collect(),
};

let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
bincode::serialize_into(&mut encoder, &shape_serialized).unwrap();
let shape_bytes = encoder.finish().unwrap();
transcript.append_message(b"R1CSShape", &shape_bytes);
}
}

impl<G: Group> R1CSWitness<G> {
/// A method to create a witness object using a vector of scalars
pub fn new(S: &R1CSShape<G>, W: &[G::Scalar]) -> Result<R1CSWitness<G>, NovaError> {
Expand Down Expand Up @@ -326,6 +369,13 @@ impl<G: Group> R1CSInstance<G> {
}
}

impl<G: Group> AppendToTranscriptTrait for R1CSInstance<G> {
fn append_to_transcript(&self, _label: &'static [u8], transcript: &mut Transcript) {
self.comm_W.append_to_transcript(b"comm_W", transcript);
self.X.append_to_transcript(b"X", transcript);
}
}

impl<G: Group> RelaxedR1CSWitness<G> {
/// Produces a default RelaxedR1CSWitness given an R1CSShape
pub fn default(S: &R1CSShape<G>) -> RelaxedR1CSWitness<G> {
Expand Down Expand Up @@ -427,3 +477,12 @@ impl<G: Group> RelaxedR1CSInstance<G> {
})
}
}

impl<G: Group> AppendToTranscriptTrait for RelaxedR1CSInstance<G> {
fn append_to_transcript(&self, _label: &'static [u8], transcript: &mut Transcript) {
self.comm_W.append_to_transcript(b"comm_W", transcript);
self.comm_E.append_to_transcript(b"comm_E", transcript);
self.X.append_to_transcript(b"X", transcript);
self.u.append_to_transcript(b"u", transcript);
}
}
20 changes: 20 additions & 0 deletions src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ pub trait CompressedGroup: Clone + Copy + Debug + Eq + Sized + Send + Sync + 'st
fn as_bytes(&self) -> &[u8];
}

/// A helper trait to append different types to the transcript
pub trait AppendToTranscriptTrait {
/// appends the value to the transcript under the provided label
fn append_to_transcript(&self, label: &'static [u8], transcript: &mut Transcript);
}

/// A helper trait to generate challenges using a transcript object
pub trait ChallengeTrait {
/// Returns a Scalar representing the challenge using the transcript
Expand Down Expand Up @@ -133,3 +139,17 @@ pub trait StepCircuit<F: PrimeField> {
z: AllocatedNum<F>,
) -> Result<AllocatedNum<F>, SynthesisError>;
}

impl<F: PrimeField> AppendToTranscriptTrait for F {
fn append_to_transcript(&self, label: &'static [u8], transcript: &mut Transcript) {
transcript.append_message(label, self.to_repr().as_ref());
}
}

impl<F: PrimeField> AppendToTranscriptTrait for [F] {
fn append_to_transcript(&self, label: &'static [u8], transcript: &mut Transcript) {
for s in self {
s.append_to_transcript(label, transcript);
}
}
}