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