Skip to main content

primitives/transcripts/
protocol_transcript.rs

1use std::num::Wrapping;
2
3use crate::{
4    random::Seed,
5    transcripts::{AutoTranscript, FolkloreTranscript, Transcript},
6    types::{identifiers::ProtocolInfo, SessionId},
7};
8
9/// A transcript that appends a counter to each message. The counter starts at 0
10/// and increments by 1 with each appended message. This ensures that each message
11/// can be uniquely identified by its position in the transcript.
12#[derive(Debug, Clone)]
13pub struct ProtocolTranscript<T: Transcript = FolkloreTranscript> {
14    transcript: T,
15    counter: Wrapping<u64>,
16    protocol_info: &'static ProtocolInfo,
17}
18
19impl<T: Transcript> Transcript for ProtocolTranscript<T> {
20    type Rng = T::Rng;
21    fn new(protocol_info: &'static ProtocolInfo, session_id: &SessionId) -> Self {
22        Self {
23            transcript: T::new(protocol_info, session_id),
24            counter: Wrapping(0),
25            protocol_info,
26        }
27    }
28
29    fn append_with<Msg: AsRef<[u8]>>(&mut self, label: &'static [u8], msg: &Msg) {
30        let counter = self.next_label();
31        self.transcript
32            .append_many_with(label, &[counter.as_ref(), msg.as_ref()]);
33    }
34
35    fn append_many_with<Msg: AsRef<[u8]>>(&mut self, label: &'static [u8], messages: &[Msg]) {
36        let auto_label = self.next_label();
37        let messages: Vec<&[u8]> = std::iter::once(auto_label.as_ref())
38            .chain(messages.iter().map(AsRef::as_ref))
39            .collect();
40        self.transcript.append_many_with(label, &messages);
41    }
42
43    fn extract(&mut self, label: &'static [u8]) -> Seed {
44        self.transcript.extract(label)
45    }
46
47    fn extract_rng(&mut self, label: &'static [u8]) -> T::Rng {
48        self.transcript.extract_rng(label)
49    }
50}
51
52impl<T: Transcript> AutoTranscript for ProtocolTranscript<T> {
53    type Label = [u8; 8];
54
55    #[inline]
56    fn get_current_label(&self) -> Self::Label {
57        self.counter.0.to_le_bytes()
58    }
59
60    #[inline]
61    fn next_label(&mut self) -> Self::Label {
62        self.counter += Wrapping(1);
63        self.get_current_label()
64    }
65
66    #[inline]
67    fn append<Msg: AsRef<[u8]>>(&mut self, msg: &Msg) {
68        self.transcript.append_with(self.protocol_info.tag(), msg);
69    }
70
71    #[inline]
72    fn append_many<Msg: AsRef<[u8]>>(&mut self, msg: &[Msg]) {
73        self.transcript
74            .append_many_with(self.protocol_info.tag(), msg);
75    }
76}