Skip to content

Commit

Permalink
added ProcessedArgs
Browse files Browse the repository at this point in the history
  • Loading branch information
conradoplg committed Aug 9, 2024
1 parent fdf5104 commit 65020ae
Show file tree
Hide file tree
Showing 8 changed files with 269 additions and 210 deletions.
177 changes: 170 additions & 7 deletions coordinator/src/args.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
use std::{
env,
error::Error,
fs,
io::{BufRead, Write},
};

use clap::Parser;
use eyre::eyre;

use frost_core::{keys::PublicKeyPackage, Ciphersuite};
use frost_rerandomized::Randomizer;

use crate::input::read_from_file_or_stdin;

#[derive(Clone, Parser, Debug, Default)]
#[command(author, version, about, long_about = None)]
Expand Down Expand Up @@ -43,16 +56,18 @@ pub struct Args {
pub public_key_package: String,

/// The messages to sign. Each instance can be a file with the raw message,
/// or "". If "" is specified, then it will be read from standard input as a
/// hex string.
/// "" or "-". If "" or "-" is specified, then it will be read from standard
/// input as a hex string. If none are passed, a single one will be read
/// from standard input.
#[arg(short = 'm', long)]
pub message: Vec<String>,

/// The randomizer to use. Can be a file with the raw randomizer, empty, or
/// "-". If empty, a random one will be generated. If "-" is specified, then
/// it will be read from standard input as a hex string.
#[arg(short = 'r', long, default_value = "")]
pub randomizer: String,
/// The randomizers to use. Each instance can be a file with the raw
/// randomizer, "" or "-". If empty or "-" it will be read from standard
/// input as a hex string. If none are passed, random ones will be
/// generated.
#[arg(short = 'r', long)]
pub randomizer: Vec<String>,

/// Where to write the generated raw bytes signature. If "-", the
/// human-readable hex-string is printed to stdout.
Expand All @@ -67,3 +82,151 @@ pub struct Args {
#[arg(short, long, default_value_t = 2744)]
pub port: u16,
}

#[derive(Clone, Debug)]
pub struct ProcessedArgs<C: Ciphersuite> {
pub ciphersuite: String,

/// CLI mode. If enabled, it will prompt for inputs from stdin
/// and print values to stdout, ignoring other flags.
/// If false, socket communication is enabled.
pub cli: bool,

/// HTTP mode. If enabled, it will use HTTP communication with a
/// FROST server.
pub http: bool,

/// The username to use in HTTP mode.
pub username: String,

/// The (actual) password to use in HTTP mode.
pub password: String,

/// The comma-separated usernames of the signers to use in HTTP mode.
/// If HTTP mode is enabled and this is empty, then the session ID
/// will be printed and will have to be shared manually.
pub signers: Vec<String>,

/// The number of participants.
pub num_signers: u16,

/// Public key package to use.
pub public_key_package: PublicKeyPackage<C>,

/// The messages to sign.
pub messages: Vec<Vec<u8>>,

/// The randomizers to use.
pub randomizers: Vec<Randomizer<C>>,

/// Where to write the generated raw bytes signature. If "-", the
/// human-readable hex-string is printed to stdout.
pub signature: String,

/// IP to bind to, if using online comms
pub ip: String,

/// Port to bind to, if using online comms
pub port: u16,
}

impl<C: Ciphersuite + 'static> ProcessedArgs<C> {
pub fn new(
args: &Args,
input: &mut dyn BufRead,
logger: &mut dyn Write,
) -> Result<Self, Box<dyn Error>> {
let password = if args.http {
env::var(&args.password).map_err(|_| eyre!("The password argument must specify the name of a environment variable containing the password"))?
} else {
String::new()
};

let num_signers = if !args.signers.is_empty() {
args.signers.len() as u16
} else if args.num_signers == 0 {
writeln!(logger, "The number of participants: ")?;

let mut participants = String::new();
input.read_line(&mut participants)?;
participants.trim().parse::<u16>()?
} else {
args.num_signers
};

let out = read_from_file_or_stdin(
input,
logger,
"public key package",
&args.public_key_package,
)?;

let public_key_package: PublicKeyPackage<C> = serde_json::from_str(&out)?;

let messages = if args.message.is_empty() {
writeln!(logger, "The message to be signed (hex encoded)")?;
let mut msg = String::new();
input.read_line(&mut msg)?;
vec![hex::decode(msg.trim())?]
} else {
args.message
.iter()
.map(|filename| {
let msg = if filename == "-" || filename.is_empty() {
writeln!(logger, "The message to be signed (hex encoded)")?;
let mut msg = String::new();
input.read_line(&mut msg)?;
hex::decode(msg.trim())?
} else {
eprintln!("Reading message from {}...", &filename);
fs::read(filename)?
};
Ok(msg)
})
.collect::<Result<_, Box<dyn Error>>>()?
};

println!("Processing randomizer {:?}", args.randomizer);
let randomizers = if args.ciphersuite == "redpallas" {
if args.randomizer.is_empty() {
Vec::new()
} else {
args.randomizer
.iter()
.map(|filename| {
let randomizer = if filename == "-" || filename.is_empty() {
writeln!(logger, "Enter the randomizer (hex string):")?;
let mut randomizer = String::new();
input.read_line(&mut randomizer)?;
let bytes = hex::decode(randomizer.trim())?;
frost_rerandomized::Randomizer::deserialize(&bytes)?
} else {
eprintln!("Reading randomizer from {}...", &filename);
let bytes = fs::read(filename)?;
frost_rerandomized::Randomizer::deserialize(&bytes)?
};
Ok(randomizer)
})
.collect::<Result<_, Box<dyn Error>>>()?
}
} else {
Vec::new()
};

Ok(ProcessedArgs {
ciphersuite: args.ciphersuite.clone(),
cli: args.cli,
http: args.http,
username: args.username.clone(),
password,
signers: args.signers.clone(),
num_signers,
public_key_package,
messages,
randomizers,
signature: args.signature.clone(),
ip: args.ip.clone(),
port: args.port,
})
}
}
24 changes: 7 additions & 17 deletions coordinator/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,60 +3,50 @@ use std::io::{BufRead, Write};
use frost_rerandomized::RandomizedCiphersuite;

use crate::args::Args;
use crate::args::ProcessedArgs;
use crate::comms::cli::CLIComms;
use crate::comms::http::HTTPComms;
use crate::comms::socket::SocketComms;
use crate::comms::Comms;
use crate::step_1::step_1;
use crate::step_2::step_2;
use crate::step_3::request_randomizer;
use crate::step_3::step_3;

pub async fn cli<C: RandomizedCiphersuite + 'static>(
args: &Args,
reader: &mut impl BufRead,
logger: &mut impl Write,
) -> Result<(), Box<dyn std::error::Error>> {
let pargs = ProcessedArgs::<C>::new(args, reader, logger)?;

writeln!(logger, "\n=== STEP 1: CHOOSE PARTICIPANTS ===\n")?;

let mut comms: Box<dyn Comms<C>> = if args.cli {
Box::new(CLIComms::new())
} else if args.http {
Box::new(HTTPComms::new(args)?)
Box::new(HTTPComms::new(&pargs)?)
} else {
Box::new(SocketComms::new(args))
};

let participants_config = step_1(args, &mut *comms, reader, logger).await?;
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(
args,
reader,
logger,
participants_config.commitments.clone(),
)?;

let randomizer = if args.ciphersuite == "redpallas" {
Some(request_randomizer(args, reader, logger, &signing_package)?)
} else {
None
};
let signing_package = step_2(&pargs, logger, participants_config.commitments.clone())?;

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

step_3(
args,
&pargs,
&mut *comms,
reader,
logger,
participants_config,
&signing_package,
randomizer,
)
.await?;

Expand Down
Loading

0 comments on commit 65020ae

Please sign in to comment.