Skip to content

Commit 3b4f2cb

Browse files
authored
Merge pull request #823 from QED-it/improve-backward-compatability-without-zsa
Add a LookupRangeCheck trait and minor modifications in preparation for ZSA
2 parents fed6b00 + 34fad99 commit 3b4f2cb

33 files changed

+27246
-792
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ jobs:
9797

9898
steps:
9999
- uses: actions/checkout@v3
100+
- run: sudo apt-get -y install libfontconfig1-dev
100101
# Check bitrot with stable (as we don't need benchmarks or the test-dev-graph
101102
# feature flag to work with MSRV).
102103
- uses: ./.github/actions/prepare
@@ -147,9 +148,10 @@ jobs:
147148
uses: actions-rs/cargo@v1
148149
with:
149150
command: tarpaulin
151+
# Extend the timeout to 3600 to ensure the code coverage test pass
150152
args: >
151153
${{ steps.prepare.outputs.feature-flags }}
152-
--timeout 600
154+
--timeout 3600
153155
--out Xml
154156
- name: Upload coverage to Codecov
155157
uses: codecov/[email protected]

halo2_gadgets/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ and this project adheres to Rust's notion of
66
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## [Unreleased]
9+
### Added
10+
- `halo2_gadgets::utilities::lookup_range_check::LookupRangeCheck`
11+
- `halo2_gadgets::utilities::lookup_range_check::PallasLookupRangeCheck` which is
12+
a shorthand for `LookupRangeCheck` specialized with `pallas::Base` and `sinsemilla::K`
13+
- `halo2_gadgets::utilities::lookup_range_check::PallasLookupRangeCheckConfig` which is
14+
a shorthand for `LookupRangeCheckConfig` specialized with `pallas::Base` and `sinsemilla::K`
15+
16+
### Changed
17+
- `halo2_gadgets::utilities::lookup_range_check::witness_short` now takes a generic `Lookup`
18+
instead of directly taking a `LookupRangeCheckConfig<F, K>` reference
919

1020
## [0.3.1] - 2024-12-16
1121
- `halo2_gadgets::poseidon::primitives` is now a re-export of the new `halo2_poseidon`

halo2_gadgets/src/ecc.rs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,7 @@ impl<C: CurveAffine, EccChip: EccInstructions<C>> FixedPointShort<C, EccChip> {
579579
pub(crate) mod tests {
580580
use ff::PrimeField;
581581
use group::{prime::PrimeCurveAffine, Curve, Group};
582+
use std::marker::PhantomData;
582583

583584
use halo2_proofs::{
584585
circuit::{Layouter, SimpleFloorPlanner, Value},
@@ -595,7 +596,10 @@ pub(crate) mod tests {
595596
},
596597
FixedPoints,
597598
};
598-
use crate::utilities::lookup_range_check::LookupRangeCheckConfig;
599+
use crate::{
600+
test_circuits::test_utils::test_against_stored_circuit,
601+
utilities::lookup_range_check::{PallasLookupRangeCheck, PallasLookupRangeCheckConfig},
602+
};
599603

600604
#[derive(Debug, Eq, PartialEq, Clone)]
601605
pub(crate) struct TestFixedBases;
@@ -723,17 +727,27 @@ pub(crate) mod tests {
723727
type Base = BaseField;
724728
}
725729

726-
struct MyCircuit {
730+
struct MyCircuit<Lookup: PallasLookupRangeCheck> {
727731
test_errors: bool,
732+
_lookup_marker: PhantomData<Lookup>,
733+
}
734+
735+
impl<Lookup: PallasLookupRangeCheck> MyCircuit<Lookup> {
736+
fn new(test_errors: bool) -> Self {
737+
Self {
738+
test_errors,
739+
_lookup_marker: PhantomData,
740+
}
741+
}
728742
}
729743

730744
#[allow(non_snake_case)]
731-
impl Circuit<pallas::Base> for MyCircuit {
732-
type Config = EccConfig<TestFixedBases>;
745+
impl<Lookup: PallasLookupRangeCheck> Circuit<pallas::Base> for MyCircuit<Lookup> {
746+
type Config = EccConfig<TestFixedBases, Lookup>;
733747
type FloorPlanner = SimpleFloorPlanner;
734748

735749
fn without_witnesses(&self) -> Self {
736-
MyCircuit { test_errors: false }
750+
MyCircuit::new(false)
737751
}
738752

739753
fn configure(meta: &mut ConstraintSystem<pallas::Base>) -> Self::Config {
@@ -764,8 +778,13 @@ pub(crate) mod tests {
764778
let constants = meta.fixed_column();
765779
meta.enable_constant(constants);
766780

767-
let range_check = LookupRangeCheckConfig::configure(meta, advices[9], lookup_table);
768-
EccChip::<TestFixedBases>::configure(meta, advices, lagrange_coeffs, range_check)
781+
let range_check = Lookup::configure(meta, advices[9], lookup_table);
782+
EccChip::<TestFixedBases, Lookup>::configure(
783+
meta,
784+
advices,
785+
lagrange_coeffs,
786+
range_check,
787+
)
769788
}
770789

771790
fn synthesize(
@@ -896,11 +915,17 @@ pub(crate) mod tests {
896915
#[test]
897916
fn ecc_chip() {
898917
let k = 13;
899-
let circuit = MyCircuit { test_errors: true };
918+
let circuit = MyCircuit::<PallasLookupRangeCheckConfig>::new(true);
900919
let prover = MockProver::run(k, &circuit, vec![]).unwrap();
901920
assert_eq!(prover.verify(), Ok(()))
902921
}
903922

923+
#[test]
924+
fn test_ecc_chip_against_stored_circuit() {
925+
let circuit = MyCircuit::<PallasLookupRangeCheckConfig>::new(false);
926+
test_against_stored_circuit(circuit, "ecc_chip", 3872);
927+
}
928+
904929
#[cfg(feature = "test-dev-graph")]
905930
#[test]
906931
fn print_ecc_chip() {
@@ -910,7 +935,7 @@ pub(crate) mod tests {
910935
root.fill(&WHITE).unwrap();
911936
let root = root.titled("Ecc Chip Layout", ("sans-serif", 60)).unwrap();
912937

913-
let circuit = MyCircuit { test_errors: false };
938+
let circuit = MyCircuit::<PallasLookupRangeCheckConfig>::new(false);
914939
halo2_proofs::dev::CircuitLayout::default()
915940
.render(13, &circuit, &root)
916941
.unwrap();

halo2_gadgets/src/ecc/chip.rs

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//! Chip implementations for the ECC gadgets.
22
33
use super::{BaseFitsInScalarInstructions, EccInstructions, FixedPoints};
4-
use crate::{
5-
sinsemilla::primitives as sinsemilla,
6-
utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions},
4+
use crate::utilities::{
5+
lookup_range_check::{PallasLookupRangeCheck, PallasLookupRangeCheckConfig},
6+
UtilitiesInstructions,
77
};
88
use arrayvec::ArrayVec;
99

@@ -137,7 +137,10 @@ impl From<NonIdentityEccPoint> for EccPoint {
137137
/// Configuration for [`EccChip`].
138138
#[derive(Clone, Debug, Eq, PartialEq)]
139139
#[allow(non_snake_case)]
140-
pub struct EccConfig<FixedPoints: super::FixedPoints<pallas::Affine>> {
140+
pub struct EccConfig<
141+
FixedPoints: super::FixedPoints<pallas::Affine>,
142+
Lookup: PallasLookupRangeCheck = PallasLookupRangeCheckConfig,
143+
> {
141144
/// Advice columns needed by instructions in the ECC chip.
142145
pub advices: [Column<Advice>; 10],
143146

@@ -148,20 +151,20 @@ pub struct EccConfig<FixedPoints: super::FixedPoints<pallas::Affine>> {
148151
add: add::Config,
149152

150153
/// Variable-base scalar multiplication
151-
mul: mul::Config,
154+
mul: mul::Config<Lookup>,
152155

153156
/// Fixed-base full-width scalar multiplication
154157
mul_fixed_full: mul_fixed::full_width::Config<FixedPoints>,
155158
/// Fixed-base signed short scalar multiplication
156159
mul_fixed_short: mul_fixed::short::Config<FixedPoints>,
157160
/// Fixed-base mul using a base field element as a scalar
158-
mul_fixed_base_field: mul_fixed::base_field_elem::Config<FixedPoints>,
161+
mul_fixed_base_field: mul_fixed::base_field_elem::Config<FixedPoints, Lookup>,
159162

160163
/// Witness point
161164
witness_point: witness_point::Config,
162165

163166
/// Lookup range check using 10-bit lookup table
164-
pub lookup_config: LookupRangeCheckConfig<pallas::Base, { sinsemilla::K }>,
167+
pub lookup_config: Lookup,
165168
}
166169

167170
/// A trait representing the kind of scalar used with a particular `FixedPoint`.
@@ -227,12 +230,17 @@ pub trait FixedPoint<C: CurveAffine>: std::fmt::Debug + Eq + Clone {
227230

228231
/// An [`EccInstructions`] chip that uses 10 advice columns.
229232
#[derive(Clone, Debug, Eq, PartialEq)]
230-
pub struct EccChip<FixedPoints: super::FixedPoints<pallas::Affine>> {
231-
config: EccConfig<FixedPoints>,
233+
pub struct EccChip<
234+
FixedPoints: super::FixedPoints<pallas::Affine>,
235+
Lookup: PallasLookupRangeCheck = PallasLookupRangeCheckConfig,
236+
> {
237+
config: EccConfig<FixedPoints, Lookup>,
232238
}
233239

234-
impl<FixedPoints: super::FixedPoints<pallas::Affine>> Chip<pallas::Base> for EccChip<FixedPoints> {
235-
type Config = EccConfig<FixedPoints>;
240+
impl<FixedPoints: super::FixedPoints<pallas::Affine>, Lookup: PallasLookupRangeCheck>
241+
Chip<pallas::Base> for EccChip<FixedPoints, Lookup>
242+
{
243+
type Config = EccConfig<FixedPoints, Lookup>;
236244
type Loaded = ();
237245

238246
fn config(&self) -> &Self::Config {
@@ -244,13 +252,15 @@ impl<FixedPoints: super::FixedPoints<pallas::Affine>> Chip<pallas::Base> for Ecc
244252
}
245253
}
246254

247-
impl<Fixed: super::FixedPoints<pallas::Affine>> UtilitiesInstructions<pallas::Base>
248-
for EccChip<Fixed>
255+
impl<Fixed: super::FixedPoints<pallas::Affine>, Lookup: PallasLookupRangeCheck>
256+
UtilitiesInstructions<pallas::Base> for EccChip<Fixed, Lookup>
249257
{
250258
type Var = AssignedCell<pallas::Base, pallas::Base>;
251259
}
252260

253-
impl<FixedPoints: super::FixedPoints<pallas::Affine>> EccChip<FixedPoints> {
261+
impl<FixedPoints: super::FixedPoints<pallas::Affine>, Lookup: PallasLookupRangeCheck>
262+
EccChip<FixedPoints, Lookup>
263+
{
254264
/// Reconstructs this chip from the given config.
255265
pub fn construct(config: <Self as Chip<pallas::Base>>::Config) -> Self {
256266
Self { config }
@@ -264,7 +274,7 @@ impl<FixedPoints: super::FixedPoints<pallas::Affine>> EccChip<FixedPoints> {
264274
meta: &mut ConstraintSystem<pallas::Base>,
265275
advices: [Column<Advice>; 10],
266276
lagrange_coeffs: [Column<Fixed>; 8],
267-
range_check: LookupRangeCheckConfig<pallas::Base, { sinsemilla::K }>,
277+
range_check: Lookup,
268278
) -> <Self as Chip<pallas::Base>>::Config {
269279
// Create witness point gate
270280
let witness_point = witness_point::Config::configure(meta, advices[0], advices[1]);
@@ -301,12 +311,13 @@ impl<FixedPoints: super::FixedPoints<pallas::Affine>> EccChip<FixedPoints> {
301311
mul_fixed::short::Config::<FixedPoints>::configure(meta, mul_fixed.clone());
302312

303313
// Create gate that is only used in fixed-base mul using a base field element.
304-
let mul_fixed_base_field = mul_fixed::base_field_elem::Config::<FixedPoints>::configure(
305-
meta,
306-
advices[6..9].try_into().unwrap(),
307-
range_check,
308-
mul_fixed,
309-
);
314+
let mul_fixed_base_field =
315+
mul_fixed::base_field_elem::Config::<FixedPoints, Lookup>::configure(
316+
meta,
317+
advices[6..9].try_into().unwrap(),
318+
range_check,
319+
mul_fixed,
320+
);
310321

311322
EccConfig {
312323
advices,
@@ -407,7 +418,8 @@ pub enum ScalarVar {
407418
FullWidth,
408419
}
409420

410-
impl<Fixed: FixedPoints<pallas::Affine>> EccInstructions<pallas::Affine> for EccChip<Fixed>
421+
impl<Fixed: FixedPoints<pallas::Affine>, Lookup: PallasLookupRangeCheck>
422+
EccInstructions<pallas::Affine> for EccChip<Fixed, Lookup>
411423
where
412424
<Fixed as FixedPoints<pallas::Affine>>::Base:
413425
FixedPoint<pallas::Affine, FixedScalarKind = BaseFieldElem>,
@@ -594,8 +606,8 @@ where
594606
}
595607
}
596608

597-
impl<Fixed: FixedPoints<pallas::Affine>> BaseFitsInScalarInstructions<pallas::Affine>
598-
for EccChip<Fixed>
609+
impl<Fixed: FixedPoints<pallas::Affine>, Lookup: PallasLookupRangeCheck>
610+
BaseFitsInScalarInstructions<pallas::Affine> for EccChip<Fixed, Lookup>
599611
where
600612
<Fixed as FixedPoints<pallas::Affine>>::Base:
601613
FixedPoint<pallas::Affine, FixedScalarKind = BaseFieldElem>,

halo2_gadgets/src/ecc/chip/mul.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::{add, EccPoint, NonIdentityEccPoint, ScalarVar, T_Q};
2-
use crate::{
3-
sinsemilla::primitives as sinsemilla,
4-
utilities::{bool_check, lookup_range_check::LookupRangeCheckConfig, ternary},
2+
use crate::utilities::{
3+
lookup_range_check::{PallasLookupRangeCheck, PallasLookupRangeCheckConfig},
4+
{bool_check, ternary},
55
};
66
use std::{
77
convert::TryInto,
@@ -46,7 +46,7 @@ const INCOMPLETE_LO_LEN: usize = INCOMPLETE_LEN - INCOMPLETE_HI_LEN;
4646
const COMPLETE_RANGE: Range<usize> = INCOMPLETE_LEN..(INCOMPLETE_LEN + NUM_COMPLETE_BITS);
4747

4848
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
49-
pub struct Config {
49+
pub struct Config<Lookup: PallasLookupRangeCheck = PallasLookupRangeCheckConfig> {
5050
// Selector used to check switching logic on LSB
5151
q_mul_lsb: Selector,
5252
// Configuration used in complete addition
@@ -58,14 +58,14 @@ pub struct Config {
5858
// Configuration used for complete addition part of double-and-add algorithm
5959
complete_config: complete::Config,
6060
// Configuration used to check for overflow
61-
overflow_config: overflow::Config,
61+
overflow_config: overflow::Config<Lookup>,
6262
}
6363

64-
impl Config {
64+
impl<Lookup: PallasLookupRangeCheck> Config<Lookup> {
6565
pub(super) fn configure(
6666
meta: &mut ConstraintSystem<pallas::Base>,
6767
add_config: add::Config,
68-
lookup_config: LookupRangeCheckConfig<pallas::Base, { sinsemilla::K }>,
68+
lookup_config: Lookup,
6969
advices: [Column<Advice>; 10],
7070
) -> Self {
7171
let hi_config = incomplete::Config::configure(
@@ -473,13 +473,13 @@ pub mod tests {
473473
tests::TestFixedBases,
474474
EccInstructions, NonIdentityPoint, Point, ScalarVar,
475475
},
476-
utilities::UtilitiesInstructions,
476+
utilities::{lookup_range_check::PallasLookupRangeCheck, UtilitiesInstructions},
477477
};
478478

479-
pub(crate) fn test_mul(
480-
chip: EccChip<TestFixedBases>,
479+
pub(crate) fn test_mul<Lookup: PallasLookupRangeCheck>(
480+
chip: EccChip<TestFixedBases, Lookup>,
481481
mut layouter: impl Layouter<pallas::Base>,
482-
p: &NonIdentityPoint<pallas::Affine, EccChip<TestFixedBases>>,
482+
p: &NonIdentityPoint<pallas::Affine, EccChip<TestFixedBases, Lookup>>,
483483
p_val: pallas::Affine,
484484
) -> Result<(), Error> {
485485
let column = chip.config().advices[0];

halo2_gadgets/src/ecc/chip/mul/overflow.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::{T_Q, Z};
22
use crate::{
3-
sinsemilla::primitives as sinsemilla, utilities::lookup_range_check::LookupRangeCheckConfig,
3+
sinsemilla::primitives as sinsemilla,
4+
utilities::lookup_range_check::{PallasLookupRangeCheck, PallasLookupRangeCheckConfig},
45
};
56

67
use group::ff::PrimeField;
@@ -15,19 +16,19 @@ use pasta_curves::pallas;
1516
use std::iter;
1617

1718
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
18-
pub struct Config {
19+
pub struct Config<Lookup: PallasLookupRangeCheck = PallasLookupRangeCheckConfig> {
1920
// Selector to check z_0 = alpha + t_q (mod p)
2021
q_mul_overflow: Selector,
2122
// 10-bit lookup table
22-
lookup_config: LookupRangeCheckConfig<pallas::Base, { sinsemilla::K }>,
23+
lookup_config: Lookup,
2324
// Advice columns
2425
advices: [Column<Advice>; 3],
2526
}
2627

27-
impl Config {
28+
impl<Lookup: PallasLookupRangeCheck> Config<Lookup> {
2829
pub(super) fn configure(
2930
meta: &mut ConstraintSystem<pallas::Base>,
30-
lookup_config: LookupRangeCheckConfig<pallas::Base, { sinsemilla::K }>,
31+
lookup_config: Lookup,
3132
advices: [Column<Advice>; 3],
3233
) -> Self {
3334
for advice in advices.iter() {

0 commit comments

Comments
 (0)