Skip to content

Commit

Permalink
Parallelize Phase2 Contributions and Preparation (#41)
Browse files Browse the repository at this point in the history
* feat(utils/groth16): read the groth16 parameters in parallel

this is useful to reduce the time required to generate the Phase 2 step

* feat(utils/groth16): run FFTs in parallel

* chore: adjust rest of codebase to use slices for phase2

* feat(phase2): contribute H and L in parallel

* feat(bls-snark-setup): contribute in parallel

* fix(bls-snark-setup): extend the file by 1 pubkey

Due to passing a slice to the contribute function, we need to manually adjust the size of the file (and as a result of the mmap) to include 1 more pubkey (this would not be needed if we just passed the file itself, but then we would not be able to parallelize as well)

* fix: use correct pubkey size

Previously we used a constant pubkey size which is wrong, since it depends on the curve being used

* fix(bls-snark-setup): use the correct phase2 size

Previously we were using just the number of constraints, while the required number is the sum of constraints, public inputs and private inputs

* chore: deduplicate crossbeam import
  • Loading branch information
gakonst authored Mar 28, 2020
1 parent 79d8e0f commit 2c99e6e
Show file tree
Hide file tree
Showing 14 changed files with 270 additions and 153 deletions.
80 changes: 38 additions & 42 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions bls-snark-setup/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ rand = "0.7.3"
thiserror = "1.0.11"
hex = "0.4.2"
tracing-subscriber = "0.2.3"
memmap = "0.7.0"
15 changes: 12 additions & 3 deletions bls-snark-setup/src/cli/contribute.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use gumdrop::Options;
use phase2::chunked_groth16::contribute as chunked_contribute;
use memmap::MmapOptions;
use phase2::{chunked_groth16::contribute as chunked_contribute, keypair::PublicKey};
use rand::Rng;
use snark_utils::Result;
use std::fs::OpenOptions;
Expand All @@ -23,13 +24,21 @@ pub struct ContributeOpts {
}

pub fn contribute<R: Rng>(opts: &ContributeOpts, rng: &mut R) -> Result<()> {
let mut file = OpenOptions::new()
let file = OpenOptions::new()
.read(true)
.write(true)
.open(&opts.data)
.expect("could not open file for writing the new MPC parameters ");
let metadata = file.metadata()?;
// extend the file by 1 pubkey
file.set_len(metadata.len() + PublicKey::<SW6>::size() as u64)?;
let mut file = unsafe {
MmapOptions::new()
.map_mut(&file)
.expect("unable to create a memory map for input")
};

chunked_contribute::<SW6, _, _>(&mut file, rng, opts.batch)?;
chunked_contribute::<SW6, _>(&mut file, rng, opts.batch)?;

Ok(())
}
25 changes: 16 additions & 9 deletions bls-snark-setup/src/cli/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use zexe_r1cs_std::test_constraint_counter::ConstraintCounter;
use phase2::parameters::{circuit_to_qap, MPCParameters};
use snark_utils::{log_2, Groth16Params, Result, UseCompression};

use memmap::MmapOptions;
use std::fs::OpenOptions;

#[derive(Debug, Options, Clone)]
Expand Down Expand Up @@ -46,46 +47,52 @@ pub fn empty_circuit(opt: &NewOpts) -> (ValidatorSetUpdate<Bls12_377>, usize) {
None, // The hashes are done over SW6 so no helper is provided for the setup
);

let num_constraints = {
let phase2_size = {
let mut counter = ConstraintCounter::new();
valset
.clone()
.generate_constraints(&mut counter)
.expect("could not calculate number of required constraints");
let constraints = counter.num_constraints();
let power = log_2(constraints) as u32;
let phase2_size = counter.num_aux + counter.num_inputs + counter.num_constraints;
let power = log_2(phase2_size) as u32;
// get the nearest power of 2
if constraints < 2usize.pow(power) {
if phase2_size < 2usize.pow(power) {
2usize.pow(power + 1)
} else {
constraints
phase2_size
}
};

(valset, num_constraints)
(valset, phase2_size)
}

pub fn new(opt: &NewOpts) -> Result<()> {
let mut phase1_transcript = OpenOptions::new()
let phase1_transcript = OpenOptions::new()
.read(true)
.write(true)
.open(&opt.phase1)
.expect("could not read phase 1 transcript file");
let mut phase1_transcript = unsafe {
MmapOptions::new()
.map_mut(&phase1_transcript)
.expect("unable to create a memory map for input")
};
let mut output = OpenOptions::new()
.read(false)
.write(true)
.create_new(true)
.open(&opt.output)
.expect("could not open file for writing the MPC parameters ");

let (valset, num_constraints) = empty_circuit(&opt);
let (valset, phase2_size) = empty_circuit(&opt);

// Read `num_constraints` Lagrange coefficients from the Phase1 Powers of Tau which were
// prepared for this step. This will fail if Phase 1 was too small.
let phase1 = Groth16Params::<SW6>::read(
&mut phase1_transcript,
COMPRESSION,
2usize.pow(opt.phase1_size),
num_constraints,
phase2_size,
)?;

// Convert it to a QAP
Expand Down
Loading

0 comments on commit 2c99e6e

Please sign in to comment.