tlsn_core/config/
prove.rs

1//! Proving configuration.
2
3use rangeset::{RangeSet, ToRangeSet, UnionMut};
4use serde::{Deserialize, Serialize};
5
6use crate::transcript::{Direction, Transcript, TranscriptCommitConfig, TranscriptCommitRequest};
7
8/// Configuration to prove information to the verifier.
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct ProveConfig {
11    server_identity: bool,
12    reveal: Option<(RangeSet<usize>, RangeSet<usize>)>,
13    transcript_commit: Option<TranscriptCommitConfig>,
14}
15
16impl ProveConfig {
17    /// Creates a new builder.
18    pub fn builder(transcript: &Transcript) -> ProveConfigBuilder<'_> {
19        ProveConfigBuilder::new(transcript)
20    }
21
22    /// Returns `true` if the server identity is to be proven.
23    pub fn server_identity(&self) -> bool {
24        self.server_identity
25    }
26
27    /// Returns the sent and received ranges of the transcript to be revealed,
28    /// respectively.
29    pub fn reveal(&self) -> Option<&(RangeSet<usize>, RangeSet<usize>)> {
30        self.reveal.as_ref()
31    }
32
33    /// Returns the transcript commitment configuration.
34    pub fn transcript_commit(&self) -> Option<&TranscriptCommitConfig> {
35        self.transcript_commit.as_ref()
36    }
37
38    /// Returns a request.
39    pub fn to_request(&self) -> ProveRequest {
40        ProveRequest {
41            server_identity: self.server_identity,
42            reveal: self.reveal.clone(),
43            transcript_commit: self
44                .transcript_commit
45                .clone()
46                .map(|config| config.to_request()),
47        }
48    }
49}
50
51/// Builder for [`ProveConfig`].
52#[derive(Debug)]
53pub struct ProveConfigBuilder<'a> {
54    transcript: &'a Transcript,
55    server_identity: bool,
56    reveal: Option<(RangeSet<usize>, RangeSet<usize>)>,
57    transcript_commit: Option<TranscriptCommitConfig>,
58}
59
60impl<'a> ProveConfigBuilder<'a> {
61    /// Creates a new builder.
62    pub fn new(transcript: &'a Transcript) -> Self {
63        Self {
64            transcript,
65            server_identity: false,
66            reveal: None,
67            transcript_commit: None,
68        }
69    }
70
71    /// Proves the server identity.
72    pub fn server_identity(&mut self) -> &mut Self {
73        self.server_identity = true;
74        self
75    }
76
77    /// Configures transcript commitments.
78    pub fn transcript_commit(&mut self, transcript_commit: TranscriptCommitConfig) -> &mut Self {
79        self.transcript_commit = Some(transcript_commit);
80        self
81    }
82
83    /// Reveals the given ranges of the transcript.
84    pub fn reveal(
85        &mut self,
86        direction: Direction,
87        ranges: &dyn ToRangeSet<usize>,
88    ) -> Result<&mut Self, ProveConfigError> {
89        let idx = ranges.to_range_set();
90
91        if idx.end().unwrap_or(0) > self.transcript.len_of_direction(direction) {
92            return Err(ProveConfigError(ErrorRepr::IndexOutOfBounds {
93                direction,
94                actual: idx.end().unwrap_or(0),
95                len: self.transcript.len_of_direction(direction),
96            }));
97        }
98
99        let (sent, recv) = self.reveal.get_or_insert_default();
100        match direction {
101            Direction::Sent => sent.union_mut(&idx),
102            Direction::Received => recv.union_mut(&idx),
103        }
104
105        Ok(self)
106    }
107
108    /// Reveals the given ranges of the sent data transcript.
109    pub fn reveal_sent(
110        &mut self,
111        ranges: &dyn ToRangeSet<usize>,
112    ) -> Result<&mut Self, ProveConfigError> {
113        self.reveal(Direction::Sent, ranges)
114    }
115
116    /// Reveals all of the sent data transcript.
117    pub fn reveal_sent_all(&mut self) -> Result<&mut Self, ProveConfigError> {
118        let len = self.transcript.len_of_direction(Direction::Sent);
119        let (sent, _) = self.reveal.get_or_insert_default();
120        sent.union_mut(&(0..len));
121        Ok(self)
122    }
123
124    /// Reveals the given ranges of the received data transcript.
125    pub fn reveal_recv(
126        &mut self,
127        ranges: &dyn ToRangeSet<usize>,
128    ) -> Result<&mut Self, ProveConfigError> {
129        self.reveal(Direction::Received, ranges)
130    }
131
132    /// Reveals all of the received data transcript.
133    pub fn reveal_recv_all(&mut self) -> Result<&mut Self, ProveConfigError> {
134        let len = self.transcript.len_of_direction(Direction::Received);
135        let (_, recv) = self.reveal.get_or_insert_default();
136        recv.union_mut(&(0..len));
137        Ok(self)
138    }
139
140    /// Builds the configuration.
141    pub fn build(self) -> Result<ProveConfig, ProveConfigError> {
142        Ok(ProveConfig {
143            server_identity: self.server_identity,
144            reveal: self.reveal,
145            transcript_commit: self.transcript_commit,
146        })
147    }
148}
149
150/// Request to prove statements about the connection.
151#[derive(Debug, Clone, Serialize, Deserialize)]
152pub struct ProveRequest {
153    server_identity: bool,
154    reveal: Option<(RangeSet<usize>, RangeSet<usize>)>,
155    transcript_commit: Option<TranscriptCommitRequest>,
156}
157
158impl ProveRequest {
159    /// Returns `true` if the server identity is to be proven.
160    pub fn server_identity(&self) -> bool {
161        self.server_identity
162    }
163
164    /// Returns the sent and received ranges of the transcript to be revealed,
165    /// respectively.
166    pub fn reveal(&self) -> Option<&(RangeSet<usize>, RangeSet<usize>)> {
167        self.reveal.as_ref()
168    }
169
170    /// Returns the transcript commitment configuration.
171    pub fn transcript_commit(&self) -> Option<&TranscriptCommitRequest> {
172        self.transcript_commit.as_ref()
173    }
174}
175
176/// Error for [`ProveConfig`].
177#[derive(Debug, thiserror::Error)]
178#[error(transparent)]
179pub struct ProveConfigError(#[from] ErrorRepr);
180
181#[derive(Debug, thiserror::Error)]
182enum ErrorRepr {
183    #[error("range is out of bounds of the transcript ({direction}): {actual} > {len}")]
184    IndexOutOfBounds {
185        direction: Direction,
186        actual: usize,
187        len: usize,
188    },
189}