add DKG tests
This commit is contained in:
parent
d0cb462907
commit
12cffcce24
|
@ -316,6 +316,7 @@ dependencies = [
|
||||||
"frost-ed25519",
|
"frost-ed25519",
|
||||||
"hex",
|
"hex",
|
||||||
"itertools 0.11.0",
|
"itertools 0.11.0",
|
||||||
|
"pipe",
|
||||||
"rand",
|
"rand",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -624,6 +625,15 @@ dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pipe"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1c7b8f27da217eb966df4c58d4159ea939431950ca03cf782c22bd7c5c1d8d75"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-channel",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "platforms"
|
name = "platforms"
|
||||||
version = "3.0.2"
|
version = "3.0.2"
|
||||||
|
|
|
@ -14,3 +14,4 @@ rand = "0.8"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
itertools = "0.11.0"
|
itertools = "0.11.0"
|
||||||
exitcode = "1.1.2"
|
exitcode = "1.1.2"
|
||||||
|
pipe = "0.4.0"
|
|
@ -71,7 +71,7 @@ pub fn request_inputs(
|
||||||
let u16_identifier = identifier_input
|
let u16_identifier = identifier_input
|
||||||
.trim()
|
.trim()
|
||||||
.parse::<u16>()
|
.parse::<u16>()
|
||||||
.map_err(|_| eyre!("Invalid identifier"))?;
|
.map_err(|_| Error::MalformedIdentifier)?;
|
||||||
let identifier = u16_identifier.try_into()?;
|
let identifier = u16_identifier.try_into()?;
|
||||||
|
|
||||||
let config = Config {
|
let config = Config {
|
||||||
|
|
|
@ -1,86 +1,93 @@
|
||||||
// use crate::inputs::{request_inputs, Config};
|
use std::io::BufWriter;
|
||||||
// use frost::Error;
|
|
||||||
// use frost_ed25519 as frost;
|
|
||||||
|
|
||||||
// #[test]
|
use crate::inputs::{request_inputs, Config};
|
||||||
// fn check_valid_input_for_signers() {
|
use frost::Error;
|
||||||
// let config = Config {
|
use frost_ed25519 as frost;
|
||||||
// min_signers: 2,
|
|
||||||
// max_signers: 3,
|
|
||||||
// secret: Vec::new(),
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let mut valid_input = "2\n3\n\n".as_bytes();
|
#[test]
|
||||||
// let expected = request_inputs(&mut valid_input);
|
fn check_valid_input_for_signers() {
|
||||||
|
let config = Config {
|
||||||
|
min_signers: 2,
|
||||||
|
max_signers: 3,
|
||||||
|
identifier: 1u16.try_into().unwrap(),
|
||||||
|
};
|
||||||
|
|
||||||
// assert_eq!(expected, Ok(config));
|
let mut buf = BufWriter::new(Vec::new());
|
||||||
// }
|
let mut valid_input = "2\n3\n1\n".as_bytes();
|
||||||
|
let expected = request_inputs(&mut valid_input, &mut buf).unwrap();
|
||||||
|
|
||||||
// #[test]
|
assert_eq!(expected, config);
|
||||||
// fn return_error_if_min_participant_greater_than_max_participant() {
|
}
|
||||||
// let mut invalid_input = "4\n3\n\n".as_bytes();
|
|
||||||
// let expected = request_inputs(&mut invalid_input);
|
|
||||||
|
|
||||||
// assert_eq!(expected, Err(Error::InvalidMinSigners));
|
#[test]
|
||||||
// }
|
fn return_error_if_min_participant_greater_than_max_participant() {
|
||||||
|
let mut invalid_input = "4\n3\n1\n".as_bytes();
|
||||||
|
let mut buf = BufWriter::new(Vec::new());
|
||||||
|
let expected = request_inputs(&mut invalid_input, &mut buf).unwrap_err();
|
||||||
|
|
||||||
// #[test]
|
assert_eq!(
|
||||||
// fn return_error_if_min_participant_is_less_than_2() {
|
*expected.downcast::<Error>().unwrap(),
|
||||||
// let mut invalid_input = "1\n3\n\n".as_bytes();
|
Error::InvalidMinSigners
|
||||||
// let expected = request_inputs(&mut invalid_input);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// assert_eq!(expected, Err(Error::InvalidMinSigners));
|
#[test]
|
||||||
// }
|
fn return_error_if_min_participant_is_less_than_2() {
|
||||||
|
let mut invalid_input = "1\n3\n1\n".as_bytes();
|
||||||
|
let mut buf = BufWriter::new(Vec::new());
|
||||||
|
let expected = request_inputs(&mut invalid_input, &mut buf).unwrap_err();
|
||||||
|
|
||||||
// #[test]
|
assert_eq!(
|
||||||
// fn return_error_if_max_participant_is_less_than_2() {
|
*expected.downcast::<Error>().unwrap(),
|
||||||
// let mut invalid_input = "2\n1\n\n".as_bytes();
|
Error::InvalidMinSigners
|
||||||
// let expected = request_inputs(&mut invalid_input);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// assert_eq!(expected, Err(Error::InvalidMaxSigners));
|
#[test]
|
||||||
// }
|
fn return_error_if_max_participant_is_less_than_2() {
|
||||||
|
let mut invalid_input = "2\n1\n1\n".as_bytes();
|
||||||
|
let mut buf = BufWriter::new(Vec::new());
|
||||||
|
let expected = request_inputs(&mut invalid_input, &mut buf).unwrap_err();
|
||||||
|
|
||||||
// // Testing inclusion of secret input
|
assert_eq!(
|
||||||
|
*expected.downcast::<Error>().unwrap(),
|
||||||
|
Error::InvalidMaxSigners
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// #[test]
|
#[test]
|
||||||
// fn check_valid_input_with_secret() {
|
fn return_error_if_invalid_min_signers_input() {
|
||||||
// let mut valid_input =
|
let mut invalid_input = "hello\n6\n1\n".as_bytes();
|
||||||
// "3\n6\n7b1c33d3f5291d85de664833beb1ad469f7fb6025a0ec78b3a790c6e13a98304\n".as_bytes();
|
let mut buf = BufWriter::new(Vec::new());
|
||||||
// let config = request_inputs(&mut valid_input).unwrap();
|
let expected = request_inputs(&mut invalid_input, &mut buf).unwrap_err();
|
||||||
|
|
||||||
// let secret: Vec<u8> = vec![
|
assert_eq!(
|
||||||
// 123, 28, 51, 211, 245, 41, 29, 133, 222, 102, 72, 51, 190, 177, 173, 70, 159, 127, 182, 2,
|
*expected.downcast::<Error>().unwrap(),
|
||||||
// 90, 14, 199, 139, 58, 121, 12, 110, 19, 169, 131, 4,
|
Error::InvalidMinSigners
|
||||||
// ];
|
);
|
||||||
// let expected = Config {
|
}
|
||||||
// min_signers: 3,
|
|
||||||
// max_signers: 6,
|
|
||||||
// secret,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// assert_eq!(expected, config)
|
#[test]
|
||||||
// }
|
fn return_error_if_invalid_max_signers_input() {
|
||||||
|
let mut invalid_input = "4\nworld\n1\n".as_bytes();
|
||||||
|
let mut buf = BufWriter::new(Vec::new());
|
||||||
|
let expected = request_inputs(&mut invalid_input, &mut buf).unwrap_err();
|
||||||
|
|
||||||
// #[test]
|
assert_eq!(
|
||||||
// fn return_error_if_invalid_min_signers_input() {
|
*expected.downcast::<Error>().unwrap(),
|
||||||
// let mut invalid_input = "hello\n6\n\n".as_bytes();
|
Error::InvalidMaxSigners
|
||||||
// let expected = request_inputs(&mut invalid_input);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// assert_eq!(expected, Err(Error::InvalidMinSigners))
|
#[test]
|
||||||
// }
|
fn return_malformed_identifier_error_if_identifier_invalid() {
|
||||||
|
let mut invalid_input = "4\n6\nasecret\n".as_bytes();
|
||||||
|
let mut buf = BufWriter::new(Vec::new());
|
||||||
|
let expected = request_inputs(&mut invalid_input, &mut buf).unwrap_err();
|
||||||
|
|
||||||
// #[test]
|
println!("{:?}", expected);
|
||||||
// fn return_error_if_invalid_max_signers_input() {
|
assert_eq!(
|
||||||
// let mut invalid_input = "4\nworld\n\n".as_bytes();
|
*expected.downcast::<Error>().unwrap(),
|
||||||
// let expected = request_inputs(&mut invalid_input);
|
Error::MalformedIdentifier
|
||||||
|
);
|
||||||
// assert_eq!(expected, Err(Error::InvalidMaxSigners))
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn return_malformed_signing_key_error_if_secret_is_invalid() {
|
|
||||||
// let mut secret_input = "4\n6\nasecret\n".as_bytes();
|
|
||||||
// let expected = request_inputs(&mut secret_input);
|
|
||||||
|
|
||||||
// assert_eq!(expected, Err(Error::MalformedSigningKey))
|
|
||||||
// }
|
|
||||||
|
|
|
@ -1,118 +1,238 @@
|
||||||
// use crate::inputs::Config;
|
use std::collections::HashMap;
|
||||||
// use crate::tests::integration_test::signature_gen::generate_key_packages;
|
use std::io::{BufRead, Write};
|
||||||
// use crate::trusted_dealer_keygen::split_secret;
|
use std::thread;
|
||||||
// use frost_ed25519 as frost;
|
|
||||||
// use rand::thread_rng;
|
|
||||||
|
|
||||||
// use crate::trusted_dealer_keygen::dkg;
|
use frost_ed25519::keys::{KeyPackage, PublicKeyPackage};
|
||||||
// mod signature_gen;
|
use frost_ed25519::Identifier;
|
||||||
|
|
||||||
// #[test]
|
use crate::cli::cli;
|
||||||
// fn check_keygen_with_dealer() {
|
|
||||||
// let mut rng = thread_rng();
|
|
||||||
// let config = Config {
|
|
||||||
// min_signers: 2,
|
|
||||||
// max_signers: 3,
|
|
||||||
// secret: Vec::new(),
|
|
||||||
// };
|
|
||||||
// let (shares, pubkeys) = dkg(&config, &mut rng).unwrap();
|
|
||||||
// let key_packages = generate_key_packages(shares);
|
|
||||||
// let (nonces, commitments) =
|
|
||||||
// signature_gen::generate_nonces_and_commitments(config.min_signers, &key_packages, &mut rng);
|
|
||||||
// let message = "message to sign".as_bytes();
|
|
||||||
// let comms = commitments.into_values().collect();
|
|
||||||
// let signing_package = frost::SigningPackage::new(comms, message.to_vec());
|
|
||||||
// let signature_shares =
|
|
||||||
// signature_gen::generate_signature_shares(nonces, &key_packages, &signing_package);
|
|
||||||
// let group_signature =
|
|
||||||
// frost::aggregate(&signing_package, &signature_shares[..], &pubkeys).unwrap();
|
|
||||||
// let verify_signature = pubkeys.group_public.verify(message, &group_signature);
|
|
||||||
|
|
||||||
// assert!(verify_signature.is_ok());
|
// Read a single line from the given reader.
|
||||||
// }
|
fn read_line(mut reader: impl BufRead) -> Result<String, std::io::Error> {
|
||||||
|
let mut s = String::new();
|
||||||
|
reader.read_line(&mut s).map(|_| s)
|
||||||
|
}
|
||||||
|
|
||||||
// #[test]
|
// Test if the DKG CLI works.
|
||||||
// fn check_keygen_with_dealer_with_large_num_of_signers() {
|
//
|
||||||
// let mut rng = thread_rng();
|
// This simulates 3 simultaneous CLIs by using threads.
|
||||||
// let config = Config {
|
//
|
||||||
// min_signers: 14,
|
// Since the `pipe` module used for sending and receiving to each thread
|
||||||
// max_signers: 20,
|
// is synchronous, the test is very strict. For example, you won't be able to
|
||||||
// secret: Vec::new(),
|
// read from a CLI if it's waiting for input, and you can't write to it if it's
|
||||||
// };
|
// waiting for some output to be read.
|
||||||
// let (shares, pubkeys) = dkg(&config, &mut rng).unwrap();
|
//
|
||||||
// let key_packages = generate_key_packages(shares);
|
// If the test gets stuck somewhere, that's likely the reason: you should be
|
||||||
// let (nonces, commitments) =
|
// writing to a CLI instead of reading, or vice-versa. Use `debug` to find
|
||||||
// signature_gen::generate_nonces_and_commitments(config.min_signers, &key_packages, &mut rng);
|
// where in the function it's getting stuck and check if the test at that point
|
||||||
// let message = "message to sign".as_bytes();
|
// is correct.
|
||||||
// let comms = commitments.into_values().collect();
|
#[test]
|
||||||
// let signing_package = frost::SigningPackage::new(comms, message.to_vec());
|
#[allow(clippy::needless_range_loop)]
|
||||||
// let signature_shares =
|
fn check_dkg() {
|
||||||
// signature_gen::generate_signature_shares(nonces, &key_packages, &signing_package);
|
let mut input_writers = Vec::new();
|
||||||
// let group_signature =
|
let mut output_readers = Vec::new();
|
||||||
// frost::aggregate(&signing_package, &signature_shares[..], &pubkeys).unwrap();
|
let mut join_handles = Vec::new();
|
||||||
// let verify_signature = pubkeys.group_public.verify(message, &group_signature);
|
|
||||||
|
|
||||||
// assert!(verify_signature.is_ok());
|
for i in 0..3 {
|
||||||
// }
|
// Spawn CLIs, one thread per participant
|
||||||
|
|
||||||
// #[test]
|
let (mut input_reader, input_writer) = pipe::pipe();
|
||||||
// fn check_keygen_with_dealer_with_secret() {
|
let (output_reader, mut output_writer) = pipe::pipe();
|
||||||
// let mut rng = thread_rng();
|
join_handles.push(thread::spawn(move || {
|
||||||
// let secret: Vec<u8> = vec![
|
cli(&mut input_reader, &mut output_writer).unwrap()
|
||||||
// 123, 28, 51, 211, 245, 41, 29, 133, 222, 102, 72, 51, 190, 177, 173, 70, 159, 127, 182, 2,
|
}));
|
||||||
// 90, 14, 199, 139, 58, 121, 12, 110, 19, 169, 131, 4,
|
input_writers.push(input_writer);
|
||||||
// ];
|
output_readers.push(output_reader);
|
||||||
// let secret_config = Config {
|
|
||||||
// min_signers: 2,
|
|
||||||
// max_signers: 3,
|
|
||||||
// secret,
|
|
||||||
// };
|
|
||||||
// let (shares, pubkeys) = split_secret(&secret_config, &mut rng).unwrap();
|
|
||||||
// let key_packages = generate_key_packages(shares);
|
|
||||||
// let (nonces, commitments) = signature_gen::generate_nonces_and_commitments(
|
|
||||||
// secret_config.min_signers,
|
|
||||||
// &key_packages,
|
|
||||||
// &mut rng,
|
|
||||||
// );
|
|
||||||
// let message = "message to sign".as_bytes();
|
|
||||||
// let comms = commitments.into_values().collect();
|
|
||||||
// let signing_package = frost::SigningPackage::new(comms, message.to_vec());
|
|
||||||
// let signature_shares =
|
|
||||||
// signature_gen::generate_signature_shares(nonces, &key_packages, &signing_package);
|
|
||||||
// let group_signature =
|
|
||||||
// frost::aggregate(&signing_package, &signature_shares[..], &pubkeys).unwrap();
|
|
||||||
// let verify_signature = pubkeys.group_public.verify(message, &group_signature);
|
|
||||||
|
|
||||||
// assert!(verify_signature.is_ok());
|
// Input the config into each CLI
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
assert_eq!(
|
||||||
// fn check_keygen_with_dealer_with_secret_with_large_num_of_signers() {
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
// let mut rng = thread_rng();
|
"The minimum number of signers: (2 or more)\n"
|
||||||
// let secret: Vec<u8> = vec![
|
);
|
||||||
// 123, 28, 51, 211, 245, 41, 29, 133, 222, 102, 72, 51, 190, 177, 173, 70, 159, 127, 182, 2,
|
writeln!(&mut input_writers[i], "2").unwrap();
|
||||||
// 90, 14, 199, 139, 58, 121, 12, 110, 19, 169, 131, 4,
|
|
||||||
// ];
|
|
||||||
// let secret_config = Config {
|
|
||||||
// min_signers: 14,
|
|
||||||
// max_signers: 20,
|
|
||||||
// secret,
|
|
||||||
// };
|
|
||||||
// let (shares, pubkeys) = split_secret(&secret_config, &mut rng).unwrap();
|
|
||||||
// let key_packages = generate_key_packages(shares);
|
|
||||||
// let (nonces, commitments) = signature_gen::generate_nonces_and_commitments(
|
|
||||||
// secret_config.min_signers,
|
|
||||||
// &key_packages,
|
|
||||||
// &mut rng,
|
|
||||||
// );
|
|
||||||
// let message = "message to sign".as_bytes();
|
|
||||||
// let comms = commitments.into_values().collect();
|
|
||||||
// let signing_package = frost::SigningPackage::new(comms, message.to_vec());
|
|
||||||
// let signature_shares =
|
|
||||||
// signature_gen::generate_signature_shares(nonces, &key_packages, &signing_package);
|
|
||||||
// let group_signature =
|
|
||||||
// frost::aggregate(&signing_package, &signature_shares[..], &pubkeys).unwrap();
|
|
||||||
// let verify_signature = pubkeys.group_public.verify(message, &group_signature);
|
|
||||||
|
|
||||||
// assert!(verify_signature.is_ok());
|
assert_eq!(
|
||||||
// }
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"The maximum number of signers:\n"
|
||||||
|
);
|
||||||
|
writeln!(&mut input_writers[i], "3").unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"Your identifier (this should be an integer between 1 and 65535):\n"
|
||||||
|
);
|
||||||
|
writeln!(&mut input_writers[i], "{}", i + 1).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut round1_packages = HashMap::new();
|
||||||
|
for i in 0..3 {
|
||||||
|
// Read the Round 1 Packages printed by each participant;
|
||||||
|
// put them in a map
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
assert_eq!(
|
||||||
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"=== ROUND 1: SEND PACKAGES ===\n"
|
||||||
|
);
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
assert!(read_line(&mut output_readers[i])
|
||||||
|
.unwrap()
|
||||||
|
.starts_with("Round 1 Package to send to all other participants"));
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
|
||||||
|
let round1_package_json = read_line(&mut output_readers[i]).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
|
||||||
|
round1_packages.insert(i, round1_package_json);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut round2_packages = HashMap::new();
|
||||||
|
for i in 0..3 {
|
||||||
|
// Input the Round 1 Packages from other participants, for each
|
||||||
|
// participant i
|
||||||
|
assert_eq!(
|
||||||
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"=== ROUND 1: RECEIVE PACKAGES ===\n"
|
||||||
|
);
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
assert_eq!(
|
||||||
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"Input Round 1 Packages from the other 2 participants.\n"
|
||||||
|
);
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
for j in 0..3 {
|
||||||
|
// Input Round 1 Package from participant j
|
||||||
|
if i == j {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
assert_eq!(
|
||||||
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"The sender's identifier (hex string):\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Write j's identifier
|
||||||
|
let jid: Identifier = ((j + 1) as u16).try_into().unwrap();
|
||||||
|
writeln!(&mut input_writers[i], "{}", hex::encode(jid.serialize())).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"Their JSON-encoded Round 1 Package:\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Write j's package
|
||||||
|
write!(&mut input_writers[i], "{}", round1_packages[&j]).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"=== ROUND 2: SEND PACKAGES ===\n"
|
||||||
|
);
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
|
||||||
|
let mut packages = HashMap::new();
|
||||||
|
for j in 0..3 {
|
||||||
|
// Read Round 2 packages to send to other participants, for
|
||||||
|
// each participant
|
||||||
|
if i == j {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
// Read line indicating who should receive that package;
|
||||||
|
// extract hex identifier
|
||||||
|
let s = read_line(&mut output_readers[i]).unwrap();
|
||||||
|
assert!(s.starts_with("Round 2 Package to send to participant"));
|
||||||
|
let participant_hex = s.split('\"').collect::<Vec<_>>()[1].to_string();
|
||||||
|
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
|
||||||
|
// Read Round 2 package
|
||||||
|
let round2_package_json = read_line(&mut output_readers[i]).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
|
||||||
|
packages.insert(participant_hex, round2_package_json);
|
||||||
|
}
|
||||||
|
round2_packages.insert(i, packages);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut public_key_packages = HashMap::new();
|
||||||
|
for i in 0..3 {
|
||||||
|
// Input Round 2 packages from other participants, for each participant
|
||||||
|
assert_eq!(
|
||||||
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"=== ROUND 2: RECEIVE PACKAGES ===\n"
|
||||||
|
);
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
assert_eq!(
|
||||||
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"Input Round 2 Packages from the other 2 participants.\n"
|
||||||
|
);
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
for j in 0..3 {
|
||||||
|
// Input Round 2 Package from participant j
|
||||||
|
if i == j {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
assert_eq!(
|
||||||
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"The sender's identifier (hex string):\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Write j's identifier
|
||||||
|
let jid: Identifier = ((j + 1) as u16).try_into().unwrap();
|
||||||
|
writeln!(&mut input_writers[i], "{}", hex::encode(jid.serialize())).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"Their JSON-encoded Round 2 Package:\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Write j's package sent to i
|
||||||
|
let iid: Identifier = ((i + 1) as u16).try_into().unwrap();
|
||||||
|
let iids = hex::encode(iid.serialize());
|
||||||
|
let s = round2_packages.get(&j).expect("j").get(&iids).expect("i");
|
||||||
|
write!(&mut input_writers[i], "{}", s).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"=== DKG FINISHED ===\n"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"Participant key package:\n"
|
||||||
|
);
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
|
||||||
|
// Read key package
|
||||||
|
let key_package_json = read_line(&mut output_readers[i]).unwrap();
|
||||||
|
let _key_package: KeyPackage = serde_json::from_str(&key_package_json).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
assert_eq!(
|
||||||
|
read_line(&mut output_readers[i]).unwrap(),
|
||||||
|
"Participant public key package:\n"
|
||||||
|
);
|
||||||
|
assert_eq!(read_line(&mut output_readers[i]).unwrap(), "\n");
|
||||||
|
|
||||||
|
// Read public key package
|
||||||
|
let public_key_package_json = read_line(&mut output_readers[i]).unwrap();
|
||||||
|
let public_key_package: PublicKeyPackage =
|
||||||
|
serde_json::from_str(&public_key_package_json).unwrap();
|
||||||
|
public_key_packages.insert(i, public_key_package);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that all public key packages are equal
|
||||||
|
assert!(public_key_packages
|
||||||
|
.values()
|
||||||
|
.all(|p| *p == public_key_packages[&0]));
|
||||||
|
|
||||||
|
// Wait for threads, which should terminate at this point
|
||||||
|
for jh in join_handles {
|
||||||
|
jh.join().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
use frost::keys::{KeyPackage, SecretShare};
|
|
||||||
use frost::round1::{SigningCommitments, SigningNonces};
|
|
||||||
use frost::round2::SignatureShare;
|
|
||||||
use frost::{Identifier, SigningPackage};
|
|
||||||
use frost_ed25519 as frost;
|
|
||||||
use rand::rngs::ThreadRng;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
pub fn generate_key_packages(
|
|
||||||
shares: HashMap<Identifier, SecretShare>,
|
|
||||||
) -> HashMap<Identifier, KeyPackage> {
|
|
||||||
let mut key_packages: HashMap<_, _> = HashMap::new();
|
|
||||||
|
|
||||||
for (k, v) in shares {
|
|
||||||
let key_package = frost::keys::KeyPackage::try_from(v).unwrap();
|
|
||||||
key_packages.insert(k, key_package);
|
|
||||||
}
|
|
||||||
key_packages
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate_nonces_and_commitments(
|
|
||||||
min_signers: u16,
|
|
||||||
key_packages: &HashMap<Identifier, KeyPackage>,
|
|
||||||
rng: &mut ThreadRng,
|
|
||||||
) -> (
|
|
||||||
HashMap<Identifier, SigningNonces>,
|
|
||||||
HashMap<Identifier, SigningCommitments>,
|
|
||||||
) {
|
|
||||||
let mut nonces = HashMap::new();
|
|
||||||
let mut commitments = HashMap::new();
|
|
||||||
|
|
||||||
for participant_index in 1..(min_signers + 1) {
|
|
||||||
let participant_identifier = participant_index.try_into().expect("should be nonzero");
|
|
||||||
let (nonce, commitment) = frost::round1::commit(
|
|
||||||
participant_identifier,
|
|
||||||
key_packages[&participant_identifier].secret_share(),
|
|
||||||
rng,
|
|
||||||
);
|
|
||||||
nonces.insert(participant_identifier, nonce);
|
|
||||||
commitments.insert(participant_identifier, commitment);
|
|
||||||
}
|
|
||||||
|
|
||||||
(nonces, commitments)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate_signature_shares(
|
|
||||||
nonces: HashMap<Identifier, SigningNonces>,
|
|
||||||
key_packages: &HashMap<Identifier, KeyPackage>,
|
|
||||||
signing_package: &SigningPackage,
|
|
||||||
) -> Vec<SignatureShare> {
|
|
||||||
let mut signature_shares = Vec::new();
|
|
||||||
|
|
||||||
for participant_identifier in nonces.keys() {
|
|
||||||
let key_package = &key_packages[participant_identifier];
|
|
||||||
let nonces_to_use = &nonces[participant_identifier];
|
|
||||||
let signature_share =
|
|
||||||
frost::round2::sign(signing_package, nonces_to_use, key_package).unwrap(); //TODO: handle errors
|
|
||||||
|
|
||||||
signature_shares.push(signature_share);
|
|
||||||
}
|
|
||||||
|
|
||||||
signature_shares
|
|
||||||
}
|
|
Loading…
Reference in New Issue