arnaucube
arnaucube/nova-studyPublic Self-hosted repository
nova-study/src/transcript.rs
src/transcript.rsRaw
 1use ark_ff::PrimeField;
 2use ark_serialize::CanonicalSerialize;
 3use merlin::Transcript as MerlinTranscript;
 4use std::marker::PhantomData;
 5
 6// TODO poseidon transcript (not keccak)
 7
 8// This Transcript approach is a modified version from https://github.com/arkworks-rs/gemini ,
 9// using Merlin transcript (https://merlin.cool).
10pub struct Transcript<F: PrimeField> {
11    phantom: PhantomData<F>,
12    transcript: MerlinTranscript,
13}
14
15impl<F: PrimeField> Transcript<F> {
16    pub fn new() -> Self {
17        Self {
18            phantom: PhantomData::default(),
19            transcript: MerlinTranscript::new(b"transcript"),
20        }
21    }
22    pub fn add<S: CanonicalSerialize>(&mut self, label: &'static [u8], r: &S) {
23        let mut msg = Vec::new();
24        r.serialize_uncompressed(&mut msg).unwrap();
25        self.transcript.append_message(label, &msg);
26    }
27    pub fn get_challenge(&mut self, label: &'static [u8]) -> F {
28        let mut bytes = [0u8; 64];
29        self.transcript.challenge_bytes(label, &mut bytes);
30        let challenge = F::from_le_bytes_mod_order(bytes.as_ref());
31        self.add(b"get challenge", &challenge);
32        challenge
33    }
34    pub fn get_challenge_vec(&mut self, label: &'static [u8], n: usize) -> Vec<F> {
35        let mut c: Vec<F> = vec![F::zero(); n];
36        for i in 0..n {
37            c[i] = self.get_challenge(label);
38        }
39        c
40    }
41}