Skip to content

Commit

Permalink
add frost-client {coordinator,participant} (#328)
Browse files Browse the repository at this point in the history
  • Loading branch information
conradoplg authored Oct 24, 2024
1 parent cecd4e7 commit 3338161
Show file tree
Hide file tree
Showing 24 changed files with 578 additions and 161 deletions.
67 changes: 33 additions & 34 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion coordinator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ eyre = "0.6.12"
frost-core = { version = "2.0.0-rc.0", features = ["serde"] }
frost-rerandomized = { version = "2.0.0-rc.0", features = ["serde"] }
frost-ed25519 = { version = "2.0.0-rc.0", features = ["serde"] }
reddsa = { git = "https://github.com/ZcashFoundation/reddsa.git", rev = "4d8c4bb337231e6e89117334d7c61dada589a953", features = ["frost", "serde"] }
reddsa = { git = "https://github.com/ZcashFoundation/reddsa.git", rev = "ed49e9ca0699a6450f6d4a9fe62ff168f5ea1ead", features = ["frost", "serde"] }
hex = { version = "0.4", features = ["serde"] }
thiserror = "1.0"
rand = "0.8"
Expand All @@ -25,6 +25,7 @@ reqwest = { version = "0.12.8", features = ["json"] }
server = { path = "../server" }
tokio = { version = "1", features = ["full"] }
message-io = "0.18"
rpassword = "7.3.1"

[features]
default = []
141 changes: 86 additions & 55 deletions coordinator/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,19 @@ pub struct Args {
#[arg(short = 's', long, default_value = "")]
pub signature: String,

/// IP to bind to, if using online comms
/// IP to bind to, if using socket comms.
/// IP to connect to, if using HTTP mode.
#[arg(short, long, default_value = "0.0.0.0")]
pub ip: String,

/// Port to bind to, if using online comms
/// Port to bind to, if using socket comms.
/// Port to connect to, if using HTTP mode.
#[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.
Expand All @@ -104,6 +104,10 @@ pub struct ProcessedArgs<C: Ciphersuite> {
/// The (actual) password to use in HTTP mode.
pub password: String,

/// The authentication token to use in HTTP mode; if not specified
/// it will login with `password`
pub authentication_token: Option<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.
Expand All @@ -125,10 +129,12 @@ pub struct ProcessedArgs<C: Ciphersuite> {
/// human-readable hex-string is printed to stdout.
pub signature: String,

/// IP to bind to, if using online comms
/// IP to bind to, if using socket comms.
/// IP to connect to, if using HTTP mode.
pub ip: String,

/// Port to bind to, if using online comms
/// Port to bind to, if using socket comms.
/// Port to connect to, if using HTTP mode.
pub port: u16,
}

Expand All @@ -142,7 +148,7 @@ impl<C: Ciphersuite + 'static> ProcessedArgs<C> {
output: &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"))?
read_password(&args.password)?
} else {
String::new()
};
Expand All @@ -168,58 +174,12 @@ impl<C: Ciphersuite + 'static> ProcessedArgs<C> {

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

let messages = if args.message.is_empty() {
writeln!(output, "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!(output, "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>>>()?
};
let messages = read_messages(&args.message, output, input)?;

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!(output, "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()
};
let randomizers = read_randomizers(&args.randomizer, output, input)?;

Ok(ProcessedArgs {
ciphersuite: args.ciphersuite.clone(),
cli: args.cli,
http: args.http,
username: args.username.clone(),
Expand All @@ -232,6 +192,77 @@ impl<C: Ciphersuite + 'static> ProcessedArgs<C> {
signature: args.signature.clone(),
ip: args.ip.clone(),
port: args.port,
authentication_token: None,
})
}
}

pub fn read_password(password_env_name: &str) -> Result<String, Box<dyn Error>> {
if password_env_name.is_empty() {
Ok(
rpassword::prompt_password("Password: ")
.map_err(|_| eyre!("Error reading password"))?,
)
} else {
Ok(env::var(password_env_name).map_err(|_| eyre!("The password argument must specify the name of a environment variable containing the password"))?)
}
}

pub fn read_messages(
message_paths: &[String],
output: &mut dyn Write,
input: &mut dyn BufRead,
) -> Result<Vec<Vec<u8>>, Box<dyn Error>> {
let messages = if message_paths.is_empty() {
writeln!(output, "The message to be signed (hex encoded)")?;
let mut msg = String::new();
input.read_line(&mut msg)?;
vec![hex::decode(msg.trim())?]
} else {
message_paths
.iter()
.map(|filename| {
let msg = if *filename == "-" || filename.is_empty() {
writeln!(output, "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>>>()?
};
Ok(messages)
}

pub fn read_randomizers<C: Ciphersuite + 'static>(
randomizer_paths: &[String],
output: &mut dyn Write,
input: &mut dyn BufRead,
) -> Result<Vec<Randomizer<C>>, Box<dyn Error>> {
let randomizers = if randomizer_paths.is_empty() {
Vec::new()
} else {
randomizer_paths
.iter()
.map(|filename| {
let randomizer = if filename == "-" || filename.is_empty() {
writeln!(output, "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>>>()?
};
Ok(randomizers)
}
Loading

0 comments on commit 3338161

Please sign in to comment.