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#149 from input-output…
…-hk/dev-benchmark/recursive-open-ipa Add Goldenfile + Criterion benchmark for recursive IPA commitment opening
- Loading branch information
Showing
6 changed files
with
361 additions
and
76 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
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,242 @@ | ||
mod ecc_circuits; | ||
mod utilities; | ||
|
||
use std::{iter::repeat_with, marker::PhantomData, time::Duration}; | ||
|
||
use criterion::{criterion_group, criterion_main, Criterion}; | ||
use group::Curve; | ||
|
||
use halo2_proofs::{ | ||
arithmetic::eval_polynomial, | ||
circuit::{floor_planner::V1, Chip}, | ||
generate_default_duplex_domain, | ||
plonk::Circuit, | ||
poly::{ | ||
commitment::{Blind, ParamsProver}, | ||
ipa::commitment::{create_proof, ParamsIPA}, | ||
Coeff, EvaluationDomain, Polynomial, | ||
}, | ||
transcript::{ | ||
poseidon::PoseidonWriteBaseFitsInScalarP128Pow5T3, EncodedChallenge, Transcript, | ||
TranscriptWrite, TranscriptWriterBuffer, | ||
}, | ||
}; | ||
use rand::thread_rng; | ||
|
||
use halo2_proofs::{ | ||
circuit::{Layouter, Value}, | ||
plonk::{ConstraintSystem, Error}, | ||
poseidon::{duplex::DuplexDomain, P128Pow5T3}, | ||
}; | ||
use halo2curves::{pasta, CurveAffine}; | ||
use std::{fmt::Debug, io::Read}; | ||
use utilities::bench_circuit; | ||
|
||
use halo2_gadgets::{ | ||
ecc::{ | ||
chip::{BaseFieldElem, FixedPoint, FullScalar, ShortScalar}, | ||
EccInstructions, FixedPoints, | ||
}, | ||
recursive_chip::DefaultRecursiveChip as RecursiveChip, | ||
recursive_circuits::ipa, | ||
transcript::{TranscriptInstructions, TranscriptReadInstructions}, | ||
}; | ||
|
||
use ecc_circuits::fixed_points::TestFixedBases; | ||
|
||
#[derive(Debug, Clone)] | ||
struct MyCircuit<FP, D, const L: usize, R: Clone> { | ||
params: ParamsIPA<C>, | ||
proof: Value<R>, | ||
evaluation: Value<<C as CurveAffine>::ScalarExt>, | ||
|
||
_marker: PhantomData<(FP, D)>, | ||
} | ||
|
||
#[allow(deprecated)] // Allow final absorb in `duplex_pattern` | ||
mod poseidon_patterns { | ||
use super::*; | ||
|
||
pub const K: u32 = 10; | ||
|
||
// Generated using `commit_open_pattern(10)` | ||
generate_default_duplex_domain!( | ||
domain, | ||
IpaCommitOpenDomain, | ||
F::ZERO, | ||
25, | ||
DuplexPatternBuilder::new() | ||
// Initialization: commitment and challenge | ||
.absorb(2) | ||
.squeeze(1) | ||
// Open commitment | ||
.absorb(2) | ||
.squeeze(2) | ||
.absorb(4) | ||
.squeeze(1) | ||
.absorb(4) | ||
.squeeze(1) | ||
.absorb(4) | ||
.squeeze(1) | ||
.absorb(4) | ||
.squeeze(1) | ||
.absorb(4) | ||
.squeeze(1) | ||
.absorb(4) | ||
.squeeze(1) | ||
.absorb(4) | ||
.squeeze(1) | ||
.absorb(4) | ||
.squeeze(1) | ||
.absorb(4) | ||
.squeeze(1) | ||
.absorb(4) | ||
.squeeze(1) | ||
.absorb(4) | ||
.build() | ||
); | ||
} | ||
|
||
use poseidon_patterns::{IpaCommitOpenDomain, K}; | ||
|
||
type C = pasta::pallas::Affine; // Limitation of `EccChip` (will be generalized later) | ||
|
||
impl<FP, D, const L: usize, R> Circuit<<C as CurveAffine>::Base> for MyCircuit<FP, D, L, R> | ||
where | ||
FP: FixedPoints<C>, | ||
<FP as FixedPoints<C>>::FullScalar: FixedPoint<C>, | ||
<FP as FixedPoints<C>>::Base: FixedPoint<C, FixedScalarKind = BaseFieldElem>, | ||
<FP as FixedPoints<C>>::FullScalar: FixedPoint<C, FixedScalarKind = FullScalar>, | ||
<FP as FixedPoints<C>>::ShortScalar: FixedPoint<C, FixedScalarKind = ShortScalar>, | ||
D: DuplexDomain<<C as CurveAffine>::Base, { P128Pow5T3::RATE }, L>, | ||
R: Read + Debug + Clone, | ||
{ | ||
type Config = <RecursiveChip<FP, D, R, L> as Chip<<C as CurveAffine>::Base>>::Config; | ||
type FloorPlanner = V1; | ||
#[cfg(feature = "circuit-params")] | ||
type Params = (); | ||
|
||
fn without_witnesses(&self) -> Self { | ||
Self { | ||
params: self.params.clone(), | ||
_marker: PhantomData, | ||
proof: Value::unknown(), | ||
evaluation: Value::unknown(), | ||
} | ||
} | ||
|
||
fn configure(meta: &mut ConstraintSystem<<C as CurveAffine>::Base>) -> Self::Config { | ||
let advice: [_; 10] = repeat_with(|| meta.advice_column()) | ||
.take(10) | ||
.collect::<Vec<_>>() | ||
.try_into() | ||
.unwrap(); | ||
let fixed: [_; 8] = repeat_with(|| meta.fixed_column()) | ||
.take(8) | ||
.collect::<Vec<_>>() | ||
.try_into() | ||
.unwrap(); | ||
let instance = [meta.instance_column()]; | ||
let lookup = meta.lookup_table_column(); | ||
|
||
RecursiveChip::configure(meta, advice, fixed, instance, lookup) | ||
} | ||
|
||
fn synthesize( | ||
&self, | ||
config: Self::Config, | ||
mut layouter: impl Layouter<<C as CurveAffine>::Base>, | ||
) -> Result<(), Error> { | ||
let mut chip = RecursiveChip::init( | ||
layouter.namespace(|| "init recursive chip"), | ||
config, | ||
self.proof.clone(), | ||
)?; | ||
|
||
let commitment = chip.read_point(layouter.namespace(|| "commitment"))?; | ||
let x = chip.squeeze_challenge(layouter.namespace(|| "challenge"))?; | ||
|
||
// `v` is the evaluation you expect: depends on the challenge but we pre-computed out | ||
// of circuit and can just pass it in | ||
let v = chip.witness_scalar_var(&mut layouter, self.evaluation)?; | ||
|
||
ipa::commitment::verify(chip, layouter, &self.params, commitment, x, v)?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
fn random_polynomial<F: ff::WithSmallOrderMulGroup<3>, R: rand::Rng>( | ||
domain: &EvaluationDomain<F>, | ||
mut rng: R, | ||
) -> Polynomial<F, Coeff> { | ||
domain.coeff_from_vec( | ||
std::iter::repeat_with(|| F::random(&mut rng)) | ||
.take(1 << domain.k() as usize) | ||
.collect(), | ||
) | ||
} | ||
|
||
fn bench_recursive_ipa_commit(c: &mut Criterion) { | ||
let params = ParamsIPA::new(K); | ||
let mut rng = thread_rng(); | ||
|
||
let domain = EvaluationDomain::<<C as CurveAffine>::ScalarExt>::new(1, K); | ||
|
||
// Randomly choose a polynomial to commit to/open | ||
let polynomial = random_polynomial(&domain, &mut rng); | ||
let blind = Blind::new(&mut rng); | ||
|
||
let commitment: <C as CurveAffine>::CurveExt = params.commit(&polynomial, blind); | ||
// Create commitment opening proof to verify | ||
let (proof, evaluation) = { | ||
let mut transcript_write = PoseidonWriteBaseFitsInScalarP128Pow5T3::< | ||
_, | ||
_, | ||
IpaCommitOpenDomain<_>, | ||
{ IpaCommitOpenDomain::<<C as CurveAffine>::Base>::L }, | ||
>::init(vec![]); | ||
|
||
transcript_write | ||
.write_point(commitment.to_affine()) | ||
.expect("transcript write failed"); | ||
let challenge_scalar = transcript_write.squeeze_challenge().get_scalar(); | ||
|
||
let evaluation = eval_polynomial(&polynomial, challenge_scalar); | ||
|
||
create_proof( | ||
¶ms, | ||
rng, | ||
&mut transcript_write, | ||
&polynomial, | ||
blind, | ||
challenge_scalar, | ||
) | ||
.expect("proof generation failed"); | ||
|
||
let proof = transcript_write.finalize(); | ||
(std::io::Cursor::new(proof), evaluation) | ||
}; | ||
|
||
let circuit = MyCircuit { | ||
params, | ||
proof: Value::known(proof), | ||
evaluation: Value::known(evaluation), | ||
_marker: PhantomData::<(TestFixedBases<C>, IpaCommitOpenDomain<_>)>, | ||
}; | ||
|
||
bench_circuit::<pasta::vesta::Affine>( | ||
c, | ||
13, | ||
"IPA recursive commitment opening: degree 2^10", | ||
&[&[]], | ||
circuit, | ||
); | ||
} | ||
|
||
criterion_group! { | ||
name = benches; | ||
config = Criterion::default().sample_size(10).measurement_time(Duration::from_secs(20)); | ||
targets = bench_recursive_ipa_commit, | ||
} | ||
|
||
criterion_main!(benches); |
2 changes: 2 additions & 0 deletions
2
halo2_gadgets/goldenfiles/cost-model/verify-ipa-commitment-circuit.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 | ||
16,10,3,15,85,5,6464 |
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.