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}