Skip to content
This repository has been archived by the owner on Apr 5, 2019. It is now read-only.

Commit

Permalink
Update spacesuit to use new R1CS API (#19)
Browse files Browse the repository at this point in the history
Update to use this API:
dalek-cryptography/bulletproofs#221

Changes:
- we no longer have to use "sort commitments" functions to separate out the different commitments from each other after they are returned in a big lump.
- added helper functions to easily commit values and allocated values.
  • Loading branch information
cathieyun authored and oleganza committed Dec 5, 2018
1 parent 82a03ae commit 4df17f9
Show file tree
Hide file tree
Showing 10 changed files with 380 additions and 517 deletions.
33 changes: 29 additions & 4 deletions benches/spacesuit.rs
Expand Up @@ -32,11 +32,12 @@ fn create_spacesuit_proof_helper(n: usize, c: &mut Criterion) {
})
.collect();
let mut outputs = inputs.clone();
rand::thread_rng().shuffle(&mut outputs);
let mut rng: rand::ThreadRng = rand::thread_rng();
rng.shuffle(&mut outputs);

// Make spacesuit proof
b.iter(|| {
prove(&bp_gens, &pc_gens, &inputs, &outputs).unwrap();
prove(&bp_gens, &pc_gens, &inputs, &outputs, &mut rng).unwrap();
})
});
}
Expand Down Expand Up @@ -80,10 +81,34 @@ fn verify_spacesuit_proof_helper(n: usize, c: &mut Criterion) {
.collect();
let mut outputs = inputs.clone();
rand::thread_rng().shuffle(&mut outputs);
let (proof, commitments) = prove(&bp_gens, &pc_gens, &inputs, &outputs).unwrap();
let mut rng: rand::ThreadRng = rand::thread_rng();
let (
proof,
tx_in_com,
merge_in_com,
merge_mid_com,
merge_out_com,
split_in_com,
split_mid_com,
split_out_com,
tx_out_com,
) = prove(&bp_gens, &pc_gens, &inputs, &outputs, &mut rng).unwrap();

b.iter(|| {
verify(&bp_gens, &pc_gens, &proof, commitments.clone(), n, n).unwrap();
verify(
&bp_gens,
&pc_gens,
&proof,
&tx_in_com,
&merge_in_com,
&merge_mid_com,
&merge_out_com,
&split_in_com,
&split_mid_com,
&split_out_com,
&tx_out_com,
)
.unwrap();
})
});
}
Expand Down
90 changes: 19 additions & 71 deletions src/gadgets/k_mix.rs
Expand Up @@ -52,13 +52,11 @@ pub fn fill_cs<CS: ConstraintSystem>(
#[cfg(test)]
mod tests {
use super::*;
use bulletproofs::r1cs::{ProverCS, Variable, VerifierCS};
use bulletproofs::r1cs::{Prover, Verifier};
use bulletproofs::{BulletproofGens, PedersenGens};
use curve25519_dalek::scalar::Scalar;
use merlin::Transcript;
use std::cmp::max;

use value::Value;
use value::{ProverCommittable, Value, VerifierCommittable};

// Helper functions to make the tests easier to read
fn yuan(q: u64) -> Value {
Expand Down Expand Up @@ -214,85 +212,35 @@ mod tests {
}

// Prover's scope
let (proof, commitments) = {
let mut values = inputs.clone();
values.append(&mut intermediates.clone());
values.append(&mut outputs.clone());

let v: Vec<Scalar> = values.iter().fold(Vec::new(), |mut vec, value| {
vec.push(value.q.into());
vec.push(value.a);
vec.push(value.t);
vec
});
let v_blinding: Vec<Scalar> = (0..v.len())
.map(|_| Scalar::random(&mut rand::thread_rng()))
.collect();

// Make v_blinding vector using RNG from transcript
let (proof, input_com, inter_com, output_com) = {
let mut prover_transcript = Transcript::new(b"KMixTest");
let (mut prover_cs, variables, commitments) = ProverCS::new(
&bp_gens,
&pc_gens,
&mut prover_transcript,
v.clone(),
v_blinding.clone(),
);
let mut rng = rand::thread_rng();

// Prover adds constraints to the constraint system
let (input_vals, inter_vals, output_vals) =
organize_values(variables, &Some(values), k, inter_count);
let mut prover = Prover::new(&bp_gens, &pc_gens, &mut prover_transcript);
let (input_com, input_vars) = inputs.commit(&mut prover, &mut rng);
let (inter_com, inter_vars) = intermediates.commit(&mut prover, &mut rng);
let (output_com, output_vars) = outputs.commit(&mut prover, &mut rng);

fill_cs(&mut prover_cs, input_vals, inter_vals, output_vals)?;
let mut prover_cs = prover.finalize_inputs();
fill_cs(&mut prover_cs, input_vars, inter_vars, output_vars)?;

let proof = prover_cs.prove()?;

(proof, commitments)
(proof, input_com, inter_com, output_com)
};

// Verifier makes a `ConstraintSystem` instance representing a merge gadget
let mut verifier_transcript = Transcript::new(b"KMixTest");
let (mut verifier_cs, variables) =
VerifierCS::new(&bp_gens, &pc_gens, &mut verifier_transcript, commitments);
let mut verifier = Verifier::new(&bp_gens, &pc_gens, &mut verifier_transcript);

// Verifier adds constraints to the constraint system
let (input_vals, inter_vals, output_vals) =
organize_values(variables, &None, k, inter_count);
let input_vars = input_com.commit(&mut verifier);
let inter_vars = inter_com.commit(&mut verifier);
let output_vars = output_com.commit(&mut verifier);

assert!(fill_cs(&mut verifier_cs, input_vals, inter_vals, output_vals).is_ok());
let mut verifier_cs = verifier.finalize_inputs();

Ok(verifier_cs.verify(&proof)?)
}

fn organize_values(
variables: Vec<Variable>,
assignments: &Option<Vec<Value>>,
k: usize,
inter_count: usize,
) -> (
Vec<AllocatedValue>,
Vec<AllocatedValue>,
Vec<AllocatedValue>,
) {
let val_count = variables.len() / 3;

let mut values = Vec::with_capacity(val_count);
for i in 0..val_count {
values.push(AllocatedValue {
q: variables[i * 3],
a: variables[i * 3 + 1],
t: variables[i * 3 + 2],
assignment: match assignments {
Some(ref a) => Some(a[i]),
None => None,
},
});
}

let input_vals = values[0..k].to_vec();
let inter_vals = values[k..k + inter_count].to_vec();
let output_vals = values[k + inter_count..2 * k + inter_count].to_vec();
// Verifier adds constraints to the constraint system
assert!(fill_cs(&mut verifier_cs, input_vars, inter_vars, output_vars).is_ok());

(input_vals, inter_vals, output_vals)
Ok(verifier_cs.verify(&proof)?)
}
}
102 changes: 23 additions & 79 deletions src/gadgets/mix.rs
Expand Up @@ -43,12 +43,11 @@ pub fn fill_cs<CS: ConstraintSystem>(
#[cfg(test)]
mod tests {
use super::*;
use bulletproofs::r1cs::{ProverCS, VerifierCS};
use bulletproofs::r1cs::{Prover, Verifier};
use bulletproofs::{BulletproofGens, PedersenGens};
use curve25519_dalek::scalar::Scalar;
use merlin::Transcript;

use value::Value;
use value::{ProverCommittable, Value, VerifierCommittable};

#[test]
fn mix_gadget() {
Expand Down Expand Up @@ -105,90 +104,35 @@ mod tests {
};

// Prover's scope
let (proof, commitments) = {
let (proof, A_com, B_com, C_com, D_com) = {
// Prover makes a `ConstraintSystem` instance representing a merge gadget
// v and v_blinding emptpy because we are only testing low-level variable constraints
let values = vec![A, B, C, D];
let v: Vec<Scalar> = values.iter().fold(Vec::new(), |mut vec, value| {
vec.push(value.q.into());
vec.push(value.a);
vec.push(value.t);
vec
});
let v_blinding: Vec<Scalar> = (0..v.len())
.map(|_| Scalar::random(&mut rand::thread_rng()))
.collect();

let mut prover_transcript = Transcript::new(b"MixTest");
let (mut prover_cs, variables, commitments) = ProverCS::new(
&bp_gens,
&pc_gens,
&mut prover_transcript,
v,
v_blinding.clone(),
);

let A = AllocatedValue {
q: variables[0],
a: variables[1],
t: variables[2],
assignment: Some(A),
};
let B = AllocatedValue {
q: variables[3],
a: variables[4],
t: variables[5],
assignment: Some(B),
};
let C = AllocatedValue {
q: variables[6],
a: variables[7],
t: variables[8],
assignment: Some(C),
};
let D = AllocatedValue {
q: variables[9],
a: variables[10],
t: variables[11],
assignment: Some(D),
};
assert!(fill_cs(&mut prover_cs, A, B, C, D).is_ok());
let mut rng = rand::thread_rng();

let proof = prover_cs.prove()?;
let mut prover = Prover::new(&bp_gens, &pc_gens, &mut prover_transcript);
let (A_com, A_var) = A.commit(&mut prover, &mut rng);
let (B_com, B_var) = B.commit(&mut prover, &mut rng);
let (C_com, C_var) = C.commit(&mut prover, &mut rng);
let (D_com, D_var) = D.commit(&mut prover, &mut rng);

let mut prover_cs = prover.finalize_inputs();
assert!(fill_cs(&mut prover_cs, A_var, B_var, C_var, D_var).is_ok());

(proof, commitments)
let proof = prover_cs.prove()?;
(proof, A_com, B_com, C_com, D_com)
};

// Verifier makes a `ConstraintSystem` instance representing a merge gadget
let mut verifier_transcript = Transcript::new(b"MixTest");
let (mut verifier_cs, variables) =
VerifierCS::new(&bp_gens, &pc_gens, &mut verifier_transcript, commitments);

let A = AllocatedValue {
q: variables[0],
a: variables[1],
t: variables[2],
assignment: None,
};
let B = AllocatedValue {
q: variables[3],
a: variables[4],
t: variables[5],
assignment: None,
};
let C = AllocatedValue {
q: variables[6],
a: variables[7],
t: variables[8],
assignment: None,
};
let D = AllocatedValue {
q: variables[9],
a: variables[10],
t: variables[11],
assignment: None,
};
assert!(fill_cs(&mut verifier_cs, A, B, C, D).is_ok());
let mut verifier = Verifier::new(&bp_gens, &pc_gens, &mut verifier_transcript);

let A_var = A_com.commit(&mut verifier);
let B_var = B_com.commit(&mut verifier);
let C_var = C_com.commit(&mut verifier);
let D_var = D_com.commit(&mut verifier);

let mut verifier_cs = verifier.finalize_inputs();
assert!(fill_cs(&mut verifier_cs, A_var, B_var, C_var, D_var).is_ok());

Ok(verifier_cs.verify(&proof)?)
}
Expand Down

0 comments on commit 4df17f9

Please sign in to comment.