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}