arnaucube
arnaucube/testudoPublic Self-hosted repository
testudo/src/poseidon_transcript.rs
src/poseidon_transcript.rsRaw
  1use crate::transcript::Transcript;
  2use ark_crypto_primitives::sponge::{
  3  poseidon::{PoseidonConfig, PoseidonSponge},
  4  Absorb, CryptographicSponge,
  5};
  6use ark_ec::{pairing::Pairing, CurveGroup};
  7use ark_ff::PrimeField;
  8use ark_serialize::CanonicalSerialize;
  9use ark_serialize::Compress;
 10#[derive(Clone)]
 11/// TODO
 12pub struct PoseidonTranscript<F: PrimeField> {
 13  sponge: PoseidonSponge<F>,
 14  params: PoseidonConfig<F>,
 15}
 16
 17impl<F: PrimeField> Transcript for PoseidonTranscript<F> {
 18  fn domain_sep(&mut self) {
 19    self.sponge.absorb(&b"testudo".to_vec());
 20  }
 21
 22  fn append<S: CanonicalSerialize>(&mut self, _label: &'static [u8], point: &S) {
 23    let mut buf = Vec::new();
 24    point
 25      .serialize_with_mode(&mut buf, Compress::Yes)
 26      .expect("serialization failed");
 27    self.sponge.absorb(&buf);
 28  }
 29
 30  fn challenge_scalar<FF: PrimeField>(&mut self, _label: &'static [u8]) -> FF {
 31    self.sponge.squeeze_field_elements(1).remove(0)
 32  }
 33}
 34
 35impl<F: PrimeField> PoseidonTranscript<F> {
 36  /// create a new transcript
 37  pub fn new(params: &PoseidonConfig<F>) -> Self {
 38    let sponge = PoseidonSponge::new(params);
 39    PoseidonTranscript {
 40      sponge,
 41      params: params.clone(),
 42    }
 43  }
 44}
 45
 46impl<F: PrimeField + Absorb> PoseidonTranscript<F> {
 47  pub fn new_from_state(&mut self, challenge: &F) {
 48    self.sponge = PoseidonSponge::new(&self.params.clone());
 49    self.append_scalar(b"", challenge);
 50  }
 51}
 52
 53impl<F: PrimeField> PoseidonTranscript<F> {
 54  pub fn append_u64(&mut self, _label: &'static [u8], x: u64) {
 55    self.sponge.absorb(&x);
 56  }
 57
 58  pub fn append_bytes(&mut self, _label: &'static [u8], x: &Vec<u8>) {
 59    self.sponge.absorb(x);
 60  }
 61
 62  pub fn append_scalar<T: PrimeField + Absorb>(&mut self, _label: &'static [u8], scalar: &T) {
 63    self.sponge.absorb(&scalar);
 64  }
 65
 66  pub fn append_point<G>(&mut self, _label: &'static [u8], point: &G)
 67  where
 68    G: CurveGroup,
 69  {
 70    let mut point_encoding = Vec::new();
 71    point
 72      .serialize_with_mode(&mut point_encoding, Compress::Yes)
 73      .unwrap();
 74    self.sponge.absorb(&point_encoding);
 75  }
 76
 77  pub fn append_scalar_vector<T: PrimeField + Absorb>(
 78    &mut self,
 79    _label: &'static [u8],
 80    scalars: &[T],
 81  ) {
 82    for scalar in scalars.iter() {
 83      self.append_scalar(b"", scalar);
 84    }
 85  }
 86
 87  pub fn append_gt<E>(&mut self, _label: &'static [u8], g_t: &E::TargetField)
 88  where
 89    E: Pairing,
 90  {
 91    let mut bytes = Vec::new();
 92    g_t.serialize_with_mode(&mut bytes, Compress::Yes).unwrap();
 93    self.append_bytes(b"", &bytes);
 94  }
 95}
 96
 97pub trait TranscriptWriter<F: PrimeField> {
 98  fn write_to_transcript(&self, transcript: &mut PoseidonTranscript<F>);
 99}
100
101#[cfg(test)]
102mod test {
103  use ark_bls12_381::Fr;
104  use ark_ff::PrimeField;
105  use poseidon_paramgen;
106  #[test]
107  fn poseidon_parameters_generation() {
108    print_modulus::<Fr>();
109    println!(
110      "{}",
111      poseidon_paramgen::poseidon_build::compile::<Fr>(128, vec![2], Fr::MODULUS, true)
112    );
113  }
114
115  fn print_modulus<F: PrimeField>() {
116    println!("modulus: {:?}", F::MODULUS);
117  }
118}