Skip to content
This repository has been archived by the owner on Nov 4, 2024. It is now read-only.

Commit

Permalink
Compile to Halo2 middleware (#263)
Browse files Browse the repository at this point in the history
Switching to a more recent Halo2 version revealed a problem with our
lookups - they don't pass a `lookup-any-sanity-checks` because they are
using only the fixed query. This is why I had to disable the default
features of all halo2 crates (that include `lookup-any-sanity-checks`)
and only enable the rest. I suppose we can refactor our lookups to use
`lookup` instead of `lookup_any`.
alxkzmn authored Jul 8, 2024
1 parent 3d35bd5 commit 32c362e
Showing 16 changed files with 733 additions and 920 deletions.
17 changes: 8 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -8,23 +8,22 @@ authors = ["Leo Lara <leo@leolara.me>"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[patch.crates-io]
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v0.3.0" }
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", default-features = false, rev = "da4983e" }

[patch."https://github.com/scroll-tech/halo2.git"]
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v0.3.0" }

halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", default-features = false, rev = "da4983e" }

[dependencies]
pyo3 = { version = "0.19.1", features = ["extension-module"] }
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", features = [
"circuit-params",
"derive_serde",
], tag = "v0.3.0" }

polyexen = { git = "https://github.com/Dhole/polyexen.git", rev = "16a85c5411f804dc49bbf373d24ff9eedadedfbe" }
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", default-features = false, features = [ "circuit-params", "derive_serde"], rev = "da4983e"}

halo2_middleware = { git = "https://github.com/privacy-scaling-explorations/halo2.git", rev = "da4983e" }
halo2_backend = { git = "https://github.com/privacy-scaling-explorations/halo2.git", features = ["derive_serde"], rev = "da4983e" }

num-bigint = { version = "0.4", features = ["rand"] }
uuid = { version = "1.4.0", features = ["v1", "rng"] }
serde = { version = "1.0", features = ["derive"] }
serde = { version = "=1.0.203", features = ["derive"] }
serde_json = "1.0"
hyperplonk_benchmark = { git = "https://github.com/qwang98/plonkish.git", branch = "main", package = "benchmark" }
plonkish_backend = { git = "https://github.com/qwang98/plonkish.git", branch = "main", package = "plonkish_backend" }
35 changes: 22 additions & 13 deletions examples/blake2f.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,10 @@ use chiquito::{
CircuitContext, StepTypeSetupContext, StepTypeWGHandler,
},
plonkish::{
backend::halo2::{chiquitoSuperCircuit2Halo2, ChiquitoHalo2SuperCircuit},
backend::halo2::{
chiquitoSuperCircuit2Halo2, halo2_verify, ChiquitoHalo2SuperCircuit, DummyRng,
Halo2Prover, PlonkishHalo2,
},
compiler::{
cell_manager::{MaxWidthCellManager, SingleRowCellManager},
config,
@@ -18,10 +21,8 @@ use chiquito::{
poly::ToExpr,
sbpir::query::Queriable,
};
use halo2_proofs::{
dev::MockProver,
halo2curves::{bn256::Fr, group::ff::PrimeField},
};
use halo2_proofs::halo2curves::{bn256::Fr, group::ff::PrimeField};
use rand_chacha::rand_core::block::BlockRng;
use std::{fmt::Write, hash::Hash};

pub const IV_LEN: usize = 8;
@@ -1480,17 +1481,25 @@ fn main() {
f: true, // 8bits
};

let circuit =
ChiquitoHalo2SuperCircuit::new(compiled, super_circuit.get_mapping().generate(values));
let witness = super_circuit.get_mapping().generate(values);
let mut circuit = ChiquitoHalo2SuperCircuit::new(compiled);

let rng = BlockRng::new(DummyRng {});

let prover = MockProver::run(9, &circuit, Vec::new()).unwrap();
let result = prover.verify();
let halo2_prover = circuit.create_halo2_prover(9, rng);

let (proof, instance) = halo2_prover.generate_proof(witness);

let result = halo2_verify(
proof,
&halo2_prover.setup.params,
&halo2_prover.setup.vk,
instance,
);

println!("result = {:#?}", result);

if let Err(failures) = &result {
for failure in failures.iter() {
println!("{}", failure);
}
if let Err(failure) = &result {
println!("{}", failure);
}
}
72 changes: 34 additions & 38 deletions examples/factorial.rs
Original file line number Diff line number Diff line change
@@ -5,14 +5,14 @@ use chiquito::{
frontend::dsl::{circuit, trace::DSLTraceGenerator}, /* main function for constructing an AST
* circuit */
plonkish::{
backend::halo2::{chiquito2Halo2, ChiquitoHalo2Circuit},
backend::halo2::{halo2_verify, DummyRng, Halo2Prover, PlonkishHalo2},
compiler::{
cell_manager::SingleRowCellManager, // input for constructing the compiler
compile, // input for constructing the compiler
config,
step_selector::SimpleStepSelectorBuilder,
PlonkishCompilationResult,
},
ir::{assignments::AssignmentGenerator, Circuit},
}, /* compiles to
* Chiquito Halo2
* backend,
@@ -22,12 +22,13 @@ use chiquito::{
* circuit */
poly::ToField,
};
use halo2_proofs::{dev::MockProver, halo2curves::bn256::Fr};
use halo2_proofs::halo2curves::bn256::Fr;
use rand_chacha::rand_core::block::BlockRng;

const MAX_FACTORIAL: usize = 10;

type AssignGen<F> = AssignmentGenerator<F, DSLTraceGenerator<F, u32>>;
fn generate<F: Field + From<u64> + Hash>() -> (Circuit<F>, Option<AssignGen<F>>) {
fn generate<F: Field + From<u64> + Hash>() -> PlonkishCompilationResult<F, DSLTraceGenerator<F, u32>>
{
// table for the circuit:
// | step_type | i | x |
// ----------------------------------
@@ -134,50 +135,45 @@ fn generate<F: Field + From<u64> + Hash>() -> (Circuit<F>, Option<AssignGen<F>>)

// standard main function for a Halo2 circuit
fn main() {
let (chiquito, wit_gen) = generate::<Fr>();
let compiled = chiquito2Halo2(chiquito);
let circuit = ChiquitoHalo2Circuit::new(compiled, wit_gen.map(|g| g.generate(0)));
let mut plonkish = generate::<Fr>();
let rng = BlockRng::new(DummyRng {});

let prover = MockProver::<Fr>::run(10, &circuit, circuit.instance()).unwrap();
let halo2_prover = plonkish.create_halo2_prover(10, rng);

let result = prover.verify();
let (proof, instance) =
halo2_prover.generate_proof(plonkish.assignment_generator.unwrap().generate(0));

let result = halo2_verify(
proof,
&halo2_prover.setup.params,
&halo2_prover.setup.vk,
instance,
);

println!("result = {:#?}", result);

if let Err(failures) = &result {
for failure in failures.iter() {
println!("{}", failure);
}
if let Err(error) = &result {
println!("{}", error);
}

// plaf boilerplate
use chiquito::plonkish::backend::plaf::chiquito2Plaf;
use polyexen::plaf::backends::halo2::PlafH2Circuit;

// get Chiquito ir
let (circuit, wit_gen) = generate::<Fr>();
// get Plaf
let (plaf, plaf_wit_gen) = chiquito2Plaf(circuit, 8, false);
let wit = plaf_wit_gen.generate(wit_gen.map(|v| v.generate(7)));
let mut plonkish = generate::<Fr>();
let rng = BlockRng::new(DummyRng {});

// debug only: print witness
// println!("{}", polyexen::plaf::WitnessDisplayCSV(&wit));
let halo2_prover = plonkish.create_halo2_prover(8, rng);

// get Plaf halo2 circuit from Plaf's halo2 backend
// this is just a proof of concept, because Plaf only has backend for halo2
// this is unnecessary because Chiquito has a halo2 backend already
let plaf_circuit = PlafH2Circuit { plaf, wit };
let (proof, instance) =
halo2_prover.generate_proof(plonkish.assignment_generator.unwrap().generate(7));

// same as halo2 boilerplate above
let prover_plaf = MockProver::<Fr>::run(8, &plaf_circuit, Vec::new()).unwrap();
let result = halo2_verify(
proof,
&halo2_prover.setup.params,
&halo2_prover.setup.vk,
instance,
);

let result_plaf = prover_plaf.verify();

println!("result = {:#?}", result_plaf);
println!("result = {:#?}", result);

if let Err(failures) = &result_plaf {
for failure in failures.iter() {
println!("{}", failure);
}
if let Err(error) = &result {
println!("{}", error);
}
}
66 changes: 20 additions & 46 deletions examples/fibo_with_padding.rs
Original file line number Diff line number Diff line change
@@ -5,14 +5,14 @@ use chiquito::{
frontend::dsl::{circuit, trace::DSLTraceGenerator}, /* main function for constructing an AST
* circuit */
plonkish::{
backend::halo2::{chiquito2Halo2, ChiquitoHalo2Circuit},
backend::halo2::{halo2_verify, DummyRng, Halo2Prover, PlonkishHalo2},
compiler::{
cell_manager::SingleRowCellManager, // input for constructing the compiler
compile, // input for constructing the compiler
config,
step_selector::SimpleStepSelectorBuilder,
PlonkishCompilationResult,
},
ir::{assignments::AssignmentGenerator, Circuit},
}, /* compiles to
* Chiquito Halo2
* backend,
@@ -22,15 +22,15 @@ use chiquito::{
* circuit */
poly::ToField,
};
use halo2_proofs::{dev::MockProver, halo2curves::bn256::Fr};
use halo2_proofs::halo2curves::bn256::Fr;
use rand_chacha::rand_core::block::BlockRng;

// This example file extends the rust example file 'fibonacci.rs',
// describing usage of multiple steptypes, padding, and exposing signals.

type AssignGen<F> = AssignmentGenerator<F, DSLTraceGenerator<F, u32>>;

// the main circuit function
fn fibo_circuit<F: Field + From<u64> + Hash>() -> (Circuit<F>, Option<AssignGen<F>>)
fn fibo_circuit<F: Field + From<u64> + Hash>(
) -> PlonkishCompilationResult<F, DSLTraceGenerator<F, u32>>
// u32 is for external input that indicates the number of fibnoacci iterations
{
use chiquito::{
@@ -205,50 +205,24 @@ fn fibo_circuit<F: Field + From<u64> + Hash>() -> (Circuit<F>, Option<AssignGen<

// standard main function for a Halo2 circuit
fn main() {
let (chiquito, wit_gen) = fibo_circuit::<Fr>();
let compiled = chiquito2Halo2(chiquito);
let circuit = ChiquitoHalo2Circuit::new(compiled, wit_gen.map(|g| g.generate(7)));

let prover = MockProver::<Fr>::run(7, &circuit, circuit.instance()).unwrap();

let result = prover.verify();
let mut plonkish = fibo_circuit::<Fr>();
let rng = BlockRng::new(DummyRng {});

println!("{:#?}", result);

if let Err(failures) = &result {
for failure in failures.iter() {
println!("{}", failure);
}
}
let halo2_prover = plonkish.create_halo2_prover(7, rng);

// plaf boilerplate
use chiquito::plonkish::backend::plaf::chiquito2Plaf;
use polyexen::plaf::{backends::halo2::PlafH2Circuit, WitnessDisplayCSV};
let (proof, instance) =
halo2_prover.generate_proof(plonkish.assignment_generator.unwrap().generate(7));

// get Chiquito ir
let (circuit, wit_gen) = fibo_circuit::<Fr>();
// get Plaf
let (plaf, plaf_wit_gen) = chiquito2Plaf(circuit, 8, false);
let wit = plaf_wit_gen.generate(wit_gen.map(|v| v.generate(7)));
let result = halo2_verify(
proof,
&halo2_prover.setup.params,
&halo2_prover.setup.vk,
instance,
);

// debug only: print witness
println!("{}", WitnessDisplayCSV(&wit));

// get Plaf halo2 circuit from Plaf's halo2 backend
// this is just a proof of concept, because Plaf only has backend for halo2
// this is unnecessary because Chiquito has a halo2 backend already
let plaf_circuit = PlafH2Circuit { plaf, wit };

// same as halo2 boilerplate above
let prover_plaf = MockProver::<Fr>::run(8, &plaf_circuit, plaf_circuit.instance()).unwrap();

let result_plaf = prover_plaf.verify();

println!("result = {:#?}", result_plaf);
println!("{:#?}", result);

if let Err(failures) = &result_plaf {
for failure in failures.iter() {
println!("{}", failure);
}
if let Err(failure) = &result {
println!("{}", failure);
}
}
Loading

0 comments on commit 32c362e

Please sign in to comment.