Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

frost-client: add message confirmation step to Comms trait #491

Merged
merged 2 commits into from
Feb 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 4 additions & 11 deletions participant/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +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 @@ -69,16 +69,9 @@ pub async fn cli_for_processed_args<C: RandomizedCiphersuite + 'static>(
)
.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());
}
comms
.confirm_message(input, logger, &round_2_config)
.await?;

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

Expand Down
36 changes: 29 additions & 7 deletions participant/src/comms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ pub mod http;
pub mod socket;

use async_trait::async_trait;
use eyre::eyre;

use frost_core::{self as frost, Ciphersuite};
use frostd::SendSigningPackageArgs;

use std::{
error::Error,
Expand Down Expand Up @@ -43,13 +45,33 @@ pub trait Comms<C: Ciphersuite> {
commitments: SigningCommitments<C>,
identifier: Identifier<C>,
rerandomized: bool,
) -> Result<
(
frost::SigningPackage<C>,
Option<frost_rerandomized::Randomizer<C>>,
),
Box<dyn Error>,
>;
) -> Result<SendSigningPackageArgs<C>, Box<dyn Error>>;

/// Ask the user if they want to sign the message.
///
/// Implementations should show the message to the user (or auxiliary data
/// that maps to the message) and ask for confirmation.
///
/// The default implementation prints the message to output and reads
/// confirmation from input.
async fn confirm_message(
&mut self,
input: &mut dyn BufRead,
output: &mut dyn Write,
signing_package: &SendSigningPackageArgs<C>,
) -> Result<(), Box<dyn Error>> {
writeln!(
output,
"Message to be signed (hex-encoded):\n{}\nDo you want to sign it? (y/n)",
hex::encode(signing_package.signing_package[0].message())
)?;
let mut sign_it = String::new();
input.read_line(&mut sign_it)?;
if sign_it.trim() != "y" {
return Err(eyre!("signing cancelled").into());
}
Ok(())
}

async fn send_signature_share(
&mut self,
Expand Down
23 changes: 14 additions & 9 deletions participant/src/comms/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use frost::{
keys::PublicKeyPackage, round1::SigningCommitments, round2::SignatureShare, Identifier,
SigningPackage,
};
use frostd::SendSigningPackageArgs;

use std::{
error::Error,
Expand Down Expand Up @@ -47,13 +48,7 @@ where
_commitments: SigningCommitments<C>,
_identifier: Identifier<C>,
rerandomized: bool,
) -> Result<
(
frost::SigningPackage<C>,
Option<frost_rerandomized::Randomizer<C>>,
),
Box<dyn Error>,
> {
) -> Result<SendSigningPackageArgs<C>, Box<dyn Error>> {
writeln!(output, "Enter the JSON-encoded SigningPackage:")?;

let mut signing_package_json = String::new();
Expand All @@ -71,9 +66,19 @@ where

let randomizer =
frost_rerandomized::Randomizer::<C>::deserialize(&hex::decode(json.trim())?)?;
Ok((signing_package, Some(randomizer)))
let r = frostd::SendSigningPackageArgs::<C> {
signing_package: vec![signing_package],
randomizer: vec![randomizer],
aux_msg: vec![],
};
Ok(r)
} else {
Ok((signing_package, None))
let r = frostd::SendSigningPackageArgs::<C> {
signing_package: vec![signing_package],
randomizer: vec![],
aux_msg: vec![],
};
Ok(r)
}
}

Expand Down
29 changes: 4 additions & 25 deletions participant/src/comms/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ use std::{

use async_trait::async_trait;
use eyre::{eyre, OptionExt};
use frost_core::{
self as frost, round1::SigningCommitments, round2::SignatureShare, Ciphersuite, Identifier,
};
use frost_core::{round1::SigningCommitments, round2::SignatureShare, Ciphersuite, Identifier};
use rand::thread_rng;
use snow::{HandshakeState, TransportState};
use xeddsa::{xed25519, Sign as _};
Expand Down Expand Up @@ -169,14 +167,8 @@ where
_output: &mut dyn Write,
commitments: SigningCommitments<C>,
_identifier: Identifier<C>,
rerandomized: bool,
) -> Result<
(
frost::SigningPackage<C>,
Option<frost_rerandomized::Randomizer<C>>,
),
Box<dyn Error>,
> {
_rerandomized: bool,
) -> Result<SendSigningPackageArgs<C>, Box<dyn Error>> {
let mut rng = thread_rng();

eprintln!("Logging in...");
Expand Down Expand Up @@ -334,20 +326,7 @@ where
}
};

if rerandomized {
let signing_package = r
.signing_package
.first()
.ok_or(eyre!("missing signing package"))?;
let randomizer = r.randomizer.first().ok_or(eyre!("missing randomizer"))?;
Ok((signing_package.clone(), Some(*randomizer)))
} else {
let signing_package = r
.signing_package
.first()
.ok_or(eyre!("missing signing package"))?;
Ok((signing_package.clone(), None))
}
Ok(r)
}

async fn send_signature_share(
Expand Down
15 changes: 7 additions & 8 deletions participant/src/comms/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use async_trait::async_trait;
use frost_core::{self as frost, Ciphersuite};

use eyre::eyre;
use frostd::SendSigningPackageArgs;
use message_io::{
network::{Endpoint, NetEvent, Transport},
node::{self, NodeHandler, NodeListener},
Expand Down Expand Up @@ -89,13 +90,7 @@ where
commitments: SigningCommitments<C>,
identifier: Identifier<C>,
_rerandomized: bool,
) -> Result<
(
frost::SigningPackage<C>,
Option<frost_rerandomized::Randomizer<C>>,
),
Box<dyn Error>,
> {
) -> Result<SendSigningPackageArgs<C>, Box<dyn Error>> {
// Send Commitments to Coordinator
let data = serde_json::to_vec(&Message::<C>::IdentifiedCommitments {
identifier,
Expand All @@ -116,7 +111,11 @@ where
randomizer,
} = message
{
Ok((signing_package, randomizer))
Ok(SendSigningPackageArgs::<C> {
signing_package: vec![signing_package],
randomizer: randomizer.map(|r| vec![r]).unwrap_or_default(),
aux_msg: vec![],
})
} else {
Err(eyre!("Expected SigningPackage message"))?
}
Expand Down
27 changes: 14 additions & 13 deletions participant/src/round2.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use frost_core::{self as frost, Ciphersuite};
use frostd::SendSigningPackageArgs;

use crate::comms::Comms;
use frost::{
Expand All @@ -24,28 +25,28 @@ pub async fn round_2_request_inputs<C: Ciphersuite>(
commitments: SigningCommitments<C>,
identifier: Identifier<C>,
rerandomized: bool,
) -> Result<Round2Config<C>, Box<dyn std::error::Error>> {
let r = comms
) -> Result<SendSigningPackageArgs<C>, Box<dyn std::error::Error>> {
comms
.get_signing_package(input, logger, commitments, identifier, rerandomized)
.await?;

Ok(Round2Config {
signing_package: r.0,
randomizer: r.1,
})
.await
}

pub fn generate_signature<C: frost_rerandomized::RandomizedCiphersuite>(
config: Round2Config<C>,
config: SendSigningPackageArgs<C>,
key_package: &KeyPackage<C>,
signing_nonces: &SigningNonces<C>,
) -> Result<SignatureShare<C>, Error<C>> {
let signing_package = config.signing_package;
let signing_package = config.signing_package.first().unwrap();

let signature = if let Some(randomizer) = config.randomizer {
frost_rerandomized::sign::<C>(&signing_package, signing_nonces, key_package, randomizer)?
let signature = if !config.randomizer.is_empty() {
frost_rerandomized::sign::<C>(
signing_package,
signing_nonces,
key_package,
config.randomizer[0],
)?
} else {
round2::sign(&signing_package, signing_nonces, key_package)?
round2::sign(signing_package, signing_nonces, key_package)?
};
Ok(signature)
}
Expand Down
10 changes: 6 additions & 4 deletions participant/src/tests/round2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use frost::{
round2::SignatureShare,
SigningPackage, VerifyingKey,
};
use frostd::SendSigningPackageArgs;
use hex::FromHex;
use participant::comms::cli::CLIComms;
use participant::round2::print_values_round_2;
Expand Down Expand Up @@ -82,7 +83,7 @@ async fn check_valid_round_2_inputs() {
assert!(round_2_config.is_ok());
assert_eq!(
expected.signing_package,
round_2_config.unwrap().signing_package
round_2_config.unwrap().signing_package[0]
)
}

Expand Down Expand Up @@ -120,9 +121,10 @@ async fn check_sign() {

let signing_package = SigningPackage::new(signer_commitments, message);

let config = Round2Config {
signing_package,
randomizer: None,
let config = SendSigningPackageArgs {
signing_package: vec![signing_package],
randomizer: vec![],
aux_msg: vec![],
};

let signature = generate_signature(config, &key_package, &nonces);
Expand Down
11 changes: 7 additions & 4 deletions participant/tests/integration_tests.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use std::collections::{BTreeMap, HashMap};
use std::vec;

use frost_ed25519 as frost;

use frost::keys::IdentifierList;
use frost::{aggregate, SigningPackage};
use participant::round2::{generate_signature, Round2Config};
use frostd::SendSigningPackageArgs;
use participant::round2::generate_signature;
use rand::thread_rng;

#[test]
Expand Down Expand Up @@ -40,9 +42,10 @@ fn check_participant() {
let mut signature_shares = BTreeMap::new();

for participant_identifier in nonces.keys() {
let config = Round2Config {
signing_package: SigningPackage::new(commitments.clone(), &message),
randomizer: None,
let config = SendSigningPackageArgs {
signing_package: vec![SigningPackage::new(commitments.clone(), &message)],
randomizer: vec![],
aux_msg: vec![],
};
let signature = generate_signature(
config,
Expand Down
Loading