Skip to content

Commit

Permalink
Merge pull request #2927 from o1-labs/dw/mina-poseidon-doc-and-tests
Browse files Browse the repository at this point in the history
Mina-poseidon: regression tests + top-level documentation
  • Loading branch information
dannywillems authored Jan 7, 2025
2 parents 2d4480d + 9b5c406 commit a340c95
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 8 deletions.
25 changes: 25 additions & 0 deletions poseidon/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
//! This crate provides a generic implementation of the Poseidon hash function.
//! It provides a [Sponge](crate::sponge::FqSponge) trait that can be
//! implemented for any field.
//!
//! Some parameters for the Pasta fields are provided in the sub-crate
//! [crate::pasta].
//!
//! To instantiate an object that can be used to generate challenges for the
//! Fiat-Shamir transformation, use the
//! [DefaultFqSponge](crate::sponge::DefaultFqSponge) struct. For instance, to
//! instantiate with the parameters used by the Mina hard-fork called Berkeley,
//! use:
//! ```rust
//! use mina_curves::pasta::{VestaParameters};
//! use mina_poseidon::sponge::DefaultFqSponge;
//! use mina_poseidon::FqSponge;
//! use mina_poseidon::constants::PlonkSpongeConstantsKimchi;
//! use mina_poseidon::pasta::fq_kimchi;
//!
//! let mut sponge = DefaultFqSponge::<VestaParameters, PlonkSpongeConstantsKimchi>::new(
//! fq_kimchi::static_params(),
//! );
//! let challenge = sponge.challenge();
//! ```
pub mod constants;
pub mod dummy_values;
pub mod pasta;
Expand Down
74 changes: 66 additions & 8 deletions poseidon/tests/poseidon_tests.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use mina_curves::pasta::Fp;
use ark_ff::{Field, UniformRand};
use mina_curves::pasta::{Fp, Fq, PallasParameters, VestaParameters};
use mina_poseidon::{
constants::{PlonkSpongeConstantsKimchi, PlonkSpongeConstantsLegacy},
pasta::{fp_kimchi as SpongeParametersKimchi, fp_legacy as SpongeParametersLegacy},
pasta::{fp_kimchi, fp_legacy, fq_kimchi},
poseidon::{ArithmeticSponge as Poseidon, Sponge as _},
sponge::DefaultFqSponge,
FqSponge as _,
};
use o1_utils::FieldHelpers;
use rand::Rng;
use serde::Deserialize;
use std::{fs::File, path::PathBuf}; // needed for ::new() sponge

Expand Down Expand Up @@ -58,9 +62,7 @@ where
#[test]
fn poseidon_test_vectors_legacy() {
fn hash(input: &[Fp]) -> Fp {
let mut hash = Poseidon::<Fp, PlonkSpongeConstantsLegacy>::new(
SpongeParametersLegacy::static_params(),
);
let mut hash = Poseidon::<Fp, PlonkSpongeConstantsLegacy>::new(fp_legacy::static_params());
hash.absorb(input);
hash.squeeze()
}
Expand All @@ -70,11 +72,67 @@ fn poseidon_test_vectors_legacy() {
#[test]
fn poseidon_test_vectors_kimchi() {
fn hash(input: &[Fp]) -> Fp {
let mut hash = Poseidon::<Fp, PlonkSpongeConstantsKimchi>::new(
SpongeParametersKimchi::static_params(),
);
let mut hash = Poseidon::<Fp, PlonkSpongeConstantsKimchi>::new(fp_kimchi::static_params());
hash.absorb(input);
hash.squeeze()
}
test_vectors("kimchi.json", hash);
}

#[test]
fn test_regression_challenge_empty_vesta_kimchi() {
let mut sponge = DefaultFqSponge::<VestaParameters, PlonkSpongeConstantsKimchi>::new(
fq_kimchi::static_params(),
);
let output = sponge.challenge();
let exp_output =
Fp::from_hex("c1e504c0184cce70a605d2f942d579c500000000000000000000000000000000").unwrap();
assert_eq!(output, exp_output);
}

#[test]
fn test_regression_challenge_empty_pallas_kimchi() {
let mut sponge = DefaultFqSponge::<PallasParameters, PlonkSpongeConstantsKimchi>::new(
fp_kimchi::static_params(),
);
let output = sponge.challenge();
let exp_output =
Fq::from_hex("a8eb9ee0f30046308abbfa5d20af73c800000000000000000000000000000000").unwrap();
assert_eq!(output, exp_output);
}

#[test]
fn test_poseidon_vesta_kimchi_challenge_is_squeezed_to_128_bits() {
// Test that the challenge is less than 2^128, i.e. the sponge state is
// squeezed to 128 bits
let mut sponge = DefaultFqSponge::<VestaParameters, PlonkSpongeConstantsKimchi>::new(
fq_kimchi::static_params(),
);
let mut rng = o1_utils::tests::make_test_rng(None);
let random_n = rng.gen_range(1..50);
let random_fq_vec = (0..random_n)
.map(|_| Fq::rand(&mut rng))
.collect::<Vec<Fq>>();
sponge.absorb_fq(&random_fq_vec);
let challenge = sponge.challenge();
let two_128 = Fp::from(2).pow([128]);
assert!(challenge < two_128);
}

#[test]
fn test_poseidon_pallas_kimchi_challenge_is_squeezed_to_128_bits() {
// Test that the challenge is less than 2^128, i.e. the sponge state is
// squeezed to 128 bits
let mut sponge = DefaultFqSponge::<PallasParameters, PlonkSpongeConstantsKimchi>::new(
fp_kimchi::static_params(),
);
let mut rng = o1_utils::tests::make_test_rng(None);
let random_n = rng.gen_range(1..50);
let random_fp_vec = (0..random_n)
.map(|_| Fp::rand(&mut rng))
.collect::<Vec<Fp>>();
sponge.absorb_fq(&random_fp_vec);
let challenge = sponge.challenge();
let two_128 = Fq::from(2).pow([128]);
assert!(challenge < two_128);
}

0 comments on commit a340c95

Please sign in to comment.