1pub mod arbiter;
128pub use arbiter::Arbiter;
129pub mod dealer;
130pub use dealer::Dealer;
131pub mod ops;
132pub mod player;
133pub use player::Player;
134
135use thiserror::Error;
136
137#[derive(Error, Debug)]
138pub enum Error {
139 #[error("unexpected polynomial")]
140 UnexpectedPolynomial,
141 #[error("commitment has wrong degree")]
142 CommitmentWrongDegree,
143 #[error("misdirected share")]
144 MisdirectedShare,
145 #[error("share does not on commitment")]
146 ShareWrongCommitment,
147 #[error("insufficient dealings")]
148 InsufficientDealings,
149 #[error("reshare mismatch")]
150 ReshareMismatch,
151 #[error("share interpolation failed")]
152 ShareInterpolationFailed,
153 #[error("public key interpolation failed")]
154 PublicKeyInterpolationFailed,
155 #[error("dealer is invalid")]
156 DealerInvalid,
157 #[error("player invalid")]
158 PlayerInvalid,
159 #[error("missing share")]
160 MissingShare,
161 #[error("missing commitment")]
162 MissingCommitment,
163 #[error("too many commitments")]
164 TooManyCommitments,
165 #[error("duplicate commitment")]
166 DuplicateCommitment,
167 #[error("duplicate share")]
168 DuplicateShare,
169 #[error("duplicate ack")]
170 DuplicateAck,
171 #[error("mismatched commitment")]
172 MismatchedCommitment,
173 #[error("mismatched share")]
174 MismatchedShare,
175 #[error("too many reveals")]
176 TooManyReveals,
177 #[error("incorrect active")]
178 IncorrectActive,
179 #[error("already active")]
180 AlreadyActive,
181 #[error("invalid commitments")]
182 InvalidCommitments,
183 #[error("dealer disqualified")]
184 DealerDisqualified,
185}
186
187#[cfg(test)]
188mod tests {
189 use super::*;
190 use crate::bls12381::primitives::ops::{
191 partial_sign_proof_of_possession, threshold_signature_recover, verify_proof_of_possession,
192 };
193 use crate::bls12381::primitives::poly::public;
194 use crate::bls12381::primitives::variant::{MinPk, MinSig, Variant};
195 use crate::{Ed25519, Signer};
196 use arbiter::Output;
197 use commonware_utils::quorum;
198 use rand::rngs::StdRng;
199 use rand::SeedableRng;
200 use std::collections::HashMap;
201
202 fn run_dkg_and_reshare<V: Variant>(
203 n_0: u32,
204 dealers_0: u32,
205 n_1: u32,
206 dealers_1: u32,
207 concurrency: usize,
208 ) {
209 let mut rng = StdRng::seed_from_u64(0);
211
212 let mut contributors = Vec::new();
214 for i in 0..n_0 {
215 let signer = Ed25519::from_seed(i as u64).public_key();
216 contributors.push(signer);
217 }
218 contributors.sort();
219
220 let mut dealer_shares = HashMap::new();
222 let mut dealers = HashMap::new();
223 for con in contributors.iter().take(dealers_0 as usize) {
224 let (dealer, commitment, shares) =
225 Dealer::<_, V>::new(&mut rng, None, contributors.clone());
226 dealer_shares.insert(con.clone(), (commitment, shares));
227 dealers.insert(con.clone(), dealer);
228 }
229
230 let mut players = HashMap::new();
232 for con in &contributors {
233 let player = Player::<_, V>::new(
234 con.clone(),
235 None,
236 contributors.clone(),
237 contributors.clone(),
238 concurrency,
239 );
240 players.insert(con.clone(), player);
241 }
242
243 let mut arb = Arbiter::<_, V>::new(
245 None,
246 contributors.clone(),
247 contributors.clone(),
248 concurrency,
249 );
250
251 assert!(!arb.ready());
253
254 for (dealer, mut dealer_obj) in dealers {
256 let (commitment, shares) = dealer_shares.get(&dealer).unwrap().clone();
258 for (player_idx, player) in contributors.iter().enumerate() {
259 let player_obj = players.get_mut(player).unwrap();
261 player_obj
262 .share(
263 dealer.clone(),
264 commitment.clone(),
265 shares[player_idx].clone(),
266 )
267 .unwrap();
268
269 dealer_obj.ack(player.clone()).unwrap();
271 }
272
273 let output = dealer_obj.finalize().unwrap();
275
276 assert!(output.inactive.is_empty());
278
279 arb.commitment(dealer, commitment, output.active, Vec::new())
281 .unwrap();
282 }
283
284 assert!(arb.ready());
286
287 let (result, disqualified) = arb.finalize();
289
290 assert_eq!(disqualified.len(), (n_0 - dealers_0) as usize);
292
293 let output: Output<V> = result.unwrap();
295
296 let expected_commitments = quorum(n_0) as usize;
298 assert_eq!(output.commitments.len(), expected_commitments);
299
300 assert!(output.reveals.is_empty());
302
303 let mut outputs = HashMap::new();
305 for player in contributors.iter() {
306 let result = players
307 .remove(player)
308 .unwrap()
309 .finalize(output.commitments.clone(), HashMap::new())
310 .unwrap();
311 outputs.insert(player.clone(), result);
312 }
313
314 let t = quorum(n_0);
316 let partials = outputs
317 .values()
318 .map(|s| partial_sign_proof_of_possession::<V>(&s.public, &s.share))
319 .collect::<Vec<_>>();
320 let signature =
321 threshold_signature_recover::<V, _>(t, &partials).expect("unable to recover signature");
322 let public_key = public::<V>(&outputs.iter().next().unwrap().1.public);
323 verify_proof_of_possession::<V>(public_key, &signature)
324 .expect("invalid proof of possession");
325
326 let mut reshare_players = Vec::new();
328 for i in 0..n_1 {
329 let player = Ed25519::from_seed((i + n_0) as u64).public_key();
330 reshare_players.push(player);
331 }
332 reshare_players.sort();
333
334 let mut reshare_shares = HashMap::new();
336 let mut reshare_dealers = HashMap::new();
337 for con in contributors.iter().take(dealers_1 as usize) {
338 let output = outputs.get(con).unwrap();
339 let (dealer, commitment, shares) = Dealer::<_, V>::new(
340 &mut rng,
341 Some(output.share.clone()),
342 reshare_players.clone(),
343 );
344 reshare_shares.insert(con.clone(), (commitment, shares));
345 reshare_dealers.insert(con.clone(), dealer);
346 }
347
348 let mut reshare_player_objs = HashMap::new();
350 for con in &reshare_players {
351 let player = Player::<_, V>::new(
352 con.clone(),
353 Some(output.public.clone()),
354 contributors.clone(),
355 reshare_players.clone(),
356 concurrency,
357 );
358 reshare_player_objs.insert(con.clone(), player);
359 }
360
361 let mut arb = Arbiter::<_, V>::new(
363 Some(output.public),
364 contributors.clone(),
365 reshare_players.clone(),
366 concurrency,
367 );
368
369 assert!(!arb.ready());
371
372 for (dealer, mut dealer_obj) in reshare_dealers {
374 let (commitment, shares) = reshare_shares.get(&dealer).unwrap().clone();
376 for (player_idx, player) in reshare_players.iter().enumerate() {
377 let player_obj = reshare_player_objs.get_mut(player).unwrap();
379 player_obj
380 .share(
381 dealer.clone(),
382 commitment.clone(),
383 shares[player_idx].clone(),
384 )
385 .unwrap();
386
387 dealer_obj.ack(player.clone()).unwrap();
389 }
390
391 let output = dealer_obj.finalize().unwrap();
393
394 assert!(output.inactive.is_empty());
396
397 arb.commitment(dealer, commitment, output.active, Vec::new())
399 .unwrap();
400 }
401
402 assert!(arb.ready());
404
405 let (result, disqualified) = arb.finalize();
407
408 assert_eq!(disqualified.len(), (n_0 - dealers_1) as usize);
410
411 let output: Output<V> = result.unwrap();
413
414 let expected_commitments = quorum(n_0) as usize;
416 assert_eq!(output.commitments.len(), expected_commitments);
417
418 assert!(output.reveals.is_empty());
420
421 let mut outputs = Vec::new();
423 for player in reshare_players.iter() {
424 let result = reshare_player_objs
425 .remove(player)
426 .unwrap()
427 .finalize(output.commitments.clone(), HashMap::new())
428 .unwrap();
429 assert_eq!(result.public, output.public);
430 outputs.push(result);
431 }
432
433 let t = quorum(n_1);
435 let partials = outputs
436 .iter()
437 .map(|s| partial_sign_proof_of_possession::<V>(&s.public, &s.share))
438 .collect::<Vec<_>>();
439 let signature =
440 threshold_signature_recover::<V, _>(t, &partials).expect("unable to recover signature");
441 let public_key = public::<V>(&outputs[0].public);
442 verify_proof_of_possession::<V>(public_key, &signature)
443 .expect("invalid proof of possession");
444 }
445
446 #[test]
447 fn test_dkg_and_reshare_all_active() {
448 run_dkg_and_reshare::<MinPk>(5, 5, 10, 5, 4);
449 run_dkg_and_reshare::<MinSig>(5, 5, 10, 5, 4);
450 }
451
452 #[test]
453 fn test_dkg_and_reshare_min_active() {
454 run_dkg_and_reshare::<MinPk>(4, 3, 4, 3, 4);
455 run_dkg_and_reshare::<MinSig>(4, 3, 4, 3, 4);
456 }
457
458 #[test]
459 fn test_dkg_and_reshare_min_active_different_sizes() {
460 run_dkg_and_reshare::<MinPk>(5, 4, 10, 4, 4);
461 run_dkg_and_reshare::<MinSig>(5, 4, 10, 4, 4);
462 }
463
464 #[test]
465 fn test_dkg_and_reshare_min_active_large() {
466 run_dkg_and_reshare::<MinPk>(20, 14, 100, 14, 4);
467 run_dkg_and_reshare::<MinSig>(20, 14, 100, 14, 4);
468 }
469
470 #[test]
471 #[should_panic]
472 fn test_dkg_and_reshare_insufficient_active() {
473 run_dkg_and_reshare::<MinPk>(5, 3, 10, 2, 4);
474 run_dkg_and_reshare::<MinSig>(5, 3, 10, 2, 4);
475 }
476
477 #[test]
478 fn test_invalid_commitment() {
479 let n = 5;
481 let mut rng = StdRng::seed_from_u64(0);
482
483 let mut contributors = Vec::new();
485 for i in 0..n {
486 let signer = Ed25519::from_seed(i as u64).public_key();
487 contributors.push(signer);
488 }
489 contributors.sort();
490
491 let (_, _, shares) = Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
493
494 let t = quorum(n);
496 let (public, _) = ops::generate_shares::<_, MinSig>(&mut rng, None, n, t);
497
498 let mut player = Player::<_, MinSig>::new(
500 contributors[0].clone(),
501 None,
502 contributors.clone(),
503 contributors.clone(),
504 1,
505 );
506
507 let result = player.share(contributors[0].clone(), public, shares[0].clone());
509 assert!(matches!(result, Err(Error::ShareWrongCommitment)));
510 }
511
512 #[test]
513 fn test_mismatched_commitment() {
514 let n = 5;
516 let mut rng = StdRng::seed_from_u64(0);
517
518 let mut contributors = Vec::new();
520 for i in 0..n {
521 let signer = Ed25519::from_seed(i as u64).public_key();
522 contributors.push(signer);
523 }
524 contributors.sort();
525
526 let (_, commitment, shares) =
528 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
529
530 let t = quorum(n);
532 let (other_commitment, _) = ops::generate_shares::<_, MinSig>(&mut rng, None, n, t);
533
534 let mut player = Player::<_, MinSig>::new(
536 contributors[0].clone(),
537 None,
538 contributors.clone(),
539 contributors.clone(),
540 1,
541 );
542
543 player
545 .share(contributors[0].clone(), commitment, shares[0].clone())
546 .unwrap();
547
548 let result = player.share(contributors[0].clone(), other_commitment, shares[0].clone());
550 assert!(matches!(result, Err(Error::MismatchedCommitment)));
551 }
552
553 #[test]
554 fn test_mismatched_share() {
555 let n = 5;
557 let mut rng = StdRng::seed_from_u64(0);
558
559 let mut contributors = Vec::new();
561 for i in 0..n {
562 let signer = Ed25519::from_seed(i as u64).public_key();
563 contributors.push(signer);
564 }
565 contributors.sort();
566
567 let (_, commitment, shares) =
569 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
570
571 let t = quorum(n);
573 let (_, other_shares) = ops::generate_shares::<_, MinSig>(&mut rng, None, n, t);
574
575 let mut player = Player::<_, MinSig>::new(
577 contributors[0].clone(),
578 None,
579 contributors.clone(),
580 contributors.clone(),
581 1,
582 );
583
584 player
586 .share(
587 contributors[0].clone(),
588 commitment.clone(),
589 shares[0].clone(),
590 )
591 .unwrap();
592
593 let result = player.share(contributors[0].clone(), commitment, other_shares[0].clone());
595 assert!(matches!(result, Err(Error::MismatchedShare)));
596 }
597
598 #[test]
599 fn test_duplicate_share() {
600 let n = 5;
602 let mut rng = StdRng::seed_from_u64(0);
603
604 let mut contributors = Vec::new();
606 for i in 0..n {
607 let signer = Ed25519::from_seed(i as u64).public_key();
608 contributors.push(signer);
609 }
610 contributors.sort();
611
612 let (_, commitment, shares) =
614 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
615
616 let mut player = Player::<_, MinSig>::new(
618 contributors[0].clone(),
619 None,
620 contributors.clone(),
621 contributors.clone(),
622 1,
623 );
624
625 player
627 .share(
628 contributors[0].clone(),
629 commitment.clone(),
630 shares[0].clone(),
631 )
632 .unwrap();
633
634 let result = player.share(contributors[0].clone(), commitment, shares[0].clone());
636 assert!(matches!(result, Err(Error::DuplicateShare)));
637 }
638
639 #[test]
640 fn test_misdirected_share() {
641 let n = 5;
643 let mut rng = StdRng::seed_from_u64(0);
644
645 let mut contributors = Vec::new();
647 for i in 0..n {
648 let signer = Ed25519::from_seed(i as u64).public_key();
649 contributors.push(signer);
650 }
651 contributors.sort();
652
653 let (_, commitment, shares) =
655 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
656
657 let mut player = Player::<_, MinSig>::new(
659 contributors[0].clone(),
660 None,
661 contributors.clone(),
662 contributors.clone(),
663 1,
664 );
665
666 let result = player.share(
668 contributors[0].clone(),
669 commitment.clone(),
670 shares[1].clone(),
671 );
672 assert!(matches!(result, Err(Error::MisdirectedShare)));
673 }
674
675 #[test]
676 fn test_invalid_dealer() {
677 let n = 5;
679 let mut rng = StdRng::seed_from_u64(0);
680
681 let mut contributors = Vec::new();
683 for i in 0..n {
684 let signer = Ed25519::from_seed(i as u64).public_key();
685 contributors.push(signer);
686 }
687 contributors.sort();
688
689 let (_, commitment, shares) =
691 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
692
693 let mut player = Player::<_, MinSig>::new(
695 contributors[0].clone(),
696 None,
697 contributors.clone(),
698 contributors.clone(),
699 1,
700 );
701
702 let dealer = Ed25519::from_seed(n as u64).public_key();
704 let result = player.share(dealer.clone(), commitment.clone(), shares[0].clone());
705 assert!(matches!(result, Err(Error::DealerInvalid)));
706
707 let mut arb =
709 Arbiter::<_, MinSig>::new(None, contributors.clone(), contributors.clone(), 1);
710
711 let result = arb.commitment(dealer, commitment, vec![0, 1, 2, 3], Vec::new());
713 assert!(matches!(result, Err(Error::DealerInvalid)));
714 }
715
716 #[test]
717 fn test_invalid_commitment_degree() {
718 let n = 5;
720 let mut rng = StdRng::seed_from_u64(0);
721
722 let mut contributors = Vec::new();
724 for i in 0..n {
725 let signer = Ed25519::from_seed(i as u64).public_key();
726 contributors.push(signer);
727 }
728 contributors.sort();
729
730 let (_, _, shares) = Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
732
733 let (public, _) = ops::generate_shares::<_, MinSig>(&mut rng, None, n * 2, 1);
735
736 let mut player = Player::<_, MinSig>::new(
738 contributors[0].clone(),
739 None,
740 contributors.clone(),
741 contributors.clone(),
742 1,
743 );
744
745 let result = player.share(contributors[0].clone(), public.clone(), shares[0].clone());
747 assert!(matches!(result, Err(Error::CommitmentWrongDegree)));
748
749 let mut arb =
751 Arbiter::<_, MinSig>::new(None, contributors.clone(), contributors.clone(), 1);
752
753 let result = arb.commitment(
755 contributors[0].clone(),
756 public,
757 vec![0, 1, 2, 3, 4],
758 Vec::new(),
759 );
760 assert!(matches!(result, Err(Error::CommitmentWrongDegree)));
761 }
762
763 #[test]
764 fn test_reveal() {
765 let n = 5;
767 let mut rng = StdRng::seed_from_u64(0);
768
769 let mut contributors = Vec::new();
771 for i in 0..n {
772 let signer = Ed25519::from_seed(i as u64).public_key();
773 contributors.push(signer);
774 }
775 contributors.sort();
776
777 let (_, commitment, shares) =
779 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
780
781 let mut arb =
783 Arbiter::<_, MinSig>::new(None, contributors.clone(), contributors.clone(), 1);
784
785 arb.commitment(
787 contributors[0].clone(),
788 commitment,
789 vec![0, 1, 2, 3],
790 vec![shares[4].clone()],
791 )
792 .unwrap();
793 }
794
795 #[test]
796 fn test_arbiter_reveals() {
797 let n = 11;
799 let q = quorum(n as u32) as usize;
800 let mut rng = StdRng::seed_from_u64(0);
801
802 let mut contributors = Vec::new();
804 for i in 0..n {
805 let signer = Ed25519::from_seed(i as u64).public_key();
806 contributors.push(signer);
807 }
808 contributors.sort();
809
810 let mut arb =
812 Arbiter::<_, MinSig>::new(None, contributors.clone(), contributors.clone(), 1);
813
814 let mut commitments = Vec::with_capacity(n);
816 let mut reveals = Vec::with_capacity(n);
817 for con in &contributors {
818 let (_, commitment, shares) =
820 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
821 commitments.push(commitment.clone());
822 reveals.push(shares[q].clone());
823
824 let acks: Vec<u32> = (0..q as u32).collect();
826 let reveals = shares[q..n].to_vec();
827 arb.commitment(con.clone(), commitment, acks, reveals)
828 .unwrap();
829 }
830
831 let (result, _) = arb.finalize();
833 let output = result.unwrap();
834
835 assert_eq!(output.commitments.len(), q);
837 for (dealer_idx, commitment) in commitments.iter().enumerate().take(q) {
838 let dealer_idx = dealer_idx as u32;
839 assert_eq!(output.commitments.get(&dealer_idx).unwrap(), commitment);
840 assert_eq!(
841 output.reveals.get(&dealer_idx).unwrap()[0],
842 reveals[dealer_idx as usize]
843 );
844 }
845 }
846
847 #[test]
848 fn test_arbiter_best() {}
849
850 #[test]
851 fn test_duplicate_commitment() {
852 let n = 5;
854 let mut rng = StdRng::seed_from_u64(0);
855
856 let mut contributors = Vec::new();
858 for i in 0..n {
859 let signer = Ed25519::from_seed(i as u64).public_key();
860 contributors.push(signer);
861 }
862 contributors.sort();
863
864 let (_, commitment, shares) =
866 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
867
868 let mut arb =
870 Arbiter::<_, MinSig>::new(None, contributors.clone(), contributors.clone(), 1);
871
872 arb.commitment(
874 contributors[0].clone(),
875 commitment.clone(),
876 vec![0, 1, 2, 3],
877 vec![shares[4].clone()],
878 )
879 .unwrap();
880
881 let result = arb.commitment(
883 contributors[0].clone(),
884 commitment,
885 vec![0, 1, 2, 3],
886 vec![shares[4].clone()],
887 );
888 assert!(matches!(result, Err(Error::DuplicateCommitment)));
889 }
890
891 #[test]
892 fn test_reveal_duplicate_player() {
893 let n = 5;
895 let mut rng = StdRng::seed_from_u64(0);
896
897 let mut contributors = Vec::new();
899 for i in 0..n {
900 let signer = Ed25519::from_seed(i as u64).public_key();
901 contributors.push(signer);
902 }
903 contributors.sort();
904
905 let (_, commitment, shares) =
907 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
908
909 let mut arb =
911 Arbiter::<_, MinSig>::new(None, contributors.clone(), contributors.clone(), 1);
912
913 let result = arb.commitment(
915 contributors[0].clone(),
916 commitment,
917 vec![0, 1, 2, 3],
918 vec![shares[3].clone()],
919 );
920 assert!(matches!(result, Err(Error::AlreadyActive)));
921 }
922
923 #[test]
924 fn test_insufficient_active() {
925 let n = 5;
927 let mut rng = StdRng::seed_from_u64(0);
928
929 let mut contributors = Vec::new();
931 for i in 0..n {
932 let signer = Ed25519::from_seed(i as u64).public_key();
933 contributors.push(signer);
934 }
935 contributors.sort();
936
937 let (_, commitment, _) = Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
939
940 let mut arb =
942 Arbiter::<_, MinSig>::new(None, contributors.clone(), contributors.clone(), 1);
943
944 let result = arb.commitment(
946 contributors[0].clone(),
947 commitment.clone(),
948 vec![0, 1, 2, 3],
949 Vec::new(),
950 );
951 assert!(matches!(result, Err(Error::IncorrectActive)));
952
953 let result = arb.commitment(
955 contributors[0].clone(),
956 commitment,
957 vec![0, 1, 2, 3, 4],
958 Vec::new(),
959 );
960 assert!(matches!(result, Err(Error::DealerDisqualified)));
961 }
962
963 #[test]
964 fn test_manual_disqualify() {
965 let n = 5;
967 let mut rng = StdRng::seed_from_u64(0);
968
969 let mut contributors = Vec::new();
971 for i in 0..n {
972 let signer = Ed25519::from_seed(i as u64).public_key();
973 contributors.push(signer);
974 }
975 contributors.sort();
976
977 let (_, commitment, _) = Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
979
980 let mut arb =
982 Arbiter::<_, MinSig>::new(None, contributors.clone(), contributors.clone(), 1);
983
984 arb.disqualify(contributors[0].clone());
986
987 let result = arb.commitment(
989 contributors[0].clone(),
990 commitment,
991 vec![0, 1, 2, 3, 4],
992 Vec::new(),
993 );
994 assert!(matches!(result, Err(Error::DealerDisqualified)));
995 }
996
997 #[test]
998 fn test_too_many_reveals() {
999 let n = 5;
1001 let mut rng = StdRng::seed_from_u64(0);
1002
1003 let mut contributors = Vec::new();
1005 for i in 0..n {
1006 let signer = Ed25519::from_seed(i as u64).public_key();
1007 contributors.push(signer);
1008 }
1009 contributors.sort();
1010
1011 let (_, commitment, shares) =
1013 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1014
1015 let mut arb =
1017 Arbiter::<_, MinSig>::new(None, contributors.clone(), contributors.clone(), 1);
1018
1019 let result = arb.commitment(
1021 contributors[0].clone(),
1022 commitment,
1023 vec![0, 1, 2],
1024 vec![shares[3].clone(), shares[4].clone()],
1025 );
1026 assert!(matches!(result, Err(Error::TooManyReveals)));
1027 }
1028
1029 #[test]
1030 fn test_incorrect_reveal() {
1031 let n = 5;
1033 let mut rng = StdRng::seed_from_u64(0);
1034
1035 let mut contributors = Vec::new();
1037 for i in 0..n {
1038 let signer = Ed25519::from_seed(i as u64).public_key();
1039 contributors.push(signer);
1040 }
1041 contributors.sort();
1042
1043 let (_, commitment, _) = Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1045
1046 let t = quorum(n);
1048 let (_, shares) = ops::generate_shares::<_, MinSig>(&mut rng, None, n, t);
1049
1050 let mut arb =
1052 Arbiter::<_, MinSig>::new(None, contributors.clone(), contributors.clone(), 1);
1053
1054 let result = arb.commitment(
1056 contributors[0].clone(),
1057 commitment,
1058 vec![0, 1, 2, 3],
1059 vec![shares[4].clone()],
1060 );
1061 assert!(matches!(result, Err(Error::ShareWrongCommitment)));
1062 }
1063
1064 #[test]
1065 fn test_reveal_corrupt_share() {
1066 let n = 5;
1068 let mut rng = StdRng::seed_from_u64(0);
1069
1070 let mut contributors = Vec::new();
1072 for i in 0..n {
1073 let signer = Ed25519::from_seed(i as u64).public_key();
1074 contributors.push(signer);
1075 }
1076 contributors.sort();
1077
1078 let (_, commitment, shares) =
1080 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1081
1082 let mut arb =
1084 Arbiter::<_, MinSig>::new(None, contributors.clone(), contributors.clone(), 1);
1085
1086 let mut share = shares[3].clone();
1088 share.index = 4;
1089
1090 let result = arb.commitment(
1092 contributors[0].clone(),
1093 commitment,
1094 vec![0, 1, 2, 3],
1095 vec![share],
1096 );
1097 assert!(matches!(result, Err(Error::ShareWrongCommitment)));
1098 }
1099
1100 #[test]
1101 fn test_reveal_duplicate_ack() {
1102 let n = 5;
1104 let mut rng = StdRng::seed_from_u64(0);
1105
1106 let mut contributors = Vec::new();
1108 for i in 0..n {
1109 let signer = Ed25519::from_seed(i as u64).public_key();
1110 contributors.push(signer);
1111 }
1112 contributors.sort();
1113
1114 let (_, commitment, _) = Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1116
1117 let mut arb =
1119 Arbiter::<_, MinSig>::new(None, contributors.clone(), contributors.clone(), 1);
1120
1121 let result = arb.commitment(
1123 contributors[0].clone(),
1124 commitment,
1125 vec![0, 1, 2, 2],
1126 Vec::new(),
1127 );
1128 assert!(matches!(result, Err(Error::AlreadyActive)));
1129 }
1130
1131 #[test]
1132 fn test_reveal_invalid_ack() {
1133 let n = 5;
1135 let mut rng = StdRng::seed_from_u64(0);
1136
1137 let mut contributors = Vec::new();
1139 for i in 0..n {
1140 let signer = Ed25519::from_seed(i as u64).public_key();
1141 contributors.push(signer);
1142 }
1143 contributors.sort();
1144
1145 let (_, commitment, _) = Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1147
1148 let mut arb =
1150 Arbiter::<_, MinSig>::new(None, contributors.clone(), contributors.clone(), 1);
1151
1152 let result = arb.commitment(
1154 contributors[0].clone(),
1155 commitment,
1156 vec![0, 1, 2, 10],
1157 Vec::new(),
1158 );
1159 assert!(matches!(result, Err(Error::PlayerInvalid)));
1160 }
1161
1162 #[test]
1163 fn test_reveal_invalid_share() {
1164 let n = 5;
1166 let mut rng = StdRng::seed_from_u64(0);
1167
1168 let mut contributors = Vec::new();
1170 for i in 0..n {
1171 let signer = Ed25519::from_seed(i as u64).public_key();
1172 contributors.push(signer);
1173 }
1174 contributors.sort();
1175
1176 let (_, commitment, shares) =
1178 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1179
1180 let mut arb =
1182 Arbiter::<_, MinSig>::new(None, contributors.clone(), contributors.clone(), 1);
1183
1184 let mut share = shares[3].clone();
1186 share.index = 10;
1187
1188 let result = arb.commitment(
1190 contributors[0].clone(),
1191 commitment,
1192 vec![0, 1, 2, 3],
1193 vec![share],
1194 );
1195 assert!(matches!(result, Err(Error::PlayerInvalid)));
1196 }
1197
1198 #[test]
1199 fn test_dealer_acks() {
1200 let n = 5;
1202 let mut rng = StdRng::seed_from_u64(0);
1203
1204 let mut contributors = Vec::new();
1206 for i in 0..n {
1207 let signer = Ed25519::from_seed(i as u64).public_key();
1208 contributors.push(signer);
1209 }
1210 contributors.sort();
1211
1212 let (mut dealer, _, _) = Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1214
1215 for player in &contributors {
1217 dealer.ack(player.clone()).unwrap();
1218 }
1219
1220 let output = dealer.finalize().unwrap();
1222 assert_eq!(output.active, vec![0, 1, 2, 3, 4]);
1223 assert!(output.inactive.is_empty());
1224 }
1225
1226 #[test]
1227 fn test_dealer_inactive() {
1228 let n = 5;
1230 let mut rng = StdRng::seed_from_u64(0);
1231
1232 let mut contributors = Vec::new();
1234 for i in 0..n {
1235 let signer = Ed25519::from_seed(i as u64).public_key();
1236 contributors.push(signer);
1237 }
1238 contributors.sort();
1239
1240 let (mut dealer, _, _) = Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1242
1243 for player in contributors.iter().take(4) {
1245 dealer.ack(player.clone()).unwrap();
1246 }
1247
1248 let output = dealer.finalize().unwrap();
1250 assert_eq!(output.active, vec![0, 1, 2, 3]);
1251 assert_eq!(output.inactive, vec![4]);
1252 }
1253
1254 #[test]
1255 fn test_dealer_insufficient() {
1256 let n = 5;
1258 let mut rng = StdRng::seed_from_u64(0);
1259
1260 let mut contributors = Vec::new();
1262 for i in 0..n {
1263 let signer = Ed25519::from_seed(i as u64).public_key();
1264 contributors.push(signer);
1265 }
1266 contributors.sort();
1267
1268 let (mut dealer, _, _) = Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1270
1271 for player in contributors.iter().take(2) {
1273 dealer.ack(player.clone()).unwrap();
1274 }
1275
1276 assert!(dealer.finalize().is_none());
1278 }
1279
1280 #[test]
1281 fn test_dealer_duplicate_ack() {
1282 let n = 5;
1284 let mut rng = StdRng::seed_from_u64(0);
1285
1286 let mut contributors = Vec::new();
1288 for i in 0..n {
1289 let signer = Ed25519::from_seed(i as u64).public_key();
1290 contributors.push(signer);
1291 }
1292 contributors.sort();
1293
1294 let (mut dealer, _, _) = Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1296
1297 let player = contributors[0].clone();
1299 dealer.ack(player.clone()).unwrap();
1300
1301 let result = dealer.ack(player);
1303 assert!(matches!(result, Err(Error::DuplicateAck)));
1304 }
1305
1306 #[test]
1307 fn test_dealer_invalid_player() {
1308 let n = 5;
1310 let mut rng = StdRng::seed_from_u64(0);
1311
1312 let mut contributors = Vec::new();
1314 for i in 0..n {
1315 let signer = Ed25519::from_seed(i as u64).public_key();
1316 contributors.push(signer);
1317 }
1318 contributors.sort();
1319
1320 let (mut dealer, _, _) = Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1322
1323 let player = Ed25519::from_seed(n as u64).public_key();
1325 let result = dealer.ack(player);
1326 assert!(matches!(result, Err(Error::PlayerInvalid)));
1327 }
1328
1329 #[test]
1330 fn test_player_reveals() {
1331 let n = 11;
1333 let q = quorum(n as u32) as usize;
1334 let mut rng = StdRng::seed_from_u64(0);
1335
1336 let mut contributors = Vec::new();
1338 for i in 0..n {
1339 let signer = Ed25519::from_seed(i as u64).public_key();
1340 contributors.push(signer);
1341 }
1342 contributors.sort();
1343
1344 let mut player = Player::<_, MinSig>::new(
1346 contributors[0].clone(),
1347 None,
1348 contributors.clone(),
1349 contributors.clone(),
1350 1,
1351 );
1352
1353 let mut commitments = HashMap::new();
1355 for (i, con) in contributors.iter().enumerate().take(q - 1) {
1356 let (_, commitment, shares) =
1357 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1358 player
1359 .share(con.clone(), commitment.clone(), shares[0].clone())
1360 .unwrap();
1361 commitments.insert(i as u32, commitment);
1362 }
1363
1364 let last = (q - 1) as u32;
1366 let (_, commitment, shares) =
1367 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1368 commitments.insert(last, commitment);
1369 let mut reveals = HashMap::new();
1370 reveals.insert(last, shares[0].clone());
1371 player.finalize(commitments, reveals).unwrap();
1372 }
1373
1374 #[test]
1375 fn test_player_missing_reveal() {
1376 let n = 11;
1378 let q = quorum(n as u32) as usize;
1379 let mut rng = StdRng::seed_from_u64(0);
1380
1381 let mut contributors = Vec::new();
1383 for i in 0..n {
1384 let signer = Ed25519::from_seed(i as u64).public_key();
1385 contributors.push(signer);
1386 }
1387 contributors.sort();
1388
1389 let mut player = Player::<_, MinSig>::new(
1391 contributors[0].clone(),
1392 None,
1393 contributors.clone(),
1394 contributors.clone(),
1395 1,
1396 );
1397
1398 let mut commitments = HashMap::new();
1400 for (i, con) in contributors.iter().enumerate().take(q - 1) {
1401 let (_, commitment, shares) =
1402 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1403 player
1404 .share(con.clone(), commitment.clone(), shares[0].clone())
1405 .unwrap();
1406 commitments.insert(i as u32, commitment);
1407 }
1408
1409 let last = (q - 1) as u32;
1411 let (_, commitment, _) = Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1412 commitments.insert(last, commitment);
1413 let result = player.finalize(commitments, HashMap::new());
1414 assert!(matches!(result, Err(Error::MissingShare)));
1415 }
1416
1417 #[test]
1418 fn test_player_insufficient_commitments() {
1419 let n = 5;
1421 let mut rng = StdRng::seed_from_u64(0);
1422
1423 let mut contributors = Vec::new();
1425 for i in 0..n {
1426 let signer = Ed25519::from_seed(i as u64).public_key();
1427 contributors.push(signer);
1428 }
1429 contributors.sort();
1430
1431 let mut player = Player::<_, MinSig>::new(
1433 contributors[0].clone(),
1434 None,
1435 contributors.clone(),
1436 contributors.clone(),
1437 1,
1438 );
1439
1440 let mut commitments = HashMap::new();
1442 for (i, con) in contributors.iter().enumerate().take(2) {
1443 let (_, commitment, shares) =
1444 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1445 player
1446 .share(con.clone(), commitment.clone(), shares[0].clone())
1447 .unwrap();
1448 commitments.insert(i as u32, commitment);
1449 }
1450
1451 let result = player.finalize(commitments, HashMap::new());
1453 assert!(matches!(result, Err(Error::InvalidCommitments)));
1454 }
1455
1456 #[test]
1457 fn test_player_misdirected_reveal() {
1458 let n = 11;
1460 let q = quorum(n as u32) as usize;
1461 let mut rng = StdRng::seed_from_u64(0);
1462
1463 let mut contributors = Vec::new();
1465 for i in 0..n {
1466 let signer = Ed25519::from_seed(i as u64).public_key();
1467 contributors.push(signer);
1468 }
1469 contributors.sort();
1470
1471 let mut player = Player::<_, MinSig>::new(
1473 contributors[0].clone(),
1474 None,
1475 contributors.clone(),
1476 contributors.clone(),
1477 1,
1478 );
1479
1480 let mut commitments = HashMap::new();
1482 for (i, con) in contributors.iter().enumerate().take(q - 1) {
1483 let (_, commitment, shares) =
1484 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1485 player
1486 .share(con.clone(), commitment.clone(), shares[0].clone())
1487 .unwrap();
1488 commitments.insert(i as u32, commitment);
1489 }
1490
1491 let last = (q - 1) as u32;
1493 let (_, commitment, shares) =
1494 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1495 commitments.insert(last, commitment);
1496 let mut reveals = HashMap::new();
1497 reveals.insert(last, shares[1].clone());
1498 let result = player.finalize(commitments, reveals);
1499 assert!(matches!(result, Err(Error::MisdirectedShare)));
1500 }
1501
1502 #[test]
1503 fn test_player_invalid_commitment() {
1504 let n = 11;
1506 let q = quorum(n as u32) as usize;
1507 let mut rng = StdRng::seed_from_u64(0);
1508
1509 let mut contributors = Vec::new();
1511 for i in 0..n {
1512 let signer = Ed25519::from_seed(i as u64).public_key();
1513 contributors.push(signer);
1514 }
1515 contributors.sort();
1516
1517 let mut player = Player::<_, MinSig>::new(
1519 contributors[0].clone(),
1520 None,
1521 contributors.clone(),
1522 contributors.clone(),
1523 1,
1524 );
1525
1526 let mut commitments = HashMap::new();
1528 for (i, con) in contributors.iter().enumerate().take(q - 1) {
1529 let (_, commitment, shares) =
1530 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1531 player
1532 .share(con.clone(), commitment.clone(), shares[0].clone())
1533 .unwrap();
1534 commitments.insert(i as u32, commitment);
1535 }
1536
1537 let last = (q - 1) as u32;
1539 let (commitment, shares) = ops::generate_shares::<_, MinSig>(&mut rng, None, n as u32, 1);
1540 commitments.insert(last, commitment);
1541 let mut reveals = HashMap::new();
1542 reveals.insert(last, shares[0].clone());
1543 let result = player.finalize(commitments, reveals);
1544 assert!(matches!(result, Err(Error::CommitmentWrongDegree)));
1545 }
1546
1547 #[test]
1548 fn test_player_invalid_reveal() {
1549 let n = 11;
1551 let q = quorum(n as u32) as usize;
1552 let mut rng = StdRng::seed_from_u64(0);
1553
1554 let mut contributors = Vec::new();
1556 for i in 0..n {
1557 let signer = Ed25519::from_seed(i as u64).public_key();
1558 contributors.push(signer);
1559 }
1560 contributors.sort();
1561
1562 let mut player = Player::<_, MinSig>::new(
1564 contributors[0].clone(),
1565 None,
1566 contributors.clone(),
1567 contributors.clone(),
1568 1,
1569 );
1570
1571 let mut commitments = HashMap::new();
1573 for (i, con) in contributors.iter().enumerate().take(q - 1) {
1574 let (_, commitment, shares) =
1575 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1576 player
1577 .share(con.clone(), commitment.clone(), shares[0].clone())
1578 .unwrap();
1579 commitments.insert(i as u32, commitment);
1580 }
1581
1582 let last = (q - 1) as u32;
1584 let (_, commitment, shares) =
1585 Dealer::<_, MinSig>::new(&mut rng, None, contributors.clone());
1586 commitments.insert(last, commitment);
1587 let mut reveals = HashMap::new();
1588 let mut share = shares[1].clone();
1589 share.index = 0;
1590 reveals.insert(last, share);
1591 let result = player.finalize(commitments, reveals);
1592 assert!(matches!(result, Err(Error::ShareWrongCommitment)));
1593 }
1594}