forked from privacy-scaling-explorations/halo2
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request privacy-scaling-explorations#34 from input-output-…
…hk/features/endoscalling Endoscaling Integration
- Loading branch information
Showing
26 changed files
with
2,778 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
...s/endoscale-base-pasta_curves::curves::EpAffine-pasta_curves::curves::EqAffine-8-64-8.csv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
max_deg,advice_columns,lookups,permutations,column_queries,point_sets,proof_size | ||
12,9,2,11,52,4,4448 |
2 changes: 2 additions & 0 deletions
2
...s/endoscale-base-pasta_curves::curves::EpAffine-pasta_curves::curves::EqAffine-8-66-9.csv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
max_deg,advice_columns,lookups,permutations,column_queries,point_sets,proof_size | ||
12,9,2,11,52,4,4448 |
2 changes: 2 additions & 0 deletions
2
...s/endoscale-base-pasta_curves::curves::EqAffine-pasta_curves::curves::EpAffine-8-64-8.csv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
max_deg,advice_columns,lookups,permutations,column_queries,point_sets,proof_size | ||
12,9,2,11,52,4,4448 |
2 changes: 2 additions & 0 deletions
2
...s/endoscale-base-pasta_curves::curves::EqAffine-pasta_curves::curves::EpAffine-8-66-9.csv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
max_deg,advice_columns,lookups,permutations,column_queries,point_sets,proof_size | ||
12,9,2,11,52,4,4448 |
2 changes: 2 additions & 0 deletions
2
...endoscale-scalar-pasta_curves::curves::EpAffine-pasta_curves::curves::EqAffine-8-64-8.csv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
max_deg,advice_columns,lookups,permutations,column_queries,point_sets,proof_size | ||
12,9,2,11,52,4,4448 |
2 changes: 2 additions & 0 deletions
2
...endoscale-scalar-pasta_curves::curves::EpAffine-pasta_curves::curves::EqAffine-8-66-9.csv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
max_deg,advice_columns,lookups,permutations,column_queries,point_sets,proof_size | ||
12,9,2,11,52,4,4448 |
2 changes: 2 additions & 0 deletions
2
...endoscale-scalar-pasta_curves::curves::EqAffine-pasta_curves::curves::EpAffine-8-64-8.csv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
max_deg,advice_columns,lookups,permutations,column_queries,point_sets,proof_size | ||
12,9,2,11,52,4,4448 |
2 changes: 2 additions & 0 deletions
2
...endoscale-scalar-pasta_curves::curves::EqAffine-pasta_curves::curves::EpAffine-8-66-9.csv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
max_deg,advice_columns,lookups,permutations,column_queries,point_sets,proof_size | ||
12,9,2,11,52,4,4448 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,317 @@ | ||
mod utilities; | ||
|
||
use halo2_gadgets::ecc::chip::NonIdentityEccPoint; | ||
use halo2_gadgets::endoscale::{ | ||
chip::{CurveEndoscale, EndoscaleConfig}, | ||
util::compute_endoscalar_with_acc, | ||
EndoscaleInstructions, | ||
}; | ||
|
||
use ff::{Field, FromUniformBytes, PrimeFieldBits}; | ||
use halo2_proofs::{ | ||
circuit::{Layouter, SimpleFloorPlanner, Value}, | ||
plonk::{ | ||
Advice, Circuit, Column, ConstraintSystem, Error, | ||
}, | ||
poly::{ | ||
commitment::ParamsProver, | ||
ipa::commitment::ParamsIPA, | ||
}, | ||
}; | ||
use halo2curves::pasta::{pallas, vesta}; | ||
use halo2curves::CurveAffine; | ||
|
||
use std::{any::type_name, convert::TryInto, marker::PhantomData}; | ||
|
||
use criterion::{criterion_group, criterion_main, Criterion}; | ||
|
||
#[derive(Clone)] | ||
struct BaseCircuit< | ||
C: CurveAffine, | ||
const K: usize, | ||
const NUM_BITS: usize, | ||
const NUM_BITS_DIV_K_CEIL: usize, | ||
> where | ||
C::Base: PrimeFieldBits, | ||
{ | ||
bitstring: Value<[bool; NUM_BITS]>, | ||
pub_input_rows: [usize; NUM_BITS_DIV_K_CEIL], | ||
_marker: PhantomData<C>, | ||
} | ||
|
||
impl< | ||
C: CurveAffine + CurveEndoscale, | ||
const K: usize, | ||
const NUM_BITS: usize, | ||
const NUM_BITS_DIV_K_CEIL: usize, | ||
> Circuit<C::Base> for BaseCircuit<C, K, NUM_BITS, NUM_BITS_DIV_K_CEIL> | ||
where | ||
C::Base: PrimeFieldBits, | ||
{ | ||
type Config = (EndoscaleConfig<C, K, 248>, Column<Advice>); | ||
type FloorPlanner = SimpleFloorPlanner; | ||
|
||
fn without_witnesses(&self) -> Self { | ||
Self { | ||
bitstring: Value::unknown(), | ||
pub_input_rows: self.pub_input_rows, | ||
_marker: PhantomData, | ||
} | ||
} | ||
|
||
fn configure(meta: &mut ConstraintSystem<C::Base>) -> Self::Config { | ||
let constants = meta.fixed_column(); | ||
meta.enable_constant(constants); | ||
|
||
let advices = (0..8) | ||
.map(|_| meta.advice_column()) | ||
.collect::<Vec<_>>() | ||
.try_into() | ||
.unwrap(); | ||
let running_sum = meta.advice_column(); | ||
let endoscalars = meta.instance_column(); | ||
|
||
( | ||
EndoscaleConfig::configure(meta, advices, running_sum, endoscalars), | ||
running_sum, | ||
) | ||
} | ||
|
||
fn synthesize( | ||
&self, | ||
config: Self::Config, | ||
mut layouter: impl Layouter<C::Base>, | ||
) -> Result<(), Error> { | ||
config.0.alg_2.table.load(&mut layouter)?; | ||
|
||
let bitstring = | ||
config | ||
.0 | ||
.witness_bitstring(&mut layouter, &self.bitstring.transpose_array(), true)?; | ||
|
||
// Alg 1 (fixed base) | ||
let g_lagrange = ParamsIPA::<C>::new(11).g_lagrange()[0]; | ||
config | ||
.0 | ||
.endoscale_fixed_base(&mut layouter, bitstring.clone(), vec![g_lagrange])?; | ||
|
||
// Alg 1 (variable base) | ||
let g_lagrange = layouter.assign_region( | ||
|| "g_lagrange", | ||
|mut region| { | ||
let x = region.assign_advice( | ||
|| "x", | ||
config.1, | ||
0, | ||
|| Value::known(*g_lagrange.coordinates().unwrap().x()), | ||
)?; | ||
let y = region.assign_advice( | ||
|| "y", | ||
config.1, | ||
1, | ||
|| Value::known(*g_lagrange.coordinates().unwrap().y()), | ||
)?; | ||
|
||
Ok(NonIdentityEccPoint::<C>::from_coordinates_unchecked( | ||
x.into(), | ||
y.into(), | ||
)) | ||
}, | ||
)?; | ||
config | ||
.0 | ||
.endoscale_var_base(&mut layouter, bitstring, vec![g_lagrange])?; | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
#[derive(Clone)] | ||
struct ScalarCircuit< | ||
C: CurveAffine, | ||
const K: usize, | ||
const NUM_BITS: usize, | ||
const NUM_BITS_DIV_K_CEIL: usize, | ||
> where | ||
C::Base: PrimeFieldBits, | ||
{ | ||
bitstring: Value<[bool; NUM_BITS]>, | ||
pub_input_rows: [usize; NUM_BITS_DIV_K_CEIL], | ||
_marker: PhantomData<C>, | ||
} | ||
|
||
impl< | ||
C: CurveAffine + CurveEndoscale, | ||
const K: usize, | ||
const NUM_BITS: usize, | ||
const NUM_BITS_DIV_K_CEIL: usize, | ||
> Circuit<C::Base> for ScalarCircuit<C, K, NUM_BITS, NUM_BITS_DIV_K_CEIL> | ||
where | ||
C::Base: PrimeFieldBits, | ||
{ | ||
type Config = EndoscaleConfig<C, K, 248>; | ||
type FloorPlanner = SimpleFloorPlanner; | ||
|
||
fn without_witnesses(&self) -> Self { | ||
Self { | ||
bitstring: Value::unknown(), | ||
pub_input_rows: self.pub_input_rows, | ||
_marker: PhantomData, | ||
} | ||
} | ||
|
||
fn configure(meta: &mut ConstraintSystem<C::Base>) -> Self::Config { | ||
let constants = meta.fixed_column(); | ||
meta.enable_constant(constants); | ||
|
||
let advices = (0..8) | ||
.map(|_| meta.advice_column()) | ||
.collect::<Vec<_>>() | ||
.try_into() | ||
.unwrap(); | ||
let running_sum = meta.advice_column(); | ||
let endoscalars = meta.instance_column(); | ||
|
||
EndoscaleConfig::configure(meta, advices, running_sum, endoscalars) | ||
} | ||
|
||
fn synthesize( | ||
&self, | ||
config: Self::Config, | ||
mut layouter: impl Layouter<C::Base>, | ||
) -> Result<(), Error> { | ||
config.alg_2.table.load(&mut layouter)?; | ||
|
||
let bitstring = | ||
config.witness_bitstring(&mut layouter, &self.bitstring.transpose_array(), false)?; | ||
|
||
// Alg 2 with lookup | ||
config.compute_endoscalar(&mut layouter, &bitstring[0])?; | ||
|
||
// Constrain bitstring | ||
config.constrain_bitstring(&mut layouter, &bitstring[0], self.pub_input_rows.to_vec())?; | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
fn bench_endoscale_base< | ||
C1, | ||
C2, | ||
const K: usize, | ||
const NUM_BITS: usize, | ||
const NUM_BITS_DIV_K_CEIL: usize, | ||
>( | ||
c: &mut Criterion, | ||
) where | ||
C1::Scalar: FromUniformBytes<64>, | ||
C1::Base: PrimeFieldBits + FromUniformBytes<64>, | ||
C2::Scalar: FromUniformBytes<64>, | ||
C2::Base: PrimeFieldBits + FromUniformBytes<64>, | ||
C1: CurveAffine<Base = C2::Scalar> + CurveEndoscale, | ||
C2: CurveAffine + CurveEndoscale, | ||
{ | ||
let bitstring: [bool; NUM_BITS] = (0..NUM_BITS) | ||
.map(|_| rand::random::<bool>()) | ||
.collect::<Vec<_>>() | ||
.try_into() | ||
.unwrap(); | ||
|
||
// Public input of endoscalars in the base field corresponding to the bits. | ||
let pub_inputs_base: Vec<C2::Scalar> = { | ||
// Pad bitstring to multiple of K. | ||
let bitstring = bitstring | ||
.iter() | ||
.copied() | ||
.chain(std::iter::repeat(false)) | ||
.take(K * NUM_BITS_DIV_K_CEIL) | ||
.collect::<Vec<_>>(); | ||
bitstring | ||
.chunks(K) | ||
.map(|chunk| compute_endoscalar_with_acc(Some(C1::Base::ZERO), chunk)) | ||
.collect() | ||
}; | ||
|
||
let base_circuit = BaseCircuit::<C1, K, NUM_BITS, NUM_BITS_DIV_K_CEIL> { | ||
bitstring: Value::known(bitstring), | ||
pub_input_rows: (0..NUM_BITS_DIV_K_CEIL) | ||
.collect::<Vec<_>>() | ||
.try_into() | ||
.unwrap(), | ||
_marker: PhantomData, | ||
}; | ||
|
||
// There needs to be an extra row, compared to testing, since it needs extra room for binding factors and stuff for ZK. | ||
let name = format!("endoscale-base-{}-{}-{}-{}-{}", type_name::<C1>(), type_name::<C2>(), K, NUM_BITS, NUM_BITS_DIV_K_CEIL); | ||
let k = (K + 1) as u32; | ||
utilities::circuit_to_csv::<C2>(k, &name, &[&pub_inputs_base[..]], base_circuit.clone()); | ||
utilities::bench_circuit::<C2>(c, k, &name, &[&pub_inputs_base[..]], base_circuit); | ||
} | ||
|
||
fn bench_endoscale_scalar< | ||
C1, | ||
C2, | ||
const K: usize, | ||
const NUM_BITS: usize, | ||
const NUM_BITS_DIV_K_CEIL: usize, | ||
>( | ||
c: &mut Criterion, | ||
) where | ||
C1::Scalar: FromUniformBytes<64>, | ||
C1::Base: PrimeFieldBits + FromUniformBytes<64>, | ||
C2::Scalar: FromUniformBytes<64>, | ||
C2::Base: PrimeFieldBits + FromUniformBytes<64>, | ||
C1: CurveAffine + CurveEndoscale, | ||
C2: CurveAffine<Base = C1::Scalar> + CurveEndoscale, | ||
{ | ||
let bitstring: [bool; NUM_BITS] = (0..NUM_BITS) | ||
.map(|_| rand::random::<bool>()) | ||
.collect::<Vec<_>>() | ||
.try_into() | ||
.unwrap(); | ||
|
||
// Public input of endoscalars in the scalar field corresponding to the bits. | ||
let pub_inputs_scalar: Vec<C1::Scalar> = { | ||
// Pad bitstring to multiple of K. | ||
let bitstring = bitstring | ||
.iter() | ||
.copied() | ||
.chain(std::iter::repeat(false)) | ||
.take(K * NUM_BITS_DIV_K_CEIL) | ||
.collect::<Vec<_>>(); | ||
bitstring | ||
.chunks(K) | ||
.map(|chunk| compute_endoscalar_with_acc(Some(C2::Base::ZERO), chunk)) | ||
.collect() | ||
}; | ||
|
||
let scalar_circuit = ScalarCircuit::<C2, K, NUM_BITS, NUM_BITS_DIV_K_CEIL> { | ||
bitstring: Value::known(bitstring), | ||
pub_input_rows: (0..NUM_BITS_DIV_K_CEIL) | ||
.collect::<Vec<_>>() | ||
.try_into() | ||
.unwrap(), | ||
_marker: PhantomData, | ||
}; | ||
|
||
// There needs to be an extra row, compared to testing, since it needs extra room for binding factors and stuff for ZK. | ||
let name = format!("endoscale-scalar-{}-{}-{}-{}-{}", type_name::<C1>(), type_name::<C2>(), K, NUM_BITS, NUM_BITS_DIV_K_CEIL); | ||
let k = (K + 1) as u32; | ||
utilities::circuit_to_csv::<C1>(k, &name, &[&pub_inputs_scalar[..]], scalar_circuit.clone()); | ||
utilities::bench_circuit::<C1>(c, k, &name, &[&pub_inputs_scalar[..]], scalar_circuit); | ||
} | ||
|
||
fn bench_endoscale(c: &mut Criterion) { | ||
bench_endoscale_base::<pallas::Affine, vesta::Affine, 8, 64, 8>(c); | ||
bench_endoscale_scalar::<pallas::Affine, vesta::Affine, 8, 64, 8>(c); | ||
bench_endoscale_base::<vesta::Affine, pallas::Affine, 8, 64, 8>(c); | ||
bench_endoscale_scalar::<vesta::Affine, pallas::Affine, 8, 64, 8>(c); | ||
|
||
bench_endoscale_base::<pallas::Affine, vesta::Affine, 8, 66, 9>(c); | ||
bench_endoscale_scalar::<pallas::Affine, vesta::Affine, 8, 66, 9>(c); | ||
bench_endoscale_base::<vesta::Affine, pallas::Affine, 8, 66, 9>(c); | ||
bench_endoscale_scalar::<vesta::Affine, pallas::Affine, 8, 66, 9>(c); | ||
} | ||
|
||
criterion_group!(benches, bench_endoscale); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.