tlsn_core/lib.rs
1//! TLSNotary core library.
2//!
3//! # Introduction
4//!
5//! This library provides core functionality for the TLSNotary **attestation**
6//! protocol, including some more general types which are useful outside
7//! of attestations.
8//!
9//! Once the MPC-TLS protocol has been completed the Prover holds a collection
10//! of commitments pertaining to the TLS connection. Most importantly, the
11//! Prover is committed to the [`ServerName`](crate::connection::ServerName),
12//! and the [`Transcript`](crate::transcript::Transcript) of application data.
13//! Subsequently, the Prover can request an
14//! [`Attestation`](crate::attestation::Attestation) from the Notary who will
15//! include the commitments as well as any additional information which may be
16//! useful to an attestation Verifier.
17//!
18//! Holding an attestation, the Prover can construct a
19//! [`Presentation`](crate::presentation::Presentation) which facilitates
20//! selectively disclosing various aspects of the TLS connection to a Verifier.
21//! If the Verifier trusts the Notary, or more specifically the verifying key of
22//! the attestation, then the Verifier can trust the authenticity of the
23//! information disclosed in the presentation.
24//!
25//! **Be sure to check out the various submodules for more information.**
26//!
27//! # Committing to the transcript
28//!
29//! The MPC-TLS protocol produces commitments to the entire transcript of
30//! application data. However, we may want to disclose only a subset of the data
31//! in a presentation. Prior to attestation, the Prover has the opportunity to
32//! slice and dice the commitments into smaller sections which can be
33//! selectively disclosed. Additionally, the Prover may want to use different
34//! commitment schemes depending on the context they expect to disclose.
35//!
36//! The primary API for this process is the
37//! [`TranscriptCommitConfigBuilder`](crate::transcript::TranscriptCommitConfigBuilder)
38//! which is used to build up a configuration.
39//!
40//! Currently, only the
41//! [`Encoding`](crate::transcript::TranscriptCommitmentKind::Encoding)
42//! commitment kind is supported. In the future you will be able to acquire hash
43//! commitments directly to the transcript data.
44//!
45//! ```no_run
46//! # use tlsn_core::transcript::{TranscriptCommitConfigBuilder, Transcript, Direction};
47//! # use tlsn_core::hash::HashAlgId;
48//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
49//! # let transcript: Transcript = unimplemented!();
50//! let (sent_len, recv_len) = transcript.len();
51//!
52//! // Create a new configuration builder.
53//! let mut builder = TranscriptCommitConfigBuilder::new(&transcript);
54//!
55//! // Specify all the transcript commitments we want to make.
56//! builder
57//! // Use BLAKE3 for encoding commitments.
58//! .encoding_hash_alg(HashAlgId::BLAKE3)
59//! // Commit to all sent data.
60//! .commit_sent(&(0..sent_len))?
61//! // Commit to the first 10 bytes of sent data.
62//! .commit_sent(&(0..10))?
63//! // Skip some bytes so it can be omitted in the presentation.
64//! .commit_sent(&(20..sent_len))?
65//! // Commit to all received data.
66//! .commit_recv(&(0..recv_len))?;
67//!
68//! let config = builder.build()?;
69//! # Ok(())
70//! # }
71//! ```
72//!
73//! # Requesting an attestation
74//!
75//! The first step in the attestation protocol is for the Prover to make a
76//! [`Request`](crate::request::Request), which can be configured using the
77//! associated [builder](crate::request::RequestConfigBuilder). With it the
78//! Prover can configure some of the details of the attestation, such as which
79//! cryptographic algorithms are used (if the Notary supports them).
80//!
81//! Upon being issued an attestation, the Prover will also hold a corresponding
82//! [`Secrets`] which contains all private information. This pair can be stored
83//! and used later to construct a
84//! [`Presentation`](crate::presentation::Presentation), [see
85//! below](#constructing-a-presentation).
86//!
87//! # Issuing an attestation
88//!
89//! Upon receiving a request, the Notary can issue an
90//! [`Attestation`](crate::attestation::Attestation) which can be configured
91//! using the associated
92//! [builder](crate::attestation::AttestationConfigBuilder).
93//!
94//! The Notary's [`CryptoProvider`] must be configured with an appropriate
95//! signing key for attestations. See
96//! [`SignerProvider`](crate::signing::SignerProvider) for more information.
97//!
98//! # Constructing a presentation
99//!
100//! A Prover can use an [`Attestation`](crate::attestation::Attestation) and the
101//! corresponding [`Secrets`] to construct a verifiable
102//! [`Presentation`](crate::presentation::Presentation).
103//!
104//! ```no_run
105//! # use tlsn_core::presentation::Presentation;
106//! # use tlsn_core::attestation::Attestation;
107//! # use tlsn_core::transcript::{TranscriptCommitmentKind, Direction};
108//! # use tlsn_core::{Secrets, CryptoProvider};
109//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
110//! # let attestation: Attestation = unimplemented!();
111//! # let secrets: Secrets = unimplemented!();
112//! # let crypto_provider: CryptoProvider = unimplemented!();
113//! let (_sent_len, recv_len) = secrets.transcript().len();
114//!
115//! // First, we decide which application data we would like to disclose.
116//! let mut builder = secrets.transcript_proof_builder();
117//!
118//! builder
119//! // Use transcript encoding commitments.
120//! .commitment_kinds(&[TranscriptCommitmentKind::Encoding])
121//! // Disclose the first 10 bytes of the sent data.
122//! .reveal(&(0..10), Direction::Sent)?
123//! // Disclose all of the received data.
124//! .reveal(&(0..recv_len), Direction::Received)?;
125//!
126//! let transcript_proof = builder.build()?;
127//!
128//! // Most cases we will also disclose the server identity.
129//! let identity_proof = secrets.identity_proof();
130//!
131//! // Now we can construct the presentation.
132//! let mut builder = attestation.presentation_builder(&crypto_provider);
133//!
134//! builder
135//! .identity_proof(identity_proof)
136//! .transcript_proof(transcript_proof);
137//!
138//! // Finally, we build the presentation. Send it to a verifier!
139//! let presentation: Presentation = builder.build()?;
140//! # Ok(())
141//! # }
142//! ```
143//!
144//! # Verifying a presentation
145//!
146//! Verifying a presentation is as simple as checking the verifier trusts the
147//! verifying key then calling
148//! [`Presentation::verify`](crate::presentation::Presentation::verify).
149//!
150//! ```no_run
151//! # use tlsn_core::presentation::{Presentation, PresentationOutput};
152//! # use tlsn_core::signing::VerifyingKey;
153//! # use tlsn_core::CryptoProvider;
154//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
155//! # let presentation: Presentation = unimplemented!();
156//! # let trusted_key: VerifyingKey = unimplemented!();
157//! # let crypto_provider: CryptoProvider = unimplemented!();
158//! // Assert that we trust the verifying key.
159//! assert_eq!(presentation.verifying_key(), &trusted_key);
160//!
161//! let PresentationOutput {
162//! attestation,
163//! server_name,
164//! connection_info,
165//! transcript,
166//! ..
167//! } = presentation.verify(&crypto_provider)?;
168//! # Ok(())
169//! # }
170//! ```
171
172#![deny(missing_docs, unreachable_pub, unused_must_use)]
173#![deny(clippy::all)]
174#![forbid(unsafe_code)]
175
176pub mod attestation;
177pub mod connection;
178#[cfg(any(test, feature = "fixtures"))]
179pub mod fixtures;
180pub mod hash;
181pub(crate) mod index;
182pub(crate) mod merkle;
183pub mod presentation;
184mod provider;
185pub mod request;
186mod secrets;
187pub(crate) mod serialize;
188pub mod signing;
189pub mod transcript;
190
191pub use provider::CryptoProvider;
192pub use secrets::Secrets;