tlsn_core/
lib.rs

1//! TLSNotary core library.
2
3#![deny(missing_docs, unreachable_pub, unused_must_use)]
4#![deny(clippy::all)]
5#![forbid(unsafe_code)]
6
7pub mod connection;
8#[cfg(any(test, feature = "fixtures"))]
9pub mod fixtures;
10pub mod hash;
11pub mod merkle;
12pub mod transcript;
13pub mod webpki;
14pub use rangeset;
15pub(crate) mod display;
16
17use rangeset::{RangeSet, ToRangeSet, UnionMut};
18use serde::{Deserialize, Serialize};
19
20use crate::{
21    connection::{HandshakeData, ServerName},
22    transcript::{
23        encoding::EncoderSecret, Direction, PartialTranscript, Transcript, TranscriptCommitConfig,
24        TranscriptCommitRequest, TranscriptCommitment, TranscriptSecret,
25    },
26};
27
28/// Configuration to prove information to the verifier.
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct ProveConfig {
31    server_identity: bool,
32    reveal: Option<(RangeSet<usize>, RangeSet<usize>)>,
33    transcript_commit: Option<TranscriptCommitConfig>,
34}
35
36impl ProveConfig {
37    /// Creates a new builder.
38    pub fn builder(transcript: &Transcript) -> ProveConfigBuilder<'_> {
39        ProveConfigBuilder::new(transcript)
40    }
41
42    /// Returns `true` if the server identity is to be proven.
43    pub fn server_identity(&self) -> bool {
44        self.server_identity
45    }
46
47    /// Returns the ranges of the transcript to be revealed.
48    pub fn reveal(&self) -> Option<&(RangeSet<usize>, RangeSet<usize>)> {
49        self.reveal.as_ref()
50    }
51
52    /// Returns the transcript commitment configuration.
53    pub fn transcript_commit(&self) -> Option<&TranscriptCommitConfig> {
54        self.transcript_commit.as_ref()
55    }
56}
57
58/// Builder for [`ProveConfig`].
59#[derive(Debug)]
60pub struct ProveConfigBuilder<'a> {
61    transcript: &'a Transcript,
62    server_identity: bool,
63    reveal: Option<(RangeSet<usize>, RangeSet<usize>)>,
64    transcript_commit: Option<TranscriptCommitConfig>,
65}
66
67impl<'a> ProveConfigBuilder<'a> {
68    /// Creates a new builder.
69    pub fn new(transcript: &'a Transcript) -> Self {
70        Self {
71            transcript,
72            server_identity: false,
73            reveal: None,
74            transcript_commit: None,
75        }
76    }
77
78    /// Proves the server identity.
79    pub fn server_identity(&mut self) -> &mut Self {
80        self.server_identity = true;
81        self
82    }
83
84    /// Configures transcript commitments.
85    pub fn transcript_commit(&mut self, transcript_commit: TranscriptCommitConfig) -> &mut Self {
86        self.transcript_commit = Some(transcript_commit);
87        self
88    }
89
90    /// Reveals the given ranges of the transcript.
91    pub fn reveal(
92        &mut self,
93        direction: Direction,
94        ranges: &dyn ToRangeSet<usize>,
95    ) -> Result<&mut Self, ProveConfigBuilderError> {
96        let idx = ranges.to_range_set();
97
98        if idx.end().unwrap_or(0) > self.transcript.len_of_direction(direction) {
99            return Err(ProveConfigBuilderError(
100                ProveConfigBuilderErrorRepr::IndexOutOfBounds {
101                    direction,
102                    actual: idx.end().unwrap_or(0),
103                    len: self.transcript.len_of_direction(direction),
104                },
105            ));
106        }
107
108        let (sent, recv) = self.reveal.get_or_insert_default();
109        match direction {
110            Direction::Sent => sent.union_mut(&idx),
111            Direction::Received => recv.union_mut(&idx),
112        }
113
114        Ok(self)
115    }
116
117    /// Reveals the given ranges of the sent data transcript.
118    pub fn reveal_sent(
119        &mut self,
120        ranges: &dyn ToRangeSet<usize>,
121    ) -> Result<&mut Self, ProveConfigBuilderError> {
122        self.reveal(Direction::Sent, ranges)
123    }
124
125    /// Reveals all of the sent data transcript.
126    pub fn reveal_sent_all(&mut self) -> Result<&mut Self, ProveConfigBuilderError> {
127        let len = self.transcript.len_of_direction(Direction::Sent);
128        let (sent, _) = self.reveal.get_or_insert_default();
129        sent.union_mut(&(0..len));
130        Ok(self)
131    }
132
133    /// Reveals the given ranges of the received data transcript.
134    pub fn reveal_recv(
135        &mut self,
136        ranges: &dyn ToRangeSet<usize>,
137    ) -> Result<&mut Self, ProveConfigBuilderError> {
138        self.reveal(Direction::Received, ranges)
139    }
140
141    /// Reveals all of the received data transcript.
142    pub fn reveal_recv_all(&mut self) -> Result<&mut Self, ProveConfigBuilderError> {
143        let len = self.transcript.len_of_direction(Direction::Received);
144        let (_, recv) = self.reveal.get_or_insert_default();
145        recv.union_mut(&(0..len));
146        Ok(self)
147    }
148
149    /// Builds the configuration.
150    pub fn build(self) -> Result<ProveConfig, ProveConfigBuilderError> {
151        Ok(ProveConfig {
152            server_identity: self.server_identity,
153            reveal: self.reveal,
154            transcript_commit: self.transcript_commit,
155        })
156    }
157}
158
159/// Error for [`ProveConfigBuilder`].
160#[derive(Debug, thiserror::Error)]
161#[error(transparent)]
162pub struct ProveConfigBuilderError(#[from] ProveConfigBuilderErrorRepr);
163
164#[derive(Debug, thiserror::Error)]
165enum ProveConfigBuilderErrorRepr {
166    #[error("range is out of bounds of the transcript ({direction}): {actual} > {len}")]
167    IndexOutOfBounds {
168        direction: Direction,
169        actual: usize,
170        len: usize,
171    },
172}
173
174/// Configuration to verify information from the prover.
175#[derive(Debug, Default, Clone, Serialize, Deserialize)]
176pub struct VerifyConfig {}
177
178impl VerifyConfig {
179    /// Creates a new builder.
180    pub fn builder() -> VerifyConfigBuilder {
181        VerifyConfigBuilder::new()
182    }
183}
184
185/// Builder for [`VerifyConfig`].
186#[derive(Debug, Default)]
187pub struct VerifyConfigBuilder {}
188
189impl VerifyConfigBuilder {
190    /// Creates a new builder.
191    pub fn new() -> Self {
192        Self {}
193    }
194
195    /// Builds the configuration.
196    pub fn build(self) -> Result<VerifyConfig, VerifyConfigBuilderError> {
197        Ok(VerifyConfig {})
198    }
199}
200
201/// Error for [`VerifyConfigBuilder`].
202#[derive(Debug, thiserror::Error)]
203#[error(transparent)]
204pub struct VerifyConfigBuilderError(#[from] VerifyConfigBuilderErrorRepr);
205
206#[derive(Debug, thiserror::Error)]
207enum VerifyConfigBuilderErrorRepr {}
208
209/// Request to prove statements about the connection.
210#[doc(hidden)]
211#[derive(Debug, Serialize, Deserialize)]
212pub struct ProveRequest {
213    /// Handshake data.
214    pub handshake: Option<(ServerName, HandshakeData)>,
215    /// Transcript data.
216    pub transcript: Option<PartialTranscript>,
217    /// Transcript commitment configuration.
218    pub transcript_commit: Option<TranscriptCommitRequest>,
219}
220
221/// Prover output.
222#[derive(Serialize, Deserialize)]
223pub struct ProverOutput {
224    /// Transcript commitments.
225    pub transcript_commitments: Vec<TranscriptCommitment>,
226    /// Transcript commitment secrets.
227    pub transcript_secrets: Vec<TranscriptSecret>,
228}
229
230opaque_debug::implement!(ProverOutput);
231
232/// Verifier output.
233#[derive(Serialize, Deserialize)]
234pub struct VerifierOutput {
235    /// Server identity.
236    pub server_name: Option<ServerName>,
237    /// Transcript data.
238    pub transcript: Option<PartialTranscript>,
239    /// Encoding commitment secret.
240    pub encoder_secret: Option<EncoderSecret>,
241    /// Transcript commitments.
242    pub transcript_commitments: Vec<TranscriptCommitment>,
243}
244
245opaque_debug::implement!(VerifierOutput);