polysig_driver/
protocol.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
//! Types for the protocol drivers.

use crate::{Error, Result};
use polysig_protocol::{hex, PartyNumber, RoundNumber};
use serde::{de::DeserializeOwned, Deserialize, Serialize};

#[cfg(feature = "cggmp")]
pub use synedrion::{self, bip32, k256};

#[cfg(feature = "frost-ed25519")]
pub use frost_ed25519;

/// Information about the current found which
/// can be retrieved from a driver.
#[derive(Debug)]
pub struct RoundInfo {
    /// Whether the round is ready to be finalized.
    pub can_finalize: bool,
    /// Whether the round is an echo round.
    pub is_echo: bool,
    /// Round number.
    pub round_number: u8,
}

/// Trait for implementations that drive
/// protocol to completion.
pub trait ProtocolDriver {
    /// Error type for results.
    type Error: std::error::Error
        + std::fmt::Debug
        + Send
        + Sync
        + From<polysig_protocol::Error>
        + 'static;

    /// Outgoing message type.
    type Message: std::fmt::Debug + Round;

    /// Output when the protocol is completed.
    type Output;

    /// Handle an incoming message.
    fn handle_incoming(
        &mut self,
        message: Self::Message,
    ) -> std::result::Result<(), Self::Error>;

    /// Proceed to the next round.
    fn proceed(
        &mut self,
    ) -> std::result::Result<Vec<Self::Message>, Self::Error>;

    /// Information about the current round for the driver.
    fn round_info(
        &self,
    ) -> std::result::Result<RoundInfo, Self::Error>;

    /// Try to finalize a round if the protocol is completed
    /// the result is returned.
    ///
    /// Must check with `can_finalize()` first.
    fn try_finalize_round(
        &mut self,
    ) -> std::result::Result<Option<Self::Output>, Self::Error>;
}

/// Trait for round messages.
pub trait Round: Serialize + DeserializeOwned + Send + Sync {
    /// Round number.
    #[allow(dead_code)]
    fn round_number(&self) -> RoundNumber;

    /// Receiver for a message.
    fn receiver(&self) -> &PartyNumber;
}

/// Round message with additional meta data.
///
/// Used to ensure round messages are grouped together and
/// out of order messages can thus be handled correctly.
#[derive(Debug, Serialize, Deserialize)]
pub struct RoundMessage<Body, Verifier>
where
    Body: Send + Sync,
{
    pub(crate) round: RoundNumber,
    pub(crate) sender: Verifier,
    pub(crate) receiver: PartyNumber,
    pub(crate) body: Body,
}

impl<Body, Verifier> RoundMessage<Body, Verifier>
where
    Body: Serialize + Send + Sync + DeserializeOwned,
    Verifier: Serialize + Send + Sync + DeserializeOwned,
{
    /// Consume this message into the sender and body.
    #[allow(dead_code)]
    pub fn into_body(self) -> (Body, Verifier) {
        (self.body, self.sender)
    }
}

impl<Body, Verifier> Round for RoundMessage<Body, Verifier>
where
    Body: Serialize + Send + Sync + DeserializeOwned,
    Verifier: Serialize + Send + Sync + DeserializeOwned,
{
    fn round_number(&self) -> RoundNumber {
        self.round
    }

    fn receiver(&self) -> &PartyNumber {
        &self.receiver
    }
}

/// Participant in a protocol session.
#[derive(Clone)]
pub struct Participant<Signer, Verifier> {
    /// Signing key for this participant.
    signing_key: Signer,
    /// Options for this participant.
    party: PartyOptions<Verifier>,
}

impl<Signer, Verifier> Participant<Signer, Verifier>
where
    Verifier: PartialEq + std::fmt::Debug,
{
    /// Create a new participant.
    pub fn new(
        signing_key: Signer,
        verifying_key: Verifier,
        party: PartyOptions<Verifier>,
    ) -> Result<Self> {
        if party
            .verifiers()
            .into_iter()
            .find(|v| *v == &verifying_key)
            .is_none()
        {
            return Err(Error::NotVerifyingParty);
        }
        Ok(Self { signing_key, party })
    }

    /// Participant signing key.
    pub fn signing_key(&self) -> &Signer {
        &self.signing_key
    }

    /// Participant party information.
    pub fn party(&self) -> &PartyOptions<Verifier> {
        &self.party
    }
}

/// Options for a party participating in a protocol.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PartyOptions<Verifier> {
    /// Public key of this party.
    #[serde(with = "hex::serde")]
    public_key: Vec<u8>,
    /// Public keys of all participants including this one.
    participants: Vec<Vec<u8>>,
    /// Whether this party is the session initiator.
    ///
    /// The initiator is responsible for disposing of a
    /// session once a protocol completes.
    is_initiator: bool,
    /// Index of the party in the participants list.
    party_index: usize,
    /// Verifying keys for all participants.
    verifiers: Vec<Verifier>,
}

impl<Verifier> PartyOptions<Verifier> {
    /// Create new party participant options.
    pub fn new(
        public_key: Vec<u8>,
        participants: Vec<Vec<u8>>,
        is_initiator: bool,
        verifiers: Vec<Verifier>,
    ) -> Result<Self> {
        let party_index = participants
            .iter()
            .position(|v| v == &public_key)
            .ok_or(Error::NotVerifyingParty)?;

        if participants.len() != verifiers.len() {
            return Err(Error::ParticipantVerifierLength(
                participants.len(),
                verifiers.len(),
            ));
        }

        Ok(Self {
            public_key,
            participants,
            is_initiator,
            party_index,
            verifiers,
        })
    }

    /// Public key of this participant.
    pub fn public_key(&self) -> &[u8] {
        &self.public_key
    }

    /// Participant public keys.
    pub fn participants(&self) -> &[Vec<u8>] {
        self.participants.as_slice()
    }

    /// Index of this participant.
    pub fn party_index(&self) -> usize {
        self.party_index
    }

    /// Whether this party is the session initator.
    pub fn is_initiator(&self) -> bool {
        self.is_initiator
    }

    /// Participant verifying keys.
    pub fn verifiers(&self) -> &[Verifier] {
        self.verifiers.as_slice()
    }
}