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, Scheme};
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).unwrap() 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).unwrap();
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).unwrap() 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).unwrap();
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, 3, 10, 3, 4);
437 }
438
439 #[test]
440 fn test_dkg_and_reshare_min_active_large() {
441 run_dkg_and_reshare(20, 13, 100, 13, 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).unwrap();
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).unwrap();
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).unwrap();
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 = 5;
751 let mut rng = StdRng::seed_from_u64(0);
752
753 let mut contributors = Vec::new();
755 for i in 0..n {
756 let signer = Ed25519::from_seed(i as u64).public_key();
757 contributors.push(signer);
758 }
759 contributors.sort();
760
761 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
763
764 let mut commitments = Vec::with_capacity(n);
766 let mut reveals = Vec::with_capacity(n);
767 for con in &contributors {
768 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
770 commitments.push(commitment.clone());
771 reveals.push(shares[4]);
772
773 arb.commitment(con.clone(), commitment, vec![0, 1, 2, 3], vec![shares[4]])
775 .unwrap();
776 }
777
778 let (result, _) = arb.finalize();
780 let output = result.unwrap();
781
782 assert_eq!(output.commitments.len(), 3);
784 for (dealer_idx, commitment) in commitments.iter().enumerate().take(3) {
785 let dealer_idx = dealer_idx as u32;
786 assert_eq!(output.commitments.get(&dealer_idx).unwrap(), commitment);
787 assert_eq!(
788 output.reveals.get(&dealer_idx).unwrap()[0],
789 reveals[dealer_idx as usize]
790 );
791 }
792 }
793
794 #[test]
795 fn test_arbiter_best() {}
796
797 #[test]
798 fn test_duplicate_commitment() {
799 let n = 5;
801 let mut rng = StdRng::seed_from_u64(0);
802
803 let mut contributors = Vec::new();
805 for i in 0..n {
806 let signer = Ed25519::from_seed(i as u64).public_key();
807 contributors.push(signer);
808 }
809 contributors.sort();
810
811 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
813
814 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
816
817 arb.commitment(
819 contributors[0].clone(),
820 commitment.clone(),
821 vec![0, 1, 2, 3],
822 vec![shares[4]],
823 )
824 .unwrap();
825
826 let result = arb.commitment(
828 contributors[0].clone(),
829 commitment,
830 vec![0, 1, 2, 3],
831 vec![shares[4]],
832 );
833 assert!(matches!(result, Err(Error::DuplicateCommitment)));
834 }
835
836 #[test]
837 fn test_reveal_duplicate_player() {
838 let n = 5;
840 let mut rng = StdRng::seed_from_u64(0);
841
842 let mut contributors = Vec::new();
844 for i in 0..n {
845 let signer = Ed25519::from_seed(i as u64).public_key();
846 contributors.push(signer);
847 }
848 contributors.sort();
849
850 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
852
853 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
855
856 let result = arb.commitment(
858 contributors[0].clone(),
859 commitment,
860 vec![0, 1, 2, 3],
861 vec![shares[3]],
862 );
863 assert!(matches!(result, Err(Error::AlreadyActive)));
864 }
865
866 #[test]
867 fn test_insufficient_active() {
868 let n = 5;
870 let mut rng = StdRng::seed_from_u64(0);
871
872 let mut contributors = Vec::new();
874 for i in 0..n {
875 let signer = Ed25519::from_seed(i as u64).public_key();
876 contributors.push(signer);
877 }
878 contributors.sort();
879
880 let (_, commitment, _) = Dealer::new(&mut rng, None, contributors.clone());
882
883 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
885
886 let result = arb.commitment(
888 contributors[0].clone(),
889 commitment.clone(),
890 vec![0, 1, 2, 3],
891 Vec::new(),
892 );
893 assert!(matches!(result, Err(Error::IncorrectActive)));
894
895 let result = arb.commitment(
897 contributors[0].clone(),
898 commitment,
899 vec![0, 1, 2, 3, 4],
900 Vec::new(),
901 );
902 assert!(matches!(result, Err(Error::DealerDisqualified)));
903 }
904
905 #[test]
906 fn test_manual_disqualify() {
907 let n = 5;
909 let mut rng = StdRng::seed_from_u64(0);
910
911 let mut contributors = Vec::new();
913 for i in 0..n {
914 let signer = Ed25519::from_seed(i as u64).public_key();
915 contributors.push(signer);
916 }
917 contributors.sort();
918
919 let (_, commitment, _) = Dealer::new(&mut rng, None, contributors.clone());
921
922 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
924
925 arb.disqualify(contributors[0].clone());
927
928 let result = arb.commitment(
930 contributors[0].clone(),
931 commitment,
932 vec![0, 1, 2, 3, 4],
933 Vec::new(),
934 );
935 assert!(matches!(result, Err(Error::DealerDisqualified)));
936 }
937
938 #[test]
939 fn test_too_many_reveals() {
940 let n = 5;
942 let mut rng = StdRng::seed_from_u64(0);
943
944 let mut contributors = Vec::new();
946 for i in 0..n {
947 let signer = Ed25519::from_seed(i as u64).public_key();
948 contributors.push(signer);
949 }
950 contributors.sort();
951
952 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
954
955 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
957
958 let result = arb.commitment(
960 contributors[0].clone(),
961 commitment,
962 vec![0, 1, 2],
963 vec![shares[3], shares[4]],
964 );
965 assert!(matches!(result, Err(Error::TooManyReveals)));
966 }
967
968 #[test]
969 fn test_incorrect_reveal() {
970 let n = 5;
972 let mut rng = StdRng::seed_from_u64(0);
973
974 let mut contributors = Vec::new();
976 for i in 0..n {
977 let signer = Ed25519::from_seed(i as u64).public_key();
978 contributors.push(signer);
979 }
980 contributors.sort();
981
982 let (_, commitment, _) = Dealer::new(&mut rng, None, contributors.clone());
984
985 let t = quorum(n).unwrap();
987 let (_, shares) = ops::generate_shares(&mut rng, None, n, t);
988
989 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
991
992 let result = arb.commitment(
994 contributors[0].clone(),
995 commitment,
996 vec![0, 1, 2, 3],
997 vec![shares[4]],
998 );
999 assert!(matches!(result, Err(Error::ShareWrongCommitment)));
1000 }
1001
1002 #[test]
1003 fn test_reveal_corrupt_share() {
1004 let n = 5;
1006 let mut rng = StdRng::seed_from_u64(0);
1007
1008 let mut contributors = Vec::new();
1010 for i in 0..n {
1011 let signer = Ed25519::from_seed(i as u64).public_key();
1012 contributors.push(signer);
1013 }
1014 contributors.sort();
1015
1016 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1018
1019 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
1021
1022 let mut share = shares[3];
1024 share.index = 4;
1025
1026 let result = arb.commitment(
1028 contributors[0].clone(),
1029 commitment,
1030 vec![0, 1, 2, 3],
1031 vec![share],
1032 );
1033 assert!(matches!(result, Err(Error::ShareWrongCommitment)));
1034 }
1035
1036 #[test]
1037 fn test_reveal_duplicate_ack() {
1038 let n = 5;
1040 let mut rng = StdRng::seed_from_u64(0);
1041
1042 let mut contributors = Vec::new();
1044 for i in 0..n {
1045 let signer = Ed25519::from_seed(i as u64).public_key();
1046 contributors.push(signer);
1047 }
1048 contributors.sort();
1049
1050 let (_, commitment, _) = Dealer::new(&mut rng, None, contributors.clone());
1052
1053 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
1055
1056 let result = arb.commitment(
1058 contributors[0].clone(),
1059 commitment,
1060 vec![0, 1, 2, 2],
1061 Vec::new(),
1062 );
1063 assert!(matches!(result, Err(Error::AlreadyActive)));
1064 }
1065
1066 #[test]
1067 fn test_reveal_invalid_ack() {
1068 let n = 5;
1070 let mut rng = StdRng::seed_from_u64(0);
1071
1072 let mut contributors = Vec::new();
1074 for i in 0..n {
1075 let signer = Ed25519::from_seed(i as u64).public_key();
1076 contributors.push(signer);
1077 }
1078 contributors.sort();
1079
1080 let (_, commitment, _) = Dealer::new(&mut rng, None, contributors.clone());
1082
1083 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
1085
1086 let result = arb.commitment(
1088 contributors[0].clone(),
1089 commitment,
1090 vec![0, 1, 2, 10],
1091 Vec::new(),
1092 );
1093 assert!(matches!(result, Err(Error::PlayerInvalid)));
1094 }
1095
1096 #[test]
1097 fn test_reveal_invalid_share() {
1098 let n = 5;
1100 let mut rng = StdRng::seed_from_u64(0);
1101
1102 let mut contributors = Vec::new();
1104 for i in 0..n {
1105 let signer = Ed25519::from_seed(i as u64).public_key();
1106 contributors.push(signer);
1107 }
1108 contributors.sort();
1109
1110 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1112
1113 let mut arb = Arbiter::new(None, contributors.clone(), contributors.clone(), 1);
1115
1116 let mut share = shares[3];
1118 share.index = 10;
1119
1120 let result = arb.commitment(
1122 contributors[0].clone(),
1123 commitment,
1124 vec![0, 1, 2, 3],
1125 vec![share],
1126 );
1127 assert!(matches!(result, Err(Error::PlayerInvalid)));
1128 }
1129
1130 #[test]
1131 fn test_dealer_acks() {
1132 let n = 5;
1134 let mut rng = StdRng::seed_from_u64(0);
1135
1136 let mut contributors = Vec::new();
1138 for i in 0..n {
1139 let signer = Ed25519::from_seed(i as u64).public_key();
1140 contributors.push(signer);
1141 }
1142 contributors.sort();
1143
1144 let (mut dealer, _, _) = Dealer::new(&mut rng, None, contributors.clone());
1146
1147 for player in &contributors {
1149 dealer.ack(player.clone()).unwrap();
1150 }
1151
1152 let output = dealer.finalize().unwrap();
1154 assert_eq!(output.active, vec![0, 1, 2, 3, 4]);
1155 assert!(output.inactive.is_empty());
1156 }
1157
1158 #[test]
1159 fn test_dealer_inactive() {
1160 let n = 5;
1162 let mut rng = StdRng::seed_from_u64(0);
1163
1164 let mut contributors = Vec::new();
1166 for i in 0..n {
1167 let signer = Ed25519::from_seed(i as u64).public_key();
1168 contributors.push(signer);
1169 }
1170 contributors.sort();
1171
1172 let (mut dealer, _, _) = Dealer::new(&mut rng, None, contributors.clone());
1174
1175 for player in contributors.iter().take(4) {
1177 dealer.ack(player.clone()).unwrap();
1178 }
1179
1180 let output = dealer.finalize().unwrap();
1182 assert_eq!(output.active, vec![0, 1, 2, 3]);
1183 assert_eq!(output.inactive, vec![4]);
1184 }
1185
1186 #[test]
1187 fn test_dealer_insufficient() {
1188 let n = 5;
1190 let mut rng = StdRng::seed_from_u64(0);
1191
1192 let mut contributors = Vec::new();
1194 for i in 0..n {
1195 let signer = Ed25519::from_seed(i as u64).public_key();
1196 contributors.push(signer);
1197 }
1198 contributors.sort();
1199
1200 let (mut dealer, _, _) = Dealer::new(&mut rng, None, contributors.clone());
1202
1203 for player in contributors.iter().take(2) {
1205 dealer.ack(player.clone()).unwrap();
1206 }
1207
1208 assert!(dealer.finalize().is_none());
1210 }
1211
1212 #[test]
1213 fn test_dealer_duplicate_ack() {
1214 let n = 5;
1216 let mut rng = StdRng::seed_from_u64(0);
1217
1218 let mut contributors = Vec::new();
1220 for i in 0..n {
1221 let signer = Ed25519::from_seed(i as u64).public_key();
1222 contributors.push(signer);
1223 }
1224 contributors.sort();
1225
1226 let (mut dealer, _, _) = Dealer::new(&mut rng, None, contributors.clone());
1228
1229 let player = contributors[0].clone();
1231 dealer.ack(player.clone()).unwrap();
1232
1233 let result = dealer.ack(player);
1235 assert!(matches!(result, Err(Error::DuplicateAck)));
1236 }
1237
1238 #[test]
1239 fn test_dealer_invalid_player() {
1240 let n = 5;
1242 let mut rng = StdRng::seed_from_u64(0);
1243
1244 let mut contributors = Vec::new();
1246 for i in 0..n {
1247 let signer = Ed25519::from_seed(i as u64).public_key();
1248 contributors.push(signer);
1249 }
1250 contributors.sort();
1251
1252 let (mut dealer, _, _) = Dealer::new(&mut rng, None, contributors.clone());
1254
1255 let player = Ed25519::from_seed(n as u64).public_key();
1257 let result = dealer.ack(player);
1258 assert!(matches!(result, Err(Error::PlayerInvalid)));
1259 }
1260
1261 #[test]
1262 fn test_player_reveals() {
1263 let n = 5;
1265 let mut rng = StdRng::seed_from_u64(0);
1266
1267 let mut contributors = Vec::new();
1269 for i in 0..n {
1270 let signer = Ed25519::from_seed(i as u64).public_key();
1271 contributors.push(signer);
1272 }
1273 contributors.sort();
1274
1275 let mut player = Player::new(
1277 contributors[0].clone(),
1278 None,
1279 contributors.clone(),
1280 contributors.clone(),
1281 1,
1282 );
1283
1284 let mut commitments = HashMap::new();
1286 for (i, con) in contributors.iter().enumerate().take(2) {
1287 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1288 player
1289 .share(con.clone(), commitment.clone(), shares[0])
1290 .unwrap();
1291 commitments.insert(i as u32, commitment);
1292 }
1293
1294 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1296 commitments.insert(2, commitment);
1297 let mut reveals = HashMap::new();
1298 reveals.insert(2, shares[0]);
1299 player.finalize(commitments, reveals).unwrap();
1300 }
1301
1302 #[test]
1303 fn test_player_missing_reveal() {
1304 let n = 5;
1306 let mut rng = StdRng::seed_from_u64(0);
1307
1308 let mut contributors = Vec::new();
1310 for i in 0..n {
1311 let signer = Ed25519::from_seed(i as u64).public_key();
1312 contributors.push(signer);
1313 }
1314 contributors.sort();
1315
1316 let mut player = Player::new(
1318 contributors[0].clone(),
1319 None,
1320 contributors.clone(),
1321 contributors.clone(),
1322 1,
1323 );
1324
1325 let mut commitments = HashMap::new();
1327 for (i, con) in contributors.iter().enumerate().take(2) {
1328 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1329 player
1330 .share(con.clone(), commitment.clone(), shares[0])
1331 .unwrap();
1332 commitments.insert(i as u32, commitment);
1333 }
1334
1335 let (_, commitment, _) = Dealer::new(&mut rng, None, contributors.clone());
1337 commitments.insert(2, commitment);
1338 let result = player.finalize(commitments, HashMap::new());
1339 assert!(matches!(result, Err(Error::MissingShare)));
1340 }
1341
1342 #[test]
1343 fn test_player_insufficient_commitments() {
1344 let n = 5;
1346 let mut rng = StdRng::seed_from_u64(0);
1347
1348 let mut contributors = Vec::new();
1350 for i in 0..n {
1351 let signer = Ed25519::from_seed(i as u64).public_key();
1352 contributors.push(signer);
1353 }
1354 contributors.sort();
1355
1356 let mut player = Player::new(
1358 contributors[0].clone(),
1359 None,
1360 contributors.clone(),
1361 contributors.clone(),
1362 1,
1363 );
1364
1365 let mut commitments = HashMap::new();
1367 for (i, con) in contributors.iter().enumerate().take(2) {
1368 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1369 player
1370 .share(con.clone(), commitment.clone(), shares[0])
1371 .unwrap();
1372 commitments.insert(i as u32, commitment);
1373 }
1374
1375 let result = player.finalize(commitments, HashMap::new());
1377 assert!(matches!(result, Err(Error::InvalidCommitments)));
1378 }
1379
1380 #[test]
1381 fn test_player_misdirected_reveal() {
1382 let n = 5;
1384 let mut rng = StdRng::seed_from_u64(0);
1385
1386 let mut contributors = Vec::new();
1388 for i in 0..n {
1389 let signer = Ed25519::from_seed(i as u64).public_key();
1390 contributors.push(signer);
1391 }
1392 contributors.sort();
1393
1394 let mut player = Player::new(
1396 contributors[0].clone(),
1397 None,
1398 contributors.clone(),
1399 contributors.clone(),
1400 1,
1401 );
1402
1403 let mut commitments = HashMap::new();
1405 for (i, con) in contributors.iter().enumerate().take(2) {
1406 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1407 player
1408 .share(con.clone(), commitment.clone(), shares[0])
1409 .unwrap();
1410 commitments.insert(i as u32, commitment);
1411 }
1412
1413 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1415 commitments.insert(2, commitment);
1416 let mut reveals = HashMap::new();
1417 reveals.insert(2, shares[1]);
1418 let result = player.finalize(commitments, reveals);
1419 assert!(matches!(result, Err(Error::MisdirectedShare)));
1420 }
1421
1422 #[test]
1423 fn test_player_invalid_commitment() {
1424 let n = 5;
1426 let mut rng = StdRng::seed_from_u64(0);
1427
1428 let mut contributors = Vec::new();
1430 for i in 0..n {
1431 let signer = Ed25519::from_seed(i as u64).public_key();
1432 contributors.push(signer);
1433 }
1434 contributors.sort();
1435
1436 let mut player = Player::new(
1438 contributors[0].clone(),
1439 None,
1440 contributors.clone(),
1441 contributors.clone(),
1442 1,
1443 );
1444
1445 let mut commitments = HashMap::new();
1447 for (i, con) in contributors.iter().enumerate().take(2) {
1448 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1449 player
1450 .share(con.clone(), commitment.clone(), shares[0])
1451 .unwrap();
1452 commitments.insert(i as u32, commitment);
1453 }
1454
1455 let (commitment, shares) = ops::generate_shares(&mut rng, None, n, 1);
1457 commitments.insert(2, commitment);
1458 let mut reveals = HashMap::new();
1459 reveals.insert(2, shares[0]);
1460 let result = player.finalize(commitments, reveals);
1461 assert!(matches!(result, Err(Error::CommitmentWrongDegree)));
1462 }
1463
1464 #[test]
1465 fn test_player_invalid_reveal() {
1466 let n = 5;
1468 let mut rng = StdRng::seed_from_u64(0);
1469
1470 let mut contributors = Vec::new();
1472 for i in 0..n {
1473 let signer = Ed25519::from_seed(i as u64).public_key();
1474 contributors.push(signer);
1475 }
1476 contributors.sort();
1477
1478 let mut player = Player::new(
1480 contributors[0].clone(),
1481 None,
1482 contributors.clone(),
1483 contributors.clone(),
1484 1,
1485 );
1486
1487 let mut commitments = HashMap::new();
1489 for (i, con) in contributors.iter().enumerate().take(2) {
1490 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1491 player
1492 .share(con.clone(), commitment.clone(), shares[0])
1493 .unwrap();
1494 commitments.insert(i as u32, commitment);
1495 }
1496
1497 let (_, commitment, shares) = Dealer::new(&mut rng, None, contributors.clone());
1499 commitments.insert(2, commitment);
1500 let mut reveals = HashMap::new();
1501 let mut share = shares[1];
1502 share.index = 0;
1503 reveals.insert(2, share);
1504 let result = player.finalize(commitments, reveals);
1505 assert!(matches!(result, Err(Error::ShareWrongCommitment)));
1506 }
1507}