Skip to content

Commit 66e91ad

Browse files
author
Hugh Cunningham
committed
implements prototype of minimal version of round3
round3_min takes as input the minimum number of fields required to run part3 of dkg and construct the public key package this includes the participant secret, the list of participant identities (excluding the participant running the round), the list of round1 frost public packages, the list of round2 frost public packages, the list of all (encrypted) group secret key shards, and the minimum number of signers reduces duplicate data from including participant identities, max signers, and min signers with each package removes unnecessary data from checksums on each package (checksums can be compared on the host machine as a form of error checking) removes extra round2 packages not intended for participant running the round
1 parent 26012b0 commit 66e91ad

File tree

3 files changed

+170
-1
lines changed

3 files changed

+170
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ hex-literal = "0.4.1"
2424
rand = "0.8.5"
2525

2626
[features]
27-
default = ["signing"]
27+
default = ["dkg"]
2828

2929
std = []
3030
signing = ["dep:blake3", "dep:rand_chacha", "std"]

src/dkg/round2.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,13 @@ impl CombinedPublicPackage {
317317
.filter(move |pkg| &pkg.recipient_identity == recipient_identity)
318318
}
319319

320+
#[inline]
321+
pub fn package_for<'a>(&'a self, recipient_identity: &'a Identity) -> Option<&PublicPackage> {
322+
self.packages
323+
.iter()
324+
.find(move |pkg| &pkg.recipient_identity == recipient_identity)
325+
}
326+
320327
pub fn serialize(&self) -> Vec<u8> {
321328
let mut buf = Vec::new();
322329
self.serialize_into(&mut buf).expect("serialization failed");

src/dkg/round3.rs

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ use crate::serde::write_u16;
2222
use crate::serde::write_variable_length;
2323
use crate::serde::write_variable_length_bytes;
2424
use core::borrow::Borrow;
25+
use reddsa::frost::redjubjub::keys::dkg::round1::Package as Round1Package;
26+
use reddsa::frost::redjubjub::keys::dkg::round2::Package as Round2Package;
2527
use reddsa::frost::redjubjub::VerifyingKey;
2628

2729
#[cfg(feature = "std")]
@@ -227,14 +229,64 @@ where
227229
))
228230
}
229231

232+
pub fn round3_min(
233+
secret: &Secret,
234+
participants: Vec<&[u8]>,
235+
round2_secret_package: &[u8],
236+
round1_frost_packages: Vec<&[u8]>,
237+
round2_frost_packages: Vec<&[u8]>,
238+
gsk_bytes: Vec<&[u8]>,
239+
min_signers: u16,
240+
) -> Result<(KeyPackage, PublicKeyPackage, GroupSecretKey), IronfishFrostError> {
241+
let round2_secret_package = import_secret_package(round2_secret_package, secret)?;
242+
243+
let mut identities: Vec<Identity> = Vec::with_capacity(participants.len() + 1);
244+
identities.push(secret.to_identity());
245+
246+
let mut round1_packages = BTreeMap::new();
247+
let mut round2_packages = BTreeMap::new();
248+
249+
for i in 0..participants.len() {
250+
let identity = Identity::deserialize_from(participants[i])?;
251+
identities.push(identity.clone());
252+
253+
let identifier = identity.to_frost_identifier();
254+
255+
let round1_package = Round1Package::deserialize(round1_frost_packages[i])?;
256+
round1_packages.insert(identifier, round1_package);
257+
258+
let round2_package = Round2Package::deserialize(round2_frost_packages[i])?;
259+
round2_packages.insert(identifier, round2_package);
260+
}
261+
262+
let (key_package, public_key_package) =
263+
part3(&round2_secret_package, &round1_packages, &round2_packages)?;
264+
265+
let public_key_package =
266+
PublicKeyPackage::from_frost(public_key_package, identities, min_signers);
267+
268+
let mut gsk_shards: Vec<GroupSecretKeyShard> = Vec::with_capacity(participants.len() + 1);
269+
for g in gsk_bytes {
270+
gsk_shards.push(GroupSecretKeyShard::import(secret, g)?);
271+
}
272+
273+
Ok((
274+
key_package,
275+
public_key_package,
276+
GroupSecretKeyShard::combine(&gsk_shards),
277+
))
278+
}
279+
230280
#[cfg(test)]
231281
mod tests {
232282
use super::round3;
283+
use super::round3_min;
233284
use super::PublicKeyPackage;
234285
use crate::dkg::round1;
235286
use crate::dkg::round2;
236287
use crate::error::IronfishFrostError;
237288
use crate::participant::Secret;
289+
use alloc::vec::Vec;
238290
use hex_literal::hex;
239291
use rand::thread_rng;
240292
use reddsa::frost::redjubjub::keys::split;
@@ -448,4 +500,114 @@ mod tests {
448500
)
449501
.expect("round 3 failed");
450502
}
503+
504+
#[test]
505+
fn test_round3_min() {
506+
let secret1 = Secret::random(thread_rng());
507+
let secret2 = Secret::random(thread_rng());
508+
let secret3 = Secret::random(thread_rng());
509+
let identity1 = secret1.to_identity();
510+
let identity2 = secret2.to_identity();
511+
let identity3 = secret3.to_identity();
512+
513+
let (round1_secret_package_1, package1) = round1::round1(
514+
&identity1,
515+
2,
516+
[&identity1, &identity2, &identity3],
517+
thread_rng(),
518+
)
519+
.expect("round 1 failed");
520+
521+
let (round1_secret_package_2, package2) = round1::round1(
522+
&identity2,
523+
2,
524+
[&identity1, &identity2, &identity3],
525+
thread_rng(),
526+
)
527+
.expect("round 1 failed");
528+
529+
let (round1_secret_package_3, package3) = round1::round1(
530+
&identity3,
531+
2,
532+
[&identity1, &identity2, &identity3],
533+
thread_rng(),
534+
)
535+
.expect("round 1 failed");
536+
537+
let (encrypted_secret_package, _) = round2::round2(
538+
&secret1,
539+
&round1_secret_package_1,
540+
[&package1, &package2, &package3],
541+
thread_rng(),
542+
)
543+
.expect("round 2 failed");
544+
545+
let (_, round2_public_packages_2) = round2::round2(
546+
&secret2,
547+
&round1_secret_package_2,
548+
[&package1, &package2, &package3],
549+
thread_rng(),
550+
)
551+
.expect("round 2 failed");
552+
553+
let (_, round2_public_packages_3) = round2::round2(
554+
&secret3,
555+
&round1_secret_package_3,
556+
[&package1, &package2, &package3],
557+
thread_rng(),
558+
)
559+
.expect("round 2 failed");
560+
561+
let mut participants = Vec::with_capacity(2);
562+
let id2_ser: &[u8] = &identity2.serialize();
563+
let id3_ser: &[u8] = &identity3.serialize();
564+
participants.push(id2_ser);
565+
participants.push(id3_ser);
566+
567+
let pkg2_ser = package2
568+
.frost_package()
569+
.serialize()
570+
.expect("serialization failed");
571+
let pkg3_ser = package3
572+
.frost_package()
573+
.serialize()
574+
.expect("serialization failed");
575+
576+
let mut round1_frost_packages: Vec<&[u8]> = Vec::with_capacity(2);
577+
round1_frost_packages.push(&pkg2_ser[..]);
578+
round1_frost_packages.push(&pkg3_ser[..]);
579+
580+
let pkg2_2 = round2_public_packages_2
581+
.package_for(&identity1)
582+
.expect("missing round2 public package for identity")
583+
.frost_package()
584+
.serialize()
585+
.expect("round2 public package serialization failed");
586+
let pkg2_3 = round2_public_packages_3
587+
.package_for(&identity1)
588+
.expect("missing round2 public package for identity")
589+
.frost_package()
590+
.serialize()
591+
.expect("round2 public package serialization failed");
592+
593+
let mut round2_frost_packages: Vec<&[u8]> = Vec::with_capacity(2);
594+
round2_frost_packages.push(&pkg2_2[..]);
595+
round2_frost_packages.push(&pkg2_3[..]);
596+
597+
let mut gsk_bytes: Vec<&[u8]> = Vec::with_capacity(3);
598+
gsk_bytes.push(package1.group_secret_key_shard_encrypted());
599+
gsk_bytes.push(package2.group_secret_key_shard_encrypted());
600+
gsk_bytes.push(package3.group_secret_key_shard_encrypted());
601+
602+
round3_min(
603+
&secret1,
604+
participants,
605+
&encrypted_secret_package,
606+
round1_frost_packages,
607+
round2_frost_packages,
608+
gsk_bytes,
609+
2,
610+
)
611+
.expect("round 3 failed");
612+
}
451613
}

0 commit comments

Comments
 (0)