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
//! 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 super::{state::Prove as ProveState, Prover, ProverError};
use mpz_garble::{Memory, Prove};
use mpz_ot::VerifiableOTReceiver;
use serio::SinkExt as _;
use tlsn_common::msg::ServerIdentityProof;
use tlsn_core::transcript::{get_value_ids, Direction, Idx, Transcript};

use tracing::{info, instrument};

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_value_ids = get_value_ids(Direction::Sent, &sent);
        let recv_value_ids = get_value_ids(Direction::Received, &recv);

        let value_refs = sent_value_ids
            .chain(recv_value_ids)
            .map(|id| {
                self.state
                    .vm
                    .get_value(id.as_str())
                    .expect("Byte should be in VM memory")
            })
            .collect::<Vec<_>>();

        self.state
            .mux_fut
            .poll_with(async {
                // Send the partial transcript to the verifier.
                self.state.io.send(partial_transcript).await?;

                info!("Sent partial transcript");

                // Prove the partial transcript to the verifier.
                self.state.vm.prove(value_refs.as_slice()).await?;

                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 {
            mut io,
            mux_ctrl,
            mut mux_fut,
            mut vm,
            mut ot_recv,
            mut ctx,
            server_cert_data,
            ..
        } = self.state;

        mux_fut
            .poll_with(async move {
                ot_recv.accept_reveal(&mut ctx).await?;

                vm.finalize().await?;

                // Send identity proof to the verifier.
                io.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.mux().close();
            mux_fut.await?;
        }

        Ok(())
    }
}