Skip to main content

tlsn/
lib.rs

1//! TLSNotary protocol implementation.
2//!
3//! This crate provides the core protocol for generating and verifying proofs
4//! of TLS sessions. A prover can demonstrate to a verifier that specific data
5//! was exchanged with a TLS server, without revealing the full transcript.
6//!
7//! # Overview
8//!
9//! The protocol involves two parties:
10//!
11//! - **Prover** ([`Prover`](prover::Prover)): connects to a TLS server and
12//!   generates proofs about the session.
13//! - **Verifier** ([`Verifier`](verifier::Verifier)): collaborates with the
14//!   prover during the TLS session and verifies the resulting proofs.
15//!
16//! Both parties communicate through an established [`Session`].
17//!
18//! # Workflow
19//!
20//! The protocol has two main phases:
21//!
22//! **Commitment**: The prover and verifier collaborate to construct a TLS
23//! transcript commitment from the prover's communication with a TLS server.
24//! This authenticates the transcript for the verifier, without the verifier
25//! learning the contents.
26//!
27//! **Selective Disclosure**: The prover selectively reveals portions of the
28//! committed transcript to the verifier, proving statements about the data
29//! exchanged with the server.
30//!
31//! ## Steps
32//!
33//! 1. Establish a communication channel between prover and verifier.
34//! 2. Create a [`Session`] on each side from the channel.
35//! 3. Create a [`Prover`](prover::Prover) or [`Verifier`](verifier::Verifier).
36//! 4. Run the commitment phase: the prover connects to the TLS server and
37//!    exchanges data to obtain a commitment to the TLS transcript.
38//! 5. (Optional) Perform selective disclosure: the prover provably reveals
39//!    selected data to the verifier.
40//!
41//! # Performance
42//!
43//! The MPC-TLS protocol is highly interactive: prover and verifier exchange
44//! many small messages, and each one is on the critical path. On such traffic,
45//! Nagle's algorithm — enabled by default on TCP sockets — coalesces small
46//! writes and waits for outstanding ACKs before sending, adding a round-trip's
47//! worth of delay to each exchange and significantly slowing the protocol.
48//!
49//! For this reason you should **disable Nagle's algorithm** by enabling
50//! `TCP_NODELAY` on every TCP socket you hand to this crate, namely:
51//!
52//! - the prover ↔ verifier channel passed to [`Session::new`];
53//! - the connection to the TLS server passed to
54//!   [`Prover::connect`](prover::Prover::connect) (MPC mode);
55//! - the connection to the TLS server passed to
56//!   [`Verifier::run`](verifier::Verifier::run) (proxy mode).
57//!
58//! With [`tokio`](https://docs.rs/tokio) this is done via
59//! [`TcpStream::set_nodelay`](https://docs.rs/tokio/latest/tokio/net/struct.TcpStream.html#method.set_nodelay):
60//!
61//! ```ignore
62//! let socket = tokio::net::TcpStream::connect(addr).await?;
63//! socket.set_nodelay(true)?;
64//! ```
65//!
66//! This setting has no effect on non-TCP transports (e.g. WebSocket relays or
67//! in-memory duplex streams).
68
69#![deny(missing_docs, unreachable_pub, unused_must_use)]
70#![deny(clippy::all)]
71#![forbid(unsafe_code)]
72
73mod deps;
74mod error;
75pub(crate) mod ghash;
76pub(crate) mod map;
77pub(crate) mod msg;
78pub mod prover;
79mod proxy;
80mod session;
81pub(crate) mod tag;
82pub(crate) mod transcript_internal;
83pub mod verifier;
84
85pub use error::Error;
86pub use rangeset;
87pub use session::{
88    Session, SessionConfig, SessionConfigBuilder, SessionConfigError, SessionDriver, SessionHandle,
89};
90pub use tlsn_attestation as attestation;
91pub use tlsn_core::{config, connection, hash, transcript, webpki};
92pub use tlsn_mux::Stream;
93
94/// Result type.
95pub type Result<T, E = Error> = core::result::Result<T, E>;
96
97use mpc_tls::SessionKeys;
98use semver::Version;
99use std::sync::LazyLock;
100use tlsn_core::{
101    config::tls_commit::{TlsCommitConfig, mpc::MpcTlsConfig, proxy::ProxyTlsConfig},
102    transcript::TlsTranscript,
103};
104
105// Package version.
106pub(crate) static VERSION: LazyLock<Version> = LazyLock::new(|| {
107    Version::parse(env!("CARGO_PKG_VERSION")).expect("cargo pkg version should be a valid semver")
108});
109
110// Prefix for the proxy stream id between prover and verifier.
111pub(crate) const PROXY_STREAM_PREFIX: &[u8] = b"proxy_stream";
112
113/// The party's role in the TLSN protocol.
114///
115/// A Notary is classified as a Verifier.
116#[derive(Debug, Clone, Copy, PartialEq, Eq)]
117pub(crate) enum Role {
118    /// The prover.
119    Prover,
120    /// The verifier.
121    Verifier,
122}
123
124/// Output of a TLS session.
125pub(crate) struct TlsOutput {
126    pub(crate) keys: SessionKeys,
127    pub(crate) tls_transcript: TlsTranscript,
128}
129
130/// Protocol variant.
131pub trait ProtocolConfig: Clone + Into<TlsCommitConfig> + sealed::Sealed {
132    /// TLS commitment protocol.
133    type Commit;
134}
135
136impl ProtocolConfig for MpcTlsConfig {
137    type Commit = Mpc;
138}
139
140impl ProtocolConfig for ProxyTlsConfig {
141    type Commit = Proxy;
142}
143
144/// MPC-TLS commitment protocol.
145#[derive(Debug)]
146pub struct Mpc {}
147
148/// Proxy-TLS commitment protocol.
149#[derive(Debug)]
150pub struct Proxy {}
151
152mod sealed {
153    pub trait Sealed {}
154
155    impl Sealed for super::MpcTlsConfig {}
156    impl Sealed for super::ProxyTlsConfig {}
157}