1use crate::{PublicKey, SignatureBytes};
7use thiserror::Error;
8
9#[derive(Debug, Error)]
11pub enum ThresholdError {
12 #[error("Not enough signatures: need {threshold}, got {actual}")]
13 InsufficientSignatures { threshold: usize, actual: usize },
14
15 #[error("Invalid signature at index {0}")]
16 InvalidSignature(usize),
17
18 #[error("Duplicate public key")]
19 DuplicatePublicKey,
20
21 #[error("Invalid threshold: {0}")]
22 InvalidThreshold(String),
23
24 #[error("Signing error: {0}")]
25 SigningError(#[from] crate::SigningError),
26}
27
28#[derive(Debug, Clone)]
33pub struct MultiSig {
34 pub signers: Vec<PublicKey>,
36 pub signatures: Vec<SignatureBytes>,
38}
39
40impl MultiSig {
41 pub fn new(signers: Vec<PublicKey>, signatures: Vec<SignatureBytes>) -> Self {
43 Self {
44 signers,
45 signatures,
46 }
47 }
48
49 pub fn verify(&self, message: &[u8]) -> Result<(), ThresholdError> {
51 use crate::signing::verify;
52
53 if self.signers.len() != self.signatures.len() {
54 return Err(ThresholdError::InsufficientSignatures {
55 threshold: self.signers.len(),
56 actual: self.signatures.len(),
57 });
58 }
59
60 for (i, (pubkey, sig)) in self.signers.iter().zip(self.signatures.iter()).enumerate() {
61 verify(pubkey, message, sig).map_err(|_| ThresholdError::InvalidSignature(i))?;
62 }
63
64 Ok(())
65 }
66
67 pub fn signer_count(&self) -> usize {
69 self.signers.len()
70 }
71}
72
73#[derive(Debug, Clone)]
77pub struct ThresholdSig {
78 pub possible_signers: Vec<PublicKey>,
80 pub threshold: usize,
82 pub signatures: Vec<(PublicKey, SignatureBytes)>,
84}
85
86impl ThresholdSig {
87 pub fn new(possible_signers: Vec<PublicKey>, threshold: usize) -> Result<Self, ThresholdError> {
89 if threshold == 0 || threshold > possible_signers.len() {
90 return Err(ThresholdError::InvalidThreshold(format!(
91 "threshold must be 1 <= M <= {}, got {}",
92 possible_signers.len(),
93 threshold
94 )));
95 }
96
97 let mut sorted = possible_signers.clone();
99 sorted.sort();
100 for i in 1..sorted.len() {
101 if sorted[i] == sorted[i - 1] {
102 return Err(ThresholdError::DuplicatePublicKey);
103 }
104 }
105
106 Ok(Self {
107 possible_signers,
108 threshold,
109 signatures: Vec::new(),
110 })
111 }
112
113 pub fn add_signature(
115 &mut self,
116 signer: PublicKey,
117 signature: SignatureBytes,
118 ) -> Result<(), ThresholdError> {
119 if !self.possible_signers.contains(&signer) {
121 return Err(ThresholdError::InvalidSignature(0));
122 }
123
124 if self.signatures.iter().any(|(pk, _)| pk == &signer) {
126 return Err(ThresholdError::DuplicatePublicKey);
127 }
128
129 self.signatures.push((signer, signature));
130 Ok(())
131 }
132
133 pub fn verify(&self, message: &[u8]) -> Result<(), ThresholdError> {
135 use crate::signing::verify;
136
137 if self.signatures.len() < self.threshold {
138 return Err(ThresholdError::InsufficientSignatures {
139 threshold: self.threshold,
140 actual: self.signatures.len(),
141 });
142 }
143
144 for (i, (pubkey, sig)) in self.signatures.iter().enumerate() {
146 if !self.possible_signers.contains(pubkey) {
148 return Err(ThresholdError::InvalidSignature(i));
149 }
150
151 verify(pubkey, message, sig).map_err(|_| ThresholdError::InvalidSignature(i))?;
153 }
154
155 Ok(())
156 }
157
158 pub fn is_complete(&self) -> bool {
160 self.signatures.len() >= self.threshold
161 }
162
163 pub fn signature_count(&self) -> usize {
165 self.signatures.len()
166 }
167}
168
169pub struct MultiSigBuilder {
171 signers: Vec<PublicKey>,
172 signatures: Vec<Option<SignatureBytes>>,
173}
174
175impl MultiSigBuilder {
176 pub fn new(signers: Vec<PublicKey>) -> Self {
178 let count = signers.len();
179 Self {
180 signers,
181 signatures: vec![None; count],
182 }
183 }
184
185 pub fn add_signature(
187 &mut self,
188 signer: &PublicKey,
189 signature: SignatureBytes,
190 ) -> Result<(), ThresholdError> {
191 let index = self
192 .signers
193 .iter()
194 .position(|pk| pk == signer)
195 .ok_or(ThresholdError::InvalidSignature(0))?;
196
197 self.signatures[index] = Some(signature);
198 Ok(())
199 }
200
201 pub fn is_complete(&self) -> bool {
203 self.signatures.iter().all(|s| s.is_some())
204 }
205
206 pub fn build(self) -> Result<MultiSig, ThresholdError> {
208 let signatures: Option<Vec<SignatureBytes>> = self.signatures.into_iter().collect();
209
210 match signatures {
211 Some(sigs) => Ok(MultiSig::new(self.signers, sigs)),
212 None => Err(ThresholdError::InsufficientSignatures {
213 threshold: self.signers.len(),
214 actual: 0,
215 }),
216 }
217 }
218}
219
220pub struct ThresholdCoordinator {
225 threshold_sig: ThresholdSig,
227 message: Vec<u8>,
229}
230
231impl ThresholdCoordinator {
232 pub fn new(
234 possible_signers: Vec<PublicKey>,
235 threshold: usize,
236 message: Vec<u8>,
237 ) -> Result<Self, ThresholdError> {
238 let threshold_sig = ThresholdSig::new(possible_signers, threshold)?;
239
240 Ok(Self {
241 threshold_sig,
242 message,
243 })
244 }
245
246 pub fn add_signature(
248 &mut self,
249 signer: PublicKey,
250 signature: SignatureBytes,
251 ) -> Result<(), ThresholdError> {
252 use crate::signing::verify;
253
254 verify(&signer, &self.message, &signature)?;
256
257 self.threshold_sig.add_signature(signer, signature)
258 }
259
260 pub fn is_complete(&self) -> bool {
262 self.threshold_sig.is_complete()
263 }
264
265 pub fn finalize(self) -> Result<ThresholdSig, ThresholdError> {
267 if !self.threshold_sig.is_complete() {
268 return Err(ThresholdError::InsufficientSignatures {
269 threshold: self.threshold_sig.threshold,
270 actual: self.threshold_sig.signature_count(),
271 });
272 }
273
274 Ok(self.threshold_sig)
275 }
276}
277
278#[cfg(test)]
279mod tests {
280 use super::*;
281 use crate::signing::KeyPair;
282
283 #[test]
284 fn test_multi_sig() {
285 let message = b"Multi-sig test message";
286
287 let kp1 = KeyPair::generate();
289 let kp2 = KeyPair::generate();
290 let kp3 = KeyPair::generate();
291
292 let signers = vec![kp1.public_key(), kp2.public_key(), kp3.public_key()];
293
294 let signatures = vec![kp1.sign(message), kp2.sign(message), kp3.sign(message)];
295
296 let multi_sig = MultiSig::new(signers, signatures);
297 assert!(multi_sig.verify(message).is_ok());
298 }
299
300 #[test]
301 fn test_multi_sig_invalid() {
302 let message = b"Test message";
303 let wrong_message = b"Wrong message";
304
305 let kp1 = KeyPair::generate();
306 let kp2 = KeyPair::generate();
307
308 let signers = vec![kp1.public_key(), kp2.public_key()];
309 let signatures = vec![kp1.sign(message), kp2.sign(wrong_message)];
310
311 let multi_sig = MultiSig::new(signers, signatures);
312 assert!(multi_sig.verify(message).is_err());
313 }
314
315 #[test]
316 fn test_threshold_sig_2_of_3() {
317 let message = b"Threshold sig test";
318
319 let kp1 = KeyPair::generate();
320 let kp2 = KeyPair::generate();
321 let kp3 = KeyPair::generate();
322
323 let possible_signers = vec![kp1.public_key(), kp2.public_key(), kp3.public_key()];
324
325 let mut threshold_sig = ThresholdSig::new(possible_signers, 2).unwrap();
326
327 threshold_sig
329 .add_signature(kp1.public_key(), kp1.sign(message))
330 .unwrap();
331 assert!(!threshold_sig.is_complete());
332
333 threshold_sig
335 .add_signature(kp2.public_key(), kp2.sign(message))
336 .unwrap();
337 assert!(threshold_sig.is_complete());
338
339 assert!(threshold_sig.verify(message).is_ok());
341 }
342
343 #[test]
344 fn test_threshold_insufficient_signatures() {
345 let message = b"Test";
346
347 let kp1 = KeyPair::generate();
348 let kp2 = KeyPair::generate();
349 let kp3 = KeyPair::generate();
350
351 let possible_signers = vec![kp1.public_key(), kp2.public_key(), kp3.public_key()];
352
353 let mut threshold_sig = ThresholdSig::new(possible_signers, 2).unwrap();
354
355 threshold_sig
357 .add_signature(kp1.public_key(), kp1.sign(message))
358 .unwrap();
359
360 assert!(threshold_sig.verify(message).is_err());
362 }
363
364 #[test]
365 fn test_multi_sig_builder() {
366 let message = b"Builder test";
367
368 let kp1 = KeyPair::generate();
369 let kp2 = KeyPair::generate();
370
371 let signers = vec![kp1.public_key(), kp2.public_key()];
372 let mut builder = MultiSigBuilder::new(signers);
373
374 assert!(!builder.is_complete());
375
376 builder
377 .add_signature(&kp1.public_key(), kp1.sign(message))
378 .unwrap();
379 assert!(!builder.is_complete());
380
381 builder
382 .add_signature(&kp2.public_key(), kp2.sign(message))
383 .unwrap();
384 assert!(builder.is_complete());
385
386 let multi_sig = builder.build().unwrap();
387 assert!(multi_sig.verify(message).is_ok());
388 }
389
390 #[test]
391 fn test_threshold_coordinator() {
392 let message = b"Coordinator test";
393
394 let kp1 = KeyPair::generate();
395 let kp2 = KeyPair::generate();
396 let kp3 = KeyPair::generate();
397
398 let signers = vec![kp1.public_key(), kp2.public_key(), kp3.public_key()];
399
400 let mut coordinator = ThresholdCoordinator::new(signers, 2, message.to_vec()).unwrap();
401
402 coordinator
403 .add_signature(kp1.public_key(), kp1.sign(message))
404 .unwrap();
405 assert!(!coordinator.is_complete());
406
407 coordinator
408 .add_signature(kp2.public_key(), kp2.sign(message))
409 .unwrap();
410 assert!(coordinator.is_complete());
411
412 let threshold_sig = coordinator.finalize().unwrap();
413 assert!(threshold_sig.verify(message).is_ok());
414 }
415
416 #[test]
417 fn test_invalid_threshold() {
418 let kp1 = KeyPair::generate();
419 let signers = vec![kp1.public_key()];
420
421 assert!(ThresholdSig::new(signers.clone(), 0).is_err());
423
424 assert!(ThresholdSig::new(signers, 2).is_err());
426 }
427}