dkls23/setup/sign.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 core::str::FromStr;
7use std::{marker::PhantomData, sync::Arc, time::Duration};
8
9use derivation_path::DerivationPath;
10use signature::{SignatureEncoding, Signer, Verifier};
11
12use sl_mpc_mate::message::InstanceId;
13
14use crate::{
15 keygen::Keyshare,
16 setup::{
17 keys::{NoSignature, NoSigningKey, NoVerifyingKey},
18 PreSignSetupMessage, ProtocolParticipant, SignSetupMessage,
19 },
20};
21
22/// Default Time-To-Live (TTL) value for messages in seconds
23const DEFAULT_TTL: u64 = 100; // smaller timeout might fail tests
24
25/// A message used for setting up signing operations in a multi-party computation protocol.
26///
27/// This struct encapsulates all necessary information for signing operations,
28/// including participant information, cryptographic keys, and protocol parameters.
29///
30/// # Type Parameters
31/// * `SK` - The type of signing key used for message signatures
32/// * `VK` - The type of verifying key used to verify message signatures
33/// * `MS` - The type of message signature
34/// * `KS` - The type of keyshare used in the protocol
35pub struct SetupMessage<
36 SK = NoSigningKey,
37 VK = NoVerifyingKey,
38 MS = NoSignature,
39 KS = Keyshare,
40> {
41 /// Index of the current party
42 party_idx: usize,
43 /// Signing key for the current party
44 sk: SK,
45 /// Verifying keys for all participants
46 vk: Vec<VK>,
47 /// Instance identifier for the protocol
48 instance: InstanceId,
49 /// Reference to the keyshare used in signing
50 keyshare: Arc<KS>,
51 /// Derivation path for key derivation
52 chain_path: DerivationPath,
53 /// Time-to-live duration for messages
54 ttl: Duration,
55 /// Hash of the message to be signed
56 hash: [u8; 32],
57 /// Phantom data to hold the message signature type
58 marker: PhantomData<MS>,
59}
60
61impl<SK, VK, MS, KS> SetupMessage<SK, VK, MS, KS> {
62 /// Creates a new setup message for signing operations.
63 ///
64 /// # Arguments
65 /// * `instance` - Instance identifier for the protocol
66 /// * `sk` - Signing key for the current party
67 /// * `party_idx` - Index of the current party
68 /// * `vk` - Vector of verifying keys for all participants
69 /// * `share` - Reference to the keyshare used in signing
70 ///
71 /// # Returns
72 /// A new `SetupMessage` instance with default TTL, root derivation path, and zero hash
73 pub fn new(
74 instance: InstanceId,
75 sk: SK,
76 party_idx: usize,
77 vk: Vec<VK>,
78 share: Arc<KS>,
79 ) -> Self {
80 Self {
81 party_idx,
82 sk,
83 vk,
84 instance,
85 keyshare: share.clone(),
86 ttl: Duration::from_secs(DEFAULT_TTL),
87 chain_path: DerivationPath::from_str("m").unwrap(),
88 hash: [0; 32],
89 marker: PhantomData,
90 }
91 }
92
93 /// Sets a custom derivation path for key derivation.
94 ///
95 /// # Arguments
96 /// * `chain_path` - The new derivation path
97 ///
98 /// # Returns
99 /// The modified `SetupMessage` instance
100 pub fn with_chain_path(mut self, chain_path: DerivationPath) -> Self {
101 self.chain_path = chain_path;
102 self
103 }
104
105 /// Sets the hash of the message to be signed.
106 ///
107 /// # Arguments
108 /// * `hash` - The 32-byte hash of the message
109 ///
110 /// # Returns
111 /// The modified `SetupMessage` instance
112 pub fn with_hash(mut self, hash: [u8; 32]) -> Self {
113 self.hash = hash;
114 self
115 }
116
117 /// Optionally sets the hash of the message to be signed.
118 ///
119 /// # Arguments
120 /// * `hash` - Optional 32-byte hash of the message
121 ///
122 /// # Returns
123 /// The modified `SetupMessage` instance
124 pub fn with_hash_opt(mut self, hash: Option<[u8; 32]>) -> Self {
125 if let Some(hash) = hash {
126 self.hash = hash;
127 }
128 self
129 }
130
131 /// Sets a custom time-to-live duration for messages.
132 ///
133 /// # Arguments
134 /// * `ttl` - The new time-to-live duration
135 ///
136 /// # Returns
137 /// The modified `SetupMessage` instance
138 pub fn with_ttl(mut self, ttl: Duration) -> Self {
139 self.ttl = ttl;
140 self
141 }
142
143 /// Returns a clone of the keyshare.
144 pub fn clone_keyshare(&self) -> Arc<KS> {
145 self.keyshare.clone()
146 }
147
148 /// Returns a reference to the derivation path.
149 pub fn get_chain_path(&self) -> &DerivationPath {
150 &self.chain_path
151 }
152}
153
154impl<SK, VK, MS, KS> ProtocolParticipant for SetupMessage<SK, VK, MS, KS>
155where
156 SK: Signer<MS>,
157 MS: SignatureEncoding,
158 VK: AsRef<[u8]> + Verifier<MS>,
159{
160 type MessageSignature = MS;
161 type MessageSigner = SK;
162 type MessageVerifier = VK;
163
164 /// Returns the signing key for the current participant.
165 fn signer(&self) -> &Self::MessageSigner {
166 &self.sk
167 }
168
169 /// Returns the verifying key for a specific participant.
170 ///
171 /// # Arguments
172 /// * `index` - The index of the participant
173 ///
174 /// # Returns
175 /// A reference to the verifying key
176 fn verifier(&self, index: usize) -> &Self::MessageVerifier {
177 &self.vk[index]
178 }
179
180 /// Returns the instance identifier for the protocol.
181 fn instance_id(&self) -> &InstanceId {
182 &self.instance
183 }
184
185 /// Returns the time-to-live duration for messages.
186 fn message_ttl(&self) -> Duration {
187 self.ttl
188 }
189
190 /// Returns the index of the current participant.
191 fn participant_index(&self) -> usize {
192 self.party_idx
193 }
194
195 /// Returns the total number of participants in the protocol.
196 fn total_participants(&self) -> usize {
197 self.vk.len()
198 }
199}
200
201impl<SK, VK, MS> PreSignSetupMessage for SetupMessage<SK, VK, MS, Keyshare>
202where
203 SK: Signer<MS>,
204 MS: SignatureEncoding,
205 VK: AsRef<[u8]> + Verifier<MS>,
206{
207 /// Returns the derivation path for key derivation.
208 fn chain_path(&self) -> &DerivationPath {
209 &self.chain_path
210 }
211
212 /// Returns a reference to the keyshare.
213 fn keyshare(&self) -> &Keyshare {
214 &self.keyshare
215 }
216}
217
218impl<SK, VK, MS> SignSetupMessage for SetupMessage<SK, VK, MS, Keyshare>
219where
220 SK: Signer<MS>,
221 MS: SignatureEncoding,
222 VK: AsRef<[u8]> + Verifier<MS>,
223{
224 /// Returns the hash of the message to be signed.
225 fn message_hash(&self) -> [u8; 32] {
226 self.hash
227 }
228}