1use rand_core::{CryptoRng, RngCore};
2use std::fmt::Debug;
3
4use hashbrown::{HashMap, HashSet};
5use serde::{Deserialize, Serialize};
6use sha2::{Digest, Sha256};
7use tracing::warn;
8
9use crate::{
10 common::{MerkleRoot, PolyCommitment, PublicNonce, SignatureShare, TupleProof},
11 curve::{
12 ecdsa,
13 point::{Point, G},
14 scalar::Scalar,
15 },
16 schnorr,
17 state_machine::PublicKeys,
18 util::hash_to_scalar,
19};
20
21pub trait Signable {
23 fn hash(&self, hasher: &mut Sha256);
25
26 fn sign(&self, private_key: &Scalar) -> Result<Vec<u8>, ecdsa::Error> {
28 let mut hasher = Sha256::new();
29
30 self.hash(&mut hasher);
31
32 let hash = hasher.finalize();
33 match ecdsa::Signature::new(hash.as_slice(), private_key) {
34 Ok(sig) => Ok(sig.to_bytes().to_vec()),
35 Err(e) => Err(e),
36 }
37 }
38
39 fn verify(&self, signature: &[u8], public_key: &ecdsa::PublicKey) -> bool {
41 let mut hasher = Sha256::new();
42
43 self.hash(&mut hasher);
44
45 let hash = hasher.finalize();
46 let sig = match ecdsa::Signature::try_from(signature) {
47 Ok(sig) => sig,
48 Err(_) => return false,
49 };
50
51 sig.verify(hash.as_slice(), public_key)
52 }
53}
54
55#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
56pub struct BadPrivateShare {
58 pub shared_key: Point,
60 pub tuple_proof: TupleProof,
62}
63
64#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
65pub enum DkgFailure {
67 Threshold,
69 BadState,
71 MissingPublicShares(HashSet<u32>),
73 BadPublicShares(HashSet<u32>),
75 MissingPrivateShares(HashSet<u32>),
77 BadPrivateShares(HashMap<u32, BadPrivateShare>),
79}
80
81#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
82pub enum DkgStatus {
84 Success,
86 Failure(DkgFailure),
88}
89
90#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
91#[allow(clippy::large_enum_variant)]
92pub enum Message {
94 DkgBegin(DkgBegin),
96 DkgPublicShares(DkgPublicShares),
98 DkgPublicSharesDone(DkgPublicSharesDone),
100 DkgPublicSharesDoneAck(DkgPublicSharesDoneAck),
102 DkgPrivateBegin(DkgPrivateBegin),
104 DkgPrivateShares(DkgPrivateShares),
106 DkgPrivateSharesDone(DkgPrivateSharesDone),
108 DkgPrivateSharesDoneAck(DkgPrivateSharesDoneAck),
110 DkgEndBegin(DkgEndBegin),
112 DkgEnd(DkgEnd),
114 NonceRequest(NonceRequest),
116 NonceResponse(NonceResponse),
118 SignatureShareRequest(SignatureShareRequest),
120 SignatureShareResponse(SignatureShareResponse),
122}
123
124impl Signable for Message {
125 fn hash(&self, hasher: &mut Sha256) {
126 match self {
127 Message::DkgBegin(msg) => msg.hash(hasher),
128 Message::DkgPublicShares(msg) => msg.hash(hasher),
129 Message::DkgPublicSharesDone(msg) => msg.hash(hasher),
130 Message::DkgPublicSharesDoneAck(msg) => msg.hash(hasher),
131 Message::DkgPrivateBegin(msg) => msg.hash(hasher),
132 Message::DkgPrivateShares(msg) => msg.hash(hasher),
133 Message::DkgPrivateSharesDone(msg) => msg.hash(hasher),
134 Message::DkgPrivateSharesDoneAck(msg) => msg.hash(hasher),
135 Message::DkgEndBegin(msg) => msg.hash(hasher),
136 Message::DkgEnd(msg) => msg.hash(hasher),
137 Message::NonceRequest(msg) => msg.hash(hasher),
138 Message::NonceResponse(msg) => msg.hash(hasher),
139 Message::SignatureShareRequest(msg) => msg.hash(hasher),
140 Message::SignatureShareResponse(msg) => msg.hash(hasher),
141 }
142 }
143}
144
145#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
146pub struct DkgBegin {
148 pub dkg_id: u64,
150}
151
152impl Signable for DkgBegin {
153 fn hash(&self, hasher: &mut Sha256) {
154 hasher.update("DKG_BEGIN".as_bytes());
155 hasher.update(self.dkg_id.to_be_bytes());
156 }
157}
158
159#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
160pub struct DkgPublicShares {
162 pub dkg_id: u64,
164 pub signer_id: u32,
166 pub comms: Vec<(u32, PolyCommitment)>,
168 pub kex_public_key: Point,
170 pub kex_proof: schnorr::Proof,
172}
173
174#[allow(non_snake_case)]
175impl DkgPublicShares {
176 pub fn kex_prove<RNG: RngCore + CryptoRng>(
178 dkg_id: u64,
179 signer_id: u32,
180 comms: &Vec<(u32, PolyCommitment)>,
181 kex_private_key: &Scalar,
182 rng: &mut RNG,
183 ) -> schnorr::Proof {
184 let r = Scalar::random(rng);
185 let R = r * G;
186 let kex_public_key = kex_private_key * G;
187 let c = Self::kex_challenge(&R, dkg_id, signer_id, comms, &kex_public_key);
188 let s = r + c * kex_private_key;
189
190 schnorr::Proof { R, s }
191 }
192
193 pub fn kex_verify(&self) -> bool {
195 let c = Self::kex_challenge(
196 &self.kex_proof.R,
197 self.dkg_id,
198 self.signer_id,
199 &self.comms,
200 &self.kex_public_key,
201 );
202 self.kex_proof.s * G == self.kex_proof.R + c * self.kex_public_key
203 }
204
205 pub fn kex_challenge(
207 R: &Point,
208 dkg_id: u64,
209 signer_id: u32,
210 comms: &Vec<(u32, PolyCommitment)>,
211 kex_public_key: &Point,
212 ) -> Scalar {
213 let mut hasher = Sha256::new();
214 let tag = "WSTS/DKG_PUBLIC_SHARES/KEX_SCHNORR_PROOF";
215
216 hasher.update(tag.as_bytes());
217 hasher.update(R.compress().as_bytes());
218 hasher.update(dkg_id.to_be_bytes());
219 hasher.update(signer_id.to_be_bytes());
220 hasher.update(kex_public_key.compress().as_bytes());
221 for (party_id, comm) in comms {
222 hasher.update(party_id.to_be_bytes());
223 for a in &comm.poly {
224 hasher.update(a.compress().as_bytes());
225 }
226 }
227
228 hash_to_scalar(&mut hasher)
229 }
230}
231
232impl Signable for DkgPublicShares {
233 fn hash(&self, hasher: &mut Sha256) {
234 hasher.update("DKG_PUBLIC_SHARES".as_bytes());
235 hasher.update(self.dkg_id.to_be_bytes());
236 hasher.update(self.signer_id.to_be_bytes());
237 hasher.update(self.kex_public_key.compress().as_bytes());
238 hasher.update(self.kex_proof.R.compress().as_bytes());
239 hasher.update(self.kex_proof.s.to_bytes());
240 for (party_id, comm) in &self.comms {
241 hasher.update(party_id.to_be_bytes());
242 for a in &comm.poly {
243 hasher.update(a.compress().as_bytes());
244 }
245 }
246 }
247}
248
249#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
250pub struct DkgPublicSharesDone {
252 pub dkg_id: u64,
254 pub signer_ids: Vec<u32>,
256}
257
258impl Signable for DkgPublicSharesDone {
259 fn hash(&self, hasher: &mut Sha256) {
260 hasher.update("DKG_PUBLIC_SHARES_DONE".as_bytes());
261 hasher.update(self.dkg_id.to_be_bytes());
262 for signer_id in &self.signer_ids {
263 hasher.update(signer_id.to_be_bytes());
264 }
265 }
266}
267
268#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
269pub struct DkgPublicSharesDoneAck {
271 pub dkg_id: u64,
273 pub signer_id: u32,
275}
276
277impl Signable for DkgPublicSharesDoneAck {
278 fn hash(&self, hasher: &mut Sha256) {
279 hasher.update("DKG_PUBLIC_SHARES_DONE_ACK".as_bytes());
280 hasher.update(self.dkg_id.to_be_bytes());
281 hasher.update(self.signer_id.to_be_bytes());
282 }
283}
284
285#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
286pub struct DkgPrivateBegin {
288 pub dkg_id: u64,
290 pub signer_ids: Vec<u32>,
292 pub key_ids: Vec<u32>,
294}
295
296impl Signable for DkgPrivateBegin {
297 fn hash(&self, hasher: &mut Sha256) {
298 hasher.update("DKG_PRIVATE_BEGIN".as_bytes());
299 hasher.update(self.dkg_id.to_be_bytes());
300 for key_id in &self.key_ids {
301 hasher.update(key_id.to_be_bytes());
302 }
303 for signer_id in &self.signer_ids {
304 hasher.update(signer_id.to_be_bytes());
305 }
306 }
307}
308
309#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
310pub struct DkgPrivateShares {
312 pub dkg_id: u64,
314 pub signer_id: u32,
316 pub shares: Vec<(u32, HashMap<u32, Vec<u8>>)>,
318}
319
320impl Signable for DkgPrivateShares {
321 fn hash(&self, hasher: &mut Sha256) {
322 hasher.update("DKG_PRIVATE_SHARES".as_bytes());
323 hasher.update(self.dkg_id.to_be_bytes());
324 hasher.update(self.signer_id.to_be_bytes());
325 for (src_id, share) in &self.shares {
327 hasher.update(src_id.to_be_bytes());
328 let mut dst_ids = share.keys().cloned().collect::<Vec<u32>>();
329 dst_ids.sort();
330 for dst_id in &dst_ids {
331 hasher.update(dst_id.to_be_bytes());
332 hasher.update(&share[dst_id]);
333 }
334 }
335 }
336}
337
338#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
339pub struct DkgPrivateSharesDone {
341 pub dkg_id: u64,
343 pub signer_ids: Vec<u32>,
345}
346
347impl Signable for DkgPrivateSharesDone {
348 fn hash(&self, hasher: &mut Sha256) {
349 hasher.update("DKG_PRIVATE_SHARES_DONE".as_bytes());
350 hasher.update(self.dkg_id.to_be_bytes());
351 for signer_id in &self.signer_ids {
352 hasher.update(signer_id.to_be_bytes());
353 }
354 }
355}
356
357#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
358pub struct DkgPrivateSharesDoneAck {
360 pub dkg_id: u64,
362 pub signer_id: u32,
364}
365
366impl Signable for DkgPrivateSharesDoneAck {
367 fn hash(&self, hasher: &mut Sha256) {
368 hasher.update("DKG_PRIVATE_SHARES_DONE_ACK".as_bytes());
369 hasher.update(self.dkg_id.to_be_bytes());
370 hasher.update(self.signer_id.to_be_bytes());
371 }
372}
373
374#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
375pub struct DkgEndBegin {
377 pub dkg_id: u64,
379 pub signer_ids: Vec<u32>,
381 pub key_ids: Vec<u32>,
383}
384
385impl Signable for DkgEndBegin {
386 fn hash(&self, hasher: &mut Sha256) {
387 hasher.update("DKG_END_BEGIN".as_bytes());
388 hasher.update(self.dkg_id.to_be_bytes());
389 for key_id in &self.key_ids {
390 hasher.update(key_id.to_be_bytes());
391 }
392 for signer_id in &self.signer_ids {
393 hasher.update(signer_id.to_be_bytes());
394 }
395 }
396}
397
398#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
399pub struct DkgEnd {
401 pub dkg_id: u64,
403 pub signer_id: u32,
405 pub status: DkgStatus,
407}
408
409impl Signable for DkgEnd {
410 fn hash(&self, hasher: &mut Sha256) {
411 hasher.update("DKG_END".as_bytes());
412 hasher.update(self.dkg_id.to_be_bytes());
413 hasher.update(self.signer_id.to_be_bytes());
414 }
415}
416
417#[derive(Clone, Serialize, Deserialize, PartialEq)]
418pub struct NonceRequest {
420 pub dkg_id: u64,
422 pub sign_id: u64,
424 pub sign_iter_id: u64,
426 pub message: Vec<u8>,
428 pub signature_type: SignatureType,
430}
431
432impl Debug for NonceRequest {
433 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
434 f.debug_struct("NonceRequest")
435 .field("dkg_id", &self.dkg_id)
436 .field("sign_id", &self.sign_id)
437 .field("sign_iter_id", &self.sign_iter_id)
438 .field("message", &hex::encode(&self.message))
439 .field("signature_type", &self.signature_type)
440 .finish()
441 }
442}
443
444impl Signable for NonceRequest {
445 fn hash(&self, hasher: &mut Sha256) {
446 hasher.update("NONCE_REQUEST".as_bytes());
447 hasher.update(self.dkg_id.to_be_bytes());
448 hasher.update(self.sign_id.to_be_bytes());
449 hasher.update(self.sign_iter_id.to_be_bytes());
450 hasher.update(self.message.as_slice());
451 match self.signature_type {
452 SignatureType::Frost => hasher.update("SIGNATURE_TYPE_FROST".as_bytes()),
453 SignatureType::Schnorr => hasher.update("SIGNATURE_TYPE_SCHNORR".as_bytes()),
454 SignatureType::Taproot(merkle_root) => {
455 hasher.update("SIGNATURE_TYPE_TAPROOT".as_bytes());
456 if let Some(merkle_root) = merkle_root {
457 hasher.update(merkle_root);
458 }
459 }
460 }
461 }
462}
463
464#[derive(Clone, Serialize, Deserialize, PartialEq)]
465pub struct NonceResponse {
467 pub dkg_id: u64,
469 pub sign_id: u64,
471 pub sign_iter_id: u64,
473 pub signer_id: u32,
475 pub key_ids: Vec<u32>,
477 pub nonces: Vec<PublicNonce>,
479 pub message: Vec<u8>,
481}
482
483impl Debug for NonceResponse {
484 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
485 f.debug_struct("NonceResponse")
486 .field("dkg_id", &self.dkg_id)
487 .field("sign_id", &self.sign_id)
488 .field("sign_iter_id", &self.sign_iter_id)
489 .field("signer_id", &self.signer_id)
490 .field("key_ids", &self.key_ids)
491 .field(
492 "nonces",
493 &self
494 .nonces
495 .iter()
496 .map(|x| x.to_string())
497 .collect::<Vec<_>>(),
498 )
499 .field("message", &hex::encode(&self.message))
500 .finish()
501 }
502}
503
504impl Signable for NonceResponse {
505 fn hash(&self, hasher: &mut Sha256) {
506 hasher.update("NONCE_RESPONSE".as_bytes());
507 hasher.update(self.dkg_id.to_be_bytes());
508 hasher.update(self.sign_id.to_be_bytes());
509 hasher.update(self.sign_iter_id.to_be_bytes());
510 hasher.update(self.signer_id.to_be_bytes());
511
512 for key_id in &self.key_ids {
513 hasher.update(key_id.to_be_bytes());
514 }
515
516 for nonce in &self.nonces {
517 hasher.update(nonce.D.compress().as_bytes());
518 hasher.update(nonce.E.compress().as_bytes());
519 }
520
521 hasher.update(self.message.as_slice());
522 }
523}
524
525#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq)]
526pub enum SignatureType {
528 Frost,
530 Schnorr,
532 Taproot(Option<MerkleRoot>),
534}
535
536#[derive(Clone, Serialize, Deserialize, PartialEq)]
537pub struct SignatureShareRequest {
539 pub dkg_id: u64,
541 pub sign_id: u64,
543 pub sign_iter_id: u64,
545 pub nonce_responses: Vec<NonceResponse>,
547 pub message: Vec<u8>,
549 pub signature_type: SignatureType,
551}
552
553impl Debug for SignatureShareRequest {
554 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
555 f.debug_struct("SignatureShareRequest")
556 .field("dkg_id", &self.dkg_id)
557 .field("sign_id", &self.sign_id)
558 .field("sign_iter_id", &self.sign_iter_id)
559 .field("nonce_responses", &self.nonce_responses)
560 .field("message", &hex::encode(&self.message))
561 .field("signature_type", &self.signature_type)
562 .finish()
563 }
564}
565
566impl Signable for SignatureShareRequest {
567 fn hash(&self, hasher: &mut Sha256) {
568 hasher.update("SIGNATURE_SHARE_REQUEST".as_bytes());
569 hasher.update(self.dkg_id.to_be_bytes());
570 hasher.update(self.sign_id.to_be_bytes());
571
572 for nonce_response in &self.nonce_responses {
573 nonce_response.hash(hasher);
574 }
575
576 hasher.update(self.message.as_slice());
577 match self.signature_type {
578 SignatureType::Frost => hasher.update("SIGNATURE_TYPE_FROST".as_bytes()),
579 SignatureType::Schnorr => hasher.update("SIGNATURE_TYPE_SCHNORR".as_bytes()),
580 SignatureType::Taproot(merkle_root) => {
581 hasher.update("SIGNATURE_TYPE_TAPROOT".as_bytes());
582 if let Some(merkle_root) = merkle_root {
583 hasher.update(merkle_root);
584 }
585 }
586 }
587 }
588}
589
590#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
591pub struct SignatureShareResponse {
593 pub dkg_id: u64,
595 pub sign_id: u64,
597 pub sign_iter_id: u64,
599 pub signer_id: u32,
601 pub signature_shares: Vec<SignatureShare>,
603}
604
605impl Signable for SignatureShareResponse {
606 fn hash(&self, hasher: &mut Sha256) {
607 hasher.update("SIGNATURE_SHARE_RESPONSE".as_bytes());
608 hasher.update(self.dkg_id.to_be_bytes());
609 hasher.update(self.sign_id.to_be_bytes());
610 hasher.update(self.signer_id.to_be_bytes());
611
612 for signature_share in &self.signature_shares {
613 hasher.update(signature_share.id.to_be_bytes());
614 hasher.update(signature_share.z_i.to_bytes());
615 for key_id in &signature_share.key_ids {
616 hasher.update(key_id.to_be_bytes());
617 }
618 }
619 }
620}
621
622#[derive(Serialize, Deserialize, Clone, PartialEq)]
623pub struct Packet {
625 pub msg: Message,
627 pub sig: Vec<u8>,
629}
630
631impl Debug for Packet {
632 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
633 f.debug_struct("Packet")
634 .field("msg", &self.msg)
635 .field("sig", &hex::encode(&self.sig))
636 .finish()
637 }
638}
639
640impl Packet {
641 pub fn verify(
644 &self,
645 signers_public_keys: &PublicKeys,
646 coordinator_public_key: &ecdsa::PublicKey,
647 ) -> bool {
648 match &self.msg {
649 Message::DkgBegin(msg) => {
650 if !msg.verify(&self.sig, coordinator_public_key) {
651 warn!("Received a DkgBegin message with an invalid signature.");
652 return false;
653 }
654 }
655 Message::DkgPrivateBegin(msg) => {
656 if !msg.verify(&self.sig, coordinator_public_key) {
657 warn!("Received a DkgPrivateBegin message with an invalid signature.");
658 return false;
659 }
660 }
661 Message::DkgEndBegin(msg) => {
662 if !msg.verify(&self.sig, coordinator_public_key) {
663 warn!("Received a DkgEndBegin message with an invalid signature.");
664 return false;
665 }
666 }
667 Message::DkgEnd(msg) => {
668 if let Some(public_key) = signers_public_keys.signers.get(&msg.signer_id) {
669 if !msg.verify(&self.sig, public_key) {
670 warn!("Received a DkgPublicEnd message with an invalid signature.");
671 return false;
672 }
673 } else {
674 warn!(
675 "Received a DkgPublicEnd message with an unknown id: {}",
676 msg.signer_id
677 );
678 return false;
679 }
680 }
681 Message::DkgPublicShares(msg) => {
682 if let Some(public_key) = signers_public_keys.signers.get(&msg.signer_id) {
683 if !msg.verify(&self.sig, public_key) {
684 warn!("Received a DkgPublicShares message with an invalid signature.");
685 return false;
686 }
687 } else {
688 warn!(
689 "Received a DkgPublicShares message with an unknown id: {}",
690 msg.signer_id
691 );
692 return false;
693 }
694 }
695 Message::DkgPublicSharesDone(msg) => {
696 if !msg.verify(&self.sig, coordinator_public_key) {
697 warn!("Received a DkgPublicSharesDone message with an invalid signature.");
698 return false;
699 }
700 }
701 Message::DkgPublicSharesDoneAck(msg) => {
702 if let Some(public_key) = signers_public_keys.signers.get(&msg.signer_id) {
703 if !msg.verify(&self.sig, public_key) {
704 warn!(
705 "Received a DkgPublicSharesDoneAck message with an invalid signature."
706 );
707 return false;
708 }
709 } else {
710 warn!(
711 "Received a DkgPublicSharesDoneAck message with an unknown id: {}",
712 msg.signer_id
713 );
714 return false;
715 }
716 }
717 Message::DkgPrivateShares(msg) => {
718 if let Some(public_key) = signers_public_keys.signers.get(&msg.signer_id) {
722 if !msg.verify(&self.sig, public_key) {
723 warn!("Received a DkgPrivateShares message with an invalid signature from signer_id {} key {}", msg.signer_id, &public_key);
724 return false;
725 }
726 } else {
727 warn!(
728 "Received a DkgPrivateShares message with an unknown id: {}",
729 msg.signer_id
730 );
731 return false;
732 }
733 }
734 Message::DkgPrivateSharesDone(msg) => {
735 if !msg.verify(&self.sig, coordinator_public_key) {
736 warn!("Received a DkgPrivateSharesDone message with an invalid signature.");
737 return false;
738 }
739 }
740 Message::DkgPrivateSharesDoneAck(msg) => {
741 if let Some(public_key) = signers_public_keys.signers.get(&msg.signer_id) {
742 if !msg.verify(&self.sig, public_key) {
743 warn!(
744 "Received a DkgPrivateSharesDoneAck message with an invalid signature."
745 );
746 return false;
747 }
748 } else {
749 warn!(
750 "Received a DkgPrivateSharesDoneAck message with an unknown id: {}",
751 msg.signer_id
752 );
753 return false;
754 }
755 }
756 Message::NonceRequest(msg) => {
757 if !msg.verify(&self.sig, coordinator_public_key) {
758 warn!("Received a NonceRequest message with an invalid signature.");
759 return false;
760 }
761 }
762 Message::NonceResponse(msg) => {
763 if let Some(public_key) = signers_public_keys.signers.get(&msg.signer_id) {
764 if !msg.verify(&self.sig, public_key) {
765 warn!("Received a NonceResponse message with an invalid signature.");
766 return false;
767 }
768 } else {
769 warn!(
770 "Received a NonceResponse message with an unknown id: {}",
771 msg.signer_id
772 );
773 return false;
774 }
775 }
776 Message::SignatureShareRequest(msg) => {
777 if !msg.verify(&self.sig, coordinator_public_key) {
778 warn!("Received a SignatureShareRequest message with an invalid signature.");
779 return false;
780 }
781 }
782 Message::SignatureShareResponse(msg) => {
783 if let Some(public_key) = signers_public_keys.signers.get(&msg.signer_id) {
784 if !msg.verify(&self.sig, public_key) {
785 warn!(
786 "Received a SignatureShareResponse message with an invalid signature."
787 );
788 return false;
789 }
790 } else {
791 warn!(
792 "Received a SignatureShareResponse message with an unknown id: {}",
793 msg.signer_id
794 );
795 return false;
796 }
797 }
798 }
799 true
800 }
801}
802
803#[cfg(test)]
804mod test {
805 use super::*;
806 use crate::schnorr::ID;
807 use crate::util::create_rng;
808 use rand_core::{CryptoRng, RngCore};
809
810 #[derive(Clone, Debug)]
811 #[allow(dead_code)]
812 pub struct TestConfig {
813 pub coordinator_private_key: Scalar,
814 pub coordinator_public_key: ecdsa::PublicKey,
815 pub signer_private_key: Scalar,
816 pub signer_public_key: ecdsa::PublicKey,
817 pub public_keys: PublicKeys,
818 }
819
820 impl TestConfig {
821 pub fn new<RNG: RngCore + CryptoRng>(rng: &mut RNG) -> Self {
822 let coordinator_private_key = Scalar::random(rng);
823 let coordinator_public_key = ecdsa::PublicKey::new(&coordinator_private_key).unwrap();
824 let signer_private_key = Scalar::random(rng);
825 let signer_public_key = ecdsa::PublicKey::new(&signer_private_key).unwrap();
826
827 let mut signer_ids_map = HashMap::new();
828 let mut signer_key_ids = HashMap::new();
829 let mut key_ids_map = HashMap::new();
830 let mut key_ids_set = HashSet::new();
831 signer_ids_map.insert(0, signer_public_key);
832 key_ids_map.insert(1, signer_public_key);
833 key_ids_set.insert(1);
834 signer_key_ids.insert(0, key_ids_set);
835
836 let public_keys = PublicKeys {
837 signers: signer_ids_map,
838 key_ids: key_ids_map,
839 signer_key_ids,
840 };
841
842 Self {
843 coordinator_private_key,
844 coordinator_public_key,
845 signer_private_key,
846 signer_public_key,
847 public_keys,
848 }
849 }
850 }
851
852 impl Default for TestConfig {
853 fn default() -> Self {
854 let mut rng = create_rng();
855 Self::new(&mut rng)
856 }
857 }
858
859 #[test]
860 fn dkg_begin_verify_msg() {
861 let test_config = TestConfig::default();
862 let dkg_begin = DkgBegin { dkg_id: 0 };
863 let dkg_private_begin = DkgPrivateBegin {
864 dkg_id: 0,
865 key_ids: Default::default(),
866 signer_ids: Default::default(),
867 };
868 let msg = Message::DkgBegin(dkg_begin.clone());
869 let coordinator_packet_dkg_begin = Packet {
870 sig: dkg_begin
871 .sign(&test_config.coordinator_private_key)
872 .expect("Failed to sign"),
873 msg: msg.clone(),
874 };
875 let signer_packet_dkg_begin = Packet {
876 sig: dkg_begin
877 .sign(&test_config.signer_private_key)
878 .expect("Failed to sign"),
879 msg,
880 };
881
882 assert!(coordinator_packet_dkg_begin.verify(
883 &test_config.public_keys,
884 &test_config.coordinator_public_key
885 ));
886 assert!(!signer_packet_dkg_begin.verify(
887 &test_config.public_keys,
888 &test_config.coordinator_public_key
889 ));
890
891 let msg = Message::DkgPrivateBegin(dkg_private_begin.clone());
892 let coordinator_packet_dkg_private_begin = Packet {
893 sig: dkg_private_begin
894 .sign(&test_config.coordinator_private_key)
895 .expect("Failed to sign"),
896 msg: msg.clone(),
897 };
898 let signer_packet_dkg_private_begin = Packet {
899 sig: dkg_private_begin
900 .sign(&test_config.signer_private_key)
901 .expect("Failed to sign"),
902 msg,
903 };
904
905 assert!(coordinator_packet_dkg_private_begin.verify(
906 &test_config.public_keys,
907 &test_config.coordinator_public_key
908 ));
909 assert!(!signer_packet_dkg_private_begin.verify(
910 &test_config.public_keys,
911 &test_config.coordinator_public_key
912 ));
913 }
914
915 #[test]
916 fn dkg_public_shares_verify_msg() {
917 let ctx = 0u64.to_be_bytes();
918 let mut rng = create_rng();
919 let test_config = TestConfig::default();
920 let public_shares = DkgPublicShares {
921 dkg_id: 0,
922 signer_id: 0,
923 comms: vec![(
924 0,
925 PolyCommitment {
926 id: ID::new(&Scalar::new(), &Scalar::new(), &ctx, &mut rng),
927 poly: vec![],
928 },
929 )],
930 kex_public_key: Point::from(Scalar::random(&mut rng)),
931 kex_proof: schnorr::Proof {
932 R: Point::new(),
933 s: Scalar::new(),
934 },
935 };
936 let msg = Message::DkgPublicShares(public_shares.clone());
937 let coordinator_packet_dkg_public_shares = Packet {
938 sig: public_shares
939 .sign(&test_config.coordinator_private_key)
940 .expect("Failed to sign"),
941 msg: msg.clone(),
942 };
943 let signer_packet_dkg_public_shares = Packet {
944 sig: public_shares
945 .sign(&test_config.signer_private_key)
946 .expect("Failed to sign"),
947 msg,
948 };
949
950 assert!(!coordinator_packet_dkg_public_shares.verify(
951 &test_config.public_keys,
952 &test_config.coordinator_public_key
953 ));
954 assert!(signer_packet_dkg_public_shares.verify(
955 &test_config.public_keys,
956 &test_config.coordinator_public_key
957 ));
958
959 let mitm_signer_packet_dkg_public_shares = Packet {
961 sig: signer_packet_dkg_public_shares.sig,
962 msg: Message::DkgPublicShares(DkgPublicShares {
963 kex_public_key: Point::from(Scalar::random(&mut rng)),
964 ..public_shares
965 }),
966 };
967 assert!(!mitm_signer_packet_dkg_public_shares.verify(
969 &test_config.public_keys,
970 &test_config.coordinator_public_key
971 ));
972 }
973
974 #[test]
975 fn dkg_private_shares_verify_msg() {
976 let test_config = TestConfig::default();
977 let private_shares = DkgPrivateShares {
978 dkg_id: 0,
979 signer_id: 0,
980 shares: vec![(0, HashMap::new())],
981 };
982 let msg = Message::DkgPrivateShares(private_shares.clone());
983 let coordinator_packet_dkg_private_shares = Packet {
984 sig: private_shares
985 .sign(&test_config.coordinator_private_key)
986 .expect("Failed to sign"),
987 msg: msg.clone(),
988 };
989 let signer_packet_dkg_private_shares = Packet {
990 sig: private_shares
991 .sign(&test_config.signer_private_key)
992 .expect("Failed to sign"),
993 msg,
994 };
995
996 assert!(!coordinator_packet_dkg_private_shares.verify(
997 &test_config.public_keys,
998 &test_config.coordinator_public_key
999 ));
1000 assert!(signer_packet_dkg_private_shares.verify(
1001 &test_config.public_keys,
1002 &test_config.coordinator_public_key
1003 ));
1004 }
1005
1006 #[test]
1007 fn dkg_end_verify_msg() {
1008 let test_config = TestConfig::default();
1009 let dkg_end = DkgEnd {
1010 dkg_id: 0,
1011 signer_id: 0,
1012 status: DkgStatus::Success,
1013 };
1014 let msg = Message::DkgEnd(dkg_end.clone());
1015
1016 let coordinator_packet_dkg_end = Packet {
1017 sig: dkg_end
1018 .sign(&test_config.coordinator_private_key)
1019 .expect("Failed to sign"),
1020 msg: msg.clone(),
1021 };
1022 let signer_packet_dkg_end = Packet {
1023 sig: dkg_end
1024 .sign(&test_config.signer_private_key)
1025 .expect("Failed to sign"),
1026 msg,
1027 };
1028 assert!(!coordinator_packet_dkg_end.verify(
1029 &test_config.public_keys,
1030 &test_config.coordinator_public_key
1031 ));
1032 assert!(signer_packet_dkg_end.verify(
1033 &test_config.public_keys,
1034 &test_config.coordinator_public_key
1035 ));
1036 }
1037 #[test]
1038 fn nonce_request_verify_msg() {
1039 let test_config = TestConfig::default();
1040 let nonce_request = NonceRequest {
1041 dkg_id: 0,
1042 sign_id: 0,
1043 sign_iter_id: 0,
1044 message: vec![],
1045 signature_type: SignatureType::Frost,
1046 };
1047 let msg = Message::NonceRequest(nonce_request.clone());
1048 let coordinator_packet_nonce_request = Packet {
1049 sig: nonce_request
1050 .sign(&test_config.coordinator_private_key)
1051 .expect("Failed to sign"),
1052 msg: msg.clone(),
1053 };
1054 let signer_packet_nonce_request = Packet {
1055 sig: nonce_request
1056 .sign(&test_config.signer_private_key)
1057 .expect("Failed to sign"),
1058 msg,
1059 };
1060 assert!(coordinator_packet_nonce_request.verify(
1061 &test_config.public_keys,
1062 &test_config.coordinator_public_key
1063 ));
1064 assert!(!signer_packet_nonce_request.verify(
1065 &test_config.public_keys,
1066 &test_config.coordinator_public_key
1067 ));
1068 }
1069 #[test]
1070 fn nonce_response_verify_msg() {
1071 let test_config = TestConfig::default();
1072
1073 let nonce_response = NonceResponse {
1074 dkg_id: 0,
1075 sign_id: 0,
1076 sign_iter_id: 0,
1077 signer_id: 0,
1078 key_ids: vec![],
1079 nonces: vec![],
1080 message: vec![],
1081 };
1082 let msg = Message::NonceResponse(nonce_response.clone());
1083 let coordinator_packet_nonce_response = Packet {
1084 sig: nonce_response
1085 .sign(&test_config.coordinator_private_key)
1086 .expect("Failed to sign"),
1087 msg: msg.clone(),
1088 };
1089 let signer_packet_nonce_response = Packet {
1090 sig: nonce_response
1091 .sign(&test_config.signer_private_key)
1092 .expect("Failed to sign"),
1093 msg,
1094 };
1095 assert!(!coordinator_packet_nonce_response.verify(
1096 &test_config.public_keys,
1097 &test_config.coordinator_public_key
1098 ));
1099 assert!(signer_packet_nonce_response.verify(
1100 &test_config.public_keys,
1101 &test_config.coordinator_public_key
1102 ));
1103 }
1104
1105 #[test]
1106 fn signature_share_request_verify_msg() {
1107 let test_config = TestConfig::default();
1108 let signature_share_request = SignatureShareRequest {
1109 dkg_id: 0,
1110 sign_id: 0,
1111 sign_iter_id: 0,
1112 nonce_responses: vec![],
1113 message: vec![],
1114 signature_type: SignatureType::Frost,
1115 };
1116 let msg = Message::SignatureShareRequest(signature_share_request.clone());
1117 let coordinator_packet_signature_share_request = Packet {
1118 sig: signature_share_request
1119 .sign(&test_config.coordinator_private_key)
1120 .expect("Failed to sign"),
1121 msg: msg.clone(),
1122 };
1123 let signer_packet_signature_share_request = Packet {
1124 sig: signature_share_request
1125 .sign(&test_config.signer_private_key)
1126 .expect("Failed to sign"),
1127 msg,
1128 };
1129 assert!(coordinator_packet_signature_share_request.verify(
1130 &test_config.public_keys,
1131 &test_config.coordinator_public_key
1132 ));
1133 assert!(!signer_packet_signature_share_request.verify(
1134 &test_config.public_keys,
1135 &test_config.coordinator_public_key
1136 ));
1137 }
1138
1139 #[test]
1140 fn signature_share_response_verify_msg() {
1141 let test_config = TestConfig::default();
1142
1143 let signature_share_response = SignatureShareResponse {
1144 dkg_id: 0,
1145 sign_id: 0,
1146 sign_iter_id: 0,
1147 signer_id: 0,
1148 signature_shares: vec![],
1149 };
1150 let msg = Message::SignatureShareResponse(signature_share_response.clone());
1151 let coordinator_packet_signature_share_response = Packet {
1152 sig: signature_share_response
1153 .sign(&test_config.coordinator_private_key)
1154 .expect("Failed to sign"),
1155 msg: msg.clone(),
1156 };
1157 let signer_packet_signature_share_response = Packet {
1158 sig: signature_share_response
1159 .sign(&test_config.signer_private_key)
1160 .expect("Failed to sign"),
1161 msg,
1162 };
1163 assert!(!coordinator_packet_signature_share_response.verify(
1164 &test_config.public_keys,
1165 &test_config.coordinator_public_key
1166 ));
1167 assert!(signer_packet_signature_share_response.verify(
1168 &test_config.public_keys,
1169 &test_config.coordinator_public_key
1170 ));
1171 }
1172
1173 #[test]
1174 fn signature_share_response_wrapped_verify_msg() {
1175 let test_config = TestConfig::default();
1176
1177 let signature_share_response = SignatureShareResponse {
1178 dkg_id: 0,
1179 sign_id: 0,
1180 sign_iter_id: 0,
1181 signer_id: 0,
1182 signature_shares: vec![],
1183 };
1184 let msg = Message::SignatureShareResponse(signature_share_response.clone());
1185 let sig = msg
1186 .sign(&test_config.coordinator_private_key)
1187 .expect("Failed to sign");
1188 assert!(msg.verify(&sig, &test_config.coordinator_public_key));
1189 }
1190}