change coordinator and participant to allow them to be non-interactive (#133)
* trusted-dealer: allow reading params from arguments, and writing to files * change coordinator and participant to allow them to be non-interactive * allow reading message from file * remove warnings * fix tests
This commit is contained in:
parent
d0c8949c32
commit
a04a829930
|
@ -3,12 +3,26 @@ use clap::Parser;
|
|||
#[derive(Parser, Debug, Default)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
pub struct Args {
|
||||
/// The number of participants. If 0, will prompt for a value.
|
||||
#[arg(short = 'n', long, default_value_t = 0)]
|
||||
pub num_signers: u16,
|
||||
|
||||
/// Public key package to use. Can be a file with a JSON-encoded
|
||||
/// package, or "-". If the file does not exist or if "-" is specified,
|
||||
/// then it will be read from standard input.
|
||||
#[arg(short = 'P', long, default_value = "public-key-package.json")]
|
||||
pub public_key_package: String,
|
||||
|
||||
/// The message to sign. Can be a file with the raw message, or "-". If "-"
|
||||
/// is specified, then it will be read from standard input as a hex string.
|
||||
#[arg(short = 'm', long, default_value = "-")]
|
||||
pub message: String,
|
||||
|
||||
/// Where to write the generated raw bytes signature. If "-", the
|
||||
/// human-readable hex-string is printed to stdout.
|
||||
#[arg(short = 's', long, default_value = "-")]
|
||||
pub signature: String,
|
||||
|
||||
/// IP to bind to, if using online comms
|
||||
#[arg(short, long, default_value = "0.0.0.0")]
|
||||
pub ip: String,
|
||||
|
|
|
@ -32,7 +32,13 @@ pub async fn cli(
|
|||
"=== STEP 2: CHOOSE MESSAGE AND GENERATE COMMITMENT PACKAGE ===\n"
|
||||
)?;
|
||||
|
||||
let signing_package = step_2(reader, logger, participants_config.commitments.clone()).await?;
|
||||
let signing_package = step_2(
|
||||
args,
|
||||
reader,
|
||||
logger,
|
||||
participants_config.commitments.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
#[cfg(feature = "redpallas")]
|
||||
let randomizer = request_randomizer(reader, logger)?;
|
||||
|
@ -40,6 +46,7 @@ pub async fn cli(
|
|||
writeln!(logger, "=== STEP 3: BUILD GROUP SIGNATURE ===\n")?;
|
||||
|
||||
step_3(
|
||||
args,
|
||||
&mut comms,
|
||||
reader,
|
||||
logger,
|
||||
|
|
|
@ -81,6 +81,7 @@ impl Comms for SocketComms {
|
|||
) -> Result<BTreeMap<Identifier, SigningCommitments>, Box<dyn Error>> {
|
||||
self.endpoints = BTreeMap::new();
|
||||
let mut signing_commitments = BTreeMap::new();
|
||||
eprintln!("Waiting for participants to send their commitments...");
|
||||
for _ in 0..num_of_participants {
|
||||
let (endpoint, data) = self
|
||||
.input_rx
|
||||
|
@ -109,6 +110,7 @@ impl Comms for SocketComms {
|
|||
signing_package: &SigningPackage,
|
||||
#[cfg(feature = "redpallas")] _randomizer: frost::round2::Randomizer,
|
||||
) -> Result<BTreeMap<Identifier, SignatureShare>, Box<dyn Error>> {
|
||||
eprintln!("Sending SigningPackage to participants...");
|
||||
// Send SigningPackage to all participants
|
||||
let data = serde_json::to_vec(&Message::SigningPackage(signing_package.clone()))?;
|
||||
for identifier in signing_package.signing_commitments().keys() {
|
||||
|
@ -118,6 +120,7 @@ impl Comms for SocketComms {
|
|||
.ok_or(eyre!("unknown identifier"))?;
|
||||
self.handler.network().send(*endpoint, &data);
|
||||
}
|
||||
eprintln!("Waiting for participants to send their SignatureShares...");
|
||||
// Read SignatureShare from all participants
|
||||
let mut signature_shares = BTreeMap::new();
|
||||
for _ in 0..signing_package.signing_commitments().len() {
|
||||
|
|
|
@ -15,7 +15,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let mut logger = io::stdout();
|
||||
cli(&args, &mut reader, &mut logger).await?;
|
||||
|
||||
Ok(())
|
||||
// Force process to exit; since socket comms spawn a thread, it will keep
|
||||
// running forever. Ideally we should join() the thread but this works for
|
||||
// now.
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
// Choose participants -> send message to those participants - gen message to send
|
||||
|
|
|
@ -50,11 +50,15 @@ async fn read_commitments(
|
|||
)?;
|
||||
let pub_key_package: PublicKeyPackage = serde_json::from_str(&pub_key_package)?;
|
||||
|
||||
writeln!(logger, "The number of participants: ")?;
|
||||
let num_of_participants = if args.num_signers == 0 {
|
||||
writeln!(logger, "The number of participants: ")?;
|
||||
|
||||
let mut participants = String::new();
|
||||
input.read_line(&mut participants)?;
|
||||
let num_of_participants = participants.trim().parse::<u16>()?;
|
||||
let mut participants = String::new();
|
||||
input.read_line(&mut participants)?;
|
||||
participants.trim().parse::<u16>()?
|
||||
} else {
|
||||
args.num_signers
|
||||
};
|
||||
|
||||
let commitments_list = comms
|
||||
.get_signing_commitments(input, logger, &pub_key_package, num_of_participants)
|
||||
|
|
|
@ -7,9 +7,12 @@ use frost::{round1::SigningCommitments, Identifier, SigningPackage};
|
|||
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
fs,
|
||||
io::{BufRead, Write},
|
||||
};
|
||||
|
||||
use crate::args::Args;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct CommitmentsConfig {
|
||||
pub message: Vec<u8>,
|
||||
|
@ -17,11 +20,12 @@ pub struct CommitmentsConfig {
|
|||
}
|
||||
|
||||
pub async fn step_2(
|
||||
args: &Args,
|
||||
input: &mut impl BufRead,
|
||||
logger: &mut dyn Write,
|
||||
commitments: BTreeMap<Identifier, SigningCommitments>,
|
||||
) -> Result<SigningPackage, Box<dyn std::error::Error>> {
|
||||
let signing_package = request_message(input, logger, commitments)?;
|
||||
let signing_package = request_message(args, input, logger, commitments)?;
|
||||
print_signing_package(logger, &signing_package);
|
||||
Ok(signing_package)
|
||||
}
|
||||
|
@ -29,16 +33,21 @@ pub async fn step_2(
|
|||
// Input required:
|
||||
// 1. message
|
||||
fn request_message(
|
||||
args: &Args,
|
||||
input: &mut impl BufRead,
|
||||
logger: &mut dyn Write,
|
||||
commitments: BTreeMap<Identifier, SigningCommitments>,
|
||||
) -> Result<SigningPackage, Box<dyn std::error::Error>> {
|
||||
writeln!(logger, "The message to be signed (hex encoded)")?;
|
||||
let message = if args.message == "-" {
|
||||
writeln!(logger, "The message to be signed (hex encoded)")?;
|
||||
|
||||
let mut msg = String::new();
|
||||
input.read_line(&mut msg)?;
|
||||
let mut msg = String::new();
|
||||
input.read_line(&mut msg)?;
|
||||
|
||||
let message = hex::decode(msg.trim())?;
|
||||
hex::decode(msg.trim())?
|
||||
} else {
|
||||
fs::read(&args.message)?
|
||||
};
|
||||
|
||||
let signing_package = SigningPackage::new(commitments, &message);
|
||||
|
||||
|
|
|
@ -5,9 +5,12 @@ use reddsa::frost::redpallas as frost;
|
|||
|
||||
use frost::{Signature, SigningPackage};
|
||||
|
||||
use std::io::{BufRead, Write};
|
||||
use std::{
|
||||
fs,
|
||||
io::{BufRead, Write},
|
||||
};
|
||||
|
||||
use crate::{comms::Comms, step_1::ParticipantsConfig};
|
||||
use crate::{args::Args, comms::Comms, step_1::ParticipantsConfig};
|
||||
|
||||
#[cfg(feature = "redpallas")]
|
||||
pub fn request_randomizer(
|
||||
|
@ -27,6 +30,7 @@ pub fn request_randomizer(
|
|||
}
|
||||
|
||||
pub async fn step_3(
|
||||
args: &Args,
|
||||
comms: &mut impl Comms,
|
||||
input: &mut dyn BufRead,
|
||||
logger: &mut dyn Write,
|
||||
|
@ -44,7 +48,7 @@ pub async fn step_3(
|
|||
randomizer,
|
||||
)
|
||||
.await?;
|
||||
print_signature(logger, group_signature);
|
||||
print_signature(args, logger, group_signature)?;
|
||||
Ok(group_signature)
|
||||
}
|
||||
|
||||
|
@ -87,11 +91,20 @@ async fn request_inputs_signature_shares(
|
|||
Ok(group_signature)
|
||||
}
|
||||
|
||||
fn print_signature(logger: &mut dyn Write, group_signature: Signature) {
|
||||
writeln!(
|
||||
logger,
|
||||
"Group signature: {}",
|
||||
serde_json::to_string(&group_signature).unwrap()
|
||||
)
|
||||
.unwrap();
|
||||
fn print_signature(
|
||||
args: &Args,
|
||||
logger: &mut dyn Write,
|
||||
group_signature: Signature,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
if args.signature == "-" {
|
||||
writeln!(
|
||||
logger,
|
||||
"Group signature: {}",
|
||||
serde_json::to_string(&group_signature)?
|
||||
)?;
|
||||
} else {
|
||||
fs::write(&args.signature, group_signature.serialize())?;
|
||||
eprintln!("Raw signature written to {}", &args.signature);
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::args::Args;
|
||||
use crate::comms::cli::CLIComms;
|
||||
|
||||
#[cfg(not(feature = "sockets"))]
|
||||
use crate::comms::cli::CLIComms;
|
||||
#[cfg(feature = "sockets")]
|
||||
use crate::comms::socket::SocketComms;
|
||||
|
||||
|
|
|
@ -15,5 +15,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let mut logger = io::stdout();
|
||||
cli(&args, &mut reader, &mut logger).await?;
|
||||
|
||||
Ok(())
|
||||
// Force process to exit; since socket comms spawn a thread, it will keep
|
||||
// running forever. Ideally we should join() the thread but this works for
|
||||
// now.
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,12 @@ async fn trusted_dealer_journey() {
|
|||
let mut buf = BufWriter::new(Vec::new());
|
||||
let mut rng = thread_rng();
|
||||
|
||||
let coordinator_args = CoordinatorArgs::default();
|
||||
let coordinator_args = CoordinatorArgs {
|
||||
public_key_package: "-".to_string(),
|
||||
signature: "-".to_string(),
|
||||
message: "-".to_string(),
|
||||
..Default::default()
|
||||
};
|
||||
let mut coordinator_comms = CoordinatorCLIComms {};
|
||||
|
||||
// For a CLI test we can use the same CLIComms instance
|
||||
|
@ -132,6 +137,7 @@ async fn trusted_dealer_journey() {
|
|||
let step_2_input = format!("{}\n", message);
|
||||
|
||||
let signing_package = coordinator::step_2::step_2(
|
||||
&coordinator_args,
|
||||
&mut step_2_input.as_bytes(),
|
||||
&mut buf,
|
||||
commitments_map.clone(),
|
||||
|
@ -172,6 +178,7 @@ async fn trusted_dealer_journey() {
|
|||
serde_json::to_string(&signature_shares[&participant_id_3]).unwrap()
|
||||
);
|
||||
let group_signature = coordinator::step_3::step_3(
|
||||
&coordinator_args,
|
||||
&mut coordinator_comms,
|
||||
&mut step_3_input.as_bytes(),
|
||||
&mut buf,
|
||||
|
|
Loading…
Reference in New Issue