Crate tlsn_core

source
Expand description

TLSNotary core library.

§Introduction

This library provides core functionality for the TLSNotary attestation protocol, including some more general types which are useful outside of attestations.

Once the MPC-TLS protocol has been completed the Prover holds a collection of commitments pertaining to the TLS connection. Most importantly, the Prover is committed to the ServerName, and the Transcript of application data. Subsequently, the Prover can request an Attestation from the Notary who will include the commitments as well as any additional information which may be useful to an attestation Verifier.

Holding an attestation, the Prover can construct a Presentation which facilitates selectively disclosing various aspects of the TLS connection to a Verifier. If the Verifier trusts the Notary, or more specifically the verifying key of the attestation, then the Verifier can trust the authenticity of the information disclosed in the presentation.

Be sure to check out the various submodules for more information.

§Committing to the transcript

The MPC-TLS protocol produces commitments to the entire transcript of application data. However, we may want to disclose only a subset of the data in a presentation. Prior to attestation, the Prover has the opportunity to slice and dice the commitments into smaller sections which can be selectively disclosed. Additionally, the Prover may want to use different commitment schemes depending on the context they expect to disclose.

The primary API for this process is the TranscriptCommitConfigBuilder which is used to build up a configuration.

Currently, only the Encoding commitment kind is supported. In the future you will be able to acquire hash commitments directly to the transcript data.

let (sent_len, recv_len) = transcript.len();

// Create a new configuration builder.
let mut builder = TranscriptCommitConfigBuilder::new(&transcript);

// Specify all the transcript commitments we want to make.
builder
    // Use BLAKE3 for encoding commitments.
    .encoding_hash_alg(HashAlgId::BLAKE3)
    // Commit to all sent data.
    .commit_sent(&(0..sent_len))?
    // Commit to the first 10 bytes of sent data.
    .commit_sent(&(0..10))?
    // Skip some bytes so it can be omitted in the presentation.
    .commit_sent(&(20..sent_len))?
    // Commit to all received data.
    .commit_recv(&(0..recv_len))?;

let config = builder.build()?;

§Requesting an attestation

The first step in the attestation protocol is for the Prover to make a Request, which can be configured using the associated builder. With it the Prover can configure some of the details of the attestation, such as which cryptographic algorithms are used (if the Notary supports them).

Upon being issued an attestation, the Prover will also hold a corresponding Secrets which contains all private information. This pair can be stored and used later to construct a Presentation, see below.

§Issuing an attestation

Upon receiving a request, the Notary can issue an Attestation which can be configured using the associated builder.

The Notary’s CryptoProvider must be configured with an appropriate signing key for attestations. See SignerProvider for more information.

§Constructing a presentation

A Prover can use an Attestation and the corresponding Secrets to construct a verifiable Presentation.

let (_sent_len, recv_len) = secrets.transcript().len();

// First, we decide which application data we would like to disclose.
let mut builder = secrets.transcript_proof_builder();

builder
    // Use transcript encoding commitments.
    .default_kind(TranscriptCommitmentKind::Encoding)
    // Disclose the first 10 bytes of the sent data.
    .reveal(&(0..10), Direction::Sent)?
    // Disclose all of the received data.
    .reveal(&(0..recv_len), Direction::Received)?;

let transcript_proof = builder.build()?;

// Most cases we will also disclose the server identity.
let identity_proof = secrets.identity_proof();

// Now we can construct the presentation.
let mut builder = attestation.presentation_builder(&crypto_provider);

builder
    .identity_proof(identity_proof)
    .transcript_proof(transcript_proof);

// Finally, we build the presentation. Send it to a verifier!
let presentation: Presentation = builder.build()?;

§Verifying a presentation

Verifying a presentation is as simple as checking the verifier trusts the verifying key then calling Presentation::verify.

// Assert that we trust the verifying key.
assert_eq!(presentation.verifying_key(), &trusted_key);

let PresentationOutput {
    attestation,
    server_name,
    connection_info,
    transcript,
    ..
} = presentation.verify(&crypto_provider)?;

Modules§

Structs§