use ark_ec::{AffineRepr, CurveGroup, Group}; use ark_ff::PrimeField; use ark_serialize::CanonicalSerialize; use std::marker::PhantomData; use ark_r1cs_std::fields::fp::FpVar; use ark_crypto_primitives::sponge::poseidon::{ constraints::PoseidonSpongeVar, PoseidonConfig, PoseidonSponge, }; use ark_crypto_primitives::sponge::{ constraints::CryptographicSpongeVar, Absorb, CryptographicSponge, }; use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError}; use ark_poly::DenseUVPolynomial; pub struct Transcript where ::BaseField: Absorb, { // where F is the Constraint Field (eq. C::ScalarField) sponge: PoseidonSponge, _c: PhantomData, } impl Transcript where ::BaseField: Absorb, { pub fn new(poseidon_config: &PoseidonConfig) -> Self { let mut sponge = PoseidonSponge::::new(&poseidon_config); Transcript { sponge, _c: PhantomData, } } pub fn add(&mut self, v: &F) { self.sponge.absorb(&v); } pub fn add_vec(&mut self, v: &[F]) { self.sponge.absorb(&v); } pub fn add_point(&mut self, v: &C) { let v_affine = v.into_affine(); let xy = v_affine.xy().unwrap(); // WIP self.sponge.absorb(&vec![xy.0, xy.1]); } pub fn get_challenge(&mut self) -> F { let c = self.sponge.squeeze_field_elements(1); self.add(&c[0]); c[0] } pub fn get_challenge_vec(&mut self, n: usize) -> Vec { let c = self.sponge.squeeze_field_elements(n); self.sponge.absorb(&c); c } } pub struct TranscriptVar { // where F is the Constraint Field sponge: PoseidonSpongeVar, } impl TranscriptVar { pub fn new(cs: ConstraintSystemRef, poseidon_config: PoseidonConfig) -> Self { let mut sponge = PoseidonSpongeVar::::new(cs.clone(), &poseidon_config); Self { sponge } } pub fn add(&mut self, v: FpVar) -> Result<(), SynthesisError> { self.sponge.absorb(&v) } pub fn get_challenge(&mut self) -> Result, SynthesisError> { let c = self.sponge.squeeze_field_elements(1)?; self.sponge.absorb(&c[0]); Ok(c[0].clone()) } pub fn get_challenge_vec(&mut self, n: usize) -> Result>, SynthesisError> { let c = self.sponge.squeeze_field_elements(n)?; self.sponge.absorb(&c); Ok(c) } } use ark_crypto_primitives::sponge::poseidon::find_poseidon_ark_and_mds; // WARNING this is for test only pub fn poseidon_test_config() -> PoseidonConfig { let full_rounds = 8; let partial_rounds = 31; let alpha = 5; let rate = 2; let (ark, mds) = find_poseidon_ark_and_mds::( F::MODULUS_BIT_SIZE as u64, rate, full_rounds, partial_rounds, 0, ); PoseidonConfig::new( full_rounds as usize, partial_rounds as usize, alpha, mds, ark, rate, 1, ) } // #[cfg(test)] // mod tests { // use super::*; // use ark_mnt4_298::{Fr, G1Projective}; // scalar field // use ark_std::{One, Zero}; // // #[test] // fn test_poseidon() { // let config = poseidon_test_config::(); // let mut tr = Transcript::::new(&config); // tr.add(&Fr::one()); // println!("c {:?}", tr.get_challenge().to_string()); // } // }