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;
14
15use rangeset::ToRangeSet;
16use serde::{Deserialize, Serialize};
17
18use crate::{
19    connection::{HandshakeData, ServerName},
20    transcript::{
21        Direction, Idx, PartialTranscript, Transcript, TranscriptCommitConfig,
22        TranscriptCommitRequest, TranscriptCommitment, TranscriptSecret,
23    },
24};
25
26/// Configuration to prove information to the verifier.
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct ProveConfig {
29    server_identity: bool,
30    transcript: Option<PartialTranscript>,
31    transcript_commit: Option<TranscriptCommitConfig>,
32}
33
34impl ProveConfig {
35    /// Creates a new builder.
36    pub fn builder(transcript: &Transcript) -> ProveConfigBuilder<'_> {
37        ProveConfigBuilder::new(transcript)
38    }
39
40    /// Returns `true` if the server identity is to be proven.
41    pub fn server_identity(&self) -> bool {
42        self.server_identity
43    }
44
45    /// Returns the transcript to be proven.
46    pub fn transcript(&self) -> Option<&PartialTranscript> {
47        self.transcript.as_ref()
48    }
49
50    /// Returns the transcript commitment configuration.
51    pub fn transcript_commit(&self) -> Option<&TranscriptCommitConfig> {
52        self.transcript_commit.as_ref()
53    }
54}
55
56/// Builder for [`ProveConfig`].
57#[derive(Debug)]
58pub struct ProveConfigBuilder<'a> {
59    transcript: &'a Transcript,
60    server_identity: bool,
61    reveal_sent: Idx,
62    reveal_recv: Idx,
63    transcript_commit: Option<TranscriptCommitConfig>,
64}
65
66impl<'a> ProveConfigBuilder<'a> {
67    /// Creates a new builder.
68    pub fn new(transcript: &'a Transcript) -> Self {
69        Self {
70            transcript,
71            server_identity: false,
72            reveal_sent: Idx::default(),
73            reveal_recv: Idx::default(),
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 = Idx::new(ranges.to_range_set());
97
98        if idx.end() > self.transcript.len_of_direction(direction) {
99            return Err(ProveConfigBuilderError(
100                ProveConfigBuilderErrorRepr::IndexOutOfBounds {
101                    direction,
102                    actual: idx.end(),
103                    len: self.transcript.len_of_direction(direction),
104                },
105            ));
106        }
107
108        match direction {
109            Direction::Sent => self.reveal_sent.union_mut(&idx),
110            Direction::Received => self.reveal_recv.union_mut(&idx),
111        }
112        Ok(self)
113    }
114
115    /// Reveals the given ranges of the sent data transcript.
116    pub fn reveal_sent(
117        &mut self,
118        ranges: &dyn ToRangeSet<usize>,
119    ) -> Result<&mut Self, ProveConfigBuilderError> {
120        self.reveal(Direction::Sent, ranges)
121    }
122
123    /// Reveals the given ranges of the received data transcript.
124    pub fn reveal_recv(
125        &mut self,
126        ranges: &dyn ToRangeSet<usize>,
127    ) -> Result<&mut Self, ProveConfigBuilderError> {
128        self.reveal(Direction::Received, ranges)
129    }
130
131    /// Builds the configuration.
132    pub fn build(self) -> Result<ProveConfig, ProveConfigBuilderError> {
133        let transcript = if !self.reveal_sent.is_empty() || !self.reveal_recv.is_empty() {
134            Some(
135                self.transcript
136                    .to_partial(self.reveal_sent, self.reveal_recv),
137            )
138        } else {
139            None
140        };
141
142        Ok(ProveConfig {
143            server_identity: self.server_identity,
144            transcript,
145            transcript_commit: self.transcript_commit,
146        })
147    }
148}
149
150/// Error for [`ProveConfigBuilder`].
151#[derive(Debug, thiserror::Error)]
152#[error(transparent)]
153pub struct ProveConfigBuilderError(#[from] ProveConfigBuilderErrorRepr);
154
155#[derive(Debug, thiserror::Error)]
156enum ProveConfigBuilderErrorRepr {
157    #[error("range is out of bounds of the transcript ({direction}): {actual} > {len}")]
158    IndexOutOfBounds {
159        direction: Direction,
160        actual: usize,
161        len: usize,
162    },
163}
164
165/// Configuration to verify information from the prover.
166#[derive(Debug, Default, Clone, Serialize, Deserialize)]
167pub struct VerifyConfig {}
168
169impl VerifyConfig {
170    /// Creates a new builder.
171    pub fn builder() -> VerifyConfigBuilder {
172        VerifyConfigBuilder::new()
173    }
174}
175
176/// Builder for [`VerifyConfig`].
177#[derive(Debug, Default)]
178pub struct VerifyConfigBuilder {}
179
180impl VerifyConfigBuilder {
181    /// Creates a new builder.
182    pub fn new() -> Self {
183        Self {}
184    }
185
186    /// Builds the configuration.
187    pub fn build(self) -> Result<VerifyConfig, VerifyConfigBuilderError> {
188        Ok(VerifyConfig {})
189    }
190}
191
192/// Error for [`VerifyConfigBuilder`].
193#[derive(Debug, thiserror::Error)]
194#[error(transparent)]
195pub struct VerifyConfigBuilderError(#[from] VerifyConfigBuilderErrorRepr);
196
197#[derive(Debug, thiserror::Error)]
198enum VerifyConfigBuilderErrorRepr {}
199
200/// Payload sent to the verifier.
201#[doc(hidden)]
202#[derive(Debug, Serialize, Deserialize)]
203pub struct ProvePayload {
204    /// Handshake data.
205    pub handshake: Option<(ServerName, HandshakeData)>,
206    /// Transcript data.
207    pub transcript: Option<PartialTranscript>,
208    /// Transcript commitment configuration.
209    pub transcript_commit: Option<TranscriptCommitRequest>,
210}
211
212/// Prover output.
213#[derive(Serialize, Deserialize)]
214pub struct ProverOutput {
215    /// Transcript commitments.
216    pub transcript_commitments: Vec<TranscriptCommitment>,
217    /// Transcript commitment secrets.
218    pub transcript_secrets: Vec<TranscriptSecret>,
219}
220
221opaque_debug::implement!(ProverOutput);
222
223/// Verifier output.
224#[derive(Serialize, Deserialize)]
225pub struct VerifierOutput {
226    /// Server identity.
227    pub server_name: Option<ServerName>,
228    /// Transcript data.
229    pub transcript: Option<PartialTranscript>,
230    /// Transcript commitments.
231    pub transcript_commitments: Vec<TranscriptCommitment>,
232}
233
234opaque_debug::implement!(VerifierOutput);