1use std::collections::BTreeMap;
87
88use rustcrypto_ff::Field;
89
90use crate::curve::DklsCurve;
91use crate::utilities::hashes::{tagged_hash, HashOutput};
92use crate::utilities::multiplication::{MulReceiver, MulSender};
93use crate::utilities::oracle_tags::{TAG_REFRESH_FAST_B, TAG_REFRESH_FAST_R0, TAG_REFRESH_FAST_R1};
94use crate::utilities::ot;
95use crate::utilities::rng;
96use crate::utilities::zero_shares::{self, ZeroShare};
97
98use crate::protocols::derivation::DerivData;
99use crate::protocols::dkg::{
100 step2, step3, step5, KeepInitMulPhase3to4, KeepInitZeroSharePhase2to3,
101 KeepInitZeroSharePhase3to4, ProofCommitment, TransmitInitMulPhase3to4,
102 TransmitInitZeroSharePhase2to4, TransmitInitZeroSharePhase3to4,
103};
104use crate::protocols::{Abort, AbortReason, PartiesMessage, Party, PartyIndex};
105
106#[derive(Clone, Debug)]
115#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
116pub struct TransmitRefreshPhase2to4 {
117 pub parties: PartiesMessage,
118 pub commitment: HashOutput,
119}
120
121#[derive(Clone, Debug)]
125#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
126pub struct TransmitRefreshPhase3to4 {
127 pub parties: PartiesMessage,
128 pub seed: zero_shares::Seed,
129 pub salt: Vec<u8>,
130}
131
132#[derive(Clone, Debug)]
138#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
139pub struct KeepRefreshPhase2to3 {
140 pub seed: zero_shares::Seed,
141 pub salt: Vec<u8>,
142}
143
144#[derive(Clone, Debug)]
148#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
149pub struct KeepRefreshPhase3to4 {
150 pub seed: zero_shares::Seed,
151}
152
153#[cfg(feature = "serde")]
155mod message_tags {
156 use super::*;
157 use crate::protocols::messages::MessageTag;
158
159 impl MessageTag for TransmitRefreshPhase2to4 {
160 const TAG: u8 = 0x20;
161 }
162 impl MessageTag for TransmitRefreshPhase3to4 {
163 const TAG: u8 = 0x21;
164 }
165}
166
167impl<C: DklsCurve> Party<C> {
169 #[must_use]
176 pub fn refresh_complete_phase1(&self) -> Vec<C::Scalar> {
177 let mut secret_polynomial: Vec<C::Scalar> =
181 Vec::with_capacity(self.parameters.threshold as usize);
182 secret_polynomial.push(C::Scalar::ZERO);
183 for _ in 1..self.parameters.threshold {
184 secret_polynomial.push(C::Scalar::random(&mut rng::get_rng()));
185 }
186
187 step2::<C>(&self.parameters, &secret_polynomial)
188 }
189
190 #[must_use]
197 pub fn refresh_complete_phase2(
198 &self,
199 refresh_sid: &[u8],
200 poly_fragments: &[C::Scalar],
201 ) -> (
202 C::Scalar,
203 ProofCommitment<C>,
204 BTreeMap<PartyIndex, KeepInitZeroSharePhase2to3>,
205 Vec<TransmitInitZeroSharePhase2to4>,
206 ) {
207 let (correction_value, proof_commitment) =
213 step3::<C>(self.party_index, refresh_sid, poly_fragments);
214
215 let mut zero_keep: BTreeMap<PartyIndex, KeepInitZeroSharePhase2to3> = BTreeMap::new();
219 let mut zero_transmit: Vec<TransmitInitZeroSharePhase2to4> =
220 Vec::with_capacity((self.parameters.share_count - 1) as usize);
221 for i in 1..=self.parameters.share_count {
222 let i_idx = PartyIndex::new(i).unwrap();
223 if i_idx == self.party_index {
224 continue;
225 }
226
227 let (seed, commitment, salt) = ZeroShare::generate_seed_with_commitment();
229
230 let keep = KeepInitZeroSharePhase2to3 { seed, salt };
232 let transmit = TransmitInitZeroSharePhase2to4 {
233 parties: PartiesMessage {
234 sender: self.party_index,
235 receiver: i_idx,
236 },
237 commitment,
238 };
239
240 zero_keep.insert(i_idx, keep);
241 zero_transmit.push(transmit);
242 }
243
244 (correction_value, proof_commitment, zero_keep, zero_transmit)
245 }
246
247 #[must_use]
252 #[allow(clippy::type_complexity)]
253 pub fn refresh_complete_phase3(
254 &self,
255 refresh_sid: &[u8],
256 zero_kept: &BTreeMap<PartyIndex, KeepInitZeroSharePhase2to3>,
257 ) -> (
258 BTreeMap<PartyIndex, KeepInitZeroSharePhase3to4>,
259 Vec<TransmitInitZeroSharePhase3to4>,
260 BTreeMap<PartyIndex, KeepInitMulPhase3to4<C>>,
261 Vec<TransmitInitMulPhase3to4<C>>,
262 ) {
263 let mut zero_keep: BTreeMap<PartyIndex, KeepInitZeroSharePhase3to4> = BTreeMap::new();
267 let mut zero_transmit: Vec<TransmitInitZeroSharePhase3to4> =
268 Vec::with_capacity((self.parameters.share_count - 1) as usize);
269 for (target_party, message_kept) in zero_kept {
270 let keep = KeepInitZeroSharePhase3to4 {
274 seed: message_kept.seed,
275 };
276 let transmit = TransmitInitZeroSharePhase3to4 {
277 parties: PartiesMessage {
278 sender: self.party_index,
279 receiver: *target_party,
280 },
281 seed: message_kept.seed,
282 salt: message_kept.salt.clone(),
283 };
284
285 zero_keep.insert(*target_party, keep);
286 zero_transmit.push(transmit);
287 }
288
289 let mut mul_keep: BTreeMap<PartyIndex, KeepInitMulPhase3to4<C>> = BTreeMap::new();
293 let mut mul_transmit: Vec<TransmitInitMulPhase3to4<C>> =
294 Vec::with_capacity((self.parameters.share_count - 1) as usize);
295 for i in 1..=self.parameters.share_count {
296 let i_idx = PartyIndex::new(i).unwrap();
297 if i_idx == self.party_index {
298 continue;
299 }
300
301 let mul_sid_receiver = [
307 "Multiplication protocol".as_bytes(),
308 &self.party_index.as_u8().to_be_bytes(),
309 &i.to_be_bytes(),
310 refresh_sid,
311 ]
312 .concat();
313
314 let (ot_sender, dlog_proof, nonce) = MulReceiver::<C>::init_phase1(&mul_sid_receiver);
315
316 let mul_sid_sender = [
322 "Multiplication protocol".as_bytes(),
323 &i.to_be_bytes(),
324 &self.party_index.as_u8().to_be_bytes(),
325 refresh_sid,
326 ]
327 .concat();
328
329 let (ot_receiver, correlation, vec_r, enc_proofs) =
330 MulSender::<C>::init_phase1(&mul_sid_sender);
331
332 let transmit = TransmitInitMulPhase3to4 {
335 parties: PartiesMessage {
336 sender: self.party_index,
337 receiver: i_idx,
338 },
339
340 dlog_proof,
342 nonce,
343
344 enc_proofs,
346 seed: ot_receiver.seed,
347 };
348 let keep = KeepInitMulPhase3to4 {
349 ot_sender,
351 nonce,
352
353 ot_receiver,
355 correlation,
356 vec_r,
357 };
358
359 mul_keep.insert(i_idx, keep);
360 mul_transmit.push(transmit);
361 }
362
363 (zero_keep, zero_transmit, mul_keep, mul_transmit)
364 }
365
366 #[allow(clippy::too_many_arguments)]
380 pub fn refresh_complete_phase4(
381 &self,
382 refresh_sid: &[u8],
383 correction_value: &C::Scalar,
384 proofs_commitments: &[ProofCommitment<C>],
385 zero_kept: &BTreeMap<PartyIndex, KeepInitZeroSharePhase3to4>,
386 zero_received_phase2: &[TransmitInitZeroSharePhase2to4],
387 zero_received_phase3: &[TransmitInitZeroSharePhase3to4],
388 mul_kept: &BTreeMap<PartyIndex, KeepInitMulPhase3to4<C>>,
389 mul_received: &[TransmitInitMulPhase3to4<C>],
390 ) -> Result<Party<C>, Abort> {
391 let (verifying_pk, _) = step5::<C>(
398 &self.parameters,
399 self.party_index,
400 refresh_sid,
401 proofs_commitments,
402 )?;
403
404 if verifying_pk != <C::AffinePoint as rustcrypto_group::prime::PrimeCurveAffine>::identity()
406 {
407 return Err(Abort::recoverable(
408 self.party_index,
409 AbortReason::PolynomialInconsistency,
410 ));
411 }
412
413 let mut zero_received_phase2_by_sender: BTreeMap<
415 PartyIndex,
416 &TransmitInitZeroSharePhase2to4,
417 > = BTreeMap::new();
418 for message in zero_received_phase2 {
419 if message.parties.receiver != self.party_index {
420 return Err(Abort::recoverable(
421 self.party_index,
422 AbortReason::MisroutedMessage {
423 expected_receiver: self.party_index,
424 actual_receiver: message.parties.receiver,
425 },
426 ));
427 }
428 if !zero_kept.contains_key(&message.parties.sender) {
429 return Err(Abort::recoverable(
430 self.party_index,
431 AbortReason::UnexpectedSender {
432 sender: message.parties.sender,
433 },
434 ));
435 }
436 if zero_received_phase2_by_sender
437 .insert(message.parties.sender, message)
438 .is_some()
439 {
440 return Err(Abort::recoverable(
441 self.party_index,
442 AbortReason::DuplicateSender {
443 sender: message.parties.sender,
444 },
445 ));
446 }
447 }
448 let mut zero_received_phase3_by_sender: BTreeMap<
449 PartyIndex,
450 &TransmitInitZeroSharePhase3to4,
451 > = BTreeMap::new();
452 for message in zero_received_phase3 {
453 if message.parties.receiver != self.party_index {
454 return Err(Abort::recoverable(
455 self.party_index,
456 AbortReason::MisroutedMessage {
457 expected_receiver: self.party_index,
458 actual_receiver: message.parties.receiver,
459 },
460 ));
461 }
462 if !zero_kept.contains_key(&message.parties.sender) {
463 return Err(Abort::recoverable(
464 self.party_index,
465 AbortReason::UnexpectedSender {
466 sender: message.parties.sender,
467 },
468 ));
469 }
470 if zero_received_phase3_by_sender
471 .insert(message.parties.sender, message)
472 .is_some()
473 {
474 return Err(Abort::recoverable(
475 self.party_index,
476 AbortReason::DuplicateSender {
477 sender: message.parties.sender,
478 },
479 ));
480 }
481 }
482 if zero_received_phase2_by_sender.len() != zero_kept.len() {
483 return Err(Abort::recoverable(
484 self.party_index,
485 AbortReason::WrongMessageCount {
486 expected: zero_kept.len(),
487 got: zero_received_phase2_by_sender.len(),
488 },
489 ));
490 }
491 if zero_received_phase3_by_sender.len() != zero_kept.len() {
492 return Err(Abort::recoverable(
493 self.party_index,
494 AbortReason::WrongMessageCount {
495 expected: zero_kept.len(),
496 got: zero_received_phase3_by_sender.len(),
497 },
498 ));
499 }
500
501 let mut seeds: Vec<zero_shares::SeedPair> =
502 Vec::with_capacity((self.parameters.share_count - 1) as usize);
503 for (target_party, message_kept) in zero_kept {
504 let message_received_2 = zero_received_phase2_by_sender
505 .get(target_party)
506 .ok_or_else(|| {
507 Abort::recoverable(
508 self.party_index,
509 AbortReason::MissingMessageFromParty {
510 party: *target_party,
511 },
512 )
513 })?;
514 let message_received_3 = zero_received_phase3_by_sender
515 .get(target_party)
516 .ok_or_else(|| {
517 Abort::recoverable(
518 self.party_index,
519 AbortReason::MissingMessageFromParty {
520 party: *target_party,
521 },
522 )
523 })?;
524
525 let verification = ZeroShare::verify_seed(
527 &message_received_3.seed,
528 &message_received_2.commitment,
529 &message_received_3.salt,
530 );
531 if !verification {
532 return Err(Abort::recoverable(
533 self.party_index,
534 AbortReason::ZeroShareDecommitFailed {
535 counterparty: *target_party,
536 },
537 ));
538 }
539
540 seeds.push(ZeroShare::generate_seed_pair(
542 self.party_index,
543 *target_party,
544 &message_kept.seed,
545 &message_received_3.seed,
546 ));
547 }
548
549 let zero_share = ZeroShare::initialize(seeds);
551
552 let mut mul_receivers: BTreeMap<PartyIndex, MulReceiver<C>> = BTreeMap::new();
554 let mut mul_senders: BTreeMap<PartyIndex, MulSender<C>> = BTreeMap::new();
555 let mut mul_received_by_sender: BTreeMap<PartyIndex, &TransmitInitMulPhase3to4<C>> =
556 BTreeMap::new();
557 for message in mul_received {
558 if message.parties.receiver != self.party_index {
559 return Err(Abort::recoverable(
560 self.party_index,
561 AbortReason::MisroutedMessage {
562 expected_receiver: self.party_index,
563 actual_receiver: message.parties.receiver,
564 },
565 ));
566 }
567 if !mul_kept.contains_key(&message.parties.sender) {
568 return Err(Abort::recoverable(
569 self.party_index,
570 AbortReason::UnexpectedSender {
571 sender: message.parties.sender,
572 },
573 ));
574 }
575 if mul_received_by_sender
576 .insert(message.parties.sender, message)
577 .is_some()
578 {
579 return Err(Abort::recoverable(
580 self.party_index,
581 AbortReason::DuplicateSender {
582 sender: message.parties.sender,
583 },
584 ));
585 }
586 }
587 if mul_received_by_sender.len() != mul_kept.len() {
588 return Err(Abort::recoverable(
589 self.party_index,
590 AbortReason::WrongMessageCount {
591 expected: mul_kept.len(),
592 got: mul_received_by_sender.len(),
593 },
594 ));
595 }
596
597 for (target_party, message_kept) in mul_kept {
598 let message_received = mul_received_by_sender.get(target_party).ok_or_else(|| {
599 Abort::recoverable(
600 self.party_index,
601 AbortReason::MissingMessageFromParty {
602 party: *target_party,
603 },
604 )
605 })?;
606
607 let mul_sid_receiver = [
613 "Multiplication protocol".as_bytes(),
614 &self.party_index.as_u8().to_be_bytes(),
615 &target_party.as_u8().to_be_bytes(),
616 refresh_sid,
617 ]
618 .concat();
619
620 let receiver_result = MulReceiver::<C>::init_phase2(
621 &message_kept.ot_sender,
622 &mul_sid_receiver,
623 &message_received.seed,
624 &message_received.enc_proofs,
625 &message_kept.nonce,
626 );
627
628 let mul_receiver: MulReceiver<C> = match receiver_result {
629 Ok(r) => r,
630 Err(error) => {
631 return Err(Abort::recoverable(
634 self.party_index,
635 AbortReason::MultiplicationVerificationFailed {
636 counterparty: *target_party,
637 detail: error.description.clone(),
638 },
639 ));
640 }
641 };
642
643 let mul_sid_sender = [
649 "Multiplication protocol".as_bytes(),
650 &target_party.as_u8().to_be_bytes(),
651 &self.party_index.as_u8().to_be_bytes(),
652 refresh_sid,
653 ]
654 .concat();
655
656 let sender_result = MulSender::<C>::init_phase2(
657 &message_kept.ot_receiver,
658 &mul_sid_sender,
659 message_kept.correlation.clone(),
660 &message_kept.vec_r,
661 &message_received.dlog_proof,
662 &message_received.nonce,
663 );
664
665 let mul_sender: MulSender<C> = match sender_result {
666 Ok(s) => s,
667 Err(error) => {
668 return Err(Abort::recoverable(
671 self.party_index,
672 AbortReason::MultiplicationVerificationFailed {
673 counterparty: *target_party,
674 detail: error.description.clone(),
675 },
676 ));
677 }
678 };
679
680 mul_receivers.insert(*target_party, mul_receiver);
682 mul_senders.insert(*target_party, mul_sender.clone());
683 }
684
685 let derivation_data = DerivData {
687 depth: self.derivation_data.depth,
688 child_number: self.derivation_data.child_number,
689 parent_fingerprint: self.derivation_data.parent_fingerprint,
690 poly_point: self.poly_point + correction_value, pk: self.pk,
692 chain_code: self.derivation_data.chain_code,
693 };
694
695 let party = Party {
696 parameters: self.parameters.clone(),
697 party_index: self.party_index,
698 session_id: refresh_sid.to_vec(), poly_point: self.poly_point + correction_value, pk: self.pk,
702
703 zero_share,
704
705 mul_senders,
706 mul_receivers,
707
708 derivation_data,
709
710 address: self.address.clone(),
711 };
712
713 Ok(party)
714 }
715
716 #[must_use]
723 pub fn refresh_phase1(&self) -> Vec<C::Scalar> {
724 let mut secret_polynomial: Vec<C::Scalar> =
728 Vec::with_capacity(self.parameters.threshold as usize);
729 secret_polynomial.push(C::Scalar::ZERO);
730 for _ in 1..self.parameters.threshold {
731 secret_polynomial.push(C::Scalar::random(&mut rng::get_rng()));
732 }
733
734 step2::<C>(&self.parameters, &secret_polynomial)
735 }
736
737 #[must_use]
744 pub fn refresh_phase2(
745 &self,
746 refresh_sid: &[u8],
747 poly_fragments: &[C::Scalar],
748 ) -> (
749 C::Scalar,
750 ProofCommitment<C>,
751 BTreeMap<PartyIndex, KeepRefreshPhase2to3>,
752 Vec<TransmitRefreshPhase2to4>,
753 ) {
754 let (correction_value, proof_commitment) =
760 step3::<C>(self.party_index, refresh_sid, poly_fragments);
761
762 let mut keep: BTreeMap<PartyIndex, KeepRefreshPhase2to3> = BTreeMap::new();
766 let mut transmit: Vec<TransmitRefreshPhase2to4> =
767 Vec::with_capacity((self.parameters.share_count - 1) as usize);
768 for i in 1..=self.parameters.share_count {
769 let i_idx = PartyIndex::new(i).unwrap();
770 if i_idx == self.party_index {
771 continue;
772 }
773
774 let (seed, commitment, salt) = ZeroShare::generate_seed_with_commitment();
776
777 keep.insert(i_idx, KeepRefreshPhase2to3 { seed, salt });
779 transmit.push(TransmitRefreshPhase2to4 {
780 parties: PartiesMessage {
781 sender: self.party_index,
782 receiver: i_idx,
783 },
784 commitment,
785 });
786 }
787
788 (correction_value, proof_commitment, keep, transmit)
789 }
790
791 #[must_use]
796 pub fn refresh_phase3(
797 &self,
798 kept: &BTreeMap<PartyIndex, KeepRefreshPhase2to3>,
799 ) -> (
800 BTreeMap<PartyIndex, KeepRefreshPhase3to4>,
801 Vec<TransmitRefreshPhase3to4>,
802 ) {
803 let mut keep: BTreeMap<PartyIndex, KeepRefreshPhase3to4> = BTreeMap::new();
807 let mut transmit: Vec<TransmitRefreshPhase3to4> =
808 Vec::with_capacity((self.parameters.share_count - 1) as usize);
809 for (target_party, message_kept) in kept {
810 keep.insert(
814 *target_party,
815 KeepRefreshPhase3to4 {
816 seed: message_kept.seed,
817 },
818 );
819 transmit.push(TransmitRefreshPhase3to4 {
820 parties: PartiesMessage {
821 sender: self.party_index,
822 receiver: *target_party,
823 },
824 seed: message_kept.seed,
825 salt: message_kept.salt.clone(),
826 });
827 }
828
829 (keep, transmit)
830 }
831
832 pub fn refresh_phase4(
850 &self,
851 refresh_sid: &[u8],
852 correction_value: &C::Scalar,
853 proofs_commitments: &[ProofCommitment<C>],
854 kept: &BTreeMap<PartyIndex, KeepRefreshPhase3to4>,
855 received_phase2: &[TransmitRefreshPhase2to4],
856 received_phase3: &[TransmitRefreshPhase3to4],
857 ) -> Result<Party<C>, Abort> {
858 let (verifying_pk, _) = step5::<C>(
865 &self.parameters,
866 self.party_index,
867 refresh_sid,
868 proofs_commitments,
869 )?;
870
871 if verifying_pk != <C::AffinePoint as rustcrypto_group::prime::PrimeCurveAffine>::identity()
873 {
874 return Err(Abort::recoverable(
875 self.party_index,
876 AbortReason::PolynomialInconsistency,
877 ));
878 }
879
880 let mut received_phase2_by_sender: BTreeMap<PartyIndex, &TransmitRefreshPhase2to4> =
882 BTreeMap::new();
883 for message in received_phase2 {
884 if message.parties.receiver != self.party_index {
885 return Err(Abort::recoverable(
886 self.party_index,
887 AbortReason::MisroutedMessage {
888 expected_receiver: self.party_index,
889 actual_receiver: message.parties.receiver,
890 },
891 ));
892 }
893 if !kept.contains_key(&message.parties.sender) {
894 return Err(Abort::recoverable(
895 self.party_index,
896 AbortReason::UnexpectedSender {
897 sender: message.parties.sender,
898 },
899 ));
900 }
901 if received_phase2_by_sender
902 .insert(message.parties.sender, message)
903 .is_some()
904 {
905 return Err(Abort::recoverable(
906 self.party_index,
907 AbortReason::DuplicateSender {
908 sender: message.parties.sender,
909 },
910 ));
911 }
912 }
913 let mut received_phase3_by_sender: BTreeMap<PartyIndex, &TransmitRefreshPhase3to4> =
914 BTreeMap::new();
915 for message in received_phase3 {
916 if message.parties.receiver != self.party_index {
917 return Err(Abort::recoverable(
918 self.party_index,
919 AbortReason::MisroutedMessage {
920 expected_receiver: self.party_index,
921 actual_receiver: message.parties.receiver,
922 },
923 ));
924 }
925 if !kept.contains_key(&message.parties.sender) {
926 return Err(Abort::recoverable(
927 self.party_index,
928 AbortReason::UnexpectedSender {
929 sender: message.parties.sender,
930 },
931 ));
932 }
933 if received_phase3_by_sender
934 .insert(message.parties.sender, message)
935 .is_some()
936 {
937 return Err(Abort::recoverable(
938 self.party_index,
939 AbortReason::DuplicateSender {
940 sender: message.parties.sender,
941 },
942 ));
943 }
944 }
945 if received_phase2_by_sender.len() != kept.len() {
946 return Err(Abort::recoverable(
947 self.party_index,
948 AbortReason::WrongMessageCount {
949 expected: kept.len(),
950 got: received_phase2_by_sender.len(),
951 },
952 ));
953 }
954 if received_phase3_by_sender.len() != kept.len() {
955 return Err(Abort::recoverable(
956 self.party_index,
957 AbortReason::WrongMessageCount {
958 expected: kept.len(),
959 got: received_phase3_by_sender.len(),
960 },
961 ));
962 }
963
964 let mut seeds: Vec<zero_shares::SeedPair> =
965 Vec::with_capacity((self.parameters.share_count - 1) as usize);
966 for (target_party, message_kept) in kept {
967 let message_received_2 =
968 received_phase2_by_sender.get(target_party).ok_or_else(|| {
969 Abort::recoverable(
970 self.party_index,
971 AbortReason::MissingMessageFromParty {
972 party: *target_party,
973 },
974 )
975 })?;
976 let message_received_3 =
977 received_phase3_by_sender.get(target_party).ok_or_else(|| {
978 Abort::recoverable(
979 self.party_index,
980 AbortReason::MissingMessageFromParty {
981 party: *target_party,
982 },
983 )
984 })?;
985
986 let verification = ZeroShare::verify_seed(
988 &message_received_3.seed,
989 &message_received_2.commitment,
990 &message_received_3.salt,
991 );
992 if !verification {
993 return Err(Abort::recoverable(
994 self.party_index,
995 AbortReason::ZeroShareDecommitFailed {
996 counterparty: *target_party,
997 },
998 ));
999 }
1000
1001 seeds.push(ZeroShare::generate_seed_pair(
1003 self.party_index,
1004 *target_party,
1005 &message_kept.seed,
1006 &message_received_3.seed,
1007 ));
1008 }
1009
1010 let mut mul_senders: BTreeMap<PartyIndex, MulSender<C>> = BTreeMap::new();
1013 let mut mul_receivers: BTreeMap<PartyIndex, MulReceiver<C>> = BTreeMap::new();
1014
1015 for seed_pair in &seeds {
1016 let their_index = seed_pair.index_counterparty;
1019 let seed = seed_pair.seed;
1020
1021 let mul_sender = self.mul_senders.get(&their_index).ok_or_else(|| {
1022 Abort::recoverable(
1023 self.party_index,
1024 AbortReason::MissingMulState {
1025 counterparty: their_index,
1026 },
1027 )
1028 })?;
1029 let mul_receiver = self.mul_receivers.get(&their_index).ok_or_else(|| {
1030 Abort::recoverable(
1031 self.party_index,
1032 AbortReason::MissingMulState {
1033 counterparty: their_index,
1034 },
1035 )
1036 })?;
1037
1038 let mut new_ote_sender = mul_sender.ote_sender.clone();
1041 let mut new_ote_receiver = mul_receiver.ote_receiver.clone();
1042
1043 for i in 0..(ot::extension::KAPPA) {
1044 let i_bytes = i.to_be_bytes();
1052 let sender_bytes = u16::from(self.party_index.as_u8()).to_be_bytes();
1053 let receiver_bytes = u16::from(their_index.as_u8()).to_be_bytes();
1054
1055 let r0_prime = tagged_hash(
1056 TAG_REFRESH_FAST_R0,
1057 &[refresh_sid, &i_bytes, &sender_bytes, &receiver_bytes, &seed],
1058 );
1059 let r1_prime = tagged_hash(
1060 TAG_REFRESH_FAST_R1,
1061 &[refresh_sid, &i_bytes, &sender_bytes, &receiver_bytes, &seed],
1062 );
1063 let b_prime = (tagged_hash(
1064 TAG_REFRESH_FAST_B,
1065 &[refresh_sid, &i_bytes, &sender_bytes, &receiver_bytes, &seed],
1066 )[0] % 2)
1067 == 1; let b_double_prime = new_ote_sender.correlation[i as usize] ^ b_prime;
1070 let r_prime_b_double_prime = if b_double_prime { r1_prime } else { r0_prime };
1071
1072 let mut r_double_prime: HashOutput = [0; crate::SECURITY as usize];
1073 for j in 0..crate::SECURITY {
1074 r_double_prime[j as usize] = new_ote_sender.seeds[i as usize][j as usize]
1075 ^ r_prime_b_double_prime[j as usize];
1076 }
1077
1078 new_ote_sender.correlation[i as usize] = b_double_prime;
1080 new_ote_sender.seeds[i as usize] = r_double_prime;
1081
1082 let i_bytes = i.to_be_bytes();
1084 let sender_bytes = u16::from(their_index.as_u8()).to_be_bytes();
1085 let receiver_bytes = u16::from(self.party_index.as_u8()).to_be_bytes();
1086
1087 let r0_prime = tagged_hash(
1088 TAG_REFRESH_FAST_R0,
1089 &[refresh_sid, &i_bytes, &sender_bytes, &receiver_bytes, &seed],
1090 );
1091 let r1_prime = tagged_hash(
1092 TAG_REFRESH_FAST_R1,
1093 &[refresh_sid, &i_bytes, &sender_bytes, &receiver_bytes, &seed],
1094 );
1095 let b_prime = (tagged_hash(
1096 TAG_REFRESH_FAST_B,
1097 &[refresh_sid, &i_bytes, &sender_bytes, &receiver_bytes, &seed],
1098 )[0] % 2)
1099 == 1; let r_b_prime = if b_prime {
1102 new_ote_receiver.seeds1[i as usize]
1103 } else {
1104 new_ote_receiver.seeds0[i as usize]
1105 };
1106 let r_opposite_b_prime = if b_prime {
1107 new_ote_receiver.seeds0[i as usize]
1108 } else {
1109 new_ote_receiver.seeds1[i as usize]
1110 };
1111
1112 let mut r0_double_prime: HashOutput = [0; crate::SECURITY as usize];
1113 let mut r1_double_prime: HashOutput = [0; crate::SECURITY as usize];
1114 for j in 0..crate::SECURITY {
1115 r0_double_prime[j as usize] = r_b_prime[j as usize] ^ r0_prime[j as usize];
1116 r1_double_prime[j as usize] =
1117 r_opposite_b_prime[j as usize] ^ r1_prime[j as usize];
1118 }
1119
1120 new_ote_receiver.seeds0[i as usize] = r0_double_prime;
1122 new_ote_receiver.seeds1[i as usize] = r1_double_prime;
1123 }
1124
1125 mul_senders.insert(
1127 their_index,
1128 MulSender {
1129 public_gadget: mul_sender.public_gadget.clone(),
1130 ote_sender: new_ote_sender,
1131 _curve: core::marker::PhantomData,
1132 },
1133 );
1134 mul_receivers.insert(
1135 their_index,
1136 MulReceiver {
1137 public_gadget: mul_receiver.public_gadget.clone(),
1138 ote_receiver: new_ote_receiver,
1139 _curve: core::marker::PhantomData,
1140 },
1141 );
1142 }
1143
1144 let zero_share = ZeroShare::initialize(seeds);
1146
1147 let derivation_data = DerivData {
1149 depth: self.derivation_data.depth,
1150 child_number: self.derivation_data.child_number,
1151 parent_fingerprint: self.derivation_data.parent_fingerprint,
1152 poly_point: self.poly_point + correction_value, pk: self.pk,
1154 chain_code: self.derivation_data.chain_code,
1155 };
1156
1157 let party = Party {
1159 parameters: self.parameters.clone(),
1160 party_index: self.party_index,
1161 session_id: refresh_sid.to_vec(), poly_point: self.poly_point + correction_value, pk: self.pk,
1165
1166 zero_share,
1167
1168 mul_senders,
1169 mul_receivers,
1170
1171 derivation_data,
1172
1173 address: self.address.clone(),
1174 };
1175
1176 Ok(party)
1177 }
1178}
1179
1180#[cfg(test)]
1181mod tests {
1182
1183 use super::*;
1184
1185 use k256::Secp256k1;
1186
1187 use crate::protocols::re_key::re_key;
1188 use crate::protocols::signing::*;
1189 use crate::protocols::{AbortKind, AbortReason, Parameters};
1190 use crate::utilities::hashes::tagged_hash;
1191
1192 use rand::RngExt;
1193
1194 const SESSION_ID_LEN: usize = 32;
1195
1196 struct CompleteRefreshPhase4Inputs {
1197 parties: Vec<Party<Secp256k1>>,
1198 refresh_sid: [u8; SESSION_ID_LEN],
1199 correction_values: Vec<k256::Scalar>,
1200 proofs_commitments: Vec<ProofCommitment<Secp256k1>>,
1201 zero_kept_3to4: Vec<BTreeMap<PartyIndex, KeepInitZeroSharePhase3to4>>,
1202 zero_received_2to4: Vec<Vec<TransmitInitZeroSharePhase2to4>>,
1203 zero_received_3to4: Vec<Vec<TransmitInitZeroSharePhase3to4>>,
1204 mul_kept_3to4: Vec<BTreeMap<PartyIndex, KeepInitMulPhase3to4<Secp256k1>>>,
1205 mul_received_3to4: Vec<Vec<TransmitInitMulPhase3to4<Secp256k1>>>,
1206 }
1207
1208 fn setup_two_party_complete_refresh_phase4_inputs() -> CompleteRefreshPhase4Inputs {
1209 let parameters = Parameters {
1210 threshold: 2,
1211 share_count: 2,
1212 };
1213 let session_id = rng::get_rng().random::<[u8; SESSION_ID_LEN]>();
1214 let secret_key = k256::Scalar::random(&mut rng::get_rng());
1215 let (parties, _) = re_key::<Secp256k1>(¶meters, &session_id, &secret_key, None, |_| {
1216 String::new()
1217 });
1218
1219 let refresh_sid = rng::get_rng().random::<[u8; SESSION_ID_LEN]>();
1220
1221 let mut dkg_1: Vec<Vec<k256::Scalar>> = Vec::with_capacity(parameters.share_count as usize);
1223 for i in 0..parameters.share_count {
1224 dkg_1.push(parties[i as usize].refresh_complete_phase1());
1225 }
1226
1227 let mut poly_fragments =
1229 vec![
1230 Vec::<k256::Scalar>::with_capacity(parameters.share_count as usize);
1231 parameters.share_count as usize
1232 ];
1233 for row_i in dkg_1 {
1234 for j in 0..parameters.share_count {
1235 poly_fragments[j as usize].push(row_i[j as usize]);
1236 }
1237 }
1238
1239 let mut correction_values: Vec<k256::Scalar> =
1241 Vec::with_capacity(parameters.share_count as usize);
1242 let mut proofs_commitments: Vec<ProofCommitment<Secp256k1>> =
1243 Vec::with_capacity(parameters.share_count as usize);
1244 let mut zero_kept_2to3: Vec<BTreeMap<PartyIndex, KeepInitZeroSharePhase2to3>> =
1245 Vec::with_capacity(parameters.share_count as usize);
1246 let mut zero_transmit_2to4: Vec<Vec<TransmitInitZeroSharePhase2to4>> =
1247 Vec::with_capacity(parameters.share_count as usize);
1248 for i in 0..parameters.share_count {
1249 let (out1, out2, out3, out4) = parties[i as usize]
1250 .refresh_complete_phase2(&refresh_sid, &poly_fragments[i as usize]);
1251
1252 correction_values.push(out1);
1253 proofs_commitments.push(out2);
1254 zero_kept_2to3.push(out3);
1255 zero_transmit_2to4.push(out4);
1256 }
1257
1258 let mut zero_received_2to4: Vec<Vec<TransmitInitZeroSharePhase2to4>> =
1260 Vec::with_capacity(parameters.share_count as usize);
1261 for i in 1..=parameters.share_count {
1262 let i_idx = PartyIndex::new(i).unwrap();
1263 let mut new_row: Vec<TransmitInitZeroSharePhase2to4> =
1264 Vec::with_capacity((parameters.share_count - 1) as usize);
1265 for party in &zero_transmit_2to4 {
1266 for message in party {
1267 if message.parties.receiver == i_idx {
1268 new_row.push(message.clone());
1269 }
1270 }
1271 }
1272 zero_received_2to4.push(new_row);
1273 }
1274
1275 let mut zero_kept_3to4: Vec<BTreeMap<PartyIndex, KeepInitZeroSharePhase3to4>> =
1277 Vec::with_capacity(parameters.share_count as usize);
1278 let mut zero_transmit_3to4: Vec<Vec<TransmitInitZeroSharePhase3to4>> =
1279 Vec::with_capacity(parameters.share_count as usize);
1280 let mut mul_kept_3to4: Vec<BTreeMap<PartyIndex, KeepInitMulPhase3to4<Secp256k1>>> =
1281 Vec::with_capacity(parameters.share_count as usize);
1282 let mut mul_transmit_3to4: Vec<Vec<TransmitInitMulPhase3to4<Secp256k1>>> =
1283 Vec::with_capacity(parameters.share_count as usize);
1284 for i in 0..parameters.share_count {
1285 let (out1, out2, out3, out4) = parties[i as usize]
1286 .refresh_complete_phase3(&refresh_sid, &zero_kept_2to3[i as usize]);
1287
1288 zero_kept_3to4.push(out1);
1289 zero_transmit_3to4.push(out2);
1290 mul_kept_3to4.push(out3);
1291 mul_transmit_3to4.push(out4);
1292 }
1293
1294 let mut zero_received_3to4: Vec<Vec<TransmitInitZeroSharePhase3to4>> =
1296 Vec::with_capacity(parameters.share_count as usize);
1297 let mut mul_received_3to4: Vec<Vec<TransmitInitMulPhase3to4<Secp256k1>>> =
1298 Vec::with_capacity(parameters.share_count as usize);
1299 for i in 1..=parameters.share_count {
1300 let i_idx = PartyIndex::new(i).unwrap();
1301 let mut zero_row: Vec<TransmitInitZeroSharePhase3to4> =
1302 Vec::with_capacity((parameters.share_count - 1) as usize);
1303 for party in &zero_transmit_3to4 {
1304 for message in party {
1305 if message.parties.receiver == i_idx {
1306 zero_row.push(message.clone());
1307 }
1308 }
1309 }
1310 zero_received_3to4.push(zero_row);
1311
1312 let mut mul_row: Vec<TransmitInitMulPhase3to4<Secp256k1>> =
1313 Vec::with_capacity((parameters.share_count - 1) as usize);
1314 for party in &mul_transmit_3to4 {
1315 for message in party {
1316 if message.parties.receiver == i_idx {
1317 mul_row.push(message.clone());
1318 }
1319 }
1320 }
1321 mul_received_3to4.push(mul_row);
1322 }
1323
1324 CompleteRefreshPhase4Inputs {
1325 parties,
1326 refresh_sid,
1327 correction_values,
1328 proofs_commitments,
1329 zero_kept_3to4,
1330 zero_received_2to4,
1331 zero_received_3to4,
1332 mul_kept_3to4,
1333 mul_received_3to4,
1334 }
1335 }
1336
1337 #[test]
1339 fn test_refresh_complete_phase4_aborts_on_tampered_enc_proof() {
1340 let mut data = setup_two_party_complete_refresh_phase4_inputs();
1341
1342 let tampered = data.mul_received_3to4[0]
1343 .iter_mut()
1344 .find(|message| {
1345 message.parties.sender == PartyIndex::new(2).unwrap()
1346 && message.parties.receiver == PartyIndex::new(1).unwrap()
1347 })
1348 .expect("expected party-2 message for party 1 in complete refresh");
1349 assert!(
1350 !tampered.enc_proofs.is_empty(),
1351 "expected non-empty enc_proofs in complete refresh test setup"
1352 );
1353 tampered.enc_proofs[0].challenge0 += k256::Scalar::ONE;
1354
1355 let result = data.parties[0].refresh_complete_phase4(
1356 &data.refresh_sid,
1357 &data.correction_values[0],
1358 &data.proofs_commitments,
1359 &data.zero_kept_3to4[0],
1360 &data.zero_received_2to4[0],
1361 &data.zero_received_3to4[0],
1362 &data.mul_kept_3to4[0],
1363 &data.mul_received_3to4[0],
1364 );
1365 let abort = result.expect_err("tampered complete-refresh enc proof should be rejected");
1366 assert_eq!(abort.kind, AbortKind::Recoverable);
1367 assert!(
1368 matches!(abort.reason, AbortReason::MultiplicationVerificationFailed { counterparty, .. } if counterparty == PartyIndex::new(2).unwrap())
1369 );
1370 }
1371
1372 #[test]
1374 fn test_refresh_complete_phase4_aborts_on_tampered_dlog_proof() {
1375 let mut data = setup_two_party_complete_refresh_phase4_inputs();
1376
1377 let tampered = data.mul_received_3to4[0]
1378 .iter_mut()
1379 .find(|message| {
1380 message.parties.sender == PartyIndex::new(2).unwrap()
1381 && message.parties.receiver == PartyIndex::new(1).unwrap()
1382 })
1383 .expect("expected party-2 message for party 1 in complete refresh");
1384 assert!(
1385 !tampered.dlog_proof.proofs.is_empty(),
1386 "expected non-empty DLog proof vector in complete refresh test setup"
1387 );
1388 tampered.dlog_proof.proofs[0].challenge_response += k256::Scalar::ONE;
1389
1390 let result = data.parties[0].refresh_complete_phase4(
1391 &data.refresh_sid,
1392 &data.correction_values[0],
1393 &data.proofs_commitments,
1394 &data.zero_kept_3to4[0],
1395 &data.zero_received_2to4[0],
1396 &data.zero_received_3to4[0],
1397 &data.mul_kept_3to4[0],
1398 &data.mul_received_3to4[0],
1399 );
1400 let abort = result.expect_err("tampered complete-refresh DLog proof should be rejected");
1401 assert_eq!(abort.kind, AbortKind::Recoverable);
1402 assert!(
1403 matches!(abort.reason, AbortReason::MultiplicationVerificationFailed { counterparty, .. } if counterparty == PartyIndex::new(2).unwrap())
1404 );
1405 }
1406
1407 #[test]
1409 fn test_refresh_complete_phase4_rejects_duplicate_mul_init_sender() {
1410 let mut data = setup_two_party_complete_refresh_phase4_inputs();
1411
1412 let duplicate = data.mul_received_3to4[0]
1413 .first()
1414 .expect("expected at least one mul-init message in test setup")
1415 .clone();
1416 data.mul_received_3to4[0].push(duplicate);
1417
1418 let result = data.parties[0].refresh_complete_phase4(
1419 &data.refresh_sid,
1420 &data.correction_values[0],
1421 &data.proofs_commitments,
1422 &data.zero_kept_3to4[0],
1423 &data.zero_received_2to4[0],
1424 &data.zero_received_3to4[0],
1425 &data.mul_kept_3to4[0],
1426 &data.mul_received_3to4[0],
1427 );
1428 let abort = result.expect_err("duplicate mul-init sender should be rejected");
1429 assert_eq!(abort.kind, AbortKind::Recoverable);
1430 assert!(
1431 matches!(abort.reason, AbortReason::DuplicateSender { sender } if sender == PartyIndex::new(2).unwrap())
1432 );
1433 }
1434
1435 #[test]
1440 fn test_refresh_complete() {
1441 let threshold = rng::get_rng().random_range(2..=5); let offset = rng::get_rng().random_range(0..=5);
1443
1444 let parameters = Parameters {
1445 threshold,
1446 share_count: threshold + offset,
1447 }; let session_id = rng::get_rng().random::<[u8; SESSION_ID_LEN]>();
1451 let secret_key = k256::Scalar::random(&mut rng::get_rng());
1452 let (parties, _) = re_key::<Secp256k1>(¶meters, &session_id, &secret_key, None, |_| {
1453 String::new()
1454 });
1455
1456 let refresh_sid = rng::get_rng().random::<[u8; SESSION_ID_LEN]>();
1459
1460 let mut dkg_1: Vec<Vec<k256::Scalar>> = Vec::with_capacity(parameters.share_count as usize);
1462 for i in 0..parameters.share_count {
1463 let out1 = parties[i as usize].refresh_complete_phase1();
1464
1465 dkg_1.push(out1);
1466 }
1467
1468 let mut poly_fragments =
1471 vec![
1472 Vec::<k256::Scalar>::with_capacity(parameters.share_count as usize);
1473 parameters.share_count as usize
1474 ];
1475 for row_i in dkg_1 {
1476 for j in 0..parameters.share_count {
1477 poly_fragments[j as usize].push(row_i[j as usize]);
1478 }
1479 }
1480
1481 let mut correction_values: Vec<k256::Scalar> =
1483 Vec::with_capacity(parameters.share_count as usize);
1484 let mut proofs_commitments: Vec<ProofCommitment<Secp256k1>> =
1485 Vec::with_capacity(parameters.share_count as usize);
1486 let mut zero_kept_2to3: Vec<BTreeMap<PartyIndex, KeepInitZeroSharePhase2to3>> =
1487 Vec::with_capacity(parameters.share_count as usize);
1488 let mut zero_transmit_2to4: Vec<Vec<TransmitInitZeroSharePhase2to4>> =
1489 Vec::with_capacity(parameters.share_count as usize);
1490 for i in 0..parameters.share_count {
1491 let (out1, out2, out3, out4) = parties[i as usize]
1492 .refresh_complete_phase2(&refresh_sid, &poly_fragments[i as usize]);
1493
1494 correction_values.push(out1);
1495 proofs_commitments.push(out2);
1496 zero_kept_2to3.push(out3);
1497 zero_transmit_2to4.push(out4);
1498 }
1499
1500 let mut zero_received_2to4: Vec<Vec<TransmitInitZeroSharePhase2to4>> =
1502 Vec::with_capacity(parameters.share_count as usize);
1503 for i in 1..=parameters.share_count {
1504 let i_idx = PartyIndex::new(i).unwrap();
1508 let mut new_row: Vec<TransmitInitZeroSharePhase2to4> =
1509 Vec::with_capacity((parameters.share_count - 1) as usize);
1510 for party in &zero_transmit_2to4 {
1511 for message in party {
1512 if message.parties.receiver == i_idx {
1514 new_row.push(message.clone());
1515 }
1516 }
1517 }
1518 zero_received_2to4.push(new_row);
1519 }
1520
1521 let mut zero_kept_3to4: Vec<BTreeMap<PartyIndex, KeepInitZeroSharePhase3to4>> =
1523 Vec::with_capacity(parameters.share_count as usize);
1524 let mut zero_transmit_3to4: Vec<Vec<TransmitInitZeroSharePhase3to4>> =
1525 Vec::with_capacity(parameters.share_count as usize);
1526 let mut mul_kept_3to4: Vec<BTreeMap<PartyIndex, KeepInitMulPhase3to4<Secp256k1>>> =
1527 Vec::with_capacity(parameters.share_count as usize);
1528 let mut mul_transmit_3to4: Vec<Vec<TransmitInitMulPhase3to4<Secp256k1>>> =
1529 Vec::with_capacity(parameters.share_count as usize);
1530 for i in 0..parameters.share_count {
1531 let (out1, out2, out3, out4) = parties[i as usize]
1532 .refresh_complete_phase3(&refresh_sid, &zero_kept_2to3[i as usize]);
1533
1534 zero_kept_3to4.push(out1);
1535 zero_transmit_3to4.push(out2);
1536 mul_kept_3to4.push(out3);
1537 mul_transmit_3to4.push(out4);
1538 }
1539
1540 let mut zero_received_3to4: Vec<Vec<TransmitInitZeroSharePhase3to4>> =
1542 Vec::with_capacity(parameters.share_count as usize);
1543 let mut mul_received_3to4: Vec<Vec<TransmitInitMulPhase3to4<Secp256k1>>> =
1544 Vec::with_capacity(parameters.share_count as usize);
1545 for i in 1..=parameters.share_count {
1546 let i_idx = PartyIndex::new(i).unwrap();
1550 let mut new_row: Vec<TransmitInitZeroSharePhase3to4> =
1551 Vec::with_capacity((parameters.share_count - 1) as usize);
1552 for party in &zero_transmit_3to4 {
1553 for message in party {
1554 if message.parties.receiver == i_idx {
1556 new_row.push(message.clone());
1557 }
1558 }
1559 }
1560 zero_received_3to4.push(new_row);
1561
1562 let mut new_row: Vec<TransmitInitMulPhase3to4<Secp256k1>> =
1563 Vec::with_capacity((parameters.share_count - 1) as usize);
1564 for party in &mul_transmit_3to4 {
1565 for message in party {
1566 if message.parties.receiver == i_idx {
1568 new_row.push(message.clone());
1569 }
1570 }
1571 }
1572 mul_received_3to4.push(new_row);
1573 }
1574
1575 let mut refreshed_parties: Vec<Party<Secp256k1>> =
1577 Vec::with_capacity(parameters.share_count as usize);
1578 for i in 0..parameters.share_count {
1579 let result = parties[i as usize].refresh_complete_phase4(
1580 &refresh_sid,
1581 &correction_values[i as usize],
1582 &proofs_commitments,
1583 &zero_kept_3to4[i as usize],
1584 &zero_received_2to4[i as usize],
1585 &zero_received_3to4[i as usize],
1586 &mul_kept_3to4[i as usize],
1587 &mul_received_3to4[i as usize],
1588 );
1589 match result {
1590 Err(abort) => {
1591 panic!("Party {} aborted: {:?}", abort.index, abort.description());
1592 }
1593 Ok(party) => {
1594 refreshed_parties.push(party);
1595 }
1596 }
1597 }
1598
1599 let parties = refreshed_parties;
1600
1601 let sign_id = rng::get_rng().random::<[u8; SESSION_ID_LEN]>();
1604 let message_to_sign = tagged_hash(b"test-sign", &[b"Message to sign!"]);
1605
1606 let executing_parties: Vec<PartyIndex> = (1..=parameters.threshold)
1608 .map(|i| PartyIndex::new(i).unwrap())
1609 .collect();
1610
1611 let mut all_data: BTreeMap<PartyIndex, SignData> = BTreeMap::new();
1613 for party_index in executing_parties.clone() {
1614 let mut counterparties = executing_parties.clone();
1616 counterparties.retain(|index| *index != party_index);
1617
1618 all_data.insert(
1619 party_index,
1620 SignData {
1621 sign_id: sign_id.to_vec(),
1622 counterparties,
1623 message_hash: message_to_sign,
1624 },
1625 );
1626 }
1627
1628 let mut unique_kept_1to2: BTreeMap<PartyIndex, UniqueKeep1to2<Secp256k1>> = BTreeMap::new();
1630 let mut kept_1to2: BTreeMap<PartyIndex, BTreeMap<PartyIndex, KeepPhase1to2<Secp256k1>>> =
1631 BTreeMap::new();
1632 let mut transmit_1to2: BTreeMap<PartyIndex, Vec<TransmitPhase1to2>> = BTreeMap::new();
1633 for party_index in executing_parties.clone() {
1634 let (unique_keep, keep, transmit) = parties[(party_index.as_u8() - 1) as usize]
1635 .sign_phase1(all_data.get(&party_index).unwrap())
1636 .unwrap();
1637
1638 unique_kept_1to2.insert(party_index, unique_keep);
1639 kept_1to2.insert(party_index, keep);
1640 transmit_1to2.insert(party_index, transmit);
1641 }
1642
1643 let mut received_1to2: BTreeMap<PartyIndex, Vec<TransmitPhase1to2>> = BTreeMap::new();
1645 for &party_index in &executing_parties {
1646 let messages_for_party: Vec<TransmitPhase1to2> = transmit_1to2
1647 .values()
1648 .flatten()
1649 .filter(|message| message.parties.receiver == party_index)
1650 .cloned()
1651 .collect();
1652
1653 received_1to2.insert(party_index, messages_for_party);
1654 }
1655
1656 let mut unique_kept_2to3: BTreeMap<PartyIndex, UniqueKeep2to3<Secp256k1>> = BTreeMap::new();
1658 let mut kept_2to3: BTreeMap<PartyIndex, BTreeMap<PartyIndex, KeepPhase2to3<Secp256k1>>> =
1659 BTreeMap::new();
1660 let mut transmit_2to3: BTreeMap<PartyIndex, Vec<TransmitPhase2to3<Secp256k1>>> =
1661 BTreeMap::new();
1662 for party_index in executing_parties.clone() {
1663 let result = parties[(party_index.as_u8() - 1) as usize].sign_phase2(
1664 all_data.get(&party_index).unwrap(),
1665 unique_kept_1to2.get(&party_index).unwrap(),
1666 kept_1to2.get(&party_index).unwrap(),
1667 received_1to2.get(&party_index).unwrap(),
1668 );
1669 match result {
1670 Err(abort) => {
1671 panic!("Party {} aborted: {:?}", abort.index, abort.description());
1672 }
1673 Ok((unique_keep, keep, transmit)) => {
1674 unique_kept_2to3.insert(party_index, unique_keep);
1675 kept_2to3.insert(party_index, keep);
1676 transmit_2to3.insert(party_index, transmit);
1677 }
1678 }
1679 }
1680
1681 let mut received_2to3: BTreeMap<PartyIndex, Vec<TransmitPhase2to3<Secp256k1>>> =
1683 BTreeMap::new();
1684
1685 for &party_index in &executing_parties {
1686 let filtered_messages: Vec<_> = transmit_2to3
1687 .values()
1688 .flatten()
1689 .filter(|msg| msg.parties.receiver == party_index)
1690 .cloned()
1691 .collect();
1692
1693 received_2to3.insert(party_index, filtered_messages);
1694 }
1695
1696 let mut x_coords: Vec<String> = Vec::with_capacity(parameters.threshold as usize);
1698 let mut broadcast_3to4: Vec<Broadcast3to4<Secp256k1>> =
1699 Vec::with_capacity(parameters.threshold as usize);
1700 for party_index in executing_parties.clone() {
1701 let result = parties[(party_index.as_u8() - 1) as usize].sign_phase3(
1702 all_data.get(&party_index).unwrap(),
1703 unique_kept_2to3.get(&party_index).unwrap(),
1704 kept_2to3.get(&party_index).unwrap(),
1705 received_2to3.get(&party_index).unwrap(),
1706 );
1707 match result {
1708 Err(abort) => {
1709 panic!("Party {} aborted: {:?}", abort.index, abort.description());
1710 }
1711 Ok((x_coord, broadcast)) => {
1712 x_coords.push(x_coord);
1713 broadcast_3to4.push(broadcast);
1714 }
1715 }
1716 }
1717
1718 let x_coord = x_coords[0].clone(); for i in 1..parameters.threshold {
1721 assert_eq!(x_coord, x_coords[i as usize]);
1722 }
1723
1724 let some_index = executing_parties[0];
1729 let result = parties[(some_index.as_u8() - 1) as usize].sign_phase4(
1730 all_data.get(&some_index).unwrap(),
1731 &x_coord,
1732 &broadcast_3to4,
1733 true,
1734 );
1735 if let Err(abort) = result {
1736 panic!("Party {} aborted: {:?}", abort.index, abort.description());
1737 }
1738 }
1739
1740 #[test]
1745 fn test_refresh() {
1746 let threshold = rng::get_rng().random_range(2..=5); let offset = rng::get_rng().random_range(0..=5);
1748
1749 let parameters = Parameters {
1750 threshold,
1751 share_count: threshold + offset,
1752 }; let session_id = rng::get_rng().random::<[u8; SESSION_ID_LEN]>();
1756 let secret_key = k256::Scalar::random(&mut rng::get_rng());
1757 let (parties, _) = re_key::<Secp256k1>(¶meters, &session_id, &secret_key, None, |_| {
1758 String::new()
1759 });
1760
1761 let refresh_sid = rng::get_rng().random::<[u8; SESSION_ID_LEN]>();
1764
1765 let mut dkg_1: Vec<Vec<k256::Scalar>> = Vec::with_capacity(parameters.share_count as usize);
1767 for i in 0..parameters.share_count {
1768 let out1 = parties[i as usize].refresh_phase1();
1769
1770 dkg_1.push(out1);
1771 }
1772
1773 let mut poly_fragments =
1776 vec![
1777 Vec::<k256::Scalar>::with_capacity(parameters.share_count as usize);
1778 parameters.share_count as usize
1779 ];
1780 for row_i in dkg_1 {
1781 for j in 0..parameters.share_count {
1782 poly_fragments[j as usize].push(row_i[j as usize]);
1783 }
1784 }
1785
1786 let mut correction_values: Vec<k256::Scalar> =
1788 Vec::with_capacity(parameters.share_count as usize);
1789 let mut proofs_commitments: Vec<ProofCommitment<Secp256k1>> =
1790 Vec::with_capacity(parameters.share_count as usize);
1791 let mut kept_2to3: Vec<BTreeMap<PartyIndex, KeepRefreshPhase2to3>> =
1792 Vec::with_capacity(parameters.share_count as usize);
1793 let mut transmit_2to4: Vec<Vec<TransmitRefreshPhase2to4>> =
1794 Vec::with_capacity(parameters.share_count as usize);
1795 for i in 0..parameters.share_count {
1796 let (out1, out2, out3, out4) =
1797 parties[i as usize].refresh_phase2(&refresh_sid, &poly_fragments[i as usize]);
1798
1799 correction_values.push(out1);
1800 proofs_commitments.push(out2);
1801 kept_2to3.push(out3);
1802 transmit_2to4.push(out4);
1803 }
1804
1805 let mut received_2to4: Vec<Vec<TransmitRefreshPhase2to4>> =
1807 Vec::with_capacity(parameters.share_count as usize);
1808 for i in 1..=parameters.share_count {
1809 let i_idx = PartyIndex::new(i).unwrap();
1813 let mut new_row: Vec<TransmitRefreshPhase2to4> =
1814 Vec::with_capacity((parameters.share_count - 1) as usize);
1815 for party in &transmit_2to4 {
1816 for message in party {
1817 if message.parties.receiver == i_idx {
1819 new_row.push(message.clone());
1820 }
1821 }
1822 }
1823 received_2to4.push(new_row);
1824 }
1825
1826 let mut kept_3to4: Vec<BTreeMap<PartyIndex, KeepRefreshPhase3to4>> =
1828 Vec::with_capacity(parameters.share_count as usize);
1829 let mut transmit_3to4: Vec<Vec<TransmitRefreshPhase3to4>> =
1830 Vec::with_capacity(parameters.share_count as usize);
1831 for i in 0..parameters.share_count {
1832 let (out1, out2) = parties[i as usize].refresh_phase3(&kept_2to3[i as usize]);
1833
1834 kept_3to4.push(out1);
1835 transmit_3to4.push(out2);
1836 }
1837
1838 let mut received_3to4: Vec<Vec<TransmitRefreshPhase3to4>> =
1840 Vec::with_capacity(parameters.share_count as usize);
1841 for i in 1..=parameters.share_count {
1842 let i_idx = PartyIndex::new(i).unwrap();
1846 let mut new_row: Vec<TransmitRefreshPhase3to4> =
1847 Vec::with_capacity((parameters.share_count - 1) as usize);
1848 for party in &transmit_3to4 {
1849 for message in party {
1850 if message.parties.receiver == i_idx {
1852 new_row.push(message.clone());
1853 }
1854 }
1855 }
1856 received_3to4.push(new_row);
1857 }
1858
1859 let mut refreshed_parties: Vec<Party<Secp256k1>> =
1861 Vec::with_capacity(parameters.share_count as usize);
1862 for i in 0..parameters.share_count {
1863 let result = parties[i as usize].refresh_phase4(
1864 &refresh_sid,
1865 &correction_values[i as usize],
1866 &proofs_commitments,
1867 &kept_3to4[i as usize],
1868 &received_2to4[i as usize],
1869 &received_3to4[i as usize],
1870 );
1871 match result {
1872 Err(abort) => {
1873 panic!("Party {} aborted: {:?}", abort.index, abort.description());
1874 }
1875 Ok(party) => {
1876 refreshed_parties.push(party);
1877 }
1878 }
1879 }
1880
1881 let parties = refreshed_parties;
1882
1883 let sign_id = rng::get_rng().random::<[u8; SESSION_ID_LEN]>();
1886 let message_to_sign = tagged_hash(b"test-sign", &[b"Message to sign!"]);
1887
1888 let executing_parties: Vec<PartyIndex> = (1..=parameters.threshold)
1890 .map(|i| PartyIndex::new(i).unwrap())
1891 .collect();
1892
1893 let mut all_data: BTreeMap<PartyIndex, SignData> = BTreeMap::new();
1895 for party_index in executing_parties.clone() {
1896 let mut counterparties = executing_parties.clone();
1898 counterparties.retain(|index| *index != party_index);
1899
1900 all_data.insert(
1901 party_index,
1902 SignData {
1903 sign_id: sign_id.to_vec(),
1904 counterparties,
1905 message_hash: message_to_sign,
1906 },
1907 );
1908 }
1909
1910 let mut unique_kept_1to2: BTreeMap<PartyIndex, UniqueKeep1to2<Secp256k1>> = BTreeMap::new();
1912 let mut kept_1to2: BTreeMap<PartyIndex, BTreeMap<PartyIndex, KeepPhase1to2<Secp256k1>>> =
1913 BTreeMap::new();
1914 let mut transmit_1to2: BTreeMap<PartyIndex, Vec<TransmitPhase1to2>> = BTreeMap::new();
1915 for party_index in executing_parties.clone() {
1916 let (unique_keep, keep, transmit) = parties[(party_index.as_u8() - 1) as usize]
1917 .sign_phase1(all_data.get(&party_index).unwrap())
1918 .unwrap();
1919
1920 unique_kept_1to2.insert(party_index, unique_keep);
1921 kept_1to2.insert(party_index, keep);
1922 transmit_1to2.insert(party_index, transmit);
1923 }
1924
1925 let mut received_1to2: BTreeMap<PartyIndex, Vec<TransmitPhase1to2>> = BTreeMap::new();
1927
1928 for &party_index in &executing_parties {
1929 let filtered_messages: Vec<_> = transmit_1to2
1930 .values()
1931 .flatten()
1932 .filter(|msg| msg.parties.receiver == party_index)
1933 .cloned()
1934 .collect();
1935
1936 received_1to2.insert(party_index, filtered_messages);
1937 }
1938
1939 let mut unique_kept_2to3: BTreeMap<PartyIndex, UniqueKeep2to3<Secp256k1>> = BTreeMap::new();
1941 let mut kept_2to3: BTreeMap<PartyIndex, BTreeMap<PartyIndex, KeepPhase2to3<Secp256k1>>> =
1942 BTreeMap::new();
1943 let mut transmit_2to3: BTreeMap<PartyIndex, Vec<TransmitPhase2to3<Secp256k1>>> =
1944 BTreeMap::new();
1945 for party_index in executing_parties.clone() {
1946 let result = parties[(party_index.as_u8() - 1) as usize].sign_phase2(
1947 all_data.get(&party_index).unwrap(),
1948 unique_kept_1to2.get(&party_index).unwrap(),
1949 kept_1to2.get(&party_index).unwrap(),
1950 received_1to2.get(&party_index).unwrap(),
1951 );
1952 match result {
1953 Err(abort) => {
1954 panic!("Party {} aborted: {:?}", abort.index, abort.description());
1955 }
1956 Ok((unique_keep, keep, transmit)) => {
1957 unique_kept_2to3.insert(party_index, unique_keep);
1958 kept_2to3.insert(party_index, keep);
1959 transmit_2to3.insert(party_index, transmit);
1960 }
1961 }
1962 }
1963
1964 let mut received_2to3: BTreeMap<PartyIndex, Vec<TransmitPhase2to3<Secp256k1>>> =
1966 BTreeMap::new();
1967
1968 for &party_index in &executing_parties {
1969 let messages_for_party: Vec<TransmitPhase2to3<Secp256k1>> = transmit_2to3
1970 .values()
1971 .flatten()
1972 .filter(|message| message.parties.receiver == party_index)
1973 .cloned()
1974 .collect();
1975
1976 received_2to3.insert(party_index, messages_for_party);
1977 }
1978
1979 let mut x_coords: Vec<String> = Vec::with_capacity(parameters.threshold as usize);
1981 let mut broadcast_3to4: Vec<Broadcast3to4<Secp256k1>> =
1982 Vec::with_capacity(parameters.threshold as usize);
1983 for party_index in executing_parties.clone() {
1984 let result = parties[(party_index.as_u8() - 1) as usize].sign_phase3(
1985 all_data.get(&party_index).unwrap(),
1986 unique_kept_2to3.get(&party_index).unwrap(),
1987 kept_2to3.get(&party_index).unwrap(),
1988 received_2to3.get(&party_index).unwrap(),
1989 );
1990 match result {
1991 Err(abort) => {
1992 panic!("Party {} aborted: {:?}", abort.index, abort.description());
1993 }
1994 Ok((x_coord, broadcast)) => {
1995 x_coords.push(x_coord);
1996 broadcast_3to4.push(broadcast);
1997 }
1998 }
1999 }
2000
2001 let x_coord = x_coords[0].clone(); for i in 1..parameters.threshold {
2004 assert_eq!(x_coord, x_coords[i as usize]);
2005 }
2006
2007 let some_index = executing_parties[0];
2012 let result = parties[(some_index.as_u8() - 1) as usize].sign_phase4(
2013 all_data.get(&some_index).unwrap(),
2014 &x_coord,
2015 &broadcast_3to4,
2016 true,
2017 );
2018 if let Err(abort) = result {
2019 panic!("Party {} aborted: {:?}", abort.index, abort.description());
2020 }
2021 }
2022}