Files
tlsn/crates/examples/attestation/prove.rs
Hendrik Eeckhaut dfc162929d fix(examples): fix examples for alpha.7 release (#603)
* doc: Fix examples for alpha7 release

+ Use secp256k1 key for notary server fixture
+ fix tower issue
+ Fixed doctes issues (Avoid doc test failures when ignored tests are run)
+ Run wasm tests in incognitto mode to avoid chromiumoxide ws errors

* Added comment

* minor improvements

* formatting

* polish attestation example

* use shorthand fs write

* clean

* simplify discord example

---------

Co-authored-by: sinu <65924192+sinui0@users.noreply.github.com>
2024-10-02 20:39:47 -07:00

126 lines
4.6 KiB
Rust

// This example demonstrates how to use the Prover to acquire an attestation for
// an HTTP request sent to example.com. The attestation and secrets are saved to
// disk.
use http_body_util::Empty;
use hyper::{body::Bytes, Request, StatusCode};
use hyper_util::rt::TokioIo;
use tokio_util::compat::{FuturesAsyncReadCompatExt, TokioAsyncReadCompatExt};
use tlsn_common::config::ProtocolConfig;
use tlsn_core::{request::RequestConfig, transcript::TranscriptCommitConfig};
use tlsn_examples::run_notary;
use tlsn_formats::http::{DefaultHttpCommitter, HttpCommit, HttpTranscript};
use tlsn_prover::{Prover, ProverConfig};
// Setting of the application server
const SERVER_DOMAIN: &str = "example.com";
const USER_AGENT: &str = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36";
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
let (prover_socket, notary_socket) = tokio::io::duplex(1 << 16);
// Start a local simple notary service
tokio::spawn(run_notary(notary_socket.compat()));
// Prover configuration.
let config = ProverConfig::builder()
.server_name(SERVER_DOMAIN)
.protocol_config(
ProtocolConfig::builder()
// We must configure the amount of data we expect to exchange beforehand, which will
// be preprocessed prior to the connection. Reducing these limits will improve
// performance.
.max_sent_data(1024)
.max_recv_data(4096)
.build()?,
)
.build()?;
// Create a new prover and perform necessary setup.
let prover = Prover::new(config).setup(prover_socket.compat()).await?;
// Open a TCP connection to the server.
let client_socket = tokio::net::TcpStream::connect((SERVER_DOMAIN, 443)).await?;
// Bind the prover to the server connection.
// The returned `mpc_tls_connection` is an MPC TLS connection to the server: all
// data written to/read from it will be encrypted/decrypted using MPC with
// the notary.
let (mpc_tls_connection, prover_fut) = prover.connect(client_socket.compat()).await?;
let mpc_tls_connection = TokioIo::new(mpc_tls_connection.compat());
// Spawn the prover task to be run concurrently in the background.
let prover_task = tokio::spawn(prover_fut);
// Attach the hyper HTTP client to the connection.
let (mut request_sender, connection) =
hyper::client::conn::http1::handshake(mpc_tls_connection).await?;
// Spawn the HTTP task to be run concurrently in the background.
tokio::spawn(connection);
// Build a simple HTTP request with common headers
let request = Request::builder()
.uri("/")
.header("Host", SERVER_DOMAIN)
.header("Accept", "*/*")
// Using "identity" instructs the Server not to use compression for its HTTP response.
// TLSNotary tooling does not support compression.
.header("Accept-Encoding", "identity")
.header("Connection", "close")
.header("User-Agent", USER_AGENT)
.body(Empty::<Bytes>::new())?;
println!("Starting an MPC TLS connection with the server");
// Send the request to the server and wait for the response.
let response = request_sender.send_request(request).await?;
println!("Got a response from the server");
assert!(response.status() == StatusCode::OK);
// The prover task should be done now, so we can await it.
let prover = prover_task.await??;
// Prepare for notarization.
let mut prover = prover.start_notarize();
// Parse the HTTP transcript.
let transcript = HttpTranscript::parse(prover.transcript())?;
// Commit to the transcript.
let mut builder = TranscriptCommitConfig::builder(prover.transcript());
DefaultHttpCommitter::default().commit_transcript(&mut builder, &transcript)?;
prover.transcript_commit(builder.build()?);
// Request an attestation.
let config = RequestConfig::default();
let (attestation, secrets) = prover.finalize(&config).await?;
// Write the attestation to disk.
tokio::fs::write(
"example.attestation.tlsn",
bincode::serialize(&attestation)?,
)
.await?;
// Write the secrets to disk.
tokio::fs::write("example.secrets.tlsn", bincode::serialize(&secrets)?).await?;
println!("Notarization completed successfully!");
println!(
"The attestation has been written to `example.attestation.tlsn` and the \
corresponding secrets to `example.secrets.tlsn`."
);
Ok(())
}