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