Skip to content

Commit

Permalink
optimize LinearCombination
Browse files Browse the repository at this point in the history
  • Loading branch information
dignifiedquire committed Sep 3, 2021
1 parent ab40fb6 commit c0d55b7
Show file tree
Hide file tree
Showing 9 changed files with 381 additions and 256 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ rand = "0.7"
rayon = "1.3.0"
memmap = "0.7.0"
thiserror = "1.0.10"
rustc-hash = "1.1.0"
num_cpus = "1"
crossbeam-channel = "0.5.0"
digest = "0.9.0"
Expand Down
4 changes: 2 additions & 2 deletions src/gadgets/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ impl<E: ScalarEngine> Num<E> {
}

pub fn scale(mut self, scalar: E::Fr) -> Self {
for (_variable, fr) in self.lc.0.iter_mut() {
for (_variable, fr) in self.lc.iter_mut() {
fr.mul_assign(&scalar);
}

Expand Down Expand Up @@ -655,7 +655,7 @@ mod test {
assert_eq!(scaled_value, scaled_num.value.unwrap());

// Each variable has the expected coefficient, the sume of those added by its Index.
scaled_num.lc.0.iter().for_each(|(var, coeff)| match var.0 {
scaled_num.lc.iter().for_each(|(var, coeff)| match var.0 {
Index::Aux(i) => {
let mut tmp = expected_sums[i];
tmp.mul_assign(&scalar);
Expand Down
4 changes: 2 additions & 2 deletions src/gadgets/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl Ord for OrderedVariable {

fn proc_lc<E: ScalarEngine>(terms: &LinearCombination<E>) -> BTreeMap<OrderedVariable, E::Fr> {
let mut map = BTreeMap::new();
for (&var, &coeff) in terms.0.iter() {
for (var, &coeff) in terms.iter() {
map.entry(OrderedVariable(var))
.or_insert_with(E::Fr::zero)
.add_assign(&coeff);
Expand Down Expand Up @@ -119,7 +119,7 @@ fn eval_lc<E: ScalarEngine>(
) -> E::Fr {
let mut acc = E::Fr::zero();

for (&var, coeff) in terms.0.iter() {
for (var, coeff) in terms.iter() {
let mut tmp = match var.get_unchecked() {
Index::Input(index) => inputs[index].0,
Index::Aux(index) => aux[index].0,
Expand Down
6 changes: 3 additions & 3 deletions src/groth16/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ impl<E: Engine> ConstraintSystem<E> for KeypairAssembly<E> {
aux: &mut [Vec<(E::Fr, usize)>],
this_constraint: usize,
) {
for (index, coeff) in l.0 {
for (index, coeff) in l.iter() {
match index {
Variable(Index::Input(id)) => inputs[id].push((coeff, this_constraint)),
Variable(Index::Aux(id)) => aux[id].push((coeff, this_constraint)),
Variable(Index::Input(id)) => inputs[id].push((*coeff, this_constraint)),
Variable(Index::Aux(id)) => aux[id].push((*coeff, this_constraint)),
}
}
}
Expand Down
86 changes: 30 additions & 56 deletions src/groth16/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,44 +22,6 @@ use log::trace;
#[cfg(feature = "gpu")]
use crate::gpu::PriorityLock;

fn eval<E: Engine>(
lc: &LinearCombination<E>,
mut input_density: Option<&mut DensityTracker>,
mut aux_density: Option<&mut DensityTracker>,
input_assignment: &[E::Fr],
aux_assignment: &[E::Fr],
) -> E::Fr {
let mut acc = E::Fr::zero();

for (&index, &coeff) in lc.0.iter() {
let mut tmp;

match index {
Variable(Index::Input(i)) => {
tmp = input_assignment[i];
if let Some(ref mut v) = input_density {
v.inc(i);
}
}
Variable(Index::Aux(i)) => {
tmp = aux_assignment[i];
if let Some(ref mut v) = aux_density {
v.inc(i);
}
}
}

if coeff == E::Fr::one() {
acc.add_assign(&tmp);
} else {
tmp.mul_assign(&coeff);
acc.add_assign(&tmp);
}
}

acc
}

struct ProvingAssignment<E: Engine> {
// Density of queries
a_aux_density: DensityTracker,
Expand Down Expand Up @@ -179,34 +141,43 @@ impl<E: Engine> ConstraintSystem<E> for ProvingAssignment<E> {
let b = b(LinearCombination::zero());
let c = c(LinearCombination::zero());

self.a.push(Scalar(eval(
&a,
let input_assignment = &self.input_assignment;
let aux_assignment = &self.aux_assignment;
let a_aux_density = &mut self.a_aux_density;
let b_input_density = &mut self.b_input_density;
let b_aux_density = &mut self.b_aux_density;

let a_res = a.eval(
// Inputs have full density in the A query
// because there are constraints of the
// form x * 0 = 0 for each input.
None,
Some(&mut self.a_aux_density),
&self.input_assignment,
&self.aux_assignment,
)));
self.b.push(Scalar(eval(
&b,
Some(&mut self.b_input_density),
Some(&mut self.b_aux_density),
&self.input_assignment,
&self.aux_assignment,
)));
self.c.push(Scalar(eval(
&c,
Some(a_aux_density),
input_assignment,
aux_assignment,
);

let b_res = b.eval(
Some(b_input_density),
Some(b_aux_density),
input_assignment,
aux_assignment,
);

let c_res = c.eval(
// There is no C polynomial query,
// though there is an (beta)A + (alpha)B + C
// query for all aux variables.
// However, that query has full density.
None,
None,
&self.input_assignment,
&self.aux_assignment,
)));
input_assignment,
aux_assignment,
);

self.a.push(Scalar(a_res));
self.b.push(Scalar(b_res));
self.c.push(Scalar(c_res));
}

fn push_namespace<NR, N>(&mut self, _: N)
Expand Down Expand Up @@ -540,6 +511,7 @@ where
E: Engine,
C: Circuit<E> + Send,
{
let start = Instant::now();
let mut provers = circuits
.into_par_iter()
.map(|circuit| -> Result<_, SynthesisError> {
Expand All @@ -557,6 +529,8 @@ where
})
.collect::<Result<Vec<_>, _>>()?;

info!("synthesis time: {:?}", start.elapsed());

// Start fft/multiexp prover timer
let start = Instant::now();
info!("starting proof timer");
Expand Down
Loading

0 comments on commit c0d55b7

Please sign in to comment.