Skip to content

Commit

Permalink
Working
Browse files Browse the repository at this point in the history
  • Loading branch information
adria0 committed Jun 17, 2024
1 parent f3843ee commit 8d1a0c7
Show file tree
Hide file tree
Showing 28 changed files with 314 additions and 250 deletions.
2 changes: 1 addition & 1 deletion halo2_backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ authors = [
"Privacy Scaling Explorations team",
]
edition = "2021"
rust-version = "1.66.0"
rust-version = "1.70.0"
description = """
Halo2 backend implementation. This package implements the halo2 proof system which includes setup (key generation), proving and verifying.
"""
Expand Down
2 changes: 1 addition & 1 deletion halo2_debug/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ authors = [
"Privacy Scaling Explorations team",
]
edition = "2021"
rust-version = "1.66.0"
rust-version = "1.70.0"
description = """
Halo2 Debug. This package contains utilities for debugging and testing within
the halo2 ecosystem.
Expand Down
5 changes: 1 addition & 4 deletions halo2_frontend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ authors = [
"Privacy Scaling Explorations team",
]
edition = "2021"
rust-version = "1.66.0"
rust-version = "1.70.0"
description = """
Halo2 frontend implementation. This package implements an API to write circuits, handles witness generation and contains the MockProver.
"""
Expand Down Expand Up @@ -38,9 +38,6 @@ halo2_middleware = { path = "../halo2_middleware" }
# Developer tooling dependencies
plotters = { version = "0.3.0", default-features = false, optional = true }
tabbycat = { version = "0.1", features = ["attributes"], optional = true }
once_cell = "1.19.0"
parking_lot = "0.12.3"
paste = "1.0.15"

[dev-dependencies]
proptest = "1"
Expand Down
2 changes: 1 addition & 1 deletion halo2_frontend/src/circuit/table_layouter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ mod tests {
meta.lookup("", |cells| {
let a = cells.query_advice(a, Rotation::cur());

vec![(a.clone(), table.0), (a, table.1)]
vec![(a, table.0), (a, table.1)]
});

Self::Config { table }
Expand Down
15 changes: 6 additions & 9 deletions halo2_frontend/src/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ impl<F: FieldFront> Mul<F> for Value<F> {
/// use halo2_frontend::{
/// circuit::{Layouter, SimpleFloorPlanner, Value},
/// dev::{FailureLocation, MockProver, VerifyFailure},
/// plonk::{circuit::Column, Circuit, ConstraintSystem, Error, Advice, Selector},
/// plonk::{circuit::Column, Circuit, ConstraintSystem, Error, Advice, Selector, FieldFront},
/// };
/// use halo2_middleware::circuit::{Any, ColumnMid};
/// use halo2_middleware::poly::Rotation;
Expand All @@ -206,7 +206,7 @@ impl<F: FieldFront> Mul<F> for Value<F> {
/// b: Value<u64>,
/// }
///
/// impl<F: PrimeField> Circuit<F> for MyCircuit {
/// impl<F: FieldFront + From<u64>> Circuit<F> for MyCircuit {
/// type Config = MyConfig;
/// type FloorPlanner = SimpleFloorPlanner;
/// #[cfg(feature = "circuit-params")]
Expand Down Expand Up @@ -284,7 +284,7 @@ impl<F: FieldFront> Mul<F> for Value<F> {
/// MockProver::<Fp>::run(2, &circuit, vec![]).unwrap_err()
/// });
/// assert_eq!(
/// result.unwrap_err().downcast_rF::<String>().unwrap(),
/// result.unwrap_err().downcast_ref::<String>().unwrap(),
/// "n=4, minimum_rows=8, k=2"
/// );
/// ```
Expand Down Expand Up @@ -1376,13 +1376,10 @@ mod tests {

// If q is enabled, a must be in the table.
// When q is not enabled, lookup the default value instead.
let not_q = Expression::Constant(Fp::one()) - q.clone();
let not_q = Expression::Constant(Fp::one()) - q;
let default = Expression::Constant(Fp::from(2));
vec![
(
q.clone() * a.clone() + not_q.clone() * default.clone(),
table,
),
(q * a + not_q * default, table),
(q * a + not_q * default, advice_table),
]
});
Expand Down Expand Up @@ -1540,7 +1537,7 @@ mod tests {

// If q is enabled, a must be in the table.
// When q is not enabled, lookup the default value instead.
let not_q = Expression::Constant(Fp::one()) - q.clone();
let not_q = Expression::Constant(Fp::one()) - q;
let default = Expression::Constant(Fp::from(2));
vec![(q * a + not_q * default, table)]
});
Expand Down
2 changes: 1 addition & 1 deletion halo2_frontend/src/dev/gates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct Gate {
/// use halo2_frontend::{
/// circuit::{Layouter, SimpleFloorPlanner},
/// dev::CircuitGates,
/// plonk::{Circuit, ConstraintSystem, Error},
/// plonk::{Circuit, ConstraintSystem, Error, FieldFront},
/// };
/// use halo2curves::pasta::pallas;
///
Expand Down
2 changes: 1 addition & 1 deletion halo2_frontend/src/dev/tfp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use crate::{
/// use halo2_frontend::{
/// circuit::{floor_planner, Layouter, Value},
/// dev::TracingFloorPlanner,
/// plonk::{Circuit, ConstraintSystem, Error},
/// plonk::{Circuit, ConstraintSystem, Error, FieldFront},
/// };
///
/// # struct MyCircuit<F: FieldFront> {
Expand Down
3 changes: 3 additions & 0 deletions halo2_frontend/src/plonk/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ use crate::plonk::{Assigned, Error};
use halo2_middleware::circuit::Any;
use halo2_middleware::poly::Rotation;

pub mod arena;
pub mod compress_selectors;
pub mod constraint_system;
pub mod expression;

pub use arena::FieldFront;

pub use constraint_system::*;
pub use expression::*;

Expand Down
73 changes: 73 additions & 0 deletions halo2_frontend/src/plonk/circuit/arena.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use super::ExprRef;
use super::Expression;

use halo2_middleware::ff::Field;

/// A field that allows to store `Expression`s in an arena.
pub trait FieldFront: Field {
// Since base trait is not referenciable, we need a way to access it.
// This is necessary to provide a way to transform fields from/to backend.
type Field: Field;

/// Transform FieldFront to Field
fn into_field(self) -> Self::Field;

/// Transform Field to FieldFront
fn into_fieldfront(f: Self::Field) -> Self;

/// Allocate a new expression to the arena.
fn alloc(expr: Expression<Self>) -> ExprRef<Self>;

/// Get an expression from the arena, panics if the reference is invalid.
fn get(ref_: &ExprRef<Self>) -> Expression<Self>;
}

#[derive(Default)]
struct ExprArena<F: FieldFront>(Vec<Expression<F>>);

impl<F: FieldFront> ExprArena<F> {
fn push(&mut self, expr: Expression<F>) -> crate::plonk::ExprRef<F> {
let index = self.0.len();
self.0.push(expr);
ExprRef(index, std::marker::PhantomData)
}
fn get(&self, ref_: crate::plonk::ExprRef<F>) -> &Expression<F> {
&self.0[ref_.0]
}
}

#[macro_export]
macro_rules! expression_arena {
($arena:ident, $field:ty) => {
fn $arena() -> &'static std::sync::RwLock<ExprArena<$field>> {
static LINES: std::sync::OnceLock<std::sync::RwLock<ExprArena<$field>>> =
std::sync::OnceLock::new();
LINES.get_or_init(|| std::sync::RwLock::new(ExprArena::default()))
}

impl $crate::plonk::FieldFront for $field {
type Field = $field;
fn into_field(self) -> Self::Field {
self
}
fn into_fieldfront(f: Self::Field) -> Self {
f
}
fn alloc(expr: $crate::plonk::Expression<Self>) -> $crate::plonk::ExprRef<Self> {
$arena().write().unwrap().push(expr)
}
fn get(ref_: &$crate::plonk::ExprRef<Self>) -> $crate::plonk::Expression<Self> {
*$arena().read().unwrap().get(*ref_)
}
}
impl From<$field> for $crate::plonk::ExprRef<$field> {
fn from(f: $field) -> Self {
$crate::plonk::FieldFront::alloc($crate::plonk::Expression::Constant(f))
}
}
};
}

// Field scalar arenas
expression_arena!(arena_bn256_fr, halo2curves::bn256::Fr);
expression_arena!(arena_pasta_fp, halo2curves::pasta::Fp);
4 changes: 2 additions & 2 deletions halo2_frontend/src/plonk/circuit/compress_selectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,11 @@ where
// which is non-zero only on rows where `combination_assignment` is set to
// `assigned_root`. In particular, rows set to 0 correspond to all selectors
// being disabled.
let mut expression = query.clone();
let mut expression = query;
let mut root = F::ONE;
for _ in 0..combination_len {
if root != assigned_root {
expression = expression * (Expression::Constant(root) - query.clone());
expression = expression * (Expression::Constant(root) - query);
}
root += F::ONE;
}
Expand Down
2 changes: 1 addition & 1 deletion halo2_frontend/src/plonk/circuit/constraint_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ impl<F: FieldFront> ConstraintSystem<F> {
assert!(!selector.is_simple());
}

selector_replacements[selector.0].clone()
selector_replacements[selector.0]
},
&|query| Expression::Fixed(query),
&|query| Expression::Advice(query),
Expand Down
121 changes: 19 additions & 102 deletions halo2_frontend/src/plonk/circuit/expression.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::arena::FieldFront;
use crate::circuit::Region;
use crate::plonk::circuit::{Advice, ColumnType, Fixed, Instance, VirtualCells};
use crate::plonk::Error;
Expand Down Expand Up @@ -253,7 +254,7 @@ impl SealedPhase for ThirdPhase {
/// row when required:
/// ```
/// use halo2_frontend::circuit::{Chip, Layouter, Value};
/// use halo2_frontend::plonk::{Advice, Fixed, Error, Column, Selector};
/// use halo2_frontend::plonk::{Advice, Fixed, Error, Column, Selector, FieldFront};
/// use halo2_middleware::ff::Field;
///
/// struct Config {
Expand Down Expand Up @@ -470,47 +471,16 @@ pub enum Expression<F: FieldFront> {
Ref(ExprRef<F>),
}

// Arena context
pub trait FieldFront: Field {
type Field: Field;
fn alloc(expr: Expression<Self>) -> ExprRef<Self>;
fn get(ref_: &ExprRef<Self>) -> Expression<Self>;
fn into_field(self) -> Self::Field;
fn into_field_fr(f: Self::Field) -> Self;
}

#[derive(Clone, Copy, Eq, PartialEq)]
pub struct ExprRef<F>(usize, std::marker::PhantomData<F>);
impl<F: FieldFront> Into<ExprRef<F>> for Expression<F> {
fn into(self) -> ExprRef<F> {
F::alloc(self)
}
}

#[allow(unused)]
struct ArenaPool<F: FieldFront> {
expressions: Vec<Expression<F>>,
}

#[allow(unused)]
impl<F: FieldFront> ArenaPool<F> {
fn new() -> Self {
Self {
expressions: Vec::new(),
}
}
fn push(&mut self, expr: Expression<F>) -> ExprRef<F> {
let index = self.expressions.len();
self.expressions.push(expr);
ExprRef(index, std::marker::PhantomData)
}
fn get(&self, ref_: ExprRef<F>) -> &Expression<F> {
&self.expressions[ref_.0]
pub struct ExprRef<F>(pub(crate) usize, pub(crate) std::marker::PhantomData<F>);
impl<F: FieldFront> From<Expression<F>> for ExprRef<F> {
fn from(val: Expression<F>) -> Self {
F::alloc(val)
}
}

impl<F: FieldFront<Field = IF>, IF: Field> From<Expression<F>> for ExpressionMid<IF> {
fn from(val: Expression<F>) -> Self {
impl<FF: FieldFront<Field = F>, F: Field> From<Expression<FF>> for ExpressionMid<F> {
fn from(val: Expression<FF>) -> Self {
match val {
Expression::Constant(c) => ExpressionMid::Constant(c.into_field()),
Expression::Selector(_) => unreachable!(),
Expand Down Expand Up @@ -542,18 +512,20 @@ impl<F: FieldFront<Field = IF>, IF: Field> From<Expression<F>> for ExpressionMid
rotation,
})),
Expression::Challenge(c) => ExpressionMid::Var(VarMid::Challenge(c.into())),
Expression::Negated(e) => ExpressionMid::Negated(Box::new((F::get(&e)).into())),
Expression::Sum(lhs, rhs) => {
ExpressionMid::Sum(Box::new(F::get(&lhs).into()), Box::new(F::get(&rhs).into()))
}
Expression::Product(lhs, rhs) => {
ExpressionMid::Product(Box::new(F::get(&lhs).into()), Box::new(F::get(&rhs).into()))
}
Expression::Negated(e) => ExpressionMid::Negated(Box::new((FF::get(&e)).into())),
Expression::Sum(lhs, rhs) => ExpressionMid::Sum(
Box::new(FF::get(&lhs).into()),
Box::new(FF::get(&rhs).into()),
),
Expression::Product(lhs, rhs) => ExpressionMid::Product(
Box::new(FF::get(&lhs).into()),
Box::new(FF::get(&rhs).into()),
),
Expression::Scaled(e, c) => ExpressionMid::Product(
Box::new(F::get(&e).into()),
Box::new(FF::get(&e).into()),
Box::new(ExpressionMid::Constant(c.into_field())),
),
Expression::Ref(ref_) => F::get(&ref_).into(),
Expression::Ref(ref_) => FF::get(&ref_).into(),
}
}
}
Expand Down Expand Up @@ -1182,61 +1154,6 @@ impl<F: FieldFront> Product<Self> for Expression<F> {
}
}

#[allow(non_camel_case_types)]
pub struct ExprArena<F: FieldFront>(Vec<Expression<F>>);

impl<F: FieldFront> ExprArena<F> {
pub fn new() -> Self {
Self(Vec::new())
}
pub fn push(&mut self, expr: Expression<F>) -> crate::plonk::ExprRef<F> {
let index = self.0.len();
self.0.push(expr);
ExprRef(index, std::marker::PhantomData)
}
pub fn get(&self, ref_: crate::plonk::ExprRef<F>) -> &Expression<F> {
&self.0[ref_.0]
}
}

#[macro_export]
macro_rules! expression_arena {
($arena:ident, $field:ty) => {
fn $arena() -> &'static std::sync::RwLock<ExprArena<$field>> {
static LINES: std::sync::OnceLock<std::sync::RwLock<ExprArena<$field>>> =
std::sync::OnceLock::new();
LINES.get_or_init(|| std::sync::RwLock::new(ExprArena::new()))
}

impl crate::plonk::FieldFront for $field {
type Field = $field;
fn into_field(self) -> Self::Field {
self
}
fn into_field_fr(f: Self::Field) -> Self {
f
}
fn alloc(expr: crate::plonk::Expression<Self>) -> crate::plonk::ExprRef<Self> {
$arena().write().unwrap().push(expr)
}
fn get(ref_: &crate::plonk::ExprRef<Self>) -> crate::plonk::Expression<Self> {
*$arena().read().unwrap().get(*ref_)
}
}

impl Into<crate::plonk::ExprRef<$field>> for $field {
fn into(self) -> crate::plonk::ExprRef<$field> {
crate::plonk::FieldFront::alloc(crate::plonk::Expression::Constant(self))
}
}
};
}

//#[cfg(test)]
expression_arena!(arena_bn256_fr, halo2curves::bn256::Fr);
expression_arena!(arena_bn256_fq, halo2curves::bn256::Fq);
expression_arena!(arena_pasta_fp, halo2curves::pasta::Fp);

#[cfg(test)]
mod tests {
use super::*;
Expand Down
2 changes: 1 addition & 1 deletion halo2_middleware/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ authors = [
"Privacy Scaling Explorations team",
]
edition = "2021"
rust-version = "1.66.0"
rust-version = "1.70.0"
description = """
Halo2 middleware. This package contains the types and traits required for the frontend-backend interaction.
"""
Expand Down
Loading

0 comments on commit 8d1a0c7

Please sign in to comment.