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::{Ed25519, Signer};
195 use commonware_utils::quorum;
196 use rand::rngs::StdRng;
197 use rand::SeedableRng;
198 use std::collections::HashMap;
199
200 fn run_dkg_and_reshare(n_0: u32, dealers_0: u32, n_1: u32, dealers_1: u32, concurrency: usize) {
201 let mut rng = StdRng::seed_from_u64(0);
203
204 let mut contributors = Vec::new();
206 for i in 0..n_0 {
207 let signer = Ed25519::from_seed(i as u64).public_key();
208 contributors.push(signer);
209 }
210 contributors.sort();
211
212 let mut dealer_shares = HashMap::new();
214 let mut dealers = HashMap::new();
215 for con in contributors.iter().take(dealers_0 as usize) {
216 let (dealer, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
217 dealer_shares.insert(con.clone(), (commitment, shares));
218 dealers.insert(con.clone(), dealer);
219 }
220
221 let mut players = HashMap::new();
223 for con in &contributors {
224 let player = Player::new(
225 con.clone(),
226 None,
227 contributors.clone(),
228 contributors.clone(),
229 concurrency,
230 );
231 players.insert(con.clone(), player);
232 }
233
234 let mut arb = Arbiter::new(
236 None,
237 contributors.clone(),
238 contributors.clone(),
239 concurrency,
240 );
241
242 assert!(!arb.ready());
244
245 for (dealer, mut dealer_obj) in dealers {
247 let (commitment, shares) = dealer_shares.get(&dealer).unwrap().clone();
249 for (player_idx, player) in contributors.iter().enumerate() {
250 let player_obj = players.get_mut(player).unwrap();
252 player_obj
253 .share(dealer.clone(), commitment.clone(), shares[player_idx])
254 .unwrap();
255
256 dealer_obj.ack(player.clone()).unwrap();
258 }
259
260 let output = dealer_obj.finalize().unwrap();
262
263 assert!(output.inactive.is_empty());
265
266 arb.commitment(dealer, commitment, output.active, Vec::new())
268 .unwrap();
269 }
270
271 assert!(arb.ready());
273
274 let (result, disqualified) = arb.finalize();
276
277 assert_eq!(disqualified.len(), (n_0 - dealers_0) as usize);
279
280 let output = result.unwrap();
282
283 let expected_commitments = quorum(n_0) as usize;
285 assert_eq!(output.commitments.len(), expected_commitments);
286
287 assert!(output.reveals.is_empty());
289
290 let mut outputs = HashMap::new();
292 for player in contributors.iter() {
293 let result = players
294 .remove(player)
295 .unwrap()
296 .finalize(output.commitments.clone(), HashMap::new())
297 .unwrap();
298 outputs.insert(player.clone(), result);
299 }
300
301 let t = quorum(n_0);
303 let partials = outputs
304 .values()
305 .map(|s| partial_sign_proof_of_possession(&s.public, &s.share))
306 .collect::<Vec<_>>();
307 let signature =
308 threshold_signature_recover(t, &partials).expect("unable to recover signature");
309 let public_key = public(&outputs.iter().next().unwrap().1.public);
310 verify_proof_of_possession(public_key, &signature).expect("invalid proof of possession");
311
312 let mut reshare_players = Vec::new();
314 for i in 0..n_1 {
315 let player = Ed25519::from_seed((i + n_0) as u64).public_key();
316 reshare_players.push(player);
317 }
318 reshare_players.sort();
319
320 let mut reshare_shares = HashMap::new();
322 let mut reshare_dealers = HashMap::new();
323 for con in contributors.iter().take(dealers_1 as usize) {
324 let output = outputs.get(con).unwrap();
325 let (dealer, commitment, shares) =
326 Dealer::new(&mut rng, Some(output.share), reshare_players.clone());
327 reshare_shares.insert(con.clone(), (commitment, shares));
328 reshare_dealers.insert(con.clone(), dealer);
329 }
330
331 let mut reshare_player_objs = HashMap::new();
333 for con in &reshare_players {
334 let player = Player::new(
335 con.clone(),
336 Some(output.public.clone()),
337 contributors.clone(),
338 reshare_players.clone(),
339 concurrency,
340 );
341 reshare_player_objs.insert(con.clone(), player);
342 }
343
344 let mut arb = Arbiter::new(
346 Some(output.public),
347 contributors.clone(),
348 reshare_players.clone(),
349 concurrency,
350 );
351
352 assert!(!arb.ready());
354
355 for (dealer, mut dealer_obj) in reshare_dealers {
357 let (commitment, shares) = reshare_shares.get(&dealer).unwrap().clone();
359 for (player_idx, player) in reshare_players.iter().enumerate() {
360 let player_obj = reshare_player_objs.get_mut(player).unwrap();
362 player_obj
363 .share(dealer.clone(), commitment.clone(), shares[player_idx])
364 .unwrap();
365
366 dealer_obj.ack(player.clone()).unwrap();
368 }
369
370 let output = dealer_obj.finalize().unwrap();
372
373 assert!(output.inactive.is_empty());
375
376 arb.commitment(dealer, commitment, output.active, Vec::new())
378 .unwrap();
379 }
380
381 assert!(arb.ready());
383
384 let (result, disqualified) = arb.finalize();
386
387 assert_eq!(disqualified.len(), (n_0 - dealers_1) as usize);
389
390 let output = result.unwrap();
392
393 let expected_commitments = quorum(n_0) as usize;
395 assert_eq!(output.commitments.len(), expected_commitments);
396
397 assert!(output.reveals.is_empty());
399
400 let mut outputs = Vec::new();
402 for player in reshare_players.iter() {
403 let result = reshare_player_objs
404 .remove(player)
405 .unwrap()
406 .finalize(output.commitments.clone(), HashMap::new())
407 .unwrap();
408 assert_eq!(result.public, output.public);
409 outputs.push(result);
410 }
411
412 let t = quorum(n_1);
414 let partials = outputs
415 .iter()
416 .map(|s| partial_sign_proof_of_possession(&s.public, &s.share))
417 .collect::<Vec<_>>();
418 let signature =
419 threshold_signature_recover(t, &partials).expect("unable to recover signature");
420 let public_key = public(&outputs[0].public);
421 verify_proof_of_possession(public_key, &signature).expect("invalid proof of possession");
422 }
423
424 #[test]
425 fn test_dkg_and_reshare_all_active() {
426 run_dkg_and_reshare(5, 5, 10, 5, 4);
427 }
428
429 #[test]
430 fn test_dkg_and_reshare_min_active() {
431 run_dkg_and_reshare(4, 3, 4, 3, 4);
432 }
433
434 #[test]
435 fn test_dkg_and_reshare_min_active_different_sizes() {
436 run_dkg_and_reshare(5, 4, 10, 4, 4);
437 }
438
439 #[test]
440 fn test_dkg_and_reshare_min_active_large() {
441 run_dkg_and_reshare(20, 14, 100, 14, 4);
442 }
443
444 #[test]
445 #[should_panic]
446 fn test_dkg_and_reshare_insufficient_active() {
447 run_dkg_and_reshare(5, 3, 10, 2, 4);
448 }
449
450 #[test]
451 fn test_invalid_commitment() {
452 let n = 5;
454 let mut rng = StdRng::seed_from_u64(0);
455
456 let mut contributors = Vec::new();
458 for i in 0..n {
459 let signer = Ed25519::from_seed(i as u64).public_key();
460 contributors.push(signer);
461 }
462 contributors.sort();
463
464 let (_, _, shares) = Dealer::new(&mut rng, None, contributors.clone());
466
467 let t = quorum(n);
469 let (public, _) = ops::generate_shares(&mut rng, None, n, t);
470
471 let mut player = Player::new(
473 contributors[0].clone(),
474 None,
475 contributors.clone(),
476 contributors.clone(),
477 1,
478 );
479
480 let result = player.share(contributors[0].clone(), public, shares[0]);
482 assert!(matches!(result, Err(Error::ShareWrongCommitment)));
483 }
484
485 #[test]
486 fn test_mismatched_commitment() {
487 let n = 5;
489 let mut rng = StdRng::seed_from_u64(0);
490
491 let mut contributors = Vec::new();
493 for i in 0..n {
494 let signer = Ed25519::from_seed(i as u64).public_key();
495 contributors.push(signer);
496 }
497 contributors.sort();
498
499 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
501
502 let t = quorum(n);
504 let (other_commitment, _) = ops::generate_shares(&mut rng, None, n, t);
505
506 let mut player = Player::new(
508 contributors[0].clone(),
509 None,
510 contributors.clone(),
511 contributors.clone(),
512 1,
513 );
514
515 player
517 .share(contributors[0].clone(), commitment, shares[0])
518 .unwrap();
519
520 let result = player.share(contributors[0].clone(), other_commitment, shares[0]);
522 assert!(matches!(result, Err(Error::MismatchedCommitment)));
523 }
524
525 #[test]
526 fn test_mismatched_share() {
527 let n = 5;
529 let mut rng = StdRng::seed_from_u64(0);
530
531 let mut contributors = Vec::new();
533 for i in 0..n {
534 let signer = Ed25519::from_seed(i as u64).public_key();
535 contributors.push(signer);
536 }
537 contributors.sort();
538
539 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
541
542 let t = quorum(n);
544 let (_, other_shares) = ops::generate_shares(&mut rng, None, n, t);
545
546 let mut player = Player::new(
548 contributors[0].clone(),
549 None,
550 contributors.clone(),
551 contributors.clone(),
552 1,
553 );
554
555 player
557 .share(contributors[0].clone(), commitment.clone(), shares[0])
558 .unwrap();
559
560 let result = player.share(contributors[0].clone(), commitment, other_shares[0]);
562 assert!(matches!(result, Err(Error::MismatchedShare)));
563 }
564
565 #[test]
566 fn test_duplicate_share() {
567 let n = 5;
569 let mut rng = StdRng::seed_from_u64(0);
570
571 let mut contributors = Vec::new();
573 for i in 0..n {
574 let signer = Ed25519::from_seed(i as u64).public_key();
575 contributors.push(signer);
576 }
577 contributors.sort();
578
579 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
581
582 let mut player = Player::new(
584 contributors[0].clone(),
585 None,
586 contributors.clone(),
587 contributors.clone(),
588 1,
589 );
590
591 player
593 .share(contributors[0].clone(), commitment.clone(), shares[0])
594 .unwrap();
595
596 let result = player.share(contributors[0].clone(), commitment, shares[0]);
598 assert!(matches!(result, Err(Error::DuplicateShare)));
599 }
600
601 #[test]
602 fn test_misdirected_share() {
603 let n = 5;
605 let mut rng = StdRng::seed_from_u64(0);
606
607 let mut contributors = Vec::new();
609 for i in 0..n {
610 let signer = Ed25519::from_seed(i as u64).public_key();
611 contributors.push(signer);
612 }
613 contributors.sort();
614
615 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
617
618 let mut player = Player::new(
620 contributors[0].clone(),
621 None,
622 contributors.clone(),
623 contributors.clone(),
624 1,
625 );
626
627 let result = player.share(contributors[0].clone(), commitment.clone(), shares[1]);
629 assert!(matches!(result, Err(Error::MisdirectedShare)));
630 }
631
632 #[test]
633 fn test_invalid_dealer() {
634 let n = 5;
636 let mut rng = StdRng::seed_from_u64(0);
637
638 let mut contributors = Vec::new();
640 for i in 0..n {
641 let signer = Ed25519::from_seed(i as u64).public_key();
642 contributors.push(signer);
643 }
644 contributors.sort();
645
646 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
648
649 let mut player = Player::new(
651 contributors[0].clone(),
652 None,
653 contributors.clone(),
654 contributors.clone(),
655 1,
656 );
657
658 let dealer = Ed25519::from_seed(n as u64).public_key();
660 let result = player.share(dealer.clone(), commitment.clone(), shares[0]);
661 assert!(matches!(result, Err(Error::DealerInvalid)));
662
663 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
665
666 let result = arb.commitment(dealer, commitment, vec![0, 1, 2, 3], Vec::new());
668 assert!(matches!(result, Err(Error::DealerInvalid)));
669 }
670
671 #[test]
672 fn test_invalid_commitment_degree() {
673 let n = 5;
675 let mut rng = StdRng::seed_from_u64(0);
676
677 let mut contributors = Vec::new();
679 for i in 0..n {
680 let signer = Ed25519::from_seed(i as u64).public_key();
681 contributors.push(signer);
682 }
683 contributors.sort();
684
685 let (_, _, shares) = Dealer::new(&mut rng, None, contributors.clone());
687
688 let (public, _) = ops::generate_shares(&mut rng, None, n * 2, 1);
690
691 let mut player = Player::new(
693 contributors[0].clone(),
694 None,
695 contributors.clone(),
696 contributors.clone(),
697 1,
698 );
699
700 let result = player.share(contributors[0].clone(), public.clone(), shares[0]);
702 assert!(matches!(result, Err(Error::CommitmentWrongDegree)));
703
704 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
706
707 let result = arb.commitment(
709 contributors[0].clone(),
710 public,
711 vec![0, 1, 2, 3, 4],
712 Vec::new(),
713 );
714 assert!(matches!(result, Err(Error::CommitmentWrongDegree)));
715 }
716
717 #[test]
718 fn test_reveal() {
719 let n = 5;
721 let mut rng = StdRng::seed_from_u64(0);
722
723 let mut contributors = Vec::new();
725 for i in 0..n {
726 let signer = Ed25519::from_seed(i as u64).public_key();
727 contributors.push(signer);
728 }
729 contributors.sort();
730
731 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
733
734 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
736
737 arb.commitment(
739 contributors[0].clone(),
740 commitment,
741 vec![0, 1, 2, 3],
742 vec![shares[4]],
743 )
744 .unwrap();
745 }
746
747 #[test]
748 fn test_arbiter_reveals() {
749 let n = 11;
751 let q = quorum(n as u32) as usize;
752 let mut rng = StdRng::seed_from_u64(0);
753
754 let mut contributors = Vec::new();
756 for i in 0..n {
757 let signer = Ed25519::from_seed(i as u64).public_key();
758 contributors.push(signer);
759 }
760 contributors.sort();
761
762 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
764
765 let mut commitments = Vec::with_capacity(n);
767 let mut reveals = Vec::with_capacity(n);
768 for con in &contributors {
769 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
771 commitments.push(commitment.clone());
772 reveals.push(shares[q]);
773
774 let acks: Vec<u32> = (0..q as u32).collect();
776 let reveals = shares[q..n].to_vec();
777 arb.commitment(con.clone(), commitment, acks, reveals)
778 .unwrap();
779 }
780
781 let (result, _) = arb.finalize();
783 let output = result.unwrap();
784
785 assert_eq!(output.commitments.len(), q);
787 for (dealer_idx, commitment) in commitments.iter().enumerate().take(q) {
788 let dealer_idx = dealer_idx as u32;
789 assert_eq!(output.commitments.get(&dealer_idx).unwrap(), commitment);
790 assert_eq!(
791 output.reveals.get(&dealer_idx).unwrap()[0],
792 reveals[dealer_idx as usize]
793 );
794 }
795 }
796
797 #[test]
798 fn test_arbiter_best() {}
799
800 #[test]
801 fn test_duplicate_commitment() {
802 let n = 5;
804 let mut rng = StdRng::seed_from_u64(0);
805
806 let mut contributors = Vec::new();
808 for i in 0..n {
809 let signer = Ed25519::from_seed(i as u64).public_key();
810 contributors.push(signer);
811 }
812 contributors.sort();
813
814 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
816
817 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
819
820 arb.commitment(
822 contributors[0].clone(),
823 commitment.clone(),
824 vec![0, 1, 2, 3],
825 vec![shares[4]],
826 )
827 .unwrap();
828
829 let result = arb.commitment(
831 contributors[0].clone(),
832 commitment,
833 vec![0, 1, 2, 3],
834 vec![shares[4]],
835 );
836 assert!(matches!(result, Err(Error::DuplicateCommitment)));
837 }
838
839 #[test]
840 fn test_reveal_duplicate_player() {
841 let n = 5;
843 let mut rng = StdRng::seed_from_u64(0);
844
845 let mut contributors = Vec::new();
847 for i in 0..n {
848 let signer = Ed25519::from_seed(i as u64).public_key();
849 contributors.push(signer);
850 }
851 contributors.sort();
852
853 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
855
856 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
858
859 let result = arb.commitment(
861 contributors[0].clone(),
862 commitment,
863 vec![0, 1, 2, 3],
864 vec![shares[3]],
865 );
866 assert!(matches!(result, Err(Error::AlreadyActive)));
867 }
868
869 #[test]
870 fn test_insufficient_active() {
871 let n = 5;
873 let mut rng = StdRng::seed_from_u64(0);
874
875 let mut contributors = Vec::new();
877 for i in 0..n {
878 let signer = Ed25519::from_seed(i as u64).public_key();
879 contributors.push(signer);
880 }
881 contributors.sort();
882
883 let (_, commitment, _) = Dealer::new(&mut rng, None, contributors.clone());
885
886 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
888
889 let result = arb.commitment(
891 contributors[0].clone(),
892 commitment.clone(),
893 vec![0, 1, 2, 3],
894 Vec::new(),
895 );
896 assert!(matches!(result, Err(Error::IncorrectActive)));
897
898 let result = arb.commitment(
900 contributors[0].clone(),
901 commitment,
902 vec![0, 1, 2, 3, 4],
903 Vec::new(),
904 );
905 assert!(matches!(result, Err(Error::DealerDisqualified)));
906 }
907
908 #[test]
909 fn test_manual_disqualify() {
910 let n = 5;
912 let mut rng = StdRng::seed_from_u64(0);
913
914 let mut contributors = Vec::new();
916 for i in 0..n {
917 let signer = Ed25519::from_seed(i as u64).public_key();
918 contributors.push(signer);
919 }
920 contributors.sort();
921
922 let (_, commitment, _) = Dealer::new(&mut rng, None, contributors.clone());
924
925 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
927
928 arb.disqualify(contributors[0].clone());
930
931 let result = arb.commitment(
933 contributors[0].clone(),
934 commitment,
935 vec![0, 1, 2, 3, 4],
936 Vec::new(),
937 );
938 assert!(matches!(result, Err(Error::DealerDisqualified)));
939 }
940
941 #[test]
942 fn test_too_many_reveals() {
943 let n = 5;
945 let mut rng = StdRng::seed_from_u64(0);
946
947 let mut contributors = Vec::new();
949 for i in 0..n {
950 let signer = Ed25519::from_seed(i as u64).public_key();
951 contributors.push(signer);
952 }
953 contributors.sort();
954
955 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
957
958 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
960
961 let result = arb.commitment(
963 contributors[0].clone(),
964 commitment,
965 vec![0, 1, 2],
966 vec![shares[3], shares[4]],
967 );
968 assert!(matches!(result, Err(Error::TooManyReveals)));
969 }
970
971 #[test]
972 fn test_incorrect_reveal() {
973 let n = 5;
975 let mut rng = StdRng::seed_from_u64(0);
976
977 let mut contributors = Vec::new();
979 for i in 0..n {
980 let signer = Ed25519::from_seed(i as u64).public_key();
981 contributors.push(signer);
982 }
983 contributors.sort();
984
985 let (_, commitment, _) = Dealer::new(&mut rng, None, contributors.clone());
987
988 let t = quorum(n);
990 let (_, shares) = ops::generate_shares(&mut rng, None, n, t);
991
992 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
994
995 let result = arb.commitment(
997 contributors[0].clone(),
998 commitment,
999 vec![0, 1, 2, 3],
1000 vec![shares[4]],
1001 );
1002 assert!(matches!(result, Err(Error::ShareWrongCommitment)));
1003 }
1004
1005 #[test]
1006 fn test_reveal_corrupt_share() {
1007 let n = 5;
1009 let mut rng = StdRng::seed_from_u64(0);
1010
1011 let mut contributors = Vec::new();
1013 for i in 0..n {
1014 let signer = Ed25519::from_seed(i as u64).public_key();
1015 contributors.push(signer);
1016 }
1017 contributors.sort();
1018
1019 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1021
1022 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
1024
1025 let mut share = shares[3];
1027 share.index = 4;
1028
1029 let result = arb.commitment(
1031 contributors[0].clone(),
1032 commitment,
1033 vec![0, 1, 2, 3],
1034 vec![share],
1035 );
1036 assert!(matches!(result, Err(Error::ShareWrongCommitment)));
1037 }
1038
1039 #[test]
1040 fn test_reveal_duplicate_ack() {
1041 let n = 5;
1043 let mut rng = StdRng::seed_from_u64(0);
1044
1045 let mut contributors = Vec::new();
1047 for i in 0..n {
1048 let signer = Ed25519::from_seed(i as u64).public_key();
1049 contributors.push(signer);
1050 }
1051 contributors.sort();
1052
1053 let (_, commitment, _) = Dealer::new(&mut rng, None, contributors.clone());
1055
1056 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
1058
1059 let result = arb.commitment(
1061 contributors[0].clone(),
1062 commitment,
1063 vec![0, 1, 2, 2],
1064 Vec::new(),
1065 );
1066 assert!(matches!(result, Err(Error::AlreadyActive)));
1067 }
1068
1069 #[test]
1070 fn test_reveal_invalid_ack() {
1071 let n = 5;
1073 let mut rng = StdRng::seed_from_u64(0);
1074
1075 let mut contributors = Vec::new();
1077 for i in 0..n {
1078 let signer = Ed25519::from_seed(i as u64).public_key();
1079 contributors.push(signer);
1080 }
1081 contributors.sort();
1082
1083 let (_, commitment, _) = Dealer::new(&mut rng, None, contributors.clone());
1085
1086 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
1088
1089 let result = arb.commitment(
1091 contributors[0].clone(),
1092 commitment,
1093 vec![0, 1, 2, 10],
1094 Vec::new(),
1095 );
1096 assert!(matches!(result, Err(Error::PlayerInvalid)));
1097 }
1098
1099 #[test]
1100 fn test_reveal_invalid_share() {
1101 let n = 5;
1103 let mut rng = StdRng::seed_from_u64(0);
1104
1105 let mut contributors = Vec::new();
1107 for i in 0..n {
1108 let signer = Ed25519::from_seed(i as u64).public_key();
1109 contributors.push(signer);
1110 }
1111 contributors.sort();
1112
1113 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1115
1116 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
1118
1119 let mut share = shares[3];
1121 share.index = 10;
1122
1123 let result = arb.commitment(
1125 contributors[0].clone(),
1126 commitment,
1127 vec![0, 1, 2, 3],
1128 vec![share],
1129 );
1130 assert!(matches!(result, Err(Error::PlayerInvalid)));
1131 }
1132
1133 #[test]
1134 fn test_dealer_acks() {
1135 let n = 5;
1137 let mut rng = StdRng::seed_from_u64(0);
1138
1139 let mut contributors = Vec::new();
1141 for i in 0..n {
1142 let signer = Ed25519::from_seed(i as u64).public_key();
1143 contributors.push(signer);
1144 }
1145 contributors.sort();
1146
1147 let (mut dealer, _, _) = Dealer::new(&mut rng, None, contributors.clone());
1149
1150 for player in &contributors {
1152 dealer.ack(player.clone()).unwrap();
1153 }
1154
1155 let output = dealer.finalize().unwrap();
1157 assert_eq!(output.active, vec![0, 1, 2, 3, 4]);
1158 assert!(output.inactive.is_empty());
1159 }
1160
1161 #[test]
1162 fn test_dealer_inactive() {
1163 let n = 5;
1165 let mut rng = StdRng::seed_from_u64(0);
1166
1167 let mut contributors = Vec::new();
1169 for i in 0..n {
1170 let signer = Ed25519::from_seed(i as u64).public_key();
1171 contributors.push(signer);
1172 }
1173 contributors.sort();
1174
1175 let (mut dealer, _, _) = Dealer::new(&mut rng, None, contributors.clone());
1177
1178 for player in contributors.iter().take(4) {
1180 dealer.ack(player.clone()).unwrap();
1181 }
1182
1183 let output = dealer.finalize().unwrap();
1185 assert_eq!(output.active, vec![0, 1, 2, 3]);
1186 assert_eq!(output.inactive, vec![4]);
1187 }
1188
1189 #[test]
1190 fn test_dealer_insufficient() {
1191 let n = 5;
1193 let mut rng = StdRng::seed_from_u64(0);
1194
1195 let mut contributors = Vec::new();
1197 for i in 0..n {
1198 let signer = Ed25519::from_seed(i as u64).public_key();
1199 contributors.push(signer);
1200 }
1201 contributors.sort();
1202
1203 let (mut dealer, _, _) = Dealer::new(&mut rng, None, contributors.clone());
1205
1206 for player in contributors.iter().take(2) {
1208 dealer.ack(player.clone()).unwrap();
1209 }
1210
1211 assert!(dealer.finalize().is_none());
1213 }
1214
1215 #[test]
1216 fn test_dealer_duplicate_ack() {
1217 let n = 5;
1219 let mut rng = StdRng::seed_from_u64(0);
1220
1221 let mut contributors = Vec::new();
1223 for i in 0..n {
1224 let signer = Ed25519::from_seed(i as u64).public_key();
1225 contributors.push(signer);
1226 }
1227 contributors.sort();
1228
1229 let (mut dealer, _, _) = Dealer::new(&mut rng, None, contributors.clone());
1231
1232 let player = contributors[0].clone();
1234 dealer.ack(player.clone()).unwrap();
1235
1236 let result = dealer.ack(player);
1238 assert!(matches!(result, Err(Error::DuplicateAck)));
1239 }
1240
1241 #[test]
1242 fn test_dealer_invalid_player() {
1243 let n = 5;
1245 let mut rng = StdRng::seed_from_u64(0);
1246
1247 let mut contributors = Vec::new();
1249 for i in 0..n {
1250 let signer = Ed25519::from_seed(i as u64).public_key();
1251 contributors.push(signer);
1252 }
1253 contributors.sort();
1254
1255 let (mut dealer, _, _) = Dealer::new(&mut rng, None, contributors.clone());
1257
1258 let player = Ed25519::from_seed(n as u64).public_key();
1260 let result = dealer.ack(player);
1261 assert!(matches!(result, Err(Error::PlayerInvalid)));
1262 }
1263
1264 #[test]
1265 fn test_player_reveals() {
1266 let n = 11;
1268 let q = quorum(n as u32) as usize;
1269 let mut rng = StdRng::seed_from_u64(0);
1270
1271 let mut contributors = Vec::new();
1273 for i in 0..n {
1274 let signer = Ed25519::from_seed(i as u64).public_key();
1275 contributors.push(signer);
1276 }
1277 contributors.sort();
1278
1279 let mut player = Player::new(
1281 contributors[0].clone(),
1282 None,
1283 contributors.clone(),
1284 contributors.clone(),
1285 1,
1286 );
1287
1288 let mut commitments = HashMap::new();
1290 for (i, con) in contributors.iter().enumerate().take(q - 1) {
1291 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1292 player
1293 .share(con.clone(), commitment.clone(), shares[0])
1294 .unwrap();
1295 commitments.insert(i as u32, commitment);
1296 }
1297
1298 let last = (q - 1) as u32;
1300 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1301 commitments.insert(last, commitment);
1302 let mut reveals = HashMap::new();
1303 reveals.insert(last, shares[0]);
1304 player.finalize(commitments, reveals).unwrap();
1305 }
1306
1307 #[test]
1308 fn test_player_missing_reveal() {
1309 let n = 11;
1311 let q = quorum(n as u32) as usize;
1312 let mut rng = StdRng::seed_from_u64(0);
1313
1314 let mut contributors = Vec::new();
1316 for i in 0..n {
1317 let signer = Ed25519::from_seed(i as u64).public_key();
1318 contributors.push(signer);
1319 }
1320 contributors.sort();
1321
1322 let mut player = Player::new(
1324 contributors[0].clone(),
1325 None,
1326 contributors.clone(),
1327 contributors.clone(),
1328 1,
1329 );
1330
1331 let mut commitments = HashMap::new();
1333 for (i, con) in contributors.iter().enumerate().take(q - 1) {
1334 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1335 player
1336 .share(con.clone(), commitment.clone(), shares[0])
1337 .unwrap();
1338 commitments.insert(i as u32, commitment);
1339 }
1340
1341 let last = (q - 1) as u32;
1343 let (_, commitment, _) = Dealer::new(&mut rng, None, contributors.clone());
1344 commitments.insert(last, commitment);
1345 let result = player.finalize(commitments, HashMap::new());
1346 assert!(matches!(result, Err(Error::MissingShare)));
1347 }
1348
1349 #[test]
1350 fn test_player_insufficient_commitments() {
1351 let n = 5;
1353 let mut rng = StdRng::seed_from_u64(0);
1354
1355 let mut contributors = Vec::new();
1357 for i in 0..n {
1358 let signer = Ed25519::from_seed(i as u64).public_key();
1359 contributors.push(signer);
1360 }
1361 contributors.sort();
1362
1363 let mut player = Player::new(
1365 contributors[0].clone(),
1366 None,
1367 contributors.clone(),
1368 contributors.clone(),
1369 1,
1370 );
1371
1372 let mut commitments = HashMap::new();
1374 for (i, con) in contributors.iter().enumerate().take(2) {
1375 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1376 player
1377 .share(con.clone(), commitment.clone(), shares[0])
1378 .unwrap();
1379 commitments.insert(i as u32, commitment);
1380 }
1381
1382 let result = player.finalize(commitments, HashMap::new());
1384 assert!(matches!(result, Err(Error::InvalidCommitments)));
1385 }
1386
1387 #[test]
1388 fn test_player_misdirected_reveal() {
1389 let n = 11;
1391 let q = quorum(n as u32) as usize;
1392 let mut rng = StdRng::seed_from_u64(0);
1393
1394 let mut contributors = Vec::new();
1396 for i in 0..n {
1397 let signer = Ed25519::from_seed(i as u64).public_key();
1398 contributors.push(signer);
1399 }
1400 contributors.sort();
1401
1402 let mut player = Player::new(
1404 contributors[0].clone(),
1405 None,
1406 contributors.clone(),
1407 contributors.clone(),
1408 1,
1409 );
1410
1411 let mut commitments = HashMap::new();
1413 for (i, con) in contributors.iter().enumerate().take(q - 1) {
1414 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1415 player
1416 .share(con.clone(), commitment.clone(), shares[0])
1417 .unwrap();
1418 commitments.insert(i as u32, commitment);
1419 }
1420
1421 let last = (q - 1) as u32;
1423 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1424 commitments.insert(last, commitment);
1425 let mut reveals = HashMap::new();
1426 reveals.insert(last, shares[1]);
1427 let result = player.finalize(commitments, reveals);
1428 assert!(matches!(result, Err(Error::MisdirectedShare)));
1429 }
1430
1431 #[test]
1432 fn test_player_invalid_commitment() {
1433 let n = 11;
1435 let q = quorum(n as u32) as usize;
1436 let mut rng = StdRng::seed_from_u64(0);
1437
1438 let mut contributors = Vec::new();
1440 for i in 0..n {
1441 let signer = Ed25519::from_seed(i as u64).public_key();
1442 contributors.push(signer);
1443 }
1444 contributors.sort();
1445
1446 let mut player = Player::new(
1448 contributors[0].clone(),
1449 None,
1450 contributors.clone(),
1451 contributors.clone(),
1452 1,
1453 );
1454
1455 let mut commitments = HashMap::new();
1457 for (i, con) in contributors.iter().enumerate().take(q - 1) {
1458 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1459 player
1460 .share(con.clone(), commitment.clone(), shares[0])
1461 .unwrap();
1462 commitments.insert(i as u32, commitment);
1463 }
1464
1465 let last = (q - 1) as u32;
1467 let (commitment, shares) = ops::generate_shares(&mut rng, None, n as u32, 1);
1468 commitments.insert(last, commitment);
1469 let mut reveals = HashMap::new();
1470 reveals.insert(last, shares[0]);
1471 let result = player.finalize(commitments, reveals);
1472 assert!(matches!(result, Err(Error::CommitmentWrongDegree)));
1473 }
1474
1475 #[test]
1476 fn test_player_invalid_reveal() {
1477 let n = 11;
1479 let q = quorum(n as u32) as usize;
1480 let mut rng = StdRng::seed_from_u64(0);
1481
1482 let mut contributors = Vec::new();
1484 for i in 0..n {
1485 let signer = Ed25519::from_seed(i as u64).public_key();
1486 contributors.push(signer);
1487 }
1488 contributors.sort();
1489
1490 let mut player = Player::new(
1492 contributors[0].clone(),
1493 None,
1494 contributors.clone(),
1495 contributors.clone(),
1496 1,
1497 );
1498
1499 let mut commitments = HashMap::new();
1501 for (i, con) in contributors.iter().enumerate().take(q - 1) {
1502 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1503 player
1504 .share(con.clone(), commitment.clone(), shares[0])
1505 .unwrap();
1506 commitments.insert(i as u32, commitment);
1507 }
1508
1509 let last = (q - 1) as u32;
1511 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1512 commitments.insert(last, commitment);
1513 let mut reveals = HashMap::new();
1514 let mut share = shares[1];
1515 share.index = 0;
1516 reveals.insert(last, share);
1517 let result = player.finalize(commitments, reveals);
1518 assert!(matches!(result, Err(Error::ShareWrongCommitment)));
1519 }
1520}