Skip to main content

primitives/transcripts/
merlin.rs

1pub use merlin::Transcript as MerlinTranscript;
2use rand::SeedableRng;
3
4use super::Transcript;
5use crate::{
6    hashing::flatten_slices,
7    random::{BaseRng, Seed},
8    types::{identifiers::ProtocolInfo, SessionId},
9};
10
11impl Transcript for MerlinTranscript {
12    type Rng = merlin::TranscriptRng;
13
14    fn new(protocol_info: &'static ProtocolInfo, session_id: &SessionId) -> Self {
15        let mut t = merlin::Transcript::new(protocol_info.name().as_bytes());
16        t.append_message(b"session_id", session_id.as_ref());
17        t
18    }
19
20    fn append_with<T: AsRef<[u8]>>(&mut self, label: &'static [u8], message: &T) {
21        self.append_message(label, message.as_ref());
22    }
23
24    fn append_many_with<T: AsRef<[u8]>>(&mut self, label: &'static [u8], values: &[T]) {
25        let concatenated = flatten_slices(values);
26        self.append_message(label, &concatenated);
27    }
28
29    fn extract(&mut self, label: &'static [u8]) -> Seed {
30        let mut seed = Seed::default();
31        self.challenge_bytes(label, seed.as_mut());
32        seed
33    }
34
35    fn extract_rng(&mut self, label: &'static [u8]) -> Self::Rng {
36        let seed = self.extract(label);
37        self.build_rng().finalize(&mut BaseRng::from_seed(seed))
38    }
39}