Skip to content

Commit

Permalink
save
Browse files Browse the repository at this point in the history
  • Loading branch information
shamatar committed Apr 23, 2020
1 parent 579d303 commit c911ec4
Show file tree
Hide file tree
Showing 11 changed files with 331 additions and 20 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ lazy_static = {version = "1", optional = true}
blake2s_const = {version = "0.6", optional = true, path = "./src/plonk/blake2_const/blake2s/"}

rescue_hash = {git = "https://github.com/shamatar/rescue_hash.git", optional = true }
poseidon_hash = {path = "../poseidon_hash", optional = true }

hex = "*"

Expand All @@ -51,7 +52,7 @@ multicore = ["crossbeam", "futures/thread-pool"]
sonic = ["tiny-keccak", "blake2-rfc"]
gm17 = []
nolog = []
plonk = ["blake2s_simd", "lazy_static", "tiny-keccak", "blake2s_const", "rescue_hash"]
plonk = ["blake2s_simd", "lazy_static", "tiny-keccak", "blake2s_const", "rescue_hash", "poseidon_hash"]
marlin = ["blake2s_simd", "tiny-keccak", "blake2s_const"]
wasm = ["web-sys"]
nightly = ["prefetch"]
189 changes: 186 additions & 3 deletions src/plonk/better_better_cs/cs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1616,6 +1616,10 @@ pub fn prove_with_rescue_bn256<P: PlonkConstraintSystemParams<bn256::Bn256>, MG:
circuit.synthesize(&mut assembly)?;
assembly.finalize();

let num_gates = assembly.n();

println!("Performing setup for {} gates", num_gates);

let params = Bn256RescueParams::new_checked_2_into_1();

use crate::plonk::commitments::transcript::{Prng, rescue_transcript};
Expand All @@ -1632,6 +1636,8 @@ pub fn prove_with_rescue_bn256<P: PlonkConstraintSystemParams<bn256::Bn256>, MG:
&worker
)?;

println!("Setup is done");

// cut permutations
for p in permutations.iter_mut() {
p.pop_last().unwrap();
Expand All @@ -1641,6 +1647,10 @@ pub fn prove_with_rescue_bn256<P: PlonkConstraintSystemParams<bn256::Bn256>, MG:
circuit.synthesize(&mut assembly)?;
assembly.finalize();

let num_gates = assembly.n();

let start = std::time::Instant::now();

let (prover, first_state, first_message) = RedshiftProver::first_step(
assembly,
hasher.clone(),
Expand Down Expand Up @@ -1670,7 +1680,7 @@ pub fn prove_with_rescue_bn256<P: PlonkConstraintSystemParams<bn256::Bn256>, MG:
&worker
)?;

println!("First message");
println!("Second message");

prng.commit_input(&second_message.grand_product_oracle_commitment);

Expand All @@ -1689,7 +1699,7 @@ pub fn prove_with_rescue_bn256<P: PlonkConstraintSystemParams<bn256::Bn256>, MG:
&worker
)?;

println!("First message");
println!("Third message");

prng.commit_input(&third_message.quotient_poly_oracle_commitment);

Expand All @@ -1709,7 +1719,7 @@ pub fn prove_with_rescue_bn256<P: PlonkConstraintSystemParams<bn256::Bn256>, MG:
&worker
)?;

println!("First message");
println!("Fourth message");

let mut wire_values_at_z = fourth_message.wire_values_at_z;
wire_values_at_z.sort_by(|a, b| a.0.cmp(&b.0));
Expand Down Expand Up @@ -1751,11 +1761,184 @@ pub fn prove_with_rescue_bn256<P: PlonkConstraintSystemParams<bn256::Bn256>, MG:
&worker
)?;

println!("Fifth message");

println!("Proving {} gates taken {:?}", num_gates, start.elapsed());

Ok(())
}


pub fn prove_with_poseidon_bn256<P: PlonkConstraintSystemParams<bn256::Bn256>, MG: MainGateEquation, C: Circuit<bn256::Bn256>>(
circuit: &C
) -> Result<(), SynthesisError> {
use super::*;
use poseidon_hash::PoseidonEngine;
use poseidon_hash::bn256::Bn256PoseidonParams;

use super::redshift::setup::*;
use super::redshift::prover::*;
use super::redshift::tree_hash::*;

use crate::worker::Worker;

let mut assembly = TrivialAssembly::<bn256::Bn256, P, MG>::new();
circuit.synthesize(&mut assembly)?;
assembly.finalize();

let num_gates = assembly.n();

println!("Performing setup for {} gates", num_gates);

let params = Bn256PoseidonParams::new_checked_2_into_1();

use crate::plonk::commitments::transcript::{Prng, poseidon_transcript};

let mut prng = poseidon_transcript::PoseidonTranscript::<bn256::Bn256>::from_params(&params);

let hasher = PoseidonBinaryTreeHasher::<bn256::Bn256>::new(&params);

let worker = Worker::new();

let (setup_multioracle, mut permutations) = SetupMultioracle::from_assembly(
assembly,
hasher.clone(),
&worker
)?;

println!("Setup is done");

// cut permutations
for p in permutations.iter_mut() {
p.pop_last().unwrap();
}

let mut assembly = TrivialAssembly::<bn256::Bn256, P, MG>::new();
circuit.synthesize(&mut assembly)?;
assembly.finalize();

let num_gates = assembly.n();

let start = std::time::Instant::now();

let (prover, first_state, first_message) = RedshiftProver::first_step(
assembly,
hasher.clone(),
&worker
)?;

println!("First message");

for input in first_message.input_values.iter() {
prng.commit_input(input);
}

prng.commit_input(&first_message.witness_multioracle_commitment);

let beta = prng.get_challenge();
let gamma = prng.get_challenge();

let first_verifier_message = FirstVerifierMessage::<bn256::Bn256> {
beta,
gamma,
};

let (second_state, second_message) = prover.second_step_from_first_step(
first_state,
first_verifier_message,
&permutations,
&worker
)?;

println!("Second message");

prng.commit_input(&second_message.grand_product_oracle_commitment);

let alpha = prng.get_challenge();

let second_verifier_message = SecondVerifierMessage::<bn256::Bn256> {
alpha,
beta,
gamma,
};

let (third_state, third_message) = prover.third_step_from_second_step(
second_state,
second_verifier_message,
&setup_multioracle,
&worker
)?;

println!("Third message");

prng.commit_input(&third_message.quotient_poly_oracle_commitment);

let z = prng.get_challenge();

let third_verifier_message = ThirdVerifierMessage::<bn256::Bn256> {
alpha,
beta,
gamma,
z,
};

let (fourth_state, fourth_message) = prover.fourth_step_from_third_step(
third_state,
third_verifier_message,
&setup_multioracle,
&worker
)?;

println!("Fourth message");

let mut wire_values_at_z = fourth_message.wire_values_at_z;
wire_values_at_z.sort_by(|a, b| a.0.cmp(&b.0));

let wire_values_at_z: Vec<_> = wire_values_at_z.into_iter().map(|el| el.1).collect();

let mut wire_values_at_z_omega = fourth_message.wire_values_at_z_omega;
wire_values_at_z_omega.sort_by(|a, b| a.0.cmp(&b.0));

let wire_values_at_z_omega: Vec<_> = wire_values_at_z_omega.into_iter().map(|el| el.1).collect();

for w in wire_values_at_z.iter()
.chain(&wire_values_at_z_omega)
.chain(&Some(fourth_message.grand_product_at_z))
.chain(&Some(fourth_message.grand_product_at_z_omega))
.chain(&fourth_message.quotient_polynomial_parts_at_z)
.chain(&fourth_message.setup_values_at_z)
.chain(&fourth_message.permutation_polynomials_at_z)
.chain(&fourth_message.gate_selector_polynomials_at_z)
{
prng.commit_input(&w);
}

let v = prng.get_challenge();

let fourth_verifier_message = FourthVerifierMessage::<bn256::Bn256> {
alpha,
beta,
gamma,
z,
v,
};

let fifth_message = prover.fifth_step_from_fourth_step(
fourth_state,
fourth_verifier_message,
&setup_multioracle,
&mut prng,
&worker
)?;

println!("Fifth message");

println!("Proving {} gates taken {:?}", num_gates, start.elapsed());

Ok(())
}


#[cfg(test)]
mod test {
use super::*;
Expand Down
2 changes: 2 additions & 0 deletions src/plonk/better_better_cs/redshift/binary_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ impl<E: Engine, H: BinaryTreeHasher<E::Fr>> BinaryTree<E, H> {
});
}

println!("Leaf hashes comleted");

// leafs are now encoded and hashed, so let's make a tree

let num_levels = log2_floor(num_leafs) as usize;
Expand Down
3 changes: 2 additions & 1 deletion src/plonk/better_better_cs/redshift/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ pub mod binary_tree;
pub mod multioracle;
pub mod setup;
pub mod prover;
pub mod simple_fri;
pub mod simple_fri;
pub mod poseidon_tree_hash;
10 changes: 10 additions & 0 deletions src/plonk/better_better_cs/redshift/multioracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ impl<'a, E: Engine, H: BinaryTreeHasher<E::Fr>> Multioracle<'a, E, H> {
// expect polynomials to be in bitreverse enumeration
let num_polys = polynomials.len();
let values_per_leaf = num_polys * num_values_from_one_poly_into_leaf;
println!("Placing {} values into single leaf", values_per_leaf);
let num_leafs = polynomials[0].size() / num_values_from_one_poly_into_leaf;
println!("{} leafs total", num_leafs);
assert!(num_leafs.is_power_of_two());

let tree_params = BinaryTreeParams {
Expand All @@ -39,6 +41,8 @@ impl<'a, E: Engine, H: BinaryTreeHasher<E::Fr>> Multioracle<'a, E, H> {

let poly_refs_ref = &poly_refs;

println!("Start combining leafs");

worker.scope(leaf_refs_combined.len(), |scope, chunk| {
for (i, lh) in leaf_refs_combined.chunks_mut(chunk)
.enumerate() {
Expand All @@ -60,12 +64,18 @@ impl<'a, E: Engine, H: BinaryTreeHasher<E::Fr>> Multioracle<'a, E, H> {
}
});

println!("Done combining leafs");

println!("Start making a tree");

let tree = BinaryTree::create_from_combined_leafs(
&leaf_refs_combined,
tree_hasher,
&tree_params
);

println!("Done making a tree");

Self {
polynomial_values_refs: poly_refs,
tree
Expand Down
47 changes: 47 additions & 0 deletions src/plonk/better_better_cs/redshift/poseidon_tree_hash.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use crate::pairing::ff::{Field, PrimeField};
use poseidon_hash::{PoseidonEngine, PoseidonHashParams, poseidon_hash};
use super::tree_hash::BinaryTreeHasher;

pub struct PoseidonBinaryTreeHasher<'a, E: PoseidonEngine> {
params: &'a E::Params,
}

impl<'a, E: PoseidonEngine> PoseidonBinaryTreeHasher<'a, E> {
pub fn new(params: &'a E::Params) -> Self {
assert_eq!(params.rate(), 2u32);
assert_eq!(params.output_len(), 1u32);
Self {
params: params
}
}
}

impl<'a, E: PoseidonEngine> Clone for PoseidonBinaryTreeHasher<'a, E> {
fn clone(&self) -> Self {
Self {
params: self.params
}
}
}


impl<'a, E: PoseidonEngine> BinaryTreeHasher<E::Fr> for PoseidonBinaryTreeHasher<'a, E> {
type Output = E::Fr;

#[inline]
fn placeholder_output() -> Self::Output {
E::Fr::zero()
}

fn leaf_hash(&self, input: &[E::Fr]) -> Self::Output {
let mut as_vec = poseidon_hash::<E>(self.params, input);

as_vec.pop().unwrap()
}

fn node_hash(&self, input: &[Self::Output; 2], _level: usize) -> Self::Output {
let mut as_vec = poseidon_hash::<E>(self.params, &input[..]);

as_vec.pop().unwrap()
}
}
Loading

0 comments on commit c911ec4

Please sign in to comment.