tlsn_prover/prove.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
//! This module handles the proving phase of the prover.
//!
//! The prover interacts with a TLS verifier directly, without involving a
//! Notary. The verifier verifies transcript data.
use mpz_memory_core::MemoryExt;
use mpz_vm_core::Execute;
use serio::SinkExt as _;
use tlsn_common::msg::ServerIdentityProof;
use tlsn_core::transcript::{Direction, Idx, Transcript};
use tracing::{info, instrument};
use crate::{state::Prove as ProveState, Prover, ProverError};
impl Prover<ProveState> {
/// Returns the transcript.
pub fn transcript(&self) -> &Transcript {
&self.state.transcript
}
/// Proves subsequences in the transcript to the verifier.
///
/// # Arguments
///
/// * `sent` - Indices of the sent data.
/// * `recv` - Indices of the received data.
#[instrument(parent = &self.span, level = "debug", skip_all, err)]
pub async fn prove_transcript(&mut self, sent: Idx, recv: Idx) -> Result<(), ProverError> {
let partial_transcript = self.transcript().to_partial(sent.clone(), recv.clone());
let sent_refs = self
.state
.transcript_refs
.get(Direction::Sent, &sent)
.expect("index is in bounds");
let recv_refs = self
.state
.transcript_refs
.get(Direction::Received, &recv)
.expect("index is in bounds");
for slice in sent_refs.into_iter().chain(recv_refs) {
// Drop the future, we don't need it.
drop(self.state.vm.decode(slice).map_err(ProverError::zk)?);
}
self.state
.mux_fut
.poll_with(async {
// Send the partial transcript to the verifier.
self.state.ctx.io_mut().send(partial_transcript).await?;
info!("Sent partial transcript");
// Prove the partial transcript to the verifier.
self.state
.vm
.flush(&mut self.state.ctx)
.await
.map_err(ProverError::zk)?;
info!("Proved partial transcript");
Ok::<_, ProverError>(())
})
.await?;
Ok(())
}
/// Finalizes the proving.
#[instrument(parent = &self.span, level = "debug", skip_all, err)]
pub async fn finalize(self) -> Result<(), ProverError> {
let ProveState {
mux_ctrl,
mut mux_fut,
mut ctx,
server_cert_data,
..
} = self.state;
mux_fut
.poll_with(async move {
// Send identity proof to the verifier.
ctx.io_mut()
.send(ServerIdentityProof {
name: self.config.server_name().clone(),
data: server_cert_data,
})
.await?;
Ok::<_, ProverError>(())
})
.await?;
// Wait for the verifier to correctly close the connection.
if !mux_fut.is_complete() {
mux_ctrl.close();
mux_fut.await?;
}
Ok(())
}
}