Skip to content

Commit

Permalink
chore: use PrimeField for OptimizedPoseidonSpec (#139)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanpwang authored Sep 8, 2023
1 parent a1fec64 commit 72b53bf
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
10 changes: 5 additions & 5 deletions halo2-base/src/poseidon/hasher/mds.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![allow(clippy::needless_range_loop)]
use crate::utils::ScalarField;
use crate::ff::PrimeField;

/// The type used to hold the MDS matrix
pub(crate) type Mds<F, const T: usize> = [[F; T]; T];
Expand All @@ -8,7 +8,7 @@ pub(crate) type Mds<F, const T: usize> = [[F; T]; T];
/// also called `pre_sparse_mds` and sparse matrices that enables us to reduce
/// number of multiplications in apply MDS step
#[derive(Debug, Clone)]
pub struct MDSMatrices<F: ScalarField, const T: usize, const RATE: usize> {
pub struct MDSMatrices<F: PrimeField, const T: usize, const RATE: usize> {
pub(crate) mds: MDSMatrix<F, T, RATE>,
pub(crate) pre_sparse_mds: MDSMatrix<F, T, RATE>,
pub(crate) sparse_matrices: Vec<SparseMDSMatrix<F, T, RATE>>,
Expand All @@ -17,16 +17,16 @@ pub struct MDSMatrices<F: ScalarField, const T: usize, const RATE: usize> {
/// `SparseMDSMatrix` are in `[row], [hat | identity]` form and used in linear
/// layer of partial rounds instead of the original MDS
#[derive(Debug, Clone)]
pub struct SparseMDSMatrix<F: ScalarField, const T: usize, const RATE: usize> {
pub struct SparseMDSMatrix<F: PrimeField, const T: usize, const RATE: usize> {
pub(crate) row: [F; T],
pub(crate) col_hat: [F; RATE],
}

/// `MDSMatrix` is applied to `State` to achive linear layer of Poseidon
#[derive(Clone, Debug)]
pub struct MDSMatrix<F: ScalarField, const T: usize, const RATE: usize>(pub(crate) Mds<F, T>);
pub struct MDSMatrix<F: PrimeField, const T: usize, const RATE: usize>(pub(crate) Mds<F, T>);

impl<F: ScalarField, const T: usize, const RATE: usize> MDSMatrix<F, T, RATE> {
impl<F: PrimeField, const T: usize, const RATE: usize> MDSMatrix<F, T, RATE> {
pub(crate) fn mul_vector(&self, v: &[F; T]) -> [F; T] {
let mut res = [F::ZERO; T];
for i in 0..T {
Expand Down
20 changes: 13 additions & 7 deletions halo2-base/src/poseidon/hasher/spec.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use crate::{poseidon::hasher::mds::*, utils::ScalarField};
use crate::{
ff::{FromUniformBytes, PrimeField},
poseidon::hasher::mds::*,
};

use poseidon_rs::poseidon::primitives::Spec as PoseidonSpec; // trait
use std::marker::PhantomData;

// struct so we can use PoseidonSpec trait to generate round constants and MDS matrix
#[derive(Debug)]
pub(crate) struct Poseidon128Pow5Gen<
F: ScalarField,
F: PrimeField,
const T: usize,
const RATE: usize,
const R_F: usize,
Expand All @@ -17,7 +20,7 @@ pub(crate) struct Poseidon128Pow5Gen<
}

impl<
F: ScalarField,
F: PrimeField,
const T: usize,
const RATE: usize,
const R_F: usize,
Expand Down Expand Up @@ -51,7 +54,7 @@ impl<
/// `OptimizedPoseidonSpec` holds construction parameters as well as constants that are used in
/// permutation step.
#[derive(Debug, Clone)]
pub struct OptimizedPoseidonSpec<F: ScalarField, const T: usize, const RATE: usize> {
pub struct OptimizedPoseidonSpec<F: PrimeField, const T: usize, const RATE: usize> {
pub(crate) r_f: usize,
pub(crate) mds_matrices: MDSMatrices<F, T, RATE>,
pub(crate) constants: OptimizedConstants<F, T>,
Expand All @@ -61,15 +64,18 @@ pub struct OptimizedPoseidonSpec<F: ScalarField, const T: usize, const RATE: usi
/// full rounds has T sized constants there is a single constant for each
/// partial round
#[derive(Debug, Clone)]
pub struct OptimizedConstants<F: ScalarField, const T: usize> {
pub struct OptimizedConstants<F: PrimeField, const T: usize> {
pub(crate) start: Vec<[F; T]>,
pub(crate) partial: Vec<F>,
pub(crate) end: Vec<[F; T]>,
}

impl<F: ScalarField, const T: usize, const RATE: usize> OptimizedPoseidonSpec<F, T, RATE> {
impl<F: PrimeField, const T: usize, const RATE: usize> OptimizedPoseidonSpec<F, T, RATE> {
/// Generate new spec with specific number of full and partial rounds. `SECURE_MDS` is usually 0, but may need to be specified because insecure matrices may sometimes be generated
pub fn new<const R_F: usize, const R_P: usize, const SECURE_MDS: usize>() -> Self {
pub fn new<const R_F: usize, const R_P: usize, const SECURE_MDS: usize>() -> Self
where
F: FromUniformBytes<64> + Ord,
{
let (round_constants, mds, mds_inv) =
Poseidon128Pow5Gen::<F, T, RATE, R_F, R_P, SECURE_MDS>::constants();
let mds = MDSMatrix(mds);
Expand Down

0 comments on commit 72b53bf

Please sign in to comment.