shared_types/transcript/
keccak_transcript.rs1use itertools::Itertools;
2use sha3::{Digest, Keccak512};
3
4use crate::Field;
5
6use super::TranscriptSponge;
7
8#[derive(Clone, Debug, Default)]
9pub struct KeccakTranscript {
10 hasher: Keccak512,
11}
12
13impl<F> TranscriptSponge<F> for KeccakTranscript
14where
15 F: Field<Repr = [u8; 32]>,
16{
17 fn absorb(&mut self, elem: F) {
18 self.hasher.update(elem.to_repr())
19 }
20
21 fn absorb_elements(&mut self, elements: &[F]) {
22 let bytes = elements.iter().flat_map(F::to_repr).collect_vec();
23 self.hasher.update(&bytes)
24 }
25
26 fn squeeze(&mut self) -> F {
27 let out = self.hasher.finalize_reset();
28 self.hasher.update(out);
29
30 F::from_uniform_bytes(out.as_slice().try_into().unwrap())
31 }
32
33 fn squeeze_elements(&mut self, num_elements: usize) -> Vec<F> {
34 (0..num_elements)
35 .map(|_| {
36 let out = self.hasher.finalize_reset();
37 self.hasher.update(out);
38
39 F::from_uniform_bytes(out.as_slice().try_into().unwrap())
40 })
41 .collect_vec()
42 }
43
44 fn absorb_initialization_label(&mut self, label: &str) {
45 let label_as_bytes = label.as_bytes();
46 let label_as_field_elems = F::vec_from_bytes_le(label_as_bytes);
47 self.absorb_elements(&label_as_field_elems);
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use halo2curves::bn256::Fq;
54
55 use crate::transcript::{
56 ec_transcript::{ECTranscript, ECTranscriptTrait},
57 ProverTranscript,
58 };
59
60 use super::KeccakTranscript;
61
62 #[test]
63 fn test_keccak() {
64 let mut transcript =
65 ECTranscript::<halo2curves::bn256::G1, KeccakTranscript>::new("new transcript");
66 transcript.append("test2", Fq::one());
67 let one = halo2curves::bn256::G1::generator();
68 transcript.append_ec_point("ec_test", one);
69 let _: Fq = transcript.get_challenge("test_challenge_2");
70 }
71}