Impl Spec for P128Pow5T3 over Fq.

This commit is contained in:
therealyingtong 2021-08-26 10:46:56 +08:00
parent 764c445a81
commit 4eb4c57827
1 changed files with 86 additions and 27 deletions

View File

@ -1,10 +1,7 @@
use halo2::arithmetic::Field; use halo2::arithmetic::Field;
use pasta_curves::pallas; use pasta_curves::{pallas, vesta};
use super::{ use super::{Mds, Spec};
fp::{MDS, MDS_INV, ROUND_CONSTANTS},
Mds, Spec,
};
/// Poseidon-128 using the $x^5$ S-box, with a width of 3 field elements, and the /// Poseidon-128 using the $x^5$ S-box, with a width of 3 field elements, and the
/// standard number of rounds for 128-bit security "with margin". /// standard number of rounds for 128-bit security "with margin".
@ -39,7 +36,43 @@ impl Spec<pallas::Base, 3, 2> for P128Pow5T3 {
Mds<pallas::Base, 3>, Mds<pallas::Base, 3>,
Mds<pallas::Base, 3>, Mds<pallas::Base, 3>,
) { ) {
(ROUND_CONSTANTS[..].to_vec(), MDS, MDS_INV) (
super::fp::ROUND_CONSTANTS[..].to_vec(),
super::fp::MDS,
super::fp::MDS_INV,
)
}
}
impl Spec<vesta::Base, 3, 2> for P128Pow5T3 {
fn full_rounds() -> usize {
8
}
fn partial_rounds() -> usize {
56
}
fn sbox(val: vesta::Base) -> vesta::Base {
val.pow_vartime(&[5])
}
fn secure_mds(&self) -> usize {
unimplemented!()
}
fn constants(
&self,
) -> (
Vec<[vesta::Base; 3]>,
Mds<vesta::Base, 3>,
Mds<vesta::Base, 3>,
) {
(
super::fq::ROUND_CONSTANTS[..].to_vec(),
super::fq::MDS,
super::fq::MDS_INV,
)
} }
} }
@ -49,30 +82,29 @@ mod tests {
use ff::PrimeField; use ff::PrimeField;
use halo2::arithmetic::FieldExt; use halo2::arithmetic::FieldExt;
use pasta_curves::pallas; use pasta_curves::{pallas, vesta};
use super::super::{fp, fq};
use crate::primitives::poseidon::{permute, ConstantLength, Hash, Spec}; use crate::primitives::poseidon::{permute, ConstantLength, Hash, Spec};
use super::{MDS, MDS_INV, ROUND_CONSTANTS};
/// The same Poseidon specification as poseidon::P128Pow5T3, but constructed /// The same Poseidon specification as poseidon::P128Pow5T3, but constructed
/// such that its constants will be generated at runtime. /// such that its constants will be generated at runtime.
#[derive(Debug)] #[derive(Debug)]
pub struct P128Pow5T3<F: FieldExt> { pub struct P128Pow5T3Gen<F: FieldExt> {
secure_mds: usize, secure_mds: usize,
_field: PhantomData<F>, _field: PhantomData<F>,
} }
impl<F: FieldExt> P128Pow5T3<F> { impl<F: FieldExt> P128Pow5T3Gen<F> {
pub fn new(secure_mds: usize) -> Self { pub fn new(secure_mds: usize) -> Self {
P128Pow5T3 { P128Pow5T3Gen {
secure_mds, secure_mds,
_field: PhantomData::default(), _field: PhantomData::default(),
} }
} }
} }
impl<F: FieldExt> Spec<F, 3, 2> for P128Pow5T3<F> { impl<F: FieldExt> Spec<F, 3, 2> for P128Pow5T3Gen<F> {
fn full_rounds() -> usize { fn full_rounds() -> usize {
8 8
} }
@ -92,23 +124,46 @@ mod tests {
#[test] #[test]
fn verify_constants() { fn verify_constants() {
let poseidon = P128Pow5T3::<pallas::Base>::new(0);
let (round_constants, mds, mds_inv) = poseidon.constants();
for (actual, expected) in round_constants
.iter()
.flatten()
.zip(ROUND_CONSTANTS.iter().flatten())
{ {
assert_eq!(actual, expected); let poseidon = P128Pow5T3Gen::<pallas::Base>::new(0);
let (round_constants, mds, mds_inv) = poseidon.constants();
for (actual, expected) in round_constants
.iter()
.flatten()
.zip(fp::ROUND_CONSTANTS.iter().flatten())
{
assert_eq!(actual, expected);
}
for (actual, expected) in mds.iter().flatten().zip(fp::MDS.iter().flatten()) {
assert_eq!(actual, expected);
}
for (actual, expected) in mds_inv.iter().flatten().zip(fp::MDS_INV.iter().flatten()) {
assert_eq!(actual, expected);
}
} }
for (actual, expected) in mds.iter().flatten().zip(MDS.iter().flatten()) { {
assert_eq!(actual, expected); let poseidon = P128Pow5T3Gen::<vesta::Base>::new(0);
} let (round_constants, mds, mds_inv) = poseidon.constants();
for (actual, expected) in mds_inv.iter().flatten().zip(MDS_INV.iter().flatten()) { for (actual, expected) in round_constants
assert_eq!(actual, expected); .iter()
.flatten()
.zip(fq::ROUND_CONSTANTS.iter().flatten())
{
assert_eq!(actual, expected);
}
for (actual, expected) in mds.iter().flatten().zip(fq::MDS.iter().flatten()) {
assert_eq!(actual, expected);
}
for (actual, expected) in mds_inv.iter().flatten().zip(fq::MDS_INV.iter().flatten()) {
assert_eq!(actual, expected);
}
} }
} }
@ -160,7 +215,11 @@ mod tests {
]), ]),
]; ];
permute::<pallas::Base, P128Pow5T3<pallas::Base>, 3, 2>(&mut input, &MDS, &ROUND_CONSTANTS); permute::<pallas::Base, P128Pow5T3Gen<pallas::Base>, 3, 2>(
&mut input,
&fp::MDS,
&fp::ROUND_CONSTANTS,
);
assert_eq!(input, expected_output); assert_eq!(input, expected_output);
} }