Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into alpha7-examples
Browse files Browse the repository at this point in the history
  • Loading branch information
heeckhau committed Oct 1, 2024
2 parents 29ab74a + 7de49c8 commit 293ea1c
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 15 deletions.
28 changes: 15 additions & 13 deletions crates/core/src/attestation.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
//! Attestation types.
//!
//! An attestation is a cryptographically signed document from a Notary who
//! An attestation is a cryptographically signed document issued by a Notary who
//! witnessed a TLS connection. It contains various fields which can be used to
//! verify statements about the connection and the associated application data.
//!
//! Attestations contain a header and a body. The header is signed by a Notary
//! and it contains a merkle root of the body fields. This allows a Prover to
//! disclose only necessary fields to a Verifier depending on the statements
//! being made.
//! Attestations are comprised of two parts: a [`Header`] and a [`Body`].
//!
//! The header is the data structure which is signed by a Notary. It
//! contains a unique identifier, the protocol version, and a Merkle root
//! of the body fields.
//!
//! The body contains the fields of the attestation. These fields include data
//! which can be used to verify aspects of a TLS connection, such as the
//! server's identity, and facts about the transcript.

mod builder;
mod config;
Expand All @@ -30,7 +35,7 @@ use crate::{
};

pub use builder::{AttestationBuilder, AttestationBuilderError};
pub use config::AttestationConfig;
pub use config::{AttestationConfig, AttestationConfigBuilder, AttestationConfigError};
pub use proof::{AttestationError, AttestationProof};

/// Current version of attestations.
Expand Down Expand Up @@ -106,9 +111,7 @@ pub enum FieldKind {

/// Attestation header.
///
/// A header is the data structure which is signed by the Notary. It contains
/// a unique identifier, the protocol version, and a Merkle root of the
/// attestation fields.
/// See [module level documentation](crate::attestation) for more information.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Header {
/// An identifier for the attestation.
Expand All @@ -123,10 +126,7 @@ impl_domain_separator!(Header);

/// Attestation body.
///
/// An attestation contains a set of fields which are cryptographically signed
/// by a Notary via a [`Header`]. These fields include data which can be
/// used to verify aspects of a TLS connection, such as the server's identity,
/// and facts about the transcript.
/// See [module level documentation](crate::attestation) for more information.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Body {
verifying_key: Field<VerifyingKey>,
Expand Down Expand Up @@ -231,6 +231,8 @@ impl Body {
}

/// An attestation.
///
/// See [module level documentation](crate::attestation) for more information.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Attestation {
/// The signature of the attestation.
Expand Down
1 change: 1 addition & 0 deletions crates/core/src/attestation/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ impl std::fmt::Display for ErrorKind {
}
}

/// Error for [`AttestationConfig`].
#[derive(Debug, thiserror::Error)]
#[error("attestation config error: kind: {kind}, reason: {reason}")]
pub struct AttestationConfigError {
Expand Down
11 changes: 10 additions & 1 deletion crates/core/src/attestation/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
hash::HashAlgorithm,
merkle::{MerkleProof, MerkleTree},
serialize::CanonicalSerialize,
signing::Signature,
signing::{Signature, VerifyingKey},
CryptoProvider,
};

Expand Down Expand Up @@ -38,6 +38,11 @@ impl AttestationProof {
})
}

/// Returns the verifying key.
pub fn verifying_key(&self) -> &VerifyingKey {
self.body.verifying_key()
}

/// Verifies the attestation proof.
///
/// # Arguments
Expand Down Expand Up @@ -98,6 +103,10 @@ impl BodyProof {
Ok(BodyProof { body, proof })
}

pub(crate) fn verifying_key(&self) -> &VerifyingKey {
&self.body.verifying_key.data
}

/// Verifies the proof against the attestation header.
pub(crate) fn verify_with_provider(
self,
Expand Down
169 changes: 169 additions & 0 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,173 @@
//! 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`](crate::connection::ServerName),
//! and the [`Transcript`](crate::transcript::Transcript) of application data.
//! Subsequently, the Prover can request an
//! [`Attestation`](crate::attestation::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`](crate::presentation::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`](crate::transcript::TranscriptCommitConfigBuilder)
//! which is used to build up a configuration.
//!
//! Currently, only the
//! [`Encoding`](crate::transcript::TranscriptCommitmentKind::Encoding)
//! commitment kind is supported. In the future you will be able to acquire hash
//! commitments directly to the transcript data.
//!
//! ```no_run
//! # use tlsn_core::transcript::{TranscriptCommitConfigBuilder, Transcript, Direction};
//! # use tlsn_core::hash::HashAlgId;
//! # fn main() -> Result<(), Box<dyn std::error::Error> {
//! # let transcript: Transcript = unimplemented!();
//! 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()?;
//! # Ok(())
//! # }
//! ```
//!
//! # Requesting an attestation
//!
//! The first step in the attestation protocol is for the Prover to make a
//! [`Request`](crate::request::Request), which can be configured using the
//! associated [builder](crate::request::RequestConfigBuilder). 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`](crate::presentation::Presentation), [see
//! below](#constructing-a-presentation).
//!
//! # Issuing an attestation
//!
//! Upon receiving a request, the Notary can issue an
//! [`Attestation`](crate::attestation::Attestation) which can be configured
//! using the associated
//! [builder](crate::attestation::AttestationConfigBuilder).
//!
//! The Notary's [`CryptoProvider`] must be configured with an appropriate
//! signing key for attestations. See
//! [`SignerProvider`](crate::signing::SignerProvider) for more information.
//!
//! # Constructing a presentation
//!
//! A Prover can use an [`Attestation`](crate::attestation::Attestation) and the
//! corresponding [`Secrets`] to construct a verifiable
//! [`Presentation`](crate::presentation::Presentation).
//!
//! ```no_run
//! # use tlsn_core::presentation::Presentation;
//! # use tlsn_core::attestation::Attestation;
//! # use tlsn_core::transcript::{TranscriptCommitmentKind, Direction};
//! # use tlsn_core::{Secrets, CryptoProvider};
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! # let attestation: Attestation = unimplemented!();
//! # let secrets: Secrets = unimplemented!();
//! # let crypto_provider: CryptoProvider = unimplemented!();
//! 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()?;
//! # Ok(())
//! # }
//! ```
//!
//! # Verifying a presentation
//!
//! Verifying a presentation is as simple as checking the verifier trusts the
//! verifying key then calling
//! [`Presentation::verify`](crate::presentation::Presentation::verify).
//!
//! ```no_run
//! # use tlsn_core::presentation::{Presentation, PresentationOutput};
//! # use tlsn_core::signing::VerifyingKey;
//! # use tlsn_core::CryptoProvider;
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! # let presentation: Presentation = unimplemented!();
//! # let trusted_key: VerifyingKey = unimplemented!();
//! # let crypto_provider: CryptoProvider = unimplemented!();
//! // 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)?;
//! # Ok(())
//! # }
//! ```

#![deny(missing_docs, unreachable_pub, unused_must_use)]
#![deny(clippy::all)]
Expand Down
31 changes: 31 additions & 0 deletions crates/core/src/presentation.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
//! Verifiable presentation.
//!
//! We borrow the term "presentation" from the
//! [W3C Verifiable Credentials Data Model](https://www.w3.org/TR/vc-data-model/#presentations-0).
//!
//! > Data derived from one or more verifiable credentials, issued by one or
//! > more issuers, that is shared with a specific verifier. A verifiable
//! > presentation is a tamper-evident presentation encoded in such a way that
//! > authorship of the data can be trusted after a process of cryptographic
//! > verification. Certain types of verifiable presentations might contain data
//! > that is synthesized from, but do not contain, the original verifiable
//! > credentials (for example, zero-knowledge proofs).
//!
//! Instead of a credential, a presentation in this context is a proof of an
//! attestation from a Notary along with additional selectively disclosed
//! information about the TLS connection such as the server's identity and the
//! application data communicated with the server.
//!
//! A presentation is self-contained and can be verified by a Verifier without
//! needing access to external data. The Verifier need only check that the key
//! used to sign the attestation, referred to as a [`VerifyingKey`], is from a
//! Notary they trust. See an [example](crate#verifying-a-presentation) in the
//! crate level documentation.

use std::fmt;

Expand All @@ -7,11 +29,15 @@ use serde::{Deserialize, Serialize};
use crate::{
attestation::{Attestation, AttestationError, AttestationProof},
connection::{ConnectionInfo, ServerIdentityProof, ServerIdentityProofError, ServerName},
signing::VerifyingKey,
transcript::{PartialTranscript, TranscriptProof, TranscriptProofError},
CryptoProvider,
};

/// A verifiable presentation.
///
/// See the [module level documentation](crate::presentation) for more
/// information.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Presentation {
attestation: AttestationProof,
Expand All @@ -28,6 +54,11 @@ impl Presentation {
PresentationBuilder::new(provider, attestation)
}

/// Returns the verifying key.
pub fn verifying_key(&self) -> &VerifyingKey {
self.attestation.verifying_key()
}

/// Verifies the presentation.
pub fn verify(
self,
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ pub trait SignatureVerifier {
}

/// Verifying key.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct VerifyingKey {
/// The key algorithm.
pub alg: KeyAlgId,
Expand Down

0 comments on commit 293ea1c

Please sign in to comment.