1#![deny(
183 missing_docs,
184 unused_import_braces,
185 unused_qualifications,
186 unused_parens,
187 unused_lifetimes,
188 unconditional_recursion,
189 unused_extern_crates,
190 trivial_casts,
191 trivial_numeric_casts
192)]
193#![cfg_attr(docsrs, feature(doc_cfg))]
194
195pub use rand_core;
196pub use vsss_rs;
197
198mod error;
199mod parameters;
200mod participant;
201mod pedersen_result;
202mod protected;
203mod secret_share;
204
205use rand_core::SeedableRng;
206use serde::{
207 de::{Error as DError, SeqAccess, Unexpected, Visitor},
208 ser::{SerializeSeq, SerializeTuple},
209 Deserialize, Deserializer, Serialize, Serializer,
210};
211use std::{
212 collections::BTreeSet,
213 fmt::{self, Display, Formatter},
214 marker::PhantomData,
215 num::NonZeroUsize,
216};
217use uint_zigzag::Uint;
218use vsss_rs::elliptic_curve::{group::GroupEncoding, Group, PrimeField};
219use zeroize::{Zeroize, ZeroizeOnDrop};
220
221pub use error::*;
222pub use parameters::*;
223pub use participant::*;
224pub use pedersen_result::*;
225
226#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq, Ord, PartialOrd, Hash)]
228pub enum Round {
229 One,
231 Two,
233 Three,
235 Four,
237 Five,
239}
240
241impl Display for Round {
242 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
243 match self {
244 Self::One => write!(f, "1"),
245 Self::Two => write!(f, "2"),
246 Self::Three => write!(f, "3"),
247 Self::Four => write!(f, "4"),
248 Self::Five => write!(f, "5"),
249 }
250 }
251}
252
253macro_rules! impl_round_to_int {
254 ($ident:ident) => {
255 impl From<Round> for $ident {
256 fn from(value: Round) -> Self {
257 match value {
258 Round::One => 1,
259 Round::Two => 2,
260 Round::Three => 3,
261 Round::Four => 4,
262 Round::Five => 5,
263 }
264 }
265 }
266 };
267}
268
269impl_round_to_int!(u8);
270impl_round_to_int!(u16);
271impl_round_to_int!(u32);
272impl_round_to_int!(u64);
273impl_round_to_int!(usize);
274
275#[derive(Clone, Debug, Serialize, Deserialize)]
277pub struct Round1BroadcastData<G: Group + GroupEncoding + Default> {
278 #[serde(serialize_with = "serialize_g", deserialize_with = "deserialize_g")]
279 message_generator: G,
280 #[serde(serialize_with = "serialize_g", deserialize_with = "deserialize_g")]
281 blinder_generator: G,
282 #[serde(
283 serialize_with = "serialize_g_vec",
284 deserialize_with = "deserialize_g_vec"
285 )]
286 pedersen_commitments: Vec<G>,
287}
288
289#[cfg(test)]
290impl<G: Group + GroupEncoding + Default> serde_encrypt::traits::SerdeEncryptSharedKey
291 for Round1BroadcastData<G>
292{
293 type S = serde_encrypt::serialize::impls::BincodeSerializer<Self>;
294}
295
296#[derive(Clone, Debug, Serialize, Deserialize)]
298pub struct Round2EchoBroadcastData {
299 valid_participant_ids: BTreeSet<usize>,
300}
301
302#[cfg(test)]
303impl serde_encrypt::traits::SerdeEncryptSharedKey for Round1P2PData {
304 type S = serde_encrypt::serialize::impls::BincodeSerializer<Self>;
305}
306
307#[derive(Clone, Debug, Serialize, Deserialize)]
309pub struct Round3BroadcastData<G: Group + GroupEncoding + Default> {
310 #[serde(
311 serialize_with = "serialize_g_vec",
312 deserialize_with = "deserialize_g_vec"
313 )]
314 commitments: Vec<G>,
315}
316
317#[derive(Copy, Debug, Clone, Serialize, Deserialize)]
319pub struct Round4EchoBroadcastData<G: Group + GroupEncoding + Default> {
320 #[serde(serialize_with = "serialize_g", deserialize_with = "deserialize_g")]
322 pub public_key: G,
323}
324
325#[derive(Clone, Debug, Serialize, Deserialize, Zeroize, ZeroizeOnDrop)]
327pub struct Round1P2PData {
328 secret_share: Vec<u8>,
329 blind_share: Vec<u8>,
330}
331
332pub(crate) fn serialize_scalar<F: PrimeField, S: Serializer>(
333 scalar: &F,
334 s: S,
335) -> Result<S::Ok, S::Error> {
336 let v = scalar.to_repr();
337 let vv = v.as_ref();
338 if s.is_human_readable() {
339 s.serialize_str(&data_encoding::BASE64URL_NOPAD.encode(vv))
340 } else {
341 let len = vv.len();
342 let mut t = s.serialize_tuple(len)?;
343 for vi in vv {
344 t.serialize_element(vi)?;
345 }
346 t.end()
347 }
348}
349
350pub(crate) fn deserialize_scalar<'de, F: PrimeField, D: Deserializer<'de>>(
351 d: D,
352) -> Result<F, D::Error> {
353 struct ScalarVisitor<F: PrimeField> {
354 marker: PhantomData<F>,
355 }
356
357 impl<'de, F: PrimeField> Visitor<'de> for ScalarVisitor<F> {
358 type Value = F;
359
360 fn expecting(&self, f: &mut Formatter) -> fmt::Result {
361 write!(f, "a byte sequence")
362 }
363
364 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
365 where
366 E: DError,
367 {
368 let bytes = data_encoding::BASE64URL_NOPAD
369 .decode(v.as_bytes())
370 .map_err(|_| DError::invalid_value(Unexpected::Str(v), &self))?;
371 let mut repr = F::default().to_repr();
372 repr.as_mut().copy_from_slice(bytes.as_slice());
373 let sc = F::from_repr(repr);
374 if sc.is_some().into() {
375 Ok(sc.unwrap())
376 } else {
377 Err(DError::custom("unable to convert to scalar".to_string()))
378 }
379 }
380
381 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
382 where
383 A: SeqAccess<'de>,
384 {
385 let mut repr = F::default().to_repr();
386 let mut i = 0;
387 let len = repr.as_ref().len();
388 while let Some(b) = seq.next_element()? {
389 repr.as_mut()[i] = b;
390 i += 1;
391 if i == len {
392 let sc = F::from_repr(repr);
393 if sc.is_some().into() {
394 return Ok(sc.unwrap());
395 }
396 }
397 }
398 Err(DError::custom("unable to convert to scalar".to_string()))
399 }
400 }
401
402 let vis = ScalarVisitor {
403 marker: PhantomData::<F>,
404 };
405 if d.is_human_readable() {
406 d.deserialize_str(vis)
407 } else {
408 let repr = F::default().to_repr();
409 let len = repr.as_ref().len();
410 d.deserialize_tuple(len, vis)
411 }
412}
413
414pub(crate) fn serialize_g<G: Group + GroupEncoding + Default, S: Serializer>(
415 g: &G,
416 s: S,
417) -> Result<S::Ok, S::Error> {
418 let v = g.to_bytes();
419 let vv = v.as_ref();
420 if s.is_human_readable() {
421 s.serialize_str(&data_encoding::BASE64URL_NOPAD.encode(vv))
422 } else {
423 let mut t = s.serialize_tuple(vv.len())?;
424 for b in vv {
425 t.serialize_element(b)?;
426 }
427 t.end()
428 }
429}
430
431pub(crate) fn deserialize_g<'de, G: Group + GroupEncoding + Default, D: Deserializer<'de>>(
432 d: D,
433) -> Result<G, D::Error> {
434 struct GVisitor<G: Group + GroupEncoding + Default> {
435 marker: PhantomData<G>,
436 }
437
438 impl<'de, G: Group + GroupEncoding + Default> Visitor<'de> for GVisitor<G> {
439 type Value = G;
440
441 fn expecting(&self, f: &mut Formatter) -> fmt::Result {
442 write!(f, "a base64 encoded string or tuple of bytes")
443 }
444
445 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
446 where
447 E: DError,
448 {
449 let mut repr = G::Repr::default();
450 let bytes = data_encoding::BASE64URL_NOPAD
451 .decode(v.as_bytes())
452 .map_err(|_| DError::invalid_value(Unexpected::Str(v), &self))?;
453 repr.as_mut().copy_from_slice(bytes.as_slice());
454 let res = G::from_bytes(&repr);
455 if res.is_some().unwrap_u8() == 1u8 {
456 Ok(res.unwrap())
457 } else {
458 Err(DError::invalid_value(Unexpected::Str(v), &self))
459 }
460 }
461
462 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
463 where
464 A: SeqAccess<'de>,
465 {
466 let mut repr = G::Repr::default();
467 let input = repr.as_mut();
468 for i in 0..input.len() {
469 input[i] = seq
470 .next_element()?
471 .ok_or_else(|| DError::invalid_length(input.len(), &self))?;
472 }
473 let res = G::from_bytes(&repr);
474 if res.is_some().unwrap_u8() == 1u8 {
475 Ok(res.unwrap())
476 } else {
477 Err(DError::invalid_value(Unexpected::Seq, &self))
478 }
479 }
480 }
481
482 let visitor = GVisitor {
483 marker: PhantomData,
484 };
485 if d.is_human_readable() {
486 d.deserialize_str(visitor)
487 } else {
488 let repr = G::Repr::default();
489 d.deserialize_tuple(repr.as_ref().len(), visitor)
490 }
491}
492
493pub(crate) fn serialize_g_vec<G: Group + GroupEncoding + Default, S: Serializer>(
494 g: &Vec<G>,
495 s: S,
496) -> Result<S::Ok, S::Error> {
497 let v = g.iter().map(|p| p.to_bytes()).collect::<Vec<G::Repr>>();
498 if s.is_human_readable() {
499 let vv = v
500 .iter()
501 .map(|b| data_encoding::BASE64URL_NOPAD.encode(b.as_ref()))
502 .collect::<Vec<String>>();
503 vv.serialize(s)
504 } else {
505 let size = G::Repr::default().as_ref().len();
506 let uint = uint_zigzag::Uint::from(g.len());
507 let length_bytes = uint.to_vec();
508 let mut seq = s.serialize_seq(Some(length_bytes.len() + size * g.len()))?;
509 for b in &length_bytes {
510 seq.serialize_element(b)?;
511 }
512 for c in &v {
513 for b in c.as_ref() {
514 seq.serialize_element(b)?;
515 }
516 }
517 seq.end()
518 }
519}
520
521pub(crate) fn deserialize_g_vec<'de, G: Group + GroupEncoding + Default, D: Deserializer<'de>>(
522 d: D,
523) -> Result<Vec<G>, D::Error> {
524 struct NonReadableVisitor<G: Group + GroupEncoding + Default> {
525 marker: PhantomData<G>,
526 }
527
528 impl<'de, G: Group + GroupEncoding + Default> Visitor<'de> for NonReadableVisitor<G> {
529 type Value = Vec<G>;
530
531 fn expecting(&self, f: &mut Formatter) -> fmt::Result {
532 write!(f, "an array of bytes")
533 }
534
535 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
536 where
537 A: SeqAccess<'de>,
538 {
539 let mut buffer = [0u8; Uint::MAX_BYTES];
540 let mut i = 0;
541 while let Some(b) = seq.next_element()? {
542 buffer[i] = b;
543 i += 1;
544 if i == Uint::MAX_BYTES {
545 break;
546 }
547 }
548 let bytes_cnt_size = Uint::peek(&buffer)
549 .ok_or_else(|| DError::invalid_value(Unexpected::Bytes(&buffer), &self))?;
550 let points = Uint::try_from(&buffer[..bytes_cnt_size])
551 .map_err(|_| DError::invalid_value(Unexpected::Bytes(&buffer), &self))?;
552
553 i = Uint::MAX_BYTES - bytes_cnt_size;
554 let mut repr = G::Repr::default();
555 {
556 let r = repr.as_mut();
557 r[..i].copy_from_slice(&buffer[bytes_cnt_size..]);
558 }
559 let repr_len = repr.as_ref().len();
560 let mut out = Vec::with_capacity(points.0 as usize);
561 while let Some(b) = seq.next_element()? {
562 repr.as_mut()[i] = b;
563 i += 1;
564 if i == repr_len {
565 i = 0;
566 let pt = G::from_bytes(&repr);
567 if pt.is_none().unwrap_u8() == 1u8 {
568 return Err(DError::invalid_value(Unexpected::Bytes(&buffer), &self));
569 }
570 out.push(pt.unwrap());
571 if out.len() == points.0 as usize {
572 break;
573 }
574 }
575 }
576 if out.len() != points.0 as usize {
577 return Err(DError::invalid_length(out.len(), &self));
578 }
579 Ok(out)
580 }
581 }
582
583 if d.is_human_readable() {
584 let s = Vec::<String>::deserialize(d)?;
585 let mut out = Vec::with_capacity(s.len());
586 for si in &s {
587 let mut repr = G::Repr::default();
588 let bytes = data_encoding::BASE64URL_NOPAD
589 .decode(si.as_bytes())
590 .map_err(|_| DError::custom("unable to decode string to bytes".to_string()))?;
591 repr.as_mut().copy_from_slice(bytes.as_slice());
592 let pt = G::from_bytes(&repr);
593 if pt.is_none().unwrap_u8() == 1u8 {
594 return Err(DError::custom(
595 "unable to convert string to point".to_string(),
596 ));
597 }
598 out.push(pt.unwrap());
599 }
600 Ok(out)
601 } else {
602 d.deserialize_seq(NonReadableVisitor {
603 marker: PhantomData,
604 })
605 }
606}
607
608#[cfg(test)]
609mod tests {
610 use super::*;
611 use serde_encrypt::traits::SerdeEncryptSharedKey;
612 use std::collections::BTreeMap;
613 use vsss_rs::{combine_shares, Share};
614
615 #[test]
616 fn one_corrupted_party_k256() {
617 one_corrupted_party::<k256::ProjectivePoint>()
618 }
619
620 #[test]
621 fn one_corrupted_party_p256() {
622 one_corrupted_party::<p256::ProjectivePoint>()
623 }
624
625 #[test]
626 fn one_corrupted_party_curve25519() {
627 one_corrupted_party::<vsss_rs::curve25519::WrappedRistretto>();
628 one_corrupted_party::<vsss_rs::curve25519::WrappedEdwards>();
629 }
630
631 #[test]
632 fn one_corrupted_party_bls12_381() {
633 one_corrupted_party::<bls12_381_plus::G1Projective>();
634 one_corrupted_party::<bls12_381_plus::G2Projective>();
635 }
636
637 fn one_corrupted_party<G: Group + GroupEncoding + Default>() {
638 const THRESHOLD: usize = 2;
639 const LIMIT: usize = 4;
640 const BAD_ID: usize = 4;
641
642 let threshold = NonZeroUsize::new(THRESHOLD).unwrap();
643 let limit = NonZeroUsize::new(LIMIT).unwrap();
644 let parameters = Parameters::<G>::new(threshold, limit);
645 let mut participants = [
646 SecretParticipant::<G>::new(NonZeroUsize::new(1).unwrap(), parameters).unwrap(),
647 SecretParticipant::<G>::new(NonZeroUsize::new(2).unwrap(), parameters).unwrap(),
648 SecretParticipant::<G>::new(NonZeroUsize::new(3).unwrap(), parameters).unwrap(),
649 SecretParticipant::<G>::new(NonZeroUsize::new(4).unwrap(), parameters).unwrap(),
650 ];
651
652 let mut r1bdata = Vec::with_capacity(LIMIT);
653 let mut r1p2pdata = Vec::with_capacity(LIMIT);
654 for p in participants.iter_mut() {
655 let (broadcast, p2p) = p.round1().expect("Round 1 should work");
656 r1bdata.push(broadcast);
657 r1p2pdata.push(p2p);
658 }
659 for p in participants.iter_mut() {
660 assert!(p.round1().is_err());
661 }
662
663 for i in 0..THRESHOLD {
665 r1bdata[BAD_ID - 1].pedersen_commitments[i] = G::identity();
666 }
667
668 let mut r2bdata = BTreeMap::new();
669
670 for i in 0..LIMIT {
671 let mut bdata = BTreeMap::new();
672 let mut p2pdata = BTreeMap::new();
673
674 let my_id = participants[i].get_id();
675 for j in 0..LIMIT {
676 let pp = &participants[j];
677 let id = pp.get_id();
678 if my_id == id {
679 continue;
680 }
681 bdata.insert(id, r1bdata[id - 1].clone());
682 p2pdata.insert(id, r1p2pdata[id - 1][&my_id].clone());
683 }
684 let p = &mut participants[i];
685 let res = p.round2(bdata, p2pdata);
686 assert!(res.is_ok());
687 if my_id == BAD_ID {
688 continue;
689 }
690 r2bdata.insert(my_id, res.unwrap());
691 }
692
693 let mut r3bdata = BTreeMap::new();
694 for p in participants.iter_mut() {
695 if BAD_ID == p.get_id() {
696 continue;
697 }
698 let res = p.round3(&r2bdata);
699 assert!(res.is_ok());
700 r3bdata.insert(p.get_id(), res.unwrap());
701 assert!(p.round3(&r2bdata).is_err());
702 }
703
704 let mut r4bdata = BTreeMap::new();
705 let mut r4shares = Vec::with_capacity(LIMIT);
706 for p in participants.iter_mut() {
707 if BAD_ID == p.get_id() {
708 continue;
709 }
710 let res = p.round4(&r3bdata);
711 assert!(res.is_ok());
712 let bdata = res.unwrap();
713 let share = p.get_secret_share().unwrap();
714 r4bdata.insert(p.get_id(), bdata);
715 r4shares.push(<Vec<u8> as Share>::from_field_element(p.get_id() as u8, share).unwrap());
716 assert!(p.round4(&r3bdata).is_err());
717 }
718
719 for p in &participants {
720 if BAD_ID == p.get_id() {
721 continue;
722 }
723 assert!(p.round5(&r4bdata).is_ok());
724 }
725
726 let res = combine_shares::<G::Scalar, u8, Vec<u8>>(&r4shares);
727 assert!(res.is_ok());
728 let secret = res.unwrap();
729
730 assert_eq!(r4bdata[&1].public_key, G::generator() * secret);
731 }
732
733 #[test]
734 fn serialization_k256() {
735 serialization_curve::<k256::ProjectivePoint>();
736 }
737
738 #[test]
739 fn serialization_p256() {
740 serialization_curve::<p256::ProjectivePoint>();
741 }
742
743 #[test]
744 fn serialization_bls12_381_g1() {
745 serialization_curve::<bls12_381_plus::G1Projective>();
746 }
747
748 #[test]
749 fn serialization_bls12_381_g2() {
750 serialization_curve::<bls12_381_plus::G2Projective>();
751 }
752
753 #[cfg(feature = "curve25519")]
754 #[test]
755 fn serialization_curve25519() {
756 serialization_curve::<vsss_rs::curve25519::WrappedRistretto>();
757 serialization_curve::<vsss_rs::curve25519::WrappedEdwards>();
758 }
759
760 fn serialization_curve<G: Group + GroupEncoding + Default>() {
761 const THRESHOLD: usize = 2;
762 const LIMIT: usize = 3;
763
764 let threshold = NonZeroUsize::new(THRESHOLD).unwrap();
765 let limit = NonZeroUsize::new(LIMIT).unwrap();
766 let parameters = Parameters::<G>::new(threshold, limit);
767 let mut participants = [
768 SecretParticipant::<G>::new(NonZeroUsize::new(1).unwrap(), parameters).unwrap(),
769 SecretParticipant::<G>::new(NonZeroUsize::new(2).unwrap(), parameters).unwrap(),
770 SecretParticipant::<G>::new(NonZeroUsize::new(3).unwrap(), parameters).unwrap(),
771 ];
772
773 let mut r1bdata = Vec::<Round1BroadcastData<G>>::with_capacity(LIMIT);
774 let mut r1pdata = Vec::<BTreeMap<usize, Round1P2PData>>::with_capacity(LIMIT);
775
776 for participant in participants.iter_mut() {
777 let (bdata, pdata) = participant.round1().unwrap();
778
779 let json = serde_json::to_string(&bdata).unwrap();
781 let res = serde_json::from_str::<Round1BroadcastData<G>>(&json);
782 assert!(res.is_ok());
783 let bdata2 = res.unwrap();
784 assert_eq!(bdata.message_generator, bdata.message_generator);
785 assert_eq!(bdata.blinder_generator, bdata2.blinder_generator);
786 assert_eq!(
787 bdata.pedersen_commitments[0],
788 bdata2.pedersen_commitments[0]
789 );
790 assert_eq!(
791 bdata.pedersen_commitments[1],
792 bdata2.pedersen_commitments[1]
793 );
794
795 let json = serde_json::to_string(&pdata).unwrap();
796 let res = serde_json::from_str::<BTreeMap<usize, Round1P2PData>>(&json);
797 assert!(res.is_ok());
798 let pdata2 = res.unwrap();
799 assert_eq!(pdata.len(), pdata2.len());
800 for (id, val) in &pdata {
801 assert!(pdata2.contains_key(id));
802 assert_eq!(val.secret_share, pdata2[id].secret_share);
803 assert_eq!(val.blind_share, pdata2[id].blind_share);
804 }
805
806 let bin = serde_bare::to_vec(&bdata).unwrap();
808 let res = serde_bare::from_slice::<Round1BroadcastData<G>>(&bin);
809 assert!(res.is_ok());
810 let bdata2 = res.unwrap();
811 assert_eq!(bdata.message_generator, bdata.message_generator);
812 assert_eq!(bdata.blinder_generator, bdata2.blinder_generator);
813 assert_eq!(
814 bdata.pedersen_commitments[0],
815 bdata2.pedersen_commitments[0]
816 );
817 assert_eq!(
818 bdata.pedersen_commitments[1],
819 bdata2.pedersen_commitments[1]
820 );
821
822 let bin = serde_bare::to_vec(&pdata).unwrap();
823 let res = serde_bare::from_slice::<BTreeMap<usize, Round1P2PData>>(&bin);
824 assert!(res.is_ok());
825 let pdata2 = res.unwrap();
826 assert_eq!(pdata.len(), pdata2.len());
827 for (id, val) in &pdata {
828 assert!(pdata2.contains_key(id));
829 assert_eq!(val.secret_share, pdata2[id].secret_share);
830 assert_eq!(val.blind_share, pdata2[id].blind_share);
831 }
832
833 let shared_key = serde_encrypt::shared_key::SharedKey::new([1u8; 32]);
834 let bin = bdata.encrypt(&shared_key).unwrap();
835 let res = Round1BroadcastData::<G>::decrypt_owned(&bin, &shared_key);
836 assert!(res.is_ok());
837 let bdata2 = res.unwrap();
838 assert_eq!(bdata.message_generator, bdata.message_generator);
839 assert_eq!(bdata.blinder_generator, bdata2.blinder_generator);
840 assert_eq!(
841 bdata.pedersen_commitments[0],
842 bdata2.pedersen_commitments[0]
843 );
844 assert_eq!(
845 bdata.pedersen_commitments[1],
846 bdata2.pedersen_commitments[1]
847 );
848
849 r1bdata.push(bdata);
850 r1pdata.push(pdata);
851 }
852
853 let mut r2bdata = BTreeMap::<usize, Round2EchoBroadcastData>::new();
854 r2bdata.insert(
855 1,
856 participants[0]
857 .round2(
858 maplit::btreemap! {
859 2 => r1bdata[1].clone(),
860 3 => r1bdata[2].clone(),
861 },
862 maplit::btreemap! {
863 2 => r1pdata[1][&1].clone(),
864 3 => r1pdata[2][&1].clone()
865 },
866 )
867 .unwrap(),
868 );
869 r2bdata.insert(
870 2,
871 participants[1]
872 .round2(
873 maplit::btreemap! {
874 1 => r1bdata[0].clone(),
875 3 => r1bdata[2].clone(),
876 },
877 maplit::btreemap! {
878 1 => r1pdata[0][&2].clone(),
879 3 => r1pdata[2][&2].clone(),
880 },
881 )
882 .unwrap(),
883 );
884 r2bdata.insert(
885 3,
886 participants[2]
887 .round2(
888 maplit::btreemap! {
889 1 => r1bdata[0].clone(),
890 2 => r1bdata[1].clone(),
891 },
892 maplit::btreemap! {
893 1 => r1pdata[0][&3].clone(),
894 2 => r1pdata[1][&3].clone(),
895 },
896 )
897 .unwrap(),
898 );
899
900 let json = serde_json::to_string(&r2bdata).unwrap();
901 let res = serde_json::from_str::<BTreeMap<usize, Round2EchoBroadcastData>>(&json);
902 assert!(res.is_ok());
903 let r2bdata2 = res.unwrap();
904 assert_eq!(
905 r2bdata[&1].valid_participant_ids,
906 r2bdata2[&1].valid_participant_ids
907 );
908
909 let bin = serde_bare::to_vec(&r2bdata).unwrap();
910 let res = serde_bare::from_slice::<BTreeMap<usize, Round2EchoBroadcastData>>(&bin);
911 assert!(res.is_ok());
912 let r2bdata2 = res.unwrap();
913 assert_eq!(
914 r2bdata[&1].valid_participant_ids,
915 r2bdata2[&1].valid_participant_ids
916 );
917
918 for i in 0..3 {
921 for j in 1..4 {
922 r1pdata[i].get_mut(&j).map(|val| val.zeroize());
923 if j != i + 1 {
924 assert!(r1pdata[i].get(&j).unwrap().secret_share.is_empty());
925 assert!(r1pdata[i].get(&j).unwrap().blind_share.is_empty());
926 }
927 }
928 }
929
930 let mut r3bdata = BTreeMap::<usize, Round3BroadcastData<G>>::new();
931 r3bdata.insert(1, participants[0].round3(&r2bdata).unwrap());
932 r3bdata.insert(2, participants[1].round3(&r2bdata).unwrap());
933 r3bdata.insert(3, participants[2].round3(&r2bdata).unwrap());
934
935 let json = serde_json::to_string(&r3bdata).unwrap();
936 let res = serde_json::from_str::<BTreeMap<usize, Round3BroadcastData<G>>>(&json);
937 assert!(res.is_ok());
938 let r3bdata2 = res.unwrap();
939 assert_eq!(
940 r3bdata.get(&1).unwrap().commitments,
941 r3bdata2.get(&1).unwrap().commitments
942 );
943 assert_eq!(
944 r3bdata.get(&2).unwrap().commitments,
945 r3bdata2.get(&2).unwrap().commitments
946 );
947 assert_eq!(
948 r3bdata.get(&3).unwrap().commitments,
949 r3bdata2.get(&3).unwrap().commitments
950 );
951
952 let bin = serde_bare::to_vec(&r3bdata).unwrap();
953 let res = serde_bare::from_slice::<BTreeMap<usize, Round3BroadcastData<G>>>(&bin);
954 assert!(res.is_ok());
955 let r3bdata2 = res.unwrap();
956 assert_eq!(
957 r3bdata.get(&1).unwrap().commitments,
958 r3bdata2.get(&1).unwrap().commitments
959 );
960 assert_eq!(
961 r3bdata.get(&2).unwrap().commitments,
962 r3bdata2.get(&2).unwrap().commitments
963 );
964 assert_eq!(
965 r3bdata.get(&3).unwrap().commitments,
966 r3bdata2.get(&3).unwrap().commitments
967 );
968
969 let mut r4bdata = BTreeMap::<usize, Round4EchoBroadcastData<G>>::new();
970 r4bdata.insert(1, participants[0].round4(&r3bdata).unwrap());
971 r4bdata.insert(2, participants[1].round4(&r3bdata).unwrap());
972 r4bdata.insert(3, participants[2].round4(&r3bdata).unwrap());
973
974 let json = serde_json::to_string(&r4bdata).unwrap();
975 let res = serde_json::from_str::<BTreeMap<usize, Round4EchoBroadcastData<G>>>(&json);
976 assert!(res.is_ok());
977 let r4bdata2 = res.unwrap();
978 assert_eq!(
979 r4bdata.get(&1).unwrap().public_key,
980 r4bdata2.get(&1).unwrap().public_key
981 );
982 assert_eq!(
983 r4bdata.get(&2).unwrap().public_key,
984 r4bdata2.get(&2).unwrap().public_key
985 );
986 assert_eq!(
987 r4bdata.get(&3).unwrap().public_key,
988 r4bdata2.get(&3).unwrap().public_key
989 );
990
991 let bin = serde_bare::to_vec(&r4bdata).unwrap();
992 let res = serde_bare::from_slice::<BTreeMap<usize, Round4EchoBroadcastData<G>>>(&bin);
993 assert!(res.is_ok());
994 let r4bdata2 = res.unwrap();
995 assert_eq!(
996 r4bdata.get(&1).unwrap().public_key,
997 r4bdata2.get(&1).unwrap().public_key
998 );
999 assert_eq!(
1000 r4bdata.get(&2).unwrap().public_key,
1001 r4bdata2.get(&2).unwrap().public_key
1002 );
1003 assert_eq!(
1004 r4bdata.get(&3).unwrap().public_key,
1005 r4bdata2.get(&3).unwrap().public_key
1006 );
1007 }
1008}