dkls23/setup/keygen.rs
1// Copyright (c) Silence Laboratories Pte. Ltd. All Rights Reserved.
2// This software is licensed under the Silence Laboratories License Agreement.
3
4#![allow(missing_docs)]
5
6use std::marker::PhantomData;
7use std::time::Duration;
8
9use sha2::{Digest, Sha256};
10use signature::{SignatureEncoding, Signer, Verifier};
11
12use sl_mpc_mate::message::InstanceId;
13
14/// Default Time-To-Live (TTL) value for messages in seconds
15const DEFAULT_TTL: u64 = 100; // smaller timeout might fail tests
16
17use crate::setup::{
18 keys::{NoSignature, NoSigningKey, NoVerifyingKey},
19 KeygenSetupMessage, ProtocolParticipant,
20};
21
22/// A message used for setting up key generation in a multi-party computation protocol.
23///
24/// This struct encapsulates all necessary information for setting up a key generation protocol,
25/// including participant information, cryptographic keys, and protocol parameters.
26///
27/// # Type Parameters
28/// * `SK` - The type of signing key used for message signatures
29/// * `VK` - The type of verifying key used to verify message signatures
30/// * `MS` - The type of message signature
31pub struct SetupMessage<
32 SK = NoSigningKey,
33 VK = NoVerifyingKey,
34 MS = NoSignature,
35> {
36 /// Total number of participants in the protocol
37 n: usize,
38 /// Threshold value for the protocol
39 t: usize,
40 /// ID of the current party
41 party_id: usize,
42 /// Ranks of all participants
43 ranks: Vec<u8>,
44 /// Signing key for the current party
45 sk: SK,
46 /// Verifying keys for all participants
47 vk: Vec<VK>,
48 /// Optional key identifier
49 key_id: Option<[u8; 32]>,
50 /// Instance identifier for the protocol
51 inst: InstanceId,
52 /// Time-to-live duration for messages
53 ttl: Duration,
54 /// Phantom data to hold the message signature type
55 marker: PhantomData<MS>,
56}
57
58impl<SK, VK, MS> SetupMessage<SK, VK, MS> {
59 /// Creates a new setup message for key generation.
60 ///
61 /// # Arguments
62 /// * `inst` - Instance identifier for the protocol
63 /// * `sk` - Signing key for the current party
64 /// * `party_id` - ID of the current party
65 /// * `vk` - Vector of verifying keys for all participants
66 /// * `ranks` - Ranks of all participants
67 /// * `t` - Threshold value for the protocol
68 ///
69 /// # Returns
70 /// A new `SetupMessage` instance with default TTL and no key ID
71 pub fn new(
72 inst: InstanceId,
73 sk: SK,
74 party_id: usize,
75 vk: Vec<VK>,
76 ranks: &[u8],
77 t: usize,
78 ) -> Self {
79 Self {
80 n: vk.len(),
81 t,
82 party_id,
83 sk,
84 vk,
85 inst,
86 key_id: None,
87 ttl: Duration::from_secs(DEFAULT_TTL),
88 ranks: ranks.to_vec(),
89 marker: PhantomData,
90 }
91 }
92
93 /// Sets a custom time-to-live duration for messages.
94 ///
95 /// # Arguments
96 /// * `ttl` - The new time-to-live duration
97 ///
98 /// # Returns
99 /// The modified `SetupMessage` instance
100 pub fn with_ttl(mut self, ttl: Duration) -> Self {
101 self.ttl = ttl;
102 self
103 }
104
105 /// Sets a custom key identifier.
106 ///
107 /// # Arguments
108 /// * `key_id` - Optional key identifier
109 ///
110 /// # Returns
111 /// The modified `SetupMessage` instance
112 pub fn with_key_id(mut self, key_id: Option<[u8; 32]>) -> Self {
113 self.key_id = key_id;
114 self
115 }
116
117 /// Returns the key identifier if it exists.
118 ///
119 /// # Returns
120 /// An optional reference to the key identifier bytes
121 pub fn key_id(&self) -> Option<&[u8]> {
122 self.key_id.as_ref().map(AsRef::as_ref)
123 }
124}
125
126impl<SK, VK, MS> ProtocolParticipant for SetupMessage<SK, VK, MS>
127where
128 SK: Signer<MS>,
129 MS: SignatureEncoding,
130 VK: AsRef<[u8]> + Verifier<MS>,
131{
132 type MessageSignature = MS;
133 type MessageSigner = SK;
134 type MessageVerifier = VK;
135
136 /// Returns the total number of participants in the protocol.
137 fn total_participants(&self) -> usize {
138 self.n
139 }
140
141 /// Returns the index of the current participant.
142 fn participant_index(&self) -> usize {
143 self.party_id
144 }
145
146 /// Returns the instance identifier for the protocol.
147 fn instance_id(&self) -> &InstanceId {
148 &self.inst
149 }
150
151 /// Returns the time-to-live duration for messages.
152 fn message_ttl(&self) -> Duration {
153 self.ttl
154 }
155
156 /// Returns the verifying key for a specific participant.
157 ///
158 /// # Arguments
159 /// * `index` - The index of the participant
160 ///
161 /// # Returns
162 /// A reference to the verifying key
163 fn verifier(&self, index: usize) -> &Self::MessageVerifier {
164 &self.vk[index]
165 }
166
167 /// Returns the signing key for the current participant.
168 fn signer(&self) -> &Self::MessageSigner {
169 &self.sk
170 }
171}
172
173impl<SK, VK, MS> KeygenSetupMessage for SetupMessage<SK, VK, MS>
174where
175 SK: Signer<MS>,
176 MS: SignatureEncoding,
177 VK: AsRef<[u8]> + Verifier<MS>,
178{
179 /// Returns the threshold value for the protocol.
180 fn threshold(&self) -> u8 {
181 self.t as u8
182 }
183
184 /// Returns the rank of a specific participant.
185 ///
186 /// # Arguments
187 /// * `index` - The index of the participant
188 ///
189 /// # Returns
190 /// The rank of the participant
191 fn participant_rank(&self, index: usize) -> u8 {
192 self.ranks[index]
193 }
194
195 /// Derives a key identifier from a public key.
196 ///
197 /// # Arguments
198 /// * `public_key` - The public key to derive the identifier from
199 ///
200 /// # Returns
201 /// A 32-byte key identifier
202 fn derive_key_id(&self, public_key: &[u8]) -> [u8; 32] {
203 self.key_id
204 .unwrap_or_else(|| Sha256::digest(public_key).into())
205 }
206}