mpc_client/protocols/frost/ed25519/
mod.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! Driver for the FROST Ed25519 protocol.
use mpc_driver::{
    frost::ed25519::{KeyShare, Participant, Signature},
    frost_ed25519::Identifier,
};

use crate::{
    new_client, wait_for_close, wait_for_driver, wait_for_session,
    wait_for_session_finish, Error, NetworkTransport, SessionHandler,
    SessionInitiator, SessionOptions, SessionParticipant, Transport,
};

mod key_gen;
mod sign;

pub use key_gen::KeyGenDriver;
pub use sign::SignatureDriver;

/// Run threshold DKG for the FROST protocol.
pub async fn keygen(
    options: SessionOptions,
    participant: Participant,
) -> crate::Result<KeyShare> {
    let n = options.parameters.parties;
    let t = options.parameters.threshold;

    // Create the client
    let (client, event_loop) = new_client(options).await?;

    let mut transport: Transport = client.into();

    // Handshake with the server
    transport.connect().await?;

    // Start the event stream
    let mut stream = event_loop.run();

    // Wait for the session to become active
    let client_session = if participant.party().is_initiator() {
        let mut other_participants =
            participant.party().participants().to_vec();
        other_participants
            .retain(|p| p != participant.party().public_key());
        SessionHandler::Initiator(SessionInitiator::new(
            transport,
            other_participants,
        ))
    } else {
        SessionHandler::Participant(SessionParticipant::new(
            transport,
        ))
    };

    let (transport, session) =
        wait_for_session(&mut stream, client_session).await?;

    let mut identifiers: Vec<Identifier> =
        Vec::with_capacity(n.into());
    for index in 1..=n {
        identifiers.push(index.try_into().map_err(Error::from)?);
    }

    let key_gen =
        KeyGenDriver::new(transport, session, n, t, identifiers)?;

    let (transport, key_share) =
        wait_for_driver(&mut stream, key_gen).await?;

    transport.close().await?;
    wait_for_close(&mut stream).await?;

    Ok(key_share)
}

/// Sign a message using the FROST protocol.
pub async fn sign(
    options: SessionOptions,
    participant: Participant,
    // Identifiers must match the KeyPackage identifiers!
    identifiers: Vec<Identifier>,
    key_share: KeyShare,
    message: Vec<u8>,
) -> crate::Result<Signature> {
    let min_signers = options.parameters.threshold as u16;

    // Create the client
    let (client, event_loop) = new_client(options).await?;

    let mut transport: Transport = client.into();

    // Handshake with the server
    transport.connect().await?;

    // Start the event stream
    let mut stream = event_loop.run();

    // Wait for the session to become active
    let client_session = if participant.party().is_initiator() {
        let mut other_participants =
            participant.party().participants().to_vec();
        other_participants
            .retain(|p| p != participant.party().public_key());
        SessionHandler::Initiator(SessionInitiator::new(
            transport,
            other_participants,
        ))
    } else {
        SessionHandler::Participant(SessionParticipant::new(
            transport,
        ))
    };

    let (transport, session) =
        wait_for_session(&mut stream, client_session).await?;

    let protocol_session_id = session.session_id;

    // Wait for message to be signed
    let driver = SignatureDriver::new(
        transport,
        session,
        identifiers,
        min_signers,
        key_share,
        message,
    )?;

    let (mut transport, signature) =
        wait_for_driver(&mut stream, driver).await?;

    // Close the session and socket
    if participant.party().is_initiator() {
        transport.close_session(protocol_session_id).await?;
        wait_for_session_finish(&mut stream, protocol_session_id)
            .await?;
    }
    transport.close().await?;
    wait_for_close(&mut stream).await?;

    Ok(signature)
}