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        Direction, PartialTranscript, Transcript, TranscriptCommitConfig, TranscriptCommitRequest,
24        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 the given ranges of the received data transcript.
126    pub fn reveal_recv(
127        &mut self,
128        ranges: &dyn ToRangeSet<usize>,
129    ) -> Result<&mut Self, ProveConfigBuilderError> {
130        self.reveal(Direction::Received, ranges)
131    }
132
133    /// Builds the configuration.
134    pub fn build(self) -> Result<ProveConfig, ProveConfigBuilderError> {
135        Ok(ProveConfig {
136            server_identity: self.server_identity,
137            reveal: self.reveal,
138            transcript_commit: self.transcript_commit,
139        })
140    }
141}
142
143/// Error for [`ProveConfigBuilder`].
144#[derive(Debug, thiserror::Error)]
145#[error(transparent)]
146pub struct ProveConfigBuilderError(#[from] ProveConfigBuilderErrorRepr);
147
148#[derive(Debug, thiserror::Error)]
149enum ProveConfigBuilderErrorRepr {
150    #[error("range is out of bounds of the transcript ({direction}): {actual} > {len}")]
151    IndexOutOfBounds {
152        direction: Direction,
153        actual: usize,
154        len: usize,
155    },
156}
157
158/// Configuration to verify information from the prover.
159#[derive(Debug, Default, Clone, Serialize, Deserialize)]
160pub struct VerifyConfig {}
161
162impl VerifyConfig {
163    /// Creates a new builder.
164    pub fn builder() -> VerifyConfigBuilder {
165        VerifyConfigBuilder::new()
166    }
167}
168
169/// Builder for [`VerifyConfig`].
170#[derive(Debug, Default)]
171pub struct VerifyConfigBuilder {}
172
173impl VerifyConfigBuilder {
174    /// Creates a new builder.
175    pub fn new() -> Self {
176        Self {}
177    }
178
179    /// Builds the configuration.
180    pub fn build(self) -> Result<VerifyConfig, VerifyConfigBuilderError> {
181        Ok(VerifyConfig {})
182    }
183}
184
185/// Error for [`VerifyConfigBuilder`].
186#[derive(Debug, thiserror::Error)]
187#[error(transparent)]
188pub struct VerifyConfigBuilderError(#[from] VerifyConfigBuilderErrorRepr);
189
190#[derive(Debug, thiserror::Error)]
191enum VerifyConfigBuilderErrorRepr {}
192
193/// Payload sent to the verifier.
194#[doc(hidden)]
195#[derive(Debug, Serialize, Deserialize)]
196pub struct ProvePayload {
197    /// Handshake data.
198    pub handshake: Option<(ServerName, HandshakeData)>,
199    /// Transcript data.
200    pub transcript: Option<PartialTranscript>,
201    /// Transcript commitment configuration.
202    pub transcript_commit: Option<TranscriptCommitRequest>,
203}
204
205/// Prover output.
206#[derive(Serialize, Deserialize)]
207pub struct ProverOutput {
208    /// Transcript commitments.
209    pub transcript_commitments: Vec<TranscriptCommitment>,
210    /// Transcript commitment secrets.
211    pub transcript_secrets: Vec<TranscriptSecret>,
212}
213
214opaque_debug::implement!(ProverOutput);
215
216/// Verifier output.
217#[derive(Serialize, Deserialize)]
218pub struct VerifierOutput {
219    /// Server identity.
220    pub server_name: Option<ServerName>,
221    /// Transcript data.
222    pub transcript: Option<PartialTranscript>,
223    /// Transcript commitments.
224    pub transcript_commitments: Vec<TranscriptCommitment>,
225}
226
227opaque_debug::implement!(VerifierOutput);