Skip to content

Commit

Permalink
frost-client: show message to gather consent; overall printing clean …
Browse files Browse the repository at this point in the history
…up (#467)
  • Loading branch information
conradoplg authored Feb 12, 2025
1 parent c8e7210 commit f4d53a5
Show file tree
Hide file tree
Showing 15 changed files with 84 additions and 28 deletions.
11 changes: 0 additions & 11 deletions coordinator/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ pub async fn cli_for_processed_args<C: RandomizedCiphersuite + 'static>(
reader: &mut impl BufRead,
logger: &mut impl Write,
) -> Result<(), Box<dyn std::error::Error>> {
writeln!(logger, "\n=== STEP 1: CHOOSE PARTICIPANTS ===\n")?;

let mut comms: Box<dyn Comms<C>> = if pargs.cli {
Box::new(CLIComms::new())
} else if pargs.http {
Expand All @@ -38,15 +36,8 @@ pub async fn cli_for_processed_args<C: RandomizedCiphersuite + 'static>(

let participants_config = step_1(&pargs, &mut *comms, reader, logger).await?;

writeln!(
logger,
"=== STEP 2: CHOOSE MESSAGE AND GENERATE COMMITMENT PACKAGE ===\n"
)?;

let signing_package = step_2(&pargs, logger, participants_config.commitments.clone())?;

writeln!(logger, "=== STEP 3: BUILD GROUP SIGNATURE ===\n")?;

step_3(
&pargs,
&mut *comms,
Expand All @@ -57,7 +48,5 @@ pub async fn cli_for_processed_args<C: RandomizedCiphersuite + 'static>(
)
.await?;

writeln!(logger, "=== END ===")?;

Ok(())
}
7 changes: 7 additions & 0 deletions coordinator/src/comms/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
_num_signers: u16,
) -> Result<BTreeMap<Identifier<C>, SigningCommitments<C>>, Box<dyn Error>> {
let mut rng = thread_rng();

eprintln!("Logging in...");
let challenge = self
.client
.post(format!("{}/challenge", self.host_port))
Expand Down Expand Up @@ -382,6 +384,7 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
.to_string(),
);

eprintln!("Creating signing session...");
let r = self
.client
.post(format!("{}/create_new_session", self.host_port))
Expand Down Expand Up @@ -555,6 +558,8 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
session_id: self.session_id.unwrap(),
})
.send()
.await?
.bytes()
.await?;

let _r = self
Expand All @@ -566,6 +571,8 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
.expect("must have been set before"),
)
.send()
.await?
.bytes()
.await?;

let signature_shares = self.state.signature_shares()?;
Expand Down
4 changes: 3 additions & 1 deletion coordinator/src/step_1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ pub async fn step_1<C: Ciphersuite>(
logger: &mut dyn Write,
) -> Result<ParticipantsConfig<C>, Box<dyn std::error::Error>> {
let participants = read_commitments(args, comms, reader, logger).await?;
print_participants(logger, &participants.commitments);
if args.cli {
print_participants(logger, &participants.commitments);
}
Ok(participants)
}

Expand Down
4 changes: 3 additions & 1 deletion coordinator/src/step_2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ pub fn step_2<C: Ciphersuite>(
commitments: BTreeMap<Identifier<C>, SigningCommitments<C>>,
) -> Result<SigningPackage<C>, Box<dyn std::error::Error>> {
let signing_package = SigningPackage::new(commitments, &args.messages[0]);
print_signing_package(logger, &signing_package);
if args.cli {
print_signing_package(logger, &signing_package);
}
Ok(signing_package)
}

Expand Down
4 changes: 2 additions & 2 deletions coordinator/src/step_3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ fn print_signature<C: Ciphersuite + 'static>(
if args.signature.is_empty() {
writeln!(
logger,
"Group signature: {}",
serde_json::to_string(&group_signature)?
"Signature:\n{}",
hex::encode(&group_signature.serialize()?)
)?;
} else {
fs::write(&args.signature, group_signature.serialize()?)?;
Expand Down
7 changes: 5 additions & 2 deletions coordinator/src/tests/steps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ async fn check_step_2() {
..
} = get_helpers();

let args = Args::default();
let args = Args {
cli: true,
..Default::default()
};
let mut buf = BufWriter::new(Vec::new());

let input = format!(
Expand Down Expand Up @@ -228,7 +231,7 @@ async fn check_step_3() {
.await
.unwrap();

let expected = format!("Please enter JSON encoded signature shares for participant {}:\nPlease enter JSON encoded signature shares for participant {}:\nGroup signature: \"{}\"\n", participant_id_1, participant_id_3, group_signature);
let expected = format!("Please enter JSON encoded signature shares for participant {}:\nPlease enter JSON encoded signature shares for participant {}:\nSignature:\n{}\n", participant_id_1, participant_id_3, group_signature);

let (_, res) = &buf.into_parts();
let actual = String::from_utf8(res.as_ref().unwrap().to_owned()).unwrap();
Expand Down
5 changes: 5 additions & 0 deletions dkg/src/comms/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,8 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
_output: &mut dyn Write,
) -> Result<(Identifier<C>, u16), Box<dyn Error>> {
let mut rng = thread_rng();

eprintln!("Logging in...");
let challenge = self
.client
.post(format!("{}/challenge", self.host_port))
Expand Down Expand Up @@ -473,6 +475,7 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
);

let session_id = if !self.args.participants.is_empty() {
eprintln!("Creating DKG session...");
let r = self
.client
.post(format!("{}/create_new_session", self.host_port))
Expand All @@ -493,6 +496,7 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
.await?;
r.session_id
} else {
eprintln!("Joining DKG session...");
match self.session_id {
Some(s) => s,
None => {
Expand All @@ -516,6 +520,7 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
};
self.session_id = Some(session_id);

eprintln!("Getting session info...");
// Get all participants' public keys, and derive their identifiers
// from them.
let session_info = self
Expand Down
4 changes: 4 additions & 0 deletions frost-client/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ pub(crate) enum Command {
/// by the group public key (use `groups` to list).
#[arg(short, long)]
group: Option<String>,
/// Whether to also close all existing sessions. Useful for cleaning
/// up lingering sessions due to errors or if participants give up.
#[arg(long, default_value_t = false)]
close_all: bool,
},
Coordinator {
/// The path to the config file to manage. If not specified, it uses
Expand Down
5 changes: 5 additions & 0 deletions frost-client/src/dkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,10 @@ pub(crate) async fn dkg_for_ciphersuite<C: Ciphersuite + MaybeIntoEvenY + 'stati
);
config.write()?;

eprintln!(
"Group created; information written to {}",
config.path().expect("should not be None").display()
);

Ok(())
}
12 changes: 12 additions & 0 deletions frost-client/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub(crate) async fn list(args: &Command) -> Result<(), Box<dyn Error>> {
config,
group,
server_url,
close_all,
} = (*args).clone()
else {
panic!("invalid Command");
Expand Down Expand Up @@ -124,6 +125,17 @@ pub(crate) async fn list(args: &Command) -> Result<(), Box<dyn Error>> {
}
}
eprintln!();

if close_all {
let _r = client
.post(format!("{}/close_session", host_port))
.bearer_auth(&access_token)
.json(&frostd::CloseSessionArgs { session_id })
.send()
.await?
.bytes()
.await?;
}
}
}

Expand Down
15 changes: 13 additions & 2 deletions frostd/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ pub(crate) async fn create_new_session(
.or_default()
.insert(id);
}
// Also add the coordinator, since they don't have to be a participant
sessions_by_pubkey
.entry(user.pubkey.clone())
.or_default()
.insert(id);
// Create Session object
let session = Session {
pubkeys: args.pubkeys.into_iter().map(|p| p.0).collect(),
Expand Down Expand Up @@ -263,11 +268,17 @@ pub(crate) async fn close_session(
return Err(AppError::NotCoordinator);
}

for username in session.pubkeys.clone() {
if let Some(v) = sessions_by_pubkey.get_mut(&username) {
// Remove session from each participant list...
for pubkey in session.pubkeys.clone() {
if let Some(v) = sessions_by_pubkey.get_mut(&pubkey) {
v.remove(&args.session_id);
}
}
// And also remove from the coordinator's list
// (might have been already removed if they are also a participant)
if let Some(v) = sessions_by_pubkey.get_mut(&user.pubkey) {
v.remove(&args.session_id);
}
sessions.remove(&args.session_id);
Ok(Json(()))
}
24 changes: 20 additions & 4 deletions participant/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::comms::Comms;

use crate::round1::{generate_nonces_and_commitments, print_values};
use crate::round2::{generate_signature, print_values_round_2, round_2_request_inputs};
use eyre::eyre;
use frost_core::Ciphersuite;
use frost_ed25519::Ed25519Sha512;
use frost_rerandomized::RandomizedCiphersuite;
Expand Down Expand Up @@ -41,12 +42,12 @@ pub async fn cli_for_processed_args<C: RandomizedCiphersuite + 'static>(

let key_package = pargs.key_package;

writeln!(logger, "Key Package succesfully created.")?;

let mut rng = thread_rng();
let (nonces, commitments) = generate_nonces_and_commitments(&key_package, &mut rng);

print_values(commitments, logger)?;
if pargs.cli {
print_values(commitments, logger)?;
}

// Round 2 - Sign

Expand All @@ -67,13 +68,28 @@ pub async fn cli_for_processed_args<C: RandomizedCiphersuite + 'static>(
rerandomized,
)
.await?;

writeln!(
logger,
"Message to be signed (hex-encoded):\n{}\nDo you want to sign it? (y/n)",
hex::encode(round_2_config.signing_package.message())
)?;
let mut sign_it = String::new();
input.read_line(&mut sign_it)?;
if sign_it.trim() != "y" {
return Err(eyre!("signing cancelled").into());
}

let signature = generate_signature(round_2_config, &key_package, &nonces)?;

comms
.send_signature_share(*key_package.identifier(), signature)
.await?;

print_values_round_2(signature, logger)?;
if pargs.cli {
print_values_round_2(signature, logger)?;
}
writeln!(logger, "Done")?;

Ok(())
}
5 changes: 4 additions & 1 deletion participant/src/comms/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ where
Box<dyn Error>,
> {
let mut rng = thread_rng();

eprintln!("Logging in...");
let challenge = self
.client
.post(format!("{}/challenge", self.host_port))
Expand Down Expand Up @@ -219,6 +221,7 @@ where
.to_string(),
);

eprintln!("Joining signing session...");
let session_id = match self.session_id {
Some(s) => s,
None => {
Expand Down Expand Up @@ -289,6 +292,7 @@ where
self.recv_noise = Some(recv_noise);

// Send Commitments to Server
eprintln!("Sending commitments to coordinator...");
let send_commitments_args = vec![commitments];
let msg = self.encrypt(serde_json::to_vec(&send_commitments_args)?)?;
self.client
Expand Down Expand Up @@ -326,7 +330,6 @@ where
} else {
eprintln!("\nSigning package received");
let msg = self.decrypt(r.msgs[0].msg.clone())?;
eprintln!("\n{}", String::from_utf8_lossy(&msg.clone()));
break serde_json::from_slice(&msg)?;
}
};
Expand Down
3 changes: 0 additions & 3 deletions participant/src/round2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ pub async fn round_2_request_inputs<C: Ciphersuite>(
identifier: Identifier<C>,
rerandomized: bool,
) -> Result<Round2Config<C>, Box<dyn std::error::Error>> {
writeln!(logger, "=== Round 2 ===")?;

let r = comms
.get_signing_package(input, logger, commitments, identifier, rerandomized)
.await?;
Expand Down Expand Up @@ -62,7 +60,6 @@ pub fn print_values_round_2<C: Ciphersuite>(
"SignatureShare:\n{}",
serde_json::to_string(&signature).unwrap()
)?;
writeln!(logger, "=== End of Round 2 ===")?;

Ok(())
}
2 changes: 1 addition & 1 deletion participant/src/tests/round2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ async fn check_print_values_round_2() {

print_values_round_2(signature_response, &mut buf).unwrap();

let log = "Please send the following to the Coordinator\nSignatureShare:\n{\"header\":{\"version\":0,\"ciphersuite\":\"FROST-ED25519-SHA512-v1\"},\"share\":\"44055c54d0604cbd006f0d1713a22474d7735c5e8816b1878f62ca94bf105900\"}\n=== End of Round 2 ===\n";
let log = "Please send the following to the Coordinator\nSignatureShare:\n{\"header\":{\"version\":0,\"ciphersuite\":\"FROST-ED25519-SHA512-v1\"},\"share\":\"44055c54d0604cbd006f0d1713a22474d7735c5e8816b1878f62ca94bf105900\"}\n";

let out = String::from_utf8(buf.into_inner().unwrap()).unwrap();

Expand Down

0 comments on commit f4d53a5

Please sign in to comment.