dkls23/
setup.rs

1// Copyright (c) Silence Laboratories Pte. Ltd. All Rights Reserved.
2// This software is licensed under the Silence Laboratories License Agreement.
3
4//! Each mpc protocol: Keygen, Sign, Quorum change, Key Export in order to bootstrap the nodes need
5//! to setup necessary information  such as protocol id, participant information, cryptographic keys, and tailored per MPC protocol parameters.
6
7use std::time::Duration;
8
9use derivation_path::DerivationPath;
10use k256::ProjectivePoint;
11pub use signature::{SignatureEncoding, Signer, Verifier};
12
13use sl_mpc_mate::message::{InstanceId, MessageTag, MsgId};
14
15use crate::{keygen::Keyshare, sign::PreSign};
16
17/// Tag for all setup messages
18pub const SETUP_MESSAGE_TAG: MessageTag = MessageTag::tag(0);
19
20/// Tag of a broadcast message indicating that sender
21/// won't participate in the protocol. The payload of
22/// the message contains error code.
23pub const ABORT_MESSAGE_TAG: MessageTag = MessageTag::tag(u64::MAX);
24
25/// An iterator for parties in range 0..total except me.
26pub struct AllOtherParties {
27    total: usize,
28    me: usize,
29    curr: usize,
30}
31
32impl Iterator for AllOtherParties {
33    type Item = usize;
34
35    fn next(&mut self) -> Option<Self::Item> {
36        loop {
37            let val = self.curr;
38
39            if val >= self.total {
40                return None;
41            }
42
43            self.curr += 1;
44
45            if val != self.me {
46                return Some(val);
47            }
48        }
49    }
50}
51
52impl ExactSizeIterator for AllOtherParties {
53    fn len(&self) -> usize {
54        self.total - 1
55    }
56}
57
58/// Type that provides a protocol participant details.
59pub trait ProtocolParticipant {
60    /// Type of a signature, added at end of all broadcast messages
61    /// passed between participants.
62    type MessageSignature: SignatureEncoding;
63
64    /// Type to sign broadcast messages, some kind of SecretKey.
65    type MessageSigner: Signer<Self::MessageSignature>;
66
67    /// Type to verify signed message, a verifying key. AsRef<[u8]> is
68    /// used to get external representation of the key to derive
69    /// message ID.
70    type MessageVerifier: Verifier<Self::MessageSignature> + AsRef<[u8]>;
71
72    /// Return total number of participants of a distributed protocol.
73    fn total_participants(&self) -> usize;
74
75    /// Return a verifying key for a messages from a participant with
76    /// given index.
77    fn verifier(&self, index: usize) -> &Self::MessageVerifier;
78
79    /// A signer to sign messages from the participant.
80    fn signer(&self) -> &Self::MessageSigner;
81
82    /// Return an index of the participant in a protocol.
83    /// This is a value in range 0..self.total_participants()
84    fn participant_index(&self) -> usize;
85
86    /// Each execution of a distributed protocol requires
87    /// a unique instance id to derive all IDs of messages.
88    fn instance_id(&self) -> &InstanceId;
89
90    /// Return message Time To Live.
91    fn message_ttl(&self) -> Duration;
92
93    /// Return reference to participant's own verifier
94    fn participant_verifier(&self) -> &Self::MessageVerifier {
95        self.verifier(self.participant_index())
96    }
97
98    /// Return iterator of all participant's indexes except own one.
99    fn all_other_parties(&self) -> AllOtherParties {
100        AllOtherParties {
101            curr: 0,
102            total: self.total_participants(),
103            me: self.participant_index(),
104        }
105    }
106
107    /// Generate ID of a message from this party to some other (or broadcast)
108    /// if passed receiver is None.
109    fn msg_id(&self, receiver: Option<usize>, tag: MessageTag) -> MsgId {
110        self.msg_id_from(self.participant_index(), receiver, tag)
111    }
112
113    /// Generate ID of a message from given sender to a given
114    /// receiver.  Receiver is designed by its index and is None for a
115    /// broadcase message.
116    fn msg_id_from(
117        &self,
118        sender: usize,
119        receiver: Option<usize>,
120        tag: MessageTag,
121    ) -> MsgId {
122        let receiver = receiver
123            .map(|p| self.verifier(p))
124            .map(AsRef::<[u8]>::as_ref);
125
126        MsgId::new(
127            self.instance_id(),
128            self.verifier(sender).as_ref(),
129            receiver.as_ref().map(AsRef::as_ref),
130            tag,
131        )
132    }
133}
134
135impl<M: ProtocolParticipant> ProtocolParticipant for &M {
136    type MessageSignature = M::MessageSignature;
137    type MessageSigner = M::MessageSigner;
138    type MessageVerifier = M::MessageVerifier;
139
140    fn total_participants(&self) -> usize {
141        (**self).total_participants()
142    }
143
144    fn verifier(&self, index: usize) -> &Self::MessageVerifier {
145        (**self).verifier(index)
146    }
147
148    fn signer(&self) -> &Self::MessageSigner {
149        (**self).signer()
150    }
151
152    fn participant_index(&self) -> usize {
153        (**self).participant_index()
154    }
155
156    fn participant_verifier(&self) -> &Self::MessageVerifier {
157        (**self).participant_verifier()
158    }
159
160    fn instance_id(&self) -> &InstanceId {
161        (**self).instance_id()
162    }
163
164    fn message_ttl(&self) -> Duration {
165        (**self).message_ttl()
166    }
167}
168
169/// A setup message for keygen::run()
170pub trait KeygenSetupMessage: ProtocolParticipant {
171    /// Threshold parameter.
172    fn threshold(&self) -> u8;
173
174    /// Return a rank of a participant with given index.
175    /// May panic is index is out of range.
176    fn participant_rank(&self, _party_index: usize) -> u8 {
177        0
178    }
179
180    /// Derive key_id from a public_key.
181    fn derive_key_id(&self, public_key: &[u8]) -> [u8; 32];
182
183    /// Additional data to amend into the Keyshare.
184    fn keyshare_extra(&self) -> &[u8] {
185        &[]
186    }
187}
188
189impl<M: KeygenSetupMessage> KeygenSetupMessage for &M {
190    fn threshold(&self) -> u8 {
191        (**self).threshold()
192    }
193
194    fn participant_rank(&self, party_index: usize) -> u8 {
195        (**self).participant_rank(party_index)
196    }
197
198    fn derive_key_id(&self, public_key: &[u8]) -> [u8; 32] {
199        (**self).derive_key_id(public_key)
200    }
201
202    fn keyshare_extra(&self) -> &[u8] {
203        (**self).keyshare_extra()
204    }
205}
206
207/// A setup message for sign::pre_signature()
208pub trait PreSignSetupMessage: ProtocolParticipant {
209    /// A shared reference to a Keyshare.
210    fn keyshare(&self) -> &Keyshare;
211
212    /// Key chain path for this signature
213    fn chain_path(&self) -> &DerivationPath;
214
215    /// Additional data to incorpatate into resulting PreSignature.
216    fn presignature_extra(&self) -> &[u8] {
217        &[]
218    }
219}
220
221/// A setup message for sign::finish()
222pub trait FinalSignSetupMessage: ProtocolParticipant {
223    /// Pre-signature created by sign::pre_signature()
224    fn pre_signature(&self) -> &PreSign;
225
226    /// Hash of a message to sign.
227    fn message_hash(&self) -> [u8; 32];
228}
229
230/// A setup message for sign::run()
231pub trait SignSetupMessage: PreSignSetupMessage {
232    /// Hash of a message to sign.
233    fn message_hash(&self) -> [u8; 32];
234}
235
236/// A setup message for key export.
237pub trait KeyExporterSetupMessage<PK, KS>: ProtocolParticipant {
238    /// Public key of a receiver party.
239    fn receiver_public_key(&self) -> &PK;
240
241    /// A shared reference to a Keyshare.
242    fn keyshare(&self) -> &KS;
243}
244
245/// A setup message for a reciever of exported key.
246pub trait KeyExportReceiverSetupMessage<SK>: ProtocolParticipant {
247    /// Private key to decrypt P2P messages.
248    fn receiver_private_key(&self) -> &SK;
249
250    /// A shared reference to a Keyshare.
251    fn keyshare(&self) -> &Keyshare;
252}
253
254/// A setup message for quorum_change::run()
255pub trait QuorumChangeSetupMessage<KS, PK>: ProtocolParticipant {
256    /// A shared reference to a Keyshare.
257    fn old_keyshare(&self) -> Option<&KS>;
258
259    /// New threshold parameter.
260    fn new_threshold(&self) -> u8;
261
262    /// New participant rank. Panics is `party_id` is out of range.
263    fn new_participant_rank(&self, _party_id: u8) -> u8 {
264        0
265    }
266
267    /// Expected public key.
268    fn expected_public_key(&self) -> &PK;
269
270    /// return new_party_id by party_index
271    fn new_party_id(&self, index: usize) -> Option<u8> {
272        self.new_party_indices()
273            .iter()
274            .position(|p| p == &index)
275            .map(|p| p as u8)
276    }
277
278    /// list of old party indices
279    fn old_party_indices(&self) -> &[usize];
280
281    /// List of indices of new parties in a list of protocol
282    /// participants. Order of indices defines assignment of party-id
283    /// to new key shares.
284    fn new_party_indices(&self) -> &[usize];
285
286    /// Additional data to incorpatate into resulting Keyshare.
287    fn keyshare_extra(&self) -> &[u8] {
288        &[]
289    }
290
291    /// Derive key_id from a public_key.
292    fn derive_key_id(&self, public_key: &[u8]) -> [u8; 32];
293}
294
295impl<KS, PK, M: QuorumChangeSetupMessage<KS, PK>>
296    QuorumChangeSetupMessage<KS, PK> for &M
297{
298    fn old_keyshare(&self) -> Option<&KS> {
299        (**self).old_keyshare()
300    }
301
302    fn new_threshold(&self) -> u8 {
303        (**self).new_threshold()
304    }
305
306    fn expected_public_key(&self) -> &PK {
307        (**self).expected_public_key()
308    }
309
310    fn old_party_indices(&self) -> &[usize] {
311        (**self).old_party_indices()
312    }
313
314    fn new_party_indices(&self) -> &[usize] {
315        (**self).new_party_indices()
316    }
317
318    fn derive_key_id(&self, public_key: &[u8]) -> [u8; 32] {
319        (**self).derive_key_id(public_key)
320    }
321}
322
323/// Setup for DKG
324pub mod keygen;
325
326/// Setup for DSG
327pub mod sign;
328
329/// Setup for Finish PreSignature
330pub mod finish;
331
332/// Setup for Key export
333pub mod key_export;
334
335pub use keys::*;
336
337mod keys;
338
339/// Setup for Quorum Change
340pub mod quorum_change;