Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: soundness error in FpChip::assert_eq due to typo #18

Merged
merged 3 commits into from
Apr 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions halo2-base/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.gi
plotters = { version = "0.3.0", optional = true }
tabbycat = { version = "0.1", features = ["attributes"], optional = true }

# test-utils
rand = { version = "0.8", optional = true }

[dev-dependencies]
ark-std = { version = "0.3.0", features = ["print-trace"] }
rand = "0.8"
Expand All @@ -44,6 +47,7 @@ halo2-pse = ["halo2_proofs"]
halo2-axiom = ["halo2_proofs_axiom"]
display = []
profile = ["halo2_proofs_axiom?/profile"]
test-utils = ["dep:rand"]

[[bench]]
name = "mul"
Expand Down
2 changes: 1 addition & 1 deletion halo2-base/src/gates/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pub mod builder;
pub mod flex_gate;
pub mod range;

#[cfg(test)]
#[cfg(any(test, feature = "test-utils"))]
pub mod tests;

pub use flex_gate::{GateChip, GateInstructions};
Expand Down
170 changes: 170 additions & 0 deletions halo2-base/src/gates/tests/general.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
use super::*;
use crate::gates::{
builder::{GateCircuitBuilder, GateThreadBuilder, RangeCircuitBuilder},
flex_gate::{GateChip, GateInstructions},
range::{RangeChip, RangeInstructions},
};
use crate::halo2_proofs::dev::MockProver;
use crate::utils::{BigPrimeField, ScalarField};
use crate::{Context, QuantumCell::Constant};
use ff::Field;
use rayon::prelude::*;

fn gate_tests<F: ScalarField>(ctx: &mut Context<F>, inputs: [F; 3]) {
let [a, b, c]: [_; 3] = ctx.assign_witnesses(inputs).try_into().unwrap();
let chip = GateChip::default();

// test add
chip.add(ctx, a, b);

// test sub
chip.sub(ctx, a, b);

// test multiply
chip.mul(ctx, c, b);

// test idx_to_indicator
chip.idx_to_indicator(ctx, Constant(F::from(3u64)), 4);

let bits = ctx.assign_witnesses([F::zero(), F::one()]);
chip.bits_to_indicator(ctx, &bits);

chip.is_equal(ctx, b, a);

chip.is_zero(ctx, a);
}

#[test]
fn test_gates() {
let k = 6;
let inputs = [10u64, 12u64, 120u64].map(Fr::from);
let mut builder = GateThreadBuilder::mock();
gate_tests(builder.main(0), inputs);

// auto-tune circuit
builder.config(k, Some(9));
// create circuit
let circuit = GateCircuitBuilder::mock(builder);

MockProver::run(k as u32, &circuit, vec![]).unwrap().assert_satisfied();
}

#[test]
fn test_multithread_gates() {
let k = 6;
let inputs = [10u64, 12u64, 120u64].map(Fr::from);
let mut builder = GateThreadBuilder::mock();
gate_tests(builder.main(0), inputs);

let thread_ids = (0..4usize).map(|_| builder.get_new_thread_id()).collect::<Vec<_>>();
let new_threads = thread_ids
.into_par_iter()
.map(|id| {
let mut ctx = Context::new(builder.witness_gen_only(), id);
gate_tests(&mut ctx, [(); 3].map(|_| Fr::random(OsRng)));
ctx
})
.collect::<Vec<_>>();
builder.threads[0].extend(new_threads);

// auto-tune circuit
builder.config(k, Some(9));
// create circuit
let circuit = GateCircuitBuilder::mock(builder);

MockProver::run(k as u32, &circuit, vec![]).unwrap().assert_satisfied();
}

#[cfg(feature = "dev-graph")]
#[test]
fn plot_gates() {
let k = 5;
use plotters::prelude::*;

let root = BitMapBackend::new("layout.png", (1024, 1024)).into_drawing_area();
root.fill(&WHITE).unwrap();
let root = root.titled("Gates Layout", ("sans-serif", 60)).unwrap();

let inputs = [Fr::zero(); 3];
let builder = GateThreadBuilder::new(false);
gate_tests(builder.main(0), inputs);

// auto-tune circuit
builder.config(k, Some(9));
// create circuit
let circuit = GateCircuitBuilder::keygen(builder);
halo2_proofs::dev::CircuitLayout::default().render(k, &circuit, &root).unwrap();
}

fn range_tests<F: BigPrimeField>(
ctx: &mut Context<F>,
lookup_bits: usize,
inputs: [F; 2],
range_bits: usize,
lt_bits: usize,
) {
let [a, b]: [_; 2] = ctx.assign_witnesses(inputs).try_into().unwrap();
let chip = RangeChip::default(lookup_bits);
std::env::set_var("LOOKUP_BITS", lookup_bits.to_string());

chip.range_check(ctx, a, range_bits);

chip.check_less_than(ctx, a, b, lt_bits);

chip.is_less_than(ctx, a, b, lt_bits);

chip.is_less_than(ctx, b, a, lt_bits);

chip.div_mod(ctx, a, 7u64, lt_bits);
}

#[test]
fn test_range_single() {
let k = 11;
let inputs = [100, 101].map(Fr::from);
let mut builder = GateThreadBuilder::mock();
range_tests(builder.main(0), 3, inputs, 8, 8);

// auto-tune circuit
builder.config(k, Some(9));
// create circuit
let circuit = RangeCircuitBuilder::mock(builder);

MockProver::run(k as u32, &circuit, vec![]).unwrap().assert_satisfied();
}

#[test]
fn test_range_multicolumn() {
let k = 5;
let inputs = [100, 101].map(Fr::from);
let mut builder = GateThreadBuilder::mock();
range_tests(builder.main(0), 3, inputs, 8, 8);

// auto-tune circuit
builder.config(k, Some(9));
// create circuit
let circuit = RangeCircuitBuilder::mock(builder);

MockProver::run(k as u32, &circuit, vec![]).unwrap().assert_satisfied();
}

#[cfg(feature = "dev-graph")]
#[test]
fn plot_range() {
use plotters::prelude::*;

let root = BitMapBackend::new("layout.png", (1024, 1024)).into_drawing_area();
root.fill(&WHITE).unwrap();
let root = root.titled("Range Layout", ("sans-serif", 60)).unwrap();

let k = 11;
let inputs = [0, 0].map(Fr::from);
let mut builder = GateThreadBuilder::new(false);
range_tests(builder.main(0), 3, inputs, 8, 8);

// auto-tune circuit
builder.config(k, Some(9));
// create circuit
let circuit = RangeCircuitBuilder::keygen(builder);
halo2_proofs::dev::CircuitLayout::default().render(7, &circuit, &root).unwrap();
}
15 changes: 11 additions & 4 deletions halo2-base/src/gates/tests/idx_to_indicator.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
use crate::halo2_proofs::{
plonk::keygen_pk,
plonk::{keygen_vk, Assigned},
poly::kzg::commitment::ParamsKZG,
use crate::{
gates::{
builder::{GateCircuitBuilder, GateThreadBuilder},
GateChip, GateInstructions,
},
halo2_proofs::{
plonk::keygen_pk,
plonk::{keygen_vk, Assigned},
poly::kzg::commitment::ParamsKZG,
},
};

use ff::Field;
use itertools::Itertools;
use rand::{thread_rng, Rng};

Expand Down
Loading