Skip to content

Commit

Permalink
refactor(examples): fix DRY for PoseidonStepCircuit
Browse files Browse the repository at this point in the history
**Motivation**
Fix DRY

**Overview**
Move example test circuit into main repo
  • Loading branch information
cyphersnake committed Feb 26, 2025
1 parent 4e51b1c commit 04340fd
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 244 deletions.
2 changes: 1 addition & 1 deletion examples/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use std::{
use clap::{Parser, Subcommand, ValueEnum};
use git2::Repository;
use halo2_proofs::halo2curves;
use poseidon::poseidon_step_circuit::TestPoseidonCircuit;
use sirius::{
ff::{FromUniformBytes, PrimeField, PrimeFieldBits},
gadgets::poseidon_step_circuit::TestPoseidonCircuit,
ivc::{cyclefold, sangria, step_circuit::trivial, StepCircuit},
poseidon::ROPair,
};
Expand Down
122 changes: 1 addition & 121 deletions examples/cyclefold_poseidon.rs
Original file line number Diff line number Diff line change
@@ -1,123 +1,3 @@
/// This module represents an implementation of `StepCircuit` based on the poseidon chip
pub mod poseidon_step_circuit {
use std::marker::PhantomData;

use halo2_proofs::{
circuit::{AssignedCell, Layouter},
plonk::ConstraintSystem,
};
use sirius::{
ff::{FromUniformBytes, PrimeFieldBits},
ivc::{StepCircuit, SynthesisError},
main_gate::{MainGate, MainGateConfig, RegionCtx, WrapValue},
poseidon::{poseidon_circuit::PoseidonChip, Spec},
};
use tracing::*;

/// Input and output size for `StepCircuit` within each step
pub const ARITY: usize = 1;

/// Spec for on-circuit poseidon circuit
const POSEIDON_PERMUTATION_WIDTH: usize = 3;
const POSEIDON_RATE: usize = POSEIDON_PERMUTATION_WIDTH - 1;

pub type CircuitPoseidonSpec<F> = Spec<F, POSEIDON_PERMUTATION_WIDTH, POSEIDON_RATE>;

const R_F1: usize = 4;
const R_P1: usize = 3;

#[derive(Clone, Debug)]
pub struct TestPoseidonCircuitConfig {
pconfig: MainGateConfig<POSEIDON_PERMUTATION_WIDTH>,
}

#[derive(Debug)]
pub struct TestPoseidonCircuit<F: PrimeFieldBits> {
repeat_count: usize,
_p: PhantomData<F>,
}

impl<F: PrimeFieldBits> Default for TestPoseidonCircuit<F> {
fn default() -> Self {
Self {
repeat_count: 1,
_p: Default::default(),
}
}
}

impl<F: PrimeFieldBits> TestPoseidonCircuit<F> {
pub fn new(repeat_count: usize) -> Self {
Self {
repeat_count,
_p: Default::default(),
}
}
}

impl<F: PrimeFieldBits + FromUniformBytes<64>> StepCircuit<ARITY, F> for TestPoseidonCircuit<F> {
type Config = TestPoseidonCircuitConfig;

fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
let pconfig = MainGate::configure(meta);
Self::Config { pconfig }
}

fn synthesize_step(
&self,
config: Self::Config,
layouter: &mut impl Layouter<F>,
z_in: &[AssignedCell<F, F>; ARITY],
) -> Result<[AssignedCell<F, F>; ARITY], SynthesisError> {
let spec = CircuitPoseidonSpec::<F>::new(R_F1, R_P1);

layouter
.assign_region(
|| "poseidon hash",
move |region| {
let mut z_i = z_in.clone();
let ctx = &mut RegionCtx::new(region, 0);

for step in 0..=self.repeat_count {
let mut pchip = PoseidonChip::new(config.pconfig.clone(), spec.clone());

pchip.update(
&z_i.iter()
.cloned()
.map(WrapValue::Assigned)
.collect::<Vec<WrapValue<F>>>(),
);

info!(
"offset for {} hash repeat count is {} (log2 = {})",
step,
ctx.offset(),
(ctx.offset() as f64).log2()
);

z_i = [pchip.squeeze(ctx).inspect_err(|err| {
error!("at step {step}: {err:?}");
})?];
}

info!(
"total offset for {} hash repeat count is {} (log2 = {})",
self.repeat_count,
ctx.offset(),
(ctx.offset() as f64).log2()
);

Ok(z_i)
},
)
.map_err(|err| {
error!("while synth {err:?}");
SynthesisError::Halo2(err)
})
}
}
}

use std::{array, env, io, path::Path};

use bn256::G1 as C1;
Expand Down Expand Up @@ -181,7 +61,7 @@ fn main() {
// To osterize the total execution time of the example
let _span = info_span!("poseidon_example").entered();

let primary = poseidon_step_circuit::TestPoseidonCircuit::default();
let primary = sirius::gadgets::poseidon_step_circuit::TestPoseidonCircuit::default();

let primary_commitment_key =
get_or_create_commitment_key::<C1Affine>(COMMITMENT_KEY_SIZE, "bn256")
Expand Down
126 changes: 4 additions & 122 deletions examples/sangria_poseidon.rs
Original file line number Diff line number Diff line change
@@ -1,130 +1,12 @@
/// This module represents an implementation of `StepCircuit` based on the poseidon chip
pub mod poseidon_step_circuit {
use std::marker::PhantomData;

use halo2_proofs::{
circuit::{AssignedCell, Layouter},
plonk::ConstraintSystem,
};
use sirius::{
ff::{FromUniformBytes, PrimeFieldBits},
ivc::{StepCircuit, SynthesisError},
main_gate::{MainGate, MainGateConfig, RegionCtx, WrapValue},
poseidon::{poseidon_circuit::PoseidonChip, Spec},
};
use tracing::*;

/// Input and output size for `StepCircuit` within each step
pub const ARITY: usize = 1;

/// Spec for on-circuit poseidon circuit
const POSEIDON_PERMUTATION_WIDTH: usize = 3;
const POSEIDON_RATE: usize = POSEIDON_PERMUTATION_WIDTH - 1;

pub type CircuitPoseidonSpec<F> = Spec<F, POSEIDON_PERMUTATION_WIDTH, POSEIDON_RATE>;

const R_F1: usize = 4;
const R_P1: usize = 3;

#[derive(Clone, Debug)]
pub struct TestPoseidonCircuitConfig {
pconfig: MainGateConfig<POSEIDON_PERMUTATION_WIDTH>,
}

#[derive(Debug)]
pub struct TestPoseidonCircuit<F: PrimeFieldBits> {
repeat_count: usize,
_p: PhantomData<F>,
}

impl<F: PrimeFieldBits> Default for TestPoseidonCircuit<F> {
fn default() -> Self {
Self {
repeat_count: 1,
_p: Default::default(),
}
}
}

impl<F: PrimeFieldBits> TestPoseidonCircuit<F> {
pub fn new(repeat_count: usize) -> Self {
Self {
repeat_count,
_p: Default::default(),
}
}
}

impl<F: PrimeFieldBits + FromUniformBytes<64>> StepCircuit<ARITY, F> for TestPoseidonCircuit<F> {
type Config = TestPoseidonCircuitConfig;

fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
let pconfig = MainGate::configure(meta);
Self::Config { pconfig }
}

fn synthesize_step(
&self,
config: Self::Config,
layouter: &mut impl Layouter<F>,
z_in: &[AssignedCell<F, F>; ARITY],
) -> Result<[AssignedCell<F, F>; ARITY], SynthesisError> {
let spec = CircuitPoseidonSpec::<F>::new(R_F1, R_P1);

layouter
.assign_region(
|| "poseidon hash",
move |region| {
let mut z_i = z_in.clone();
let ctx = &mut RegionCtx::new(region, 0);

for step in 0..=self.repeat_count {
let mut pchip = PoseidonChip::new(config.pconfig.clone(), spec.clone());

pchip.update(
&z_i.iter()
.cloned()
.map(WrapValue::Assigned)
.collect::<Vec<WrapValue<F>>>(),
);

info!(
"offset for {} hash repeat count is {} (log2 = {})",
step,
ctx.offset(),
(ctx.offset() as f64).log2()
);

z_i = [pchip.squeeze(ctx).inspect_err(|err| {
error!("at step {step}: {err:?}");
})?];
}

info!(
"total offset for {} hash repeat count is {} (log2 = {})",
self.repeat_count,
ctx.offset(),
(ctx.offset() as f64).log2()
);

Ok(z_i)
},
)
.map_err(|err| {
error!("while synth {err:?}");
SynthesisError::Halo2(err)
})
}
}
}

use std::{array, env, io, num::NonZeroUsize, path::Path};

use bn256::G1 as C1;
use grumpkin::G1 as C2;
use metadata::LevelFilter;
use sirius::{
commitment::CommitmentKey,
gadgets::poseidon_step_circuit::TestPoseidonCircuit,
group::{prime::PrimeCurve, Group},
halo2curves::{bn256, grumpkin, CurveAffine},
ivc::{sangria, step_circuit},
Expand All @@ -133,6 +15,8 @@ use sirius::{
use tracing::*;
use tracing_subscriber::{fmt::format::FmtSpan, EnvFilter};

const ARITY: usize = 1;

/// `K` table size for primary circuit
const PRIMARY_CIRCUIT_TABLE_SIZE: usize = 17;
/// `K` table size for secondary circuit
Expand All @@ -141,8 +25,6 @@ const SECONDARY_CIRCUIT_TABLE_SIZE: usize = 17;
/// Size of commitment key
const COMMITMENT_KEY_SIZE: usize = 21;

use poseidon_step_circuit::{TestPoseidonCircuit, ARITY};

/// Specification for the random oracle used within IVC
const MAIN_GATE_SIZE: usize = 5;
const RATE: usize = 4;
Expand Down Expand Up @@ -199,7 +81,7 @@ fn main() {
// To osterize the total execution time of the example
let _span = info_span!("poseidon_example").entered();

let primary = poseidon_step_circuit::TestPoseidonCircuit::default();
let primary = TestPoseidonCircuit::default();
let secondary = step_circuit::trivial::Circuit::<ARITY, _>::default();

// Specifications for random oracle used as part of the IVC algorithm
Expand Down
2 changes: 2 additions & 0 deletions src/gadgets/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub mod ecc;
pub mod nonnative;
pub(crate) mod util;

pub mod poseidon_step_circuit;
Loading

0 comments on commit 04340fd

Please sign in to comment.