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//! The Prover may also request for extensions to be added to the attestation,
82//! see [here](crate::attestation#extensions) for more information.
83//!
84//! Upon being issued an attestation, the Prover will also hold a corresponding
85//! [`Secrets`] which contains all private information. This pair can be stored
86//! and used later to construct a
87//! [`Presentation`](crate::presentation::Presentation), [see
88//! below](#constructing-a-presentation).
89//!
90//! # Issuing an attestation
91//!
92//! Upon receiving a request, the Notary can issue an
93//! [`Attestation`](crate::attestation::Attestation) which can be configured
94//! using the associated
95//! [builder](crate::attestation::AttestationConfigBuilder).
96//!
97//! The Notary's [`CryptoProvider`] must be configured with an appropriate
98//! signing key for attestations. See
99//! [`SignerProvider`](crate::signing::SignerProvider) for more information.
100//!
101//! # Constructing a presentation
102//!
103//! A Prover can use an [`Attestation`](crate::attestation::Attestation) and the
104//! corresponding [`Secrets`] to construct a verifiable
105//! [`Presentation`](crate::presentation::Presentation).
106//!
107//! ```no_run
108//! # use tlsn_core::presentation::Presentation;
109//! # use tlsn_core::attestation::Attestation;
110//! # use tlsn_core::transcript::{TranscriptCommitmentKind, Direction};
111//! # use tlsn_core::{Secrets, CryptoProvider};
112//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
113//! # let attestation: Attestation = unimplemented!();
114//! # let secrets: Secrets = unimplemented!();
115//! # let crypto_provider: CryptoProvider = unimplemented!();
116//! let (_sent_len, recv_len) = secrets.transcript().len();
117//!
118//! // First, we decide which application data we would like to disclose.
119//! let mut builder = secrets.transcript_proof_builder();
120//!
121//! builder
122//!     // Use transcript encoding commitments.
123//!     .commitment_kinds(&[TranscriptCommitmentKind::Encoding])
124//!     // Disclose the first 10 bytes of the sent data.
125//!     .reveal(&(0..10), Direction::Sent)?
126//!     // Disclose all of the received data.
127//!     .reveal(&(0..recv_len), Direction::Received)?;
128//!
129//! let transcript_proof = builder.build()?;
130//!
131//! // Most cases we will also disclose the server identity.
132//! let identity_proof = secrets.identity_proof();
133//!
134//! // Now we can construct the presentation.
135//! let mut builder = attestation.presentation_builder(&crypto_provider);
136//!
137//! builder
138//!     .identity_proof(identity_proof)
139//!     .transcript_proof(transcript_proof);
140//!
141//! // Finally, we build the presentation. Send it to a verifier!
142//! let presentation: Presentation = builder.build()?;
143//! # Ok(())
144//! # }
145//! ```
146//!
147//! # Verifying a presentation
148//!
149//! Verifying a presentation is as simple as checking the verifier trusts the
150//! verifying key then calling
151//! [`Presentation::verify`](crate::presentation::Presentation::verify).
152//!
153//! ```no_run
154//! # use tlsn_core::presentation::{Presentation, PresentationOutput};
155//! # use tlsn_core::signing::VerifyingKey;
156//! # use tlsn_core::CryptoProvider;
157//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
158//! # let presentation: Presentation = unimplemented!();
159//! # let trusted_key: VerifyingKey = unimplemented!();
160//! # let crypto_provider: CryptoProvider = unimplemented!();
161//! // Assert that we trust the verifying key.
162//! assert_eq!(presentation.verifying_key(), &trusted_key);
163//!
164//! let PresentationOutput {
165//!     attestation,
166//!     server_name,
167//!     connection_info,
168//!     transcript,
169//!     ..
170//! } = presentation.verify(&crypto_provider)?;
171//! # Ok(())
172//! # }
173//! ```
174
175#![deny(missing_docs, unreachable_pub, unused_must_use)]
176#![deny(clippy::all)]
177#![forbid(unsafe_code)]
178
179pub mod attestation;
180pub mod connection;
181#[cfg(any(test, feature = "fixtures"))]
182pub mod fixtures;
183pub mod hash;
184pub(crate) mod index;
185pub(crate) mod merkle;
186pub mod presentation;
187mod provider;
188pub mod request;
189mod secrets;
190pub(crate) mod serialize;
191pub mod signing;
192pub mod transcript;
193
194pub use provider::CryptoProvider;
195pub use secrets::Secrets;