You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To improve the modularity and usefulness of the Poseidon Parameter Setup code, we want to separate the LFSR implementation from the field element sampling algorithm and the generation of the round constants and MDS matrix.
Old Design
Right now when generating the Poseidon parameters we have something like the following interfaces:
implLFSR{/// Generates a new `LFSR` random number generator with a seed derived from a Poseidon specification.fnnew(field_size:u32,width:u32,full_rounds:u32,partial_rounds:u32) -> Self{ ...}/// Samples a random field point using rejection sampling.fnsample_field_point(&mutself) -> F{ ...}}/// Generates the Poseidon hasher from its specification.fngenerate_hasher(field_size:u32,width:u32,full_rounds:u32,partial_rounds:u32) -> Hasher{// Generates a new LFSR from the Poseidon specification.let lfsr = LFSR::new(field_size, width, full_rounds, partial_rounds);// Generates the round constants using LFSR as the random field point sampler.let round_constants = generate_round_constants(lfsr);// Generates the MDS matrix using a Cauchy matrix over `(0..t) x (t..2t)`.let mds = generate_mds(width);// Initializes the Hasher parameters checking that they match the correct sizes.Self::new(round_constants, mds)}
The issue with this design is that we are very restricted in our ability to utilize other sampling methods or PRNGs for constructing these types. We want to be able to leverage the existing random sampling APIs available in Rust and manta-crypto.
New Design
For each type we have a structure that defines its own sampling methods.
/// Linear Feedback Shift Register Pseudo-Random Number GeneratorpubstructLinearFeedbackShiftRegister{ ... }implRngCoreforLinearFeedbackShiftRegister{ ... }implSeedableRngforLinearFeedbackShiftRegister{ ... }
and in the Poseidon module:
/// Generates the canonical LFSR for Poseidon constructed for the given [`Specification`].#[inline]pubfncanonical_sampling_rng<S>() -> LinearFeedbackShiftRegisterwhereS:Specification,S::ParamterField:BinarySize,{todo!("generate the canonical LFSR based on the specification")}
where BinarySize is a trait that tells us how many bits the field is made of (trait name not final).
Rejection Sampling Utilities
NB: The following must be defined in manta_crypto::rand.
/// Returns the first value from `sample` applied to `rng` that returns `Some`.#[inline]pubfnfind_sample<R,T,F>(rng:&mutR,mutsample:F) -> TwhereF:FnMut(&mutR) -> Option<T>,{loop{ifletSome(value) = sample(rng){return value;}}}/// Rejection Sampling Distribution/// /// This distribution uses [`find_sample`] to convert a [`TrySample`] sampling algorithm into/// a [`Sample`] one by performing rejection sampling.#[derive(Clone,Copy,Debug,Default,Eq,Hash,Ord,PartialEq,PartialOrd)]pubstructRejectionSampling<D = ()>(pubD);impl<D,T>Sample<RejectionSampling<D>>forTwhereD:Clone,T:TrySample<D>,{#[inline]fnsample<R>(distribution:RejectionSampling<D>,rng:&mutR) -> Self{find_sample(rng, |rng| Self::try_sample(distribution.0.clone(), rng).ok())}}
To plug these into the Poseidon parameter generation trait we just need to add the TrySample<()> implementation to the arkworks::Fp field object then just call the standard parameter generation as:
let hasher = canonical_sampling_rng::<S>().sample(HasherDistribution{additive_round_constants:RejectionSampling,maximum_distance_separable_matrix:CauchyMatrixGenerator{xs:(0..S::WIDTH),ys:(S::WIDTH..2*S::WIDTH)}});
The text was updated successfully, but these errors were encountered:
It might have some issues if we require the RNG for AdditiveRoundConstants to be CryptoRng, because LFSR itself is not necessarily a crypto RNG. Are we going to implement CryptoRng trait for LFSR anyway?
Or shall we modify Sample trait to release the CryptoRng constraint? @bhgomes
It might have some issues if we require the RNG for AdditiveRoundConstants to be CryptoRng, because LFSR itself is not necessarily a crypto RNG. Are we going to implement CryptoRng trait for LFSR anyway?
Or shall we modify Sample trait to release the CryptoRng constraint? @bhgomes
@tsunrise We can drop CryptoRng from the requirements on Sample. I figured this was going to happen eventually.
To improve the modularity and usefulness of the Poseidon Parameter Setup code, we want to separate the LFSR implementation from the field element sampling algorithm and the generation of the round constants and MDS matrix.
Old Design
Right now when generating the Poseidon parameters we have something like the following interfaces:
The issue with this design is that we are very restricted in our ability to utilize other sampling methods or PRNGs for constructing these types. We want to be able to leverage the existing random sampling APIs available in Rust and
manta-crypto
.New Design
For each type we have a structure that defines its own sampling methods.
Additive Round Constants
Maximum Distance Separable Matrix
Poseidon Hasher
Linear Feedback Shift Register PRNG
and in the Poseidon module:
where
BinarySize
is atrait
that tells us how many bits the field is made of (trait
name not final).Rejection Sampling Utilities
NB: The following must be defined in
manta_crypto::rand
.To plug these into the Poseidon parameter generation trait we just need to add the
TrySample<()>
implementation to thearkworks::Fp
field object then just call the standard parameter generation as:The text was updated successfully, but these errors were encountered: