# prove.rs - source
Source of the Rust file `crates/tlsn/src/prover/prove.rs`.

Skip to main content

#
tlsn/prover/
prove.rs

    1use mpc_tls::SessionKeys;
    2use mpz_common::Context;
    3use mpz_memory_core::binary::Binary;
    4use mpz_vm_core::Vm;
    5use rangeset::set::RangeSet;
    6use tlsn_core::{
    7    ProverOutput,
    8    config::prove::ProveConfig,
    9    transcript::{
    10        ContentType, Direction, TlsTranscript, Transcript, TranscriptCommitment, TranscriptSecret,
    11    },
    12};
    13
    14use crate::{
    15    Error, Result,
    16    transcript_internal::{TranscriptRefs, auth::prove_plaintext, commit::hash::prove_hash},
    17};
    18
    19pub(crate) async fn prove<T: Vm<Binary> + Send + Sync>(
    20    ctx: &mut Context,
    21    vm: &mut T,
    22    keys: &SessionKeys,
    23    transcript: &Transcript,
    24    tls_transcript: &TlsTranscript,
    25    config: &ProveConfig,
    26) -> Result<ProverOutput> {
    27    let mut output = ProverOutput {
    28        transcript_commitments: Vec::default(),
    29        transcript_secrets: Vec::default(),
    30    };
    31
    32    let (reveal_sent, reveal_recv) = config.reveal().cloned().unwrap_or_default();
    33    let (mut commit_sent, mut commit_recv) = (RangeSet::default(), RangeSet::default());
    34    if let Some(commit_config) = config.transcript_commit() {
    35        commit_config
    36            .iter_hash()
    37            .for_each(|((direction, idx), _)| match direction {
    38                Direction::Sent => commit_sent.union_mut(idx),
    39                Direction::Received => commit_recv.union_mut(idx),
    40            });
    41    }
    42
    43    let transcript_refs = TranscriptRefs {
    44        sent: prove_plaintext(
    45            vm,
    46            keys.client_write_key,
    47            keys.client_write_iv,
    48            transcript.sent(),
    49            tls_transcript
    50                .sent()
    51                .iter()
    52                .filter(|record| record.typ == ContentType::ApplicationData),
    53            &reveal_sent,
    54            &commit_sent,
    55        )
    56        .map_err(|e| {
    57            Error::internal()
    58                .with_msg("proving failed during sent plaintext commitment")
    59                .with_source(e)
    60        })?,
    61        recv: prove_plaintext(
    62            vm,
    63            keys.server_write_key,
    64            keys.server_write_iv,
    65            transcript.received(),
    66            tls_transcript
    67                .recv()
    68                .iter()
    69                .filter(|record| record.typ == ContentType::ApplicationData),
    70            &reveal_recv,
    71            &commit_recv,
    72        )
    73        .map_err(|e| {
    74            Error::internal()
    75                .with_msg("proving failed during received plaintext commitment")
    76                .with_source(e)
    77        })?,
    78    };
    79
    80    let hash_commitments = if let Some(commit_config) = config.transcript_commit()
    81        && commit_config.has_hash()
    82    {
    83        Some(
    84            prove_hash(
    85                vm,
    86                &transcript_refs,
    87                commit_config
    88                    .iter_hash()
    89                    .map(|((dir, idx), alg)| (*dir, idx.clone(), *alg)),
    90            )
    91            .map_err(|e| {
    92                Error::internal()
    93                    .with_msg("proving failed during hash commitment setup")
    94                    .with_source(e)
    95            })?,
    96        )
    97    } else {
    98        None
    99    };
    100
    101    vm.execute_all(ctx).await.map_err(|e| {
    102        Error::internal()
    103            .with_msg("proving failed during zk execution")
    104            .with_source(e)
    105    })?;
    106
    107    if let Some((hash_fut, hash_secrets)) = hash_commitments {
    108        let hash_commitments = hash_fut.try_recv().map_err(|e| {
    109            Error::internal()
    110                .with_msg("proving failed during hash commitment finalization")
    111                .with_source(e)
    112        })?;
    113        for (commitment, secret) in hash_commitments.into_iter().zip(hash_secrets) {
    114            output
    115                .transcript_commitments
    116                .push(TranscriptCommitment::Hash(commitment));
    117            output
    118                .transcript_secrets
    119                .push(TranscriptSecret::Hash(secret));
    120        }
    121    }
    122
    123    Ok(output)
    124}