Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ thiserror = "1.0"
bitvec = "1"

[patch."https://github.com/privacy-scaling-explorations/halo2.git"]
halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "scroll-dev-1220" }
halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "scroll-dev-0220" }

[features]
# Use an implementation using fewer rows (8) per permutation.
Expand Down
58 changes: 30 additions & 28 deletions src/hash.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
//! The hash circuit base on poseidon.

use crate::poseidon::primitives::{
ConstantLengthIden3, Domain, Hash, P128Pow5T3, Spec, VariableLengthIden3,
};
use crate::poseidon::primitives::{ConstantLengthIden3, Domain, Hash, Spec, VariableLengthIden3};
use halo2_proofs::halo2curves::bn256::Fr;
use halo2_proofs::{arithmetic::FieldExt, circuit::AssignedCell};

mod chip_long {
use super::{SpongeChip, SpongeConfig};
use crate::poseidon::primitives::{P128Pow5T3, P128Pow5T3Constants};
use crate::poseidon::Pow5Chip;
/// The specified base hashable trait
pub trait Hashablebase: P128Pow5T3Constants {}
/// Set the spec type as P128Pow5T3
pub type HashSpec<F> = P128Pow5T3<F>;
/// The configuration of the Poseidon hash chip.
pub type PoseidonHashConfig<F> = SpongeConfig<F, Pow5Chip<F, 3, 2>>;
/// The Poseidon hash chip.
Expand All @@ -18,7 +21,12 @@ mod chip_long {

mod chip_short {
use super::{SpongeChip, SpongeConfig};
use crate::poseidon::SeptidonChip;
use crate::poseidon::primitives::P128Pow5T3Compact;
use crate::poseidon::{CachedConstants, SeptidonChip};
/// The specified base hashable trait
pub trait Hashablebase: CachedConstants {}
/// Set the spec type as P128Pow5T3Compact
pub type HashSpec<F> = P128Pow5T3Compact<F>;
/// The configuration of the Poseidon hash chip.
pub type PoseidonHashConfig<F> = SpongeConfig<F, SeptidonChip>;
/// The Poseidon hash chip.
Expand All @@ -34,7 +42,7 @@ pub use chip_long::*;
pub use chip_short::*;

/// indicate an field can be hashed in merkle tree (2 Fields to 1 Field)
pub trait Hashable: FieldExt {
pub trait Hashable: Hashablebase {
/// the spec type used in circuit for this hashable field
type SpecType: Spec<Self, 3, 2>;
/// the domain type used for hash calculation
Expand Down Expand Up @@ -66,8 +74,10 @@ pub trait MessageHashable: Hashable {
}
}

impl Hashablebase for Fr {}

impl Hashable for Fr {
type SpecType = P128Pow5T3<Self>;
type SpecType = HashSpec<Self>;
type DomainType = ConstantLengthIden3<2>;

fn hash(inp: [Self; 2]) -> Self {
Expand All @@ -89,10 +99,11 @@ use halo2_proofs::{
plonk::{Advice, Column, ConstraintSystem, Error, Expression, Selector, TableColumn},
poly::Rotation,
};
use std::fmt::Debug as DebugT;

/// The config for poseidon hash circuit
#[derive(Clone, Debug)]
pub struct SpongeConfig<Fp: FieldExt, PC: PermuteChip<Fp>> {
pub struct SpongeConfig<Fp: FieldExt, PC: Chip<Fp> + Clone + DebugT> {
permute_config: PC::Config,
hash_table: [Column<Advice>; 5],
hash_table_aux: [Column<Advice>; 6],
Expand All @@ -103,7 +114,7 @@ pub struct SpongeConfig<Fp: FieldExt, PC: PermuteChip<Fp>> {
s_custom: Selector,
}

impl<Fp: Hashable, PC: PermuteChip<Fp>> SpongeConfig<Fp, PC> {
impl<Fp: Hashable, PC: PermuteChip<Fp, Fp::SpecType, 3, 2>> SpongeConfig<Fp, PC> {
/// obtain the commitment index of hash table
pub fn commitment_index(&self) -> [usize; 5] {
self.hash_table.map(|col| col.index())
Expand Down Expand Up @@ -348,7 +359,7 @@ impl<Fp: Hashable> PoseidonHashTable<Fp> {

/// Represent the chip for Poseidon hash table
#[derive(Debug)]
pub struct SpongeChip<'d, Fp: FieldExt, const STEP: usize, PC: PermuteChip<Fp>> {
pub struct SpongeChip<'d, Fp: FieldExt, const STEP: usize, PC: Chip<Fp> + Clone + DebugT> {
calcs: usize,
nil_msg_hash: Option<Fp>,
mpt_only: bool,
Expand All @@ -357,13 +368,10 @@ pub struct SpongeChip<'d, Fp: FieldExt, const STEP: usize, PC: PermuteChip<Fp>>
}

type PermutedState<Word> = Vec<[Word; 3]>;
type PermutedStatePair<Word> = (PermutedState<Word>, PermutedState<Word>);

impl<
'd,
Fp: Hashable,
const STEP: usize,
PC: PermuteChip<Fp> + PoseidonInstructions<Fp, Fp::SpecType, 3, 2>,
> SpongeChip<'d, Fp, STEP, PC>
impl<'d, Fp: Hashable, const STEP: usize, PC: PermuteChip<Fp, Fp::SpecType, 3, 2>>
SpongeChip<'d, Fp, STEP, PC>
{
///construct the chip
pub fn construct(
Expand Down Expand Up @@ -448,7 +456,7 @@ impl<
&self,
region: &mut Region<'_, Fp>,
begin_offset: usize,
) -> Result<(PermutedState<PC::Word>, PermutedState<PC::Word>), Error> {
) -> Result<PermutedStatePair<PC::Word>, Error> {
let config = &self.config;
let data = self.data;

Expand Down Expand Up @@ -658,7 +666,7 @@ impl<
}
}

impl<Fp: FieldExt, const STEP: usize, PC: PermuteChip<Fp>> Chip<Fp>
impl<Fp: FieldExt, const STEP: usize, PC: Chip<Fp> + Clone + DebugT> Chip<Fp>
for SpongeChip<'_, Fp, STEP, PC>
{
type Config = SpongeConfig<Fp, PC>;
Expand Down Expand Up @@ -731,12 +739,12 @@ mod tests {

// test circuit derived from table data
//#[derive(Clone, Default, Debug)]
struct TestCircuit<PC: PermuteChip<Fr>> {
struct TestCircuit<PC> {
table: PoseidonHashTable<Fr>,
_phantom: PhantomData<PC>,
}

impl<PC: PermuteChip<Fr>> TestCircuit<PC> {
impl<PC: PermuteChip<Fr, <Fr as Hashable>::SpecType, 3, 2>> TestCircuit<PC> {
pub fn new(table: PoseidonHashTable<Fr>) -> Self {
TestCircuit {
table,
Expand All @@ -745,9 +753,7 @@ mod tests {
}
}

impl<PC: PermuteChip<Fr> + PoseidonInstructions<Fr, <Fr as Hashable>::SpecType, 3, 2>>
Circuit<Fr> for TestCircuit<PC>
{
impl<PC: PermuteChip<Fr, <Fr as Hashable>::SpecType, 3, 2>> Circuit<Fr> for TestCircuit<PC> {
type Config = (SpongeConfig<Fr, PC>, usize);
type FloorPlanner = SimpleFloorPlanner;

Expand Down Expand Up @@ -814,9 +820,7 @@ mod tests {
poseidon_hash_circuit_impl::<SeptidonChip>();
}

fn poseidon_hash_circuit_impl<
PC: PermuteChip<Fr> + PoseidonInstructions<Fr, <Fr as Hashable>::SpecType, 3, 2>,
>() {
fn poseidon_hash_circuit_impl<PC: PermuteChip<Fr, <Fr as Hashable>::SpecType, 3, 2>>() {
let message1 = [
Fr::from_str_vartime("1").unwrap(),
Fr::from_str_vartime("2").unwrap(),
Expand All @@ -842,9 +846,7 @@ mod tests {
poseidon_var_len_hash_circuit_impl::<SeptidonChip>();
}

fn poseidon_var_len_hash_circuit_impl<
PC: PermuteChip<Fr> + PoseidonInstructions<Fr, <Fr as Hashable>::SpecType, 3, 2>,
>() {
fn poseidon_var_len_hash_circuit_impl<PC: PermuteChip<Fr, <Fr as Hashable>::SpecType, 3, 2>>() {
let message1 = [
Fr::from_str_vartime("1").unwrap(),
Fr::from_str_vartime("2").unwrap(),
Expand Down
6 changes: 4 additions & 2 deletions src/poseidon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ mod pow5;
pub use pow5::{Pow5Chip, Pow5Config, StateWord, Var};

mod septidon;
pub use septidon::SeptidonChip;
pub use septidon::{CachedConstants, SeptidonChip};

pub mod primitives;
use primitives::{Absorbing, ConstantLength, Domain, Spec, SpongeMode, Squeezing, State};
Expand All @@ -30,7 +30,9 @@ pub enum PaddedWord<F: Field> {
}

/// This trait is the interface to chips that implement a permutation.
pub trait PermuteChip<F: FieldExt>: Chip<F> + Clone + DebugT {
pub trait PermuteChip<F: FieldExt, S: Spec<F, T, RATE>, const T: usize, const RATE: usize>:
Chip<F> + Clone + DebugT + PoseidonInstructions<F, S, T, RATE>
{
/// Configure the permutation chip.
fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config;

Expand Down
6 changes: 2 additions & 4 deletions src/poseidon/pow5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ use halo2_proofs::{
poly::Rotation,
};

use crate::Hashable;

use super::{
primitives::{Absorbing, Domain, Mds, Spec, Squeezing, State},
PaddedWord, PermuteChip, PoseidonInstructions, PoseidonSpongeInstructions,
Expand Down Expand Up @@ -260,13 +258,13 @@ impl<F: FieldExt, const WIDTH: usize, const RATE: usize> Chip<F> for Pow5Chip<F,
}
}

impl<F: Hashable> PermuteChip<F> for Pow5Chip<F, 3, 2> {
impl<F: FieldExt, S: Spec<F, 3, 2>> PermuteChip<F, S, 3, 2> for Pow5Chip<F, 3, 2> {
fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
let state = [0; 3].map(|_| meta.advice_column());
let partial_sbox = meta.advice_column();
let constants = [0; 6].map(|_| meta.fixed_column());

Pow5Chip::configure::<F::SpecType>(
Pow5Chip::configure::<S>(
meta,
state,
partial_sbox,
Expand Down
1 change: 1 addition & 0 deletions src/poseidon/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ mod p128pow5t3;
mod p128pow5t3_compact;

pub use p128pow5t3::P128Pow5T3;
pub(crate) use p128pow5t3::P128Pow5T3Constants;
pub use p128pow5t3_compact::P128Pow5T3Compact;

use grain::SboxType;
Expand Down
1 change: 1 addition & 0 deletions src/poseidon/primitives/p128pow5t3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::marker::PhantomData;

use super::{Mds, Spec};

/// The trait required for fields can handle a pow5 sbox, 3 field, 2 rate permutation
pub trait P128Pow5T3Constants: FieldExt {
fn partial_rounds() -> usize {
56
Expand Down
1 change: 1 addition & 0 deletions src/poseidon/septidon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ mod tests;
mod transition_round;
mod util;

pub use params::CachedConstants;
pub use septidon_chip::SeptidonChip;
14 changes: 9 additions & 5 deletions src/poseidon/septidon/control.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use super::params::GATE_DEGREE_5;
use super::util::query;
use halo2_proofs::arithmetic::FieldExt;
use halo2_proofs::circuit::{Region, Value};
use halo2_proofs::halo2curves::bn256::Fr as F;
//use halo2_proofs::halo2curves::bn256::Fr as F;
use halo2_proofs::plonk::{Column, ConstraintSystem, Error, Expression, Fixed, VirtualCells};
use halo2_proofs::poly::Rotation;

Expand All @@ -10,7 +11,7 @@ pub struct ControlChip {
is_last: Column<Fixed>,
}

pub struct ControlSignals {
pub struct ControlSignals<F: FieldExt> {
// Signals that control the switches between steps of the permutation.
pub break_full_rounds: Expression<F>,
pub transition_round: Expression<F>,
Expand All @@ -21,7 +22,7 @@ pub struct ControlSignals {
}

impl ControlChip {
pub fn configure(cs: &mut ConstraintSystem<F>) -> (Self, ControlSignals) {
pub fn configure<F: FieldExt>(cs: &mut ConstraintSystem<F>) -> (Self, ControlSignals<F>) {
let is_last = cs.fixed_column();

let signals = query(cs, |meta| {
Expand All @@ -42,12 +43,15 @@ impl ControlChip {
}

/// Assign the fixed positions of the last row of permutations.
pub fn assign(&self, region: &mut Region<'_, F>) -> Result<(), Error> {
pub fn assign<F: FieldExt>(&self, region: &mut Region<'_, F>) -> Result<(), Error> {
region.assign_fixed(|| "", self.is_last, 7, || Value::known(F::one()))?;
Ok(())
}

fn derive_selector(is_last: Column<Fixed>, meta: &mut VirtualCells<'_, F>) -> Expression<F> {
fn derive_selector<F: FieldExt>(
is_last: Column<Fixed>,
meta: &mut VirtualCells<'_, F>,
) -> Expression<F> {
if GATE_DEGREE_5 {
// Variant with no selector. Do not disable gates, do not increase the gate degree.
Expression::Constant(F::one())
Expand Down
17 changes: 10 additions & 7 deletions src/poseidon/septidon/full_round.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use super::loop_chip::LoopBody;
use super::params::mds;
use super::params::{mds, CachedConstants};
use super::state::{Cell, FullState, SBox};
use super::util::{join_values, matmul, query, split_values};
use halo2_proofs::circuit::{Region, Value};
use halo2_proofs::halo2curves::bn256::Fr as F;
//use halo2_proofs::halo2curves::bn256::Fr as F;
use halo2_proofs::plonk::{ConstraintSystem, Error, Expression, VirtualCells};

#[derive(Clone, Debug)]
pub struct FullRoundChip(pub FullState);

impl FullRoundChip {
pub fn configure(cs: &mut ConstraintSystem<F>) -> (Self, LoopBody) {
pub fn configure<F: CachedConstants>(cs: &mut ConstraintSystem<F>) -> (Self, LoopBody<F>) {
let chip = Self(FullState::configure(cs));

let loop_body = query(cs, |meta| {
Expand All @@ -22,17 +22,20 @@ impl FullRoundChip {
(chip, loop_body)
}

fn full_round_expr(&self, meta: &mut VirtualCells<'_, F>) -> [Expression<F>; 3] {
fn full_round_expr<F: CachedConstants>(
&self,
meta: &mut VirtualCells<'_, F>,
) -> [Expression<F>; 3] {
let sbox_out = self.0.map(|sbox: &SBox| sbox.output_expr(meta));
matmul::expr(&mds(), sbox_out)
matmul::expr(mds(), sbox_out)
}

pub fn input_cells(&self) -> [Cell; 3] {
self.0.map(|sbox| sbox.input.clone())
}

/// Assign the witness.
pub fn assign(
pub fn assign<F: CachedConstants>(
&self,
region: &mut Region<'_, F>,
offset: usize,
Expand All @@ -44,7 +47,7 @@ impl FullRoundChip {
let sbox: &SBox = &self.0 .0[i];
sbox_out[i] = sbox.assign(region, offset, round_constants[i], input[i])?;
}
let output = join_values(sbox_out).map(|sbox_out| matmul::value(&mds(), sbox_out));
let output = join_values(sbox_out).map(|sbox_out| matmul::value(mds(), sbox_out));
Ok(split_values(output))
}
}
Loading