Merge pull request #6 from mir-protocol/bin_reorg

Split main into multiple binaries
This commit is contained in:
Daniel Lubarov 2021-04-06 13:25:33 -07:00 committed by GitHub
commit 88a84d5be3
17 changed files with 217 additions and 178 deletions

View File

@ -1,8 +1,15 @@
[package]
name = "plonky2"
description = "Recursive SNARKs based on Plonk and FRI"
version = "0.1.0"
authors = ["Daniel Lubarov <daniel@lubarov.com>"]
authors = ["Daniel Lubarov <daniel@mirprotocol.org>"]
readme = "README.md"
license = "MIT OR Apache-2.0"
repository = "https://github.com/mir-protocol/plonky2"
keywords = ["cryptography", "SNARK"]
categories = ["cryptography"]
edition = "2018"
default-run = "bench_recursion"
[dependencies]
env_logger = "0.8.3"

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# plonky2
TODO: Write a readme...

View File

@ -0,0 +1,21 @@
use std::time::Instant;
use plonky2::field::crandall_field::CrandallField;
use plonky2::field::field::Field;
type F = CrandallField;
fn main() {
let m = F::from_canonical_u64(12345678901234567890);
let mut x = F::ONE;
let start = Instant::now();
let num_muls = 2000000000;
for _ in 0..num_muls {
x *= m;
}
let duration = start.elapsed();
println!("result {:?}", x);
println!("took {:?}", duration);
println!("avg {:?}ns", duration.as_secs_f64() * 1e9 / (num_muls as f64));
}

42
src/bin/bench_gmimc.rs Normal file
View File

@ -0,0 +1,42 @@
use std::thread;
use std::time::Instant;
use plonky2::field::crandall_field::CrandallField;
use plonky2::field::field::Field;
use plonky2::gmimc::gmimc_permute_array;
use plonky2::hash::{GMIMC_CONSTANTS, GMIMC_ROUNDS};
type F = CrandallField;
// 113 wire polys, 3 Z polys, 4 parts of quotient poly.
const PROVER_POLYS: usize = 113 + 3 + 4;
fn main() {
const THREADS: usize = 12;
const LDE_BITS: i32 = 3;
const W: usize = 13;
const HASHES_PER_POLY: usize = 1 << (13 + LDE_BITS);
let threads = (0..THREADS).map(|_i| {
thread::spawn(move || {
let mut x = [F::ZERO; W];
for i in 0..W {
x[i] = F::from_canonical_u64((i as u64) * 123456 + 789);
}
let hashes_per_thread = HASHES_PER_POLY * PROVER_POLYS / THREADS;
let start = Instant::now();
for _ in 0..hashes_per_thread {
x = gmimc_permute_array::<_, W, GMIMC_ROUNDS>(x, GMIMC_CONSTANTS);
}
let duration = start.elapsed();
println!("took {:?}", duration);
println!("avg {:?}us", duration.as_secs_f64() * 1e6 / (hashes_per_thread as f64));
println!("result {:?}", x);
})
}).collect::<Vec<_>>();
for t in threads {
t.join().expect("oops");
}
}

33
src/bin/bench_ldes.rs Normal file
View File

@ -0,0 +1,33 @@
use std::time::Instant;
use rayon::prelude::*;
use plonky2::field::crandall_field::CrandallField;
use plonky2::field::fft;
use plonky2::field::field::Field;
use plonky2::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues};
type F = CrandallField;
// 113 wire polys, 3 Z polys, 4 parts of quotient poly.
const PROVER_POLYS: usize = 113 + 3 + 4;
fn main() {
const DEGREE: usize = 1 << 13;
const RATE_BITS: usize = 3;
let start = Instant::now();
(0usize..PROVER_POLYS).into_par_iter().for_each(|i| {
let mut values = vec![CrandallField::ZERO; DEGREE];
for j in 0usize..DEGREE {
values[j] = CrandallField((i * j) as u64);
}
let poly_values = PolynomialValues::new(values);
let start = Instant::now();
let result = poly_values.lde(RATE_BITS);
let duration = start.elapsed();
println!("LDE took {:?}", duration);
println!("LDE result: {:?}", result.values[0]);
});
println!("FFT overall took {:?}", start.elapsed());
}

View File

@ -0,0 +1,66 @@
use std::thread;
use std::time::Instant;
use env_logger::Env;
use rayon::prelude::*;
use plonky2::circuit_builder::CircuitBuilder;
use plonky2::circuit_data::CircuitConfig;
use plonky2::field::crandall_field::CrandallField;
use plonky2::field::fft;
use plonky2::field::field::Field;
use plonky2::gates::constant::ConstantGate;
use plonky2::gates::gmimc::GMiMCGate;
use plonky2::gmimc::gmimc_permute_array;
use plonky2::hash::{GMIMC_CONSTANTS, GMIMC_ROUNDS};
use plonky2::polynomial::polynomial::PolynomialCoeffs;
use plonky2::witness::PartialWitness;
// 113 wire polys, 3 Z polys, 4 parts of quotient poly.
const PROVER_POLYS: usize = 113 + 3 + 4;
fn main() {
// Set the default log filter. This can be overridden using the `RUST_LOG` environment variable,
// e.g. `RUST_LOG=debug`.
// We default to debug for now, since there aren't many logs anyway, but we should probably
// change this to info or warn later.
env_logger::Builder::from_env(Env::default().default_filter_or("debug")).init();
bench_prove::<CrandallField>();
// bench_field_mul::<CrandallField>();
// bench_fft();
println!();
// bench_gmimc::<CrandallField>();
}
fn bench_prove<F: Field>() {
let gmimc_gate = GMiMCGate::<F, GMIMC_ROUNDS>::with_automatic_constants();
let config = CircuitConfig {
num_wires: 120,
num_routed_wires: 12,
security_bits: 128,
rate_bits: 3,
num_checks: 3,
};
let mut builder = CircuitBuilder::<F>::new(config);
for _ in 0..5000 {
builder.add_gate_no_constants(gmimc_gate.clone());
}
builder.add_gate(ConstantGate::get(), vec![F::NEG_ONE]);
// for _ in 0..(40 * 5) {
// builder.add_gate(
// FriConsistencyGate::new(2, 3, 13),
// vec![F::primitive_root_of_unity(13)]);
// }
let prover = builder.build_prover();
let inputs = PartialWitness::new();
prover.prove(inputs);
}

View File

@ -1,4 +1,4 @@
fn field_search() {
fn main() {
for deg in (61..=64).rev() {
for adic in (28..=32).rev() {
for i in 1u128..100000 {

View File

@ -13,7 +13,7 @@ const EPSILON: u64 = 2415919103;
/// A field designed for use with the Crandall reduction algorithm.
///
/// Its order is
/// ```
/// ```ignore
/// P = 2**64 - EPSILON
/// = 2**64 - 9 * 2**28 + 1
/// = 2**28 * (2**36 - 9) + 1
@ -158,6 +158,7 @@ impl Neg for CrandallField {
if self.is_zero() {
Self::ZERO
} else {
// TODO: This could underflow if we're not canonical.
Self(Self::ORDER - self.0)
}
}
@ -226,7 +227,8 @@ impl DivAssign for CrandallField {
}
}
/// no final reduction
/// Reduces to a 64-bit value. The result might not be in canonical form; it could be in between the
/// field order and `2^64`.
#[inline]
fn reduce128(x: u128) -> CrandallField {
// This is Crandall's algorithm. When we have some high-order bits (i.e. with a weight of 2^64),
@ -250,5 +252,5 @@ fn split(x: u128) -> (u64, u64) {
mod tests {
use crate::test_arithmetic;
test_arithmetic!(crate::CrandallField);
test_arithmetic!(crate::field::crandall_field::CrandallField);
}

View File

@ -35,7 +35,7 @@ impl<F: Field> FftPrecomputation<F> {
}
}
pub(crate) fn fft<F: Field>(poly: PolynomialCoeffs<F>) -> PolynomialValues<F> {
pub fn fft<F: Field>(poly: PolynomialCoeffs<F>) -> PolynomialValues<F> {
let precomputation = fft_precompute(poly.len());
fft_with_precomputation_power_of_2(poly, &precomputation)
}

View File

@ -136,7 +136,7 @@ pub fn run_binaryop_test_cases<F, BinaryOp, ExpectedOp>(
macro_rules! test_arithmetic {
($field:ty) => {
mod arithmetic {
use crate::{Field};
use crate::field::field::Field;
use std::ops::{Add, Mul, Neg, Sub};
// Can be 32 or 64; doesn't have to be computer's actual word

View File

@ -1,7 +1,6 @@
pub(crate) mod crandall_field;
pub(crate) mod field;
pub(crate) mod field_search;
pub(crate) mod fft;
pub mod crandall_field;
pub mod field;
pub mod fft;
pub(crate) mod cosets;
#[cfg(test)]

View File

@ -1,7 +1,7 @@
pub(crate) mod arithmetic;
pub(crate) mod constant;
pub mod constant;
pub(crate) mod fri_consistency_gate;
pub(crate) mod gate;
pub(crate) mod gmimc;
pub mod gmimc;
pub(crate) mod gmimc_eval;
pub(crate) mod noop;

View File

@ -13,9 +13,9 @@ pub(crate) const SPONGE_RATE: usize = 8;
pub(crate) const SPONGE_CAPACITY: usize = 4;
pub(crate) const SPONGE_WIDTH: usize = SPONGE_RATE + SPONGE_CAPACITY;
pub(crate) const GMIMC_ROUNDS: usize = 101;
pub const GMIMC_ROUNDS: usize = 101;
/// This is the result of `gmimc_automatic_constants`; i.e. it's from ChaCha20 seeded with 0.
pub(crate) const GMIMC_CONSTANTS: [u64; GMIMC_ROUNDS] = [13080132715619999810, 8594738768332784433, 12896916466795114362, 1109962092924985887, 16216730424513838303, 10137062674532189451, 15292064468290167604, 17255573296743700660, 14827154243383347999, 2846171648262623971, 16246264665335217464, 14214208089399786945, 9667108688411000080, 6470857421371427314, 14103331941574951088, 11854816474757864855, 3498097497657653643, 7947235693333396721, 11110078702363612411, 16384314114341783099, 15404405914224921002, 14077880832148466479, 9555554663682579629, 13859595359622389547, 16859897326779206643, 17685474422023725021, 17858764736437889563, 9410011023624402450, 12495243630852222748, 12416945299436348089, 5776666812952701944, 6314421663507268983, 7402742472177291738, 982536713292517255, 17321168867539521172, 2934354895304883596, 10567510599683852824, 8135543734546633309, 116353493093565855, 8029688164312877009, 9003846638141970076, 7052445133185619935, 9645665433271393194, 5446430061585660707, 16770910636054378912, 17708360573237778662, 4661556288797079635, 11977051900536351292, 4378616569536950472, 3334807503157233344, 8019184736760206441, 2395043909056213726, 6558421058999795722, 11735894061922784518, 8143540539718733269, 5991753490174091591, 12235918792748480378, 2880312033996085535, 18224748117164817283, 18070411014966027790, 8156487614951798795, 10615269511128318233, 12489426406026437595, 5055279340584943685, 7231927320516917417, 2602078848371820415, 12445944370602567717, 3978905924297801117, 16711272946032085229, 10439032362290464320, 15110119873264383151, 821141790739535246, 11073536381779174375, 4866839313593360589, 13118391690850240703, 14527674975242150843, 7612751960041028847, 6808090908507673494, 6899703780195472329, 3664666286710282218, 783179505504239941, 8990689242729919931, 9646603556395461579, 7351246026916028004, 16970959815450893036, 15735726859844361172, 10347018222946250943, 12195545879691602738, 7423314197870213963, 14908016118492485461, 5840340123122280205, 17740311464247702688, 815306422036794512, 17456357369997417977, 6982651077270605698, 11970987325834369417, 8167785009370061651, 9483259820363401119, 954550221761525285, 10339565172077536587, 8651171085167737860];
pub const GMIMC_CONSTANTS: [u64; GMIMC_ROUNDS] = [13080132715619999810, 8594738768332784433, 12896916466795114362, 1109962092924985887, 16216730424513838303, 10137062674532189451, 15292064468290167604, 17255573296743700660, 14827154243383347999, 2846171648262623971, 16246264665335217464, 14214208089399786945, 9667108688411000080, 6470857421371427314, 14103331941574951088, 11854816474757864855, 3498097497657653643, 7947235693333396721, 11110078702363612411, 16384314114341783099, 15404405914224921002, 14077880832148466479, 9555554663682579629, 13859595359622389547, 16859897326779206643, 17685474422023725021, 17858764736437889563, 9410011023624402450, 12495243630852222748, 12416945299436348089, 5776666812952701944, 6314421663507268983, 7402742472177291738, 982536713292517255, 17321168867539521172, 2934354895304883596, 10567510599683852824, 8135543734546633309, 116353493093565855, 8029688164312877009, 9003846638141970076, 7052445133185619935, 9645665433271393194, 5446430061585660707, 16770910636054378912, 17708360573237778662, 4661556288797079635, 11977051900536351292, 4378616569536950472, 3334807503157233344, 8019184736760206441, 2395043909056213726, 6558421058999795722, 11735894061922784518, 8143540539718733269, 5991753490174091591, 12235918792748480378, 2880312033996085535, 18224748117164817283, 18070411014966027790, 8156487614951798795, 10615269511128318233, 12489426406026437595, 5055279340584943685, 7231927320516917417, 2602078848371820415, 12445944370602567717, 3978905924297801117, 16711272946032085229, 10439032362290464320, 15110119873264383151, 821141790739535246, 11073536381779174375, 4866839313593360589, 13118391690850240703, 14527674975242150843, 7612751960041028847, 6808090908507673494, 6899703780195472329, 3664666286710282218, 783179505504239941, 8990689242729919931, 9646603556395461579, 7351246026916028004, 16970959815450893036, 15735726859844361172, 10347018222946250943, 12195545879691602738, 7423314197870213963, 14908016118492485461, 5840340123122280205, 17740311464247702688, 815306422036794512, 17456357369997417977, 6982651077270605698, 11970987325834369417, 8167785009370061651, 9483259820363401119, 954550221761525285, 10339565172077536587, 8651171085167737860];
/// Controls the granularity of parallelization when building Merkle trees. I.e., we will try to
/// split up the task into units of work, such that each unit involves hashing roughly this many

22
src/lib.rs Normal file
View File

@ -0,0 +1,22 @@
pub mod circuit_builder;
pub mod circuit_data;
pub mod vars;
pub mod field;
pub mod fri;
pub mod gadgets;
pub mod gates;
pub mod generator;
pub mod gmimc;
pub mod hash;
pub mod plonk_challenger;
pub mod plonk_common;
pub mod polynomial;
pub mod proof;
pub mod prover;
pub mod recursive_verifier;
pub mod rescue;
pub mod target;
pub mod util;
pub mod verifier;
pub mod wire;
pub mod witness;

View File

@ -1,156 +0,0 @@
use std::thread;
use std::time::Instant;
use env_logger::Env;
use rayon::prelude::*;
use field::crandall_field::CrandallField;
use field::fft;
use crate::circuit_builder::CircuitBuilder;
use crate::circuit_data::CircuitConfig;
use crate::field::field::Field;
use crate::gates::constant::ConstantGate;
use crate::gates::gmimc::GMiMCGate;
use crate::hash::{GMIMC_CONSTANTS, GMIMC_ROUNDS};
use crate::polynomial::polynomial::PolynomialCoeffs;
use crate::witness::PartialWitness;
mod circuit_builder;
mod circuit_data;
mod vars;
mod field;
mod fri;
mod gadgets;
mod gates;
mod generator;
mod gmimc;
mod hash;
mod plonk_challenger;
mod plonk_common;
mod polynomial;
mod proof;
mod prover;
mod recursive_verifier;
mod rescue;
mod target;
mod util;
mod verifier;
mod wire;
mod witness;
// 112 wire polys, 3 Z polys, 4 parts of quotient poly.
const PROVER_POLYS: usize = 113 + 3 + 4;
fn main() {
// Set the default log filter. This can be overridden using the `RUST_LOG` environment variable,
// e.g. `RUST_LOG=debug`.
// We default to debug for now, since there aren't many logs anyway, but we should probably
// change this to info or warn later.
env_logger::Builder::from_env(Env::default().default_filter_or("debug")).init();
bench_prove::<CrandallField>();
// bench_field_mul::<CrandallField>();
// bench_fft();
println!();
// bench_gmimc::<CrandallField>();
// field_search()
}
fn bench_field_mul<F: Field>() {
let m = F::from_canonical_u64(12345678901234567890);
let mut x = F::ONE;
let start = Instant::now();
let num_muls = 2000000000;
for _ in 0..num_muls {
x *= m;
}
let duration = start.elapsed();
println!("result {:?}", x);
println!("took {:?}", duration);
println!("avg {:?}ns", duration.as_secs_f64() * 1e9 / (num_muls as f64));
}
fn bench_prove<F: Field>() {
let gmimc_gate = GMiMCGate::<F, GMIMC_ROUNDS>::with_automatic_constants();
let config = CircuitConfig {
num_wires: 120,
num_routed_wires: 12,
security_bits: 128,
rate_bits: 3,
num_checks: 3,
};
let mut builder = CircuitBuilder::<F>::new(config);
for _ in 0..5000 {
builder.add_gate_no_constants(gmimc_gate.clone());
}
builder.add_gate(ConstantGate::get(), vec![F::NEG_ONE]);
// for _ in 0..(40 * 5) {
// builder.add_gate(
// FriConsistencyGate::new(2, 3, 13),
// vec![F::primitive_root_of_unity(13)]);
// }
let prover = builder.build_prover();
let inputs = PartialWitness::new();
prover.prove(inputs);
}
fn bench_gmimc<F: Field>() {
const THREADS: usize = 12;
const LDE_BITS: i32 = 3;
const W: usize = 13;
let hashes_per_poly = 1 << (13 + LDE_BITS);
let threads = (0..THREADS).map(|_i| {
thread::spawn(move || {
let mut x = [F::ZERO; W];
for i in 0..W {
x[i] = F::from_canonical_u64((i as u64) * 123456 + 789);
}
let hashes_per_thread = hashes_per_poly * PROVER_POLYS / THREADS;
let start = Instant::now();
for _ in 0..hashes_per_thread {
x = gmimc::gmimc_permute_array::<_, W, GMIMC_ROUNDS>(x, GMIMC_CONSTANTS);
}
let duration = start.elapsed();
println!("took {:?}", duration);
println!("avg {:?}us", duration.as_secs_f64() * 1e6 / (hashes_per_thread as f64));
println!("result {:?}", x);
})
}).collect::<Vec<_>>();
for t in threads {
t.join().expect("oops");
}
}
fn bench_fft() {
let degree = 1 << 13;
let lde_bits = 3;
let lde_size = degree << lde_bits;
println!("{} << {} = {}", degree, lde_bits, lde_size);
let start = Instant::now();
(0usize..PROVER_POLYS).into_par_iter().for_each(|i| {
let mut coeffs = vec![CrandallField::ZERO; lde_size];
for j in 0usize..lde_size {
coeffs[j] = CrandallField((i * j) as u64);
}
let start = Instant::now();
let result = fft::fft(PolynomialCoeffs { coeffs });
let duration = start.elapsed();
println!("FFT took {:?}", duration);
println!("FFT result: {:?}", result.values[0]);
});
println!("FFT overall took {:?}", start.elapsed());
}

View File

@ -1,2 +1,2 @@
pub(crate) mod division;
pub(crate) mod polynomial;
pub mod polynomial;

View File

@ -7,12 +7,12 @@ use crate::util::log2_strict;
/// The points are implicitly `g^i`, where `g` generates the subgroup whose size equals the number
/// of points.
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) struct PolynomialValues<F: Field> {
pub(crate) values: Vec<F>,
pub struct PolynomialValues<F: Field> {
pub values: Vec<F>,
}
impl<F: Field> PolynomialValues<F> {
pub(crate) fn new(values: Vec<F>) -> Self {
pub fn new(values: Vec<F>) -> Self {
assert!(values.len().is_power_of_two());
PolynomialValues { values }
}
@ -35,7 +35,7 @@ impl<F: Field> PolynomialValues<F> {
.collect()
}
pub(crate) fn lde(self, rate_bits: usize) -> Self {
pub fn lde(self, rate_bits: usize) -> Self {
let mut coeffs = ifft(self).lde(rate_bits);
fft(coeffs)
}
@ -43,12 +43,12 @@ impl<F: Field> PolynomialValues<F> {
/// A polynomial in coefficient form. The number of coefficients must be a power of two.
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) struct PolynomialCoeffs<F: Field> {
pub struct PolynomialCoeffs<F: Field> {
pub(crate) coeffs: Vec<F>,
}
impl<F: Field> PolynomialCoeffs<F> {
pub(crate) fn new(coeffs: Vec<F>) -> Self {
pub fn new(coeffs: Vec<F>) -> Self {
assert!(coeffs.len().is_power_of_two());
PolynomialCoeffs { coeffs }
}