diff --git a/coordinator/src/cli.rs b/coordinator/src/cli.rs index 28897a60..e75e3281 100644 --- a/coordinator/src/cli.rs +++ b/coordinator/src/cli.rs @@ -10,7 +10,7 @@ pub fn cli( ) -> Result<(), Box> { writeln!(logger, "\n=== STEP 1: CHOOSE PARTICIPANTS ===\n")?; - let participants_config = step_1(reader, logger); + let participants_config = step_1(reader, logger)?; writeln!( logger, diff --git a/coordinator/src/step_1.rs b/coordinator/src/step_1.rs index 7ef730c9..531f60ad 100755 --- a/coordinator/src/step_1.rs +++ b/coordinator/src/step_1.rs @@ -10,10 +10,13 @@ pub struct ParticipantsConfig { } // TODO: needs to include the coordinator's keys! -pub fn step_1(reader: &mut impl BufRead, logger: &mut dyn Write) -> ParticipantsConfig { - let participants = choose_participants(reader, logger).unwrap(); +pub fn step_1( + reader: &mut impl BufRead, + logger: &mut dyn Write, +) -> Result { + let participants = choose_participants(reader, logger)?; print_participants(logger, &participants.participants); - participants + Ok(participants) } fn validate( @@ -21,10 +24,10 @@ fn validate( key_package: PublicKeyPackage, id_list: &[Identifier], ) -> Result<(), Error> { - if key_package.signer_pubkeys().contains_key(&id) { - return Err(Error::DuplicatedIdentifier); + if !key_package.signer_pubkeys().contains_key(&id) { + return Err(Error::MalformedIdentifier); }; // TODO: Error is actually that the identifier does not exist - if !id_list.contains(&id) { + if id_list.contains(&id) { return Err(Error::DuplicatedIdentifier); }; Ok(()) @@ -81,3 +84,81 @@ pub fn print_participants(logger: &mut dyn Write, participants: &Vec writeln!(logger, "{}", serde_json::to_string(p).unwrap()).unwrap(); } } + +#[cfg(test)] +mod tests { + use std::collections::HashMap; + + use frost::{ + keys::{PublicKeyPackage, VerifyingShare}, + Error, Identifier, VerifyingKey, + }; + use frost_ed25519 as frost; + use hex::FromHex; + + use crate::step_1::validate; + + const PUBLIC_KEY_1: &str = "fc2c9b8e335c132d9ebe0403c9317aac480bbbf8cbdb1bc3730bb68eb60dadf9"; + const PUBLIC_KEY_2: &str = "2cff4148a2f965801fb1f25f1d2a4e5df2f75b3a57cd06f30471c2c774419a41"; + const GROUP_PUBLIC_KEY: &str = + "15d21ccd7ee42959562fc8aa63224c8851fb3ec85a3faf66040d380fb9738673"; + + fn build_pub_key_package() -> PublicKeyPackage { + let id_1 = Identifier::try_from(1).unwrap(); + let id_2 = Identifier::try_from(2).unwrap(); + + let mut signer_pubkeys = HashMap::new(); + signer_pubkeys.insert( + id_1, + VerifyingShare::deserialize(<[u8; 32]>::from_hex(PUBLIC_KEY_1).unwrap()).unwrap(), + ); + signer_pubkeys.insert( + id_2, + VerifyingShare::deserialize(<[u8; 32]>::from_hex(PUBLIC_KEY_2).unwrap()).unwrap(), + ); + + let group_public = VerifyingKey::from_hex(GROUP_PUBLIC_KEY).unwrap(); + + PublicKeyPackage::new(signer_pubkeys, group_public) + } + + #[test] + fn check_validate() { + let id_1 = Identifier::try_from(1).unwrap(); + let id_2 = Identifier::try_from(2).unwrap(); + + let id_list = [id_1]; + let key_package = build_pub_key_package(); + + let validated = validate(id_2, key_package, &id_list); + + assert!(validated.is_ok()) + } + + #[test] + fn check_validation_errors_for_missing_identifiers() { + let id_1 = Identifier::try_from(1).unwrap(); + let id_2 = Identifier::try_from(2).unwrap(); + let id_3 = Identifier::try_from(3).unwrap(); + + let id_list = [id_1, id_2]; + let key_package = build_pub_key_package(); + + let validated = validate(id_3, key_package, &id_list); + assert!(validated.is_err()); + assert!(validated == Err(Error::MalformedIdentifier)) + } + + #[test] + fn check_validation_errors_for_duplicate_identifiers() { + let id_1 = Identifier::try_from(1).unwrap(); + let id_2 = Identifier::try_from(2).unwrap(); + + let id_list = [id_1, id_2]; + let key_package = build_pub_key_package(); + + let validated = validate(id_1, key_package, &id_list); + assert!(validated.is_err()); + assert!(validated == Err(Error::DuplicatedIdentifier)) + } +}