Skip to content

Commit a85218f

Browse files
Hugh Cunninghammat-if
authored andcommitted
implements minimized round2 version
round2_min follows the example of round3_min and inputs/outputs the minimal amount of data to support dkg takes as input: - a participant secret - a vector of byte arrays, one for each participant identity (excluding the self identity) - a byte array containing the encrypted round1 secret package - a vector of round1 frost public packages, one for each participant (excluding the user's own public package) - an rng round2_min returns the encrypted round2 secret package and a vector of round2 frost public packages. it does NOT create a CombinedPublicPackage or ironfish PublicPackages from the frost public packages. the user can create these separately (e.g., on the host machine instead of a ledger device) before distributing the packages. the vector of round2 public packages is returned in order of the participants passed in: round2_frost_packages[i] is intended for participant[i]
1 parent 176750a commit a85218f

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

src/dkg/round2.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,51 @@ where
483483
))
484484
}
485485

486+
pub fn round2_min<R>(
487+
secret: &participant::Secret,
488+
participants: Vec<&[u8]>,
489+
round1_secret_package: &[u8],
490+
round1_frost_packages: Vec<&[u8]>,
491+
mut csrng: R,
492+
) -> Result<(Vec<u8>, Vec<Package>), IronfishFrostError>
493+
where
494+
R: RngCore + CryptoRng,
495+
{
496+
let self_identity = secret.to_identity();
497+
let round1_secret_package = round1::import_secret_package(round1_secret_package, secret)?;
498+
499+
let mut round1_packages = BTreeMap::new();
500+
for i in 0..participants.len() {
501+
let identity = Identity::deserialize_from(participants[i])?;
502+
503+
let identifier = identity.to_frost_identifier();
504+
505+
let round1_package = Round1Package::deserialize(round1_frost_packages[i])?;
506+
round1_packages.insert(identifier, round1_package);
507+
}
508+
509+
// Run the FROST DKG round 2
510+
let (round2_secret_package, mut round2_packages) =
511+
frost::keys::dkg::part2(round1_secret_package.clone(), &round1_packages)?;
512+
513+
// Encrypt the secret package
514+
let encrypted_secret_package =
515+
export_secret_package(&round2_secret_package, &self_identity, &mut csrng)?;
516+
517+
// Convert the Identifier->Package map to a Vec<Package> ordered by the
518+
// Identifier's position in the 'participants' input Vec
519+
let mut round2_public_packages = Vec::new();
520+
for participant in participants {
521+
let identity = Identity::deserialize_from(participant)?;
522+
let round2_public_package = round2_packages
523+
.remove(&identity.to_frost_identifier())
524+
.expect("missing round 2 public package for participant");
525+
round2_public_packages.push(round2_public_package);
526+
}
527+
528+
Ok((encrypted_secret_package, round2_public_packages))
529+
}
530+
486531
#[cfg(test)]
487532
mod tests {
488533
use super::*;
@@ -693,6 +738,67 @@ mod tests {
693738
.expect("round 2 public packages missing package for identity3");
694739
}
695740

741+
#[test]
742+
fn round2_min() {
743+
let secret = participant::Secret::random(thread_rng());
744+
let identity1 = secret.to_identity();
745+
let identity2 = participant::Secret::random(thread_rng()).to_identity();
746+
let identity3 = participant::Secret::random(thread_rng()).to_identity();
747+
748+
let (round1_secret_package, _) = round1::round1(
749+
&identity1,
750+
2,
751+
[&identity1, &identity2, &identity3],
752+
thread_rng(),
753+
)
754+
.expect("round 1 failed");
755+
756+
let (_, package2) = round1::round1(
757+
&identity2,
758+
2,
759+
[&identity1, &identity2, &identity3],
760+
thread_rng(),
761+
)
762+
.expect("round 1 failed");
763+
764+
let (_, package3) = round1::round1(
765+
&identity3,
766+
2,
767+
[&identity1, &identity2, &identity3],
768+
thread_rng(),
769+
)
770+
.expect("round 1 failed");
771+
772+
let id2_ser: &[u8] = &identity2.serialize();
773+
let id3_ser: &[u8] = &identity3.serialize();
774+
let participants = vec![id2_ser, id3_ser];
775+
776+
let pkg2_ser = package2
777+
.frost_package()
778+
.serialize()
779+
.expect("serialization failed");
780+
let pkg3_ser = package3
781+
.frost_package()
782+
.serialize()
783+
.expect("serialization failed");
784+
785+
let round1_frost_packages: Vec<&[u8]> = vec![&pkg2_ser[..], &pkg3_ser[..]];
786+
787+
let (secret_package, round2_public_packages) = super::round2_min(
788+
&secret,
789+
participants,
790+
&round1_secret_package,
791+
round1_frost_packages,
792+
thread_rng(),
793+
)
794+
.expect("round 2 failed");
795+
796+
import_secret_package(&secret_package, &secret)
797+
.expect("round 2 secret package import failed");
798+
799+
assert_eq!(round2_public_packages.len(), 2);
800+
}
801+
696802
#[test]
697803
fn round2_duplicate_packages() {
698804
let secret = participant::Secret::random(thread_rng());

0 commit comments

Comments
 (0)