tlsn_prover/
prove.rs

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