Phase 2: add coordinator (#157)
* phase 2: add coordinator * completed, but untested * fix bug * make it work for both ciphersuites * allow generating fresh randomizer * remove test for now
This commit is contained in:
parent
07ea1a1f66
commit
0ecf022bd9
|
@ -408,7 +408,9 @@ dependencies = [
|
||||||
"message-io",
|
"message-io",
|
||||||
"rand",
|
"rand",
|
||||||
"reddsa",
|
"reddsa",
|
||||||
|
"reqwest",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"server",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
@ -1891,10 +1893,13 @@ dependencies = [
|
||||||
"axum",
|
"axum",
|
||||||
"axum-test",
|
"axum-test",
|
||||||
"clap",
|
"clap",
|
||||||
|
"coordinator",
|
||||||
"derivative",
|
"derivative",
|
||||||
"eyre",
|
"eyre",
|
||||||
|
"frost-ed25519",
|
||||||
"rand",
|
"rand",
|
||||||
"reddsa",
|
"reddsa",
|
||||||
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|
|
@ -17,9 +17,11 @@ serde_json = "1.0"
|
||||||
itertools = "0.12.1"
|
itertools = "0.12.1"
|
||||||
exitcode = "1.1.2"
|
exitcode = "1.1.2"
|
||||||
clap = { version = "4.5.2", features = ["derive"] }
|
clap = { version = "4.5.2", features = ["derive"] }
|
||||||
|
reqwest = { version = "0.11.23", features = ["json"] }
|
||||||
|
server = { path = "../server" }
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
message-io = "0.18"
|
message-io = "0.18"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
redpallas = []
|
redpallas = ["server/redpallas"]
|
||||||
default = []
|
default = []
|
||||||
|
|
|
@ -9,6 +9,11 @@ pub struct Args {
|
||||||
#[arg(long, default_value_t = false)]
|
#[arg(long, default_value_t = false)]
|
||||||
pub cli: bool,
|
pub cli: bool,
|
||||||
|
|
||||||
|
/// HTTP mode. If enabled, it will use HTTP communication with a
|
||||||
|
/// FROST server.
|
||||||
|
#[arg(long, default_value_t = false)]
|
||||||
|
pub http: bool,
|
||||||
|
|
||||||
/// The number of participants. If 0, will prompt for a value.
|
/// The number of participants. If 0, will prompt for a value.
|
||||||
#[arg(short = 'n', long, default_value_t = 0)]
|
#[arg(short = 'n', long, default_value_t = 0)]
|
||||||
pub num_signers: u16,
|
pub num_signers: u16,
|
||||||
|
@ -24,8 +29,9 @@ pub struct Args {
|
||||||
#[arg(short = 'm', long, default_value = "")]
|
#[arg(short = 'm', long, default_value = "")]
|
||||||
pub message: String,
|
pub message: String,
|
||||||
|
|
||||||
/// The randomizer to use. Can be a file with the raw randomizer, or "-". If "-"
|
/// The randomizer to use. Can be a file with the raw randomizer, empty, or
|
||||||
/// is specified, then it will be read from standard input as a hex string.
|
/// "-". If empty, a random one will be generated. If "-" is specified, then
|
||||||
|
/// it will be read from standard input as a hex string.
|
||||||
#[cfg(feature = "redpallas")]
|
#[cfg(feature = "redpallas")]
|
||||||
#[arg(short = 'r', long, default_value = "")]
|
#[arg(short = 'r', long, default_value = "")]
|
||||||
pub randomizer: String,
|
pub randomizer: String,
|
||||||
|
|
|
@ -2,6 +2,7 @@ use std::io::{BufRead, Write};
|
||||||
|
|
||||||
use crate::args::Args;
|
use crate::args::Args;
|
||||||
use crate::comms::cli::CLIComms;
|
use crate::comms::cli::CLIComms;
|
||||||
|
use crate::comms::http::HTTPComms;
|
||||||
use crate::comms::socket::SocketComms;
|
use crate::comms::socket::SocketComms;
|
||||||
use crate::comms::Comms;
|
use crate::comms::Comms;
|
||||||
use crate::step_1::step_1;
|
use crate::step_1::step_1;
|
||||||
|
@ -20,6 +21,8 @@ pub async fn cli(
|
||||||
|
|
||||||
let mut comms: Box<dyn Comms> = if args.cli {
|
let mut comms: Box<dyn Comms> = if args.cli {
|
||||||
Box::new(CLIComms {})
|
Box::new(CLIComms {})
|
||||||
|
} else if args.http {
|
||||||
|
Box::new(HTTPComms::new(args))
|
||||||
} else {
|
} else {
|
||||||
Box::new(SocketComms::new(args))
|
Box::new(SocketComms::new(args))
|
||||||
};
|
};
|
||||||
|
@ -39,7 +42,7 @@ pub async fn cli(
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
#[cfg(feature = "redpallas")]
|
#[cfg(feature = "redpallas")]
|
||||||
let randomizer = request_randomizer(args, reader, logger)?;
|
let randomizer = request_randomizer(args, reader, logger, &signing_package)?;
|
||||||
|
|
||||||
writeln!(logger, "=== STEP 3: BUILD GROUP SIGNATURE ===\n")?;
|
writeln!(logger, "=== STEP 3: BUILD GROUP SIGNATURE ===\n")?;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod cli;
|
pub mod cli;
|
||||||
|
pub mod http;
|
||||||
pub mod socket;
|
pub mod socket;
|
||||||
|
|
||||||
#[cfg(not(feature = "redpallas"))]
|
#[cfg(not(feature = "redpallas"))]
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
//! HTTP implementation of the Comms trait.
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "redpallas"))]
|
||||||
|
use frost_ed25519 as frost;
|
||||||
|
#[cfg(feature = "redpallas")]
|
||||||
|
use reddsa::frost::redpallas as frost;
|
||||||
|
|
||||||
|
use eyre::eyre;
|
||||||
|
use server::Uuid;
|
||||||
|
|
||||||
|
use frost::{
|
||||||
|
keys::PublicKeyPackage, round1::SigningCommitments, round2::SignatureShare, Identifier,
|
||||||
|
SigningPackage,
|
||||||
|
};
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
collections::BTreeMap,
|
||||||
|
error::Error,
|
||||||
|
io::{BufRead, Write},
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::Comms;
|
||||||
|
use crate::args::Args;
|
||||||
|
|
||||||
|
pub struct HTTPComms {
|
||||||
|
client: reqwest::Client,
|
||||||
|
host_port: String,
|
||||||
|
session_id: Option<Uuid>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTTPComms {
|
||||||
|
pub fn new(args: &Args) -> Self {
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
Self {
|
||||||
|
client,
|
||||||
|
host_port: format!("http://{}:{}", args.ip, args.port),
|
||||||
|
session_id: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
impl Comms for HTTPComms {
|
||||||
|
async fn get_signing_commitments(
|
||||||
|
&mut self,
|
||||||
|
_input: &mut dyn BufRead,
|
||||||
|
_output: &mut dyn Write,
|
||||||
|
_pub_key_package: &PublicKeyPackage,
|
||||||
|
num_signers: u16,
|
||||||
|
) -> Result<BTreeMap<Identifier, SigningCommitments>, Box<dyn Error>> {
|
||||||
|
let r = self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/create_new_session", self.host_port))
|
||||||
|
.json(&server::CreateNewSessionArgs {
|
||||||
|
num_signers,
|
||||||
|
message_count: 1,
|
||||||
|
})
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.json::<server::CreateNewSessionOutput>()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
eprintln!(
|
||||||
|
"Send the following session ID to participants: {}",
|
||||||
|
r.session_id
|
||||||
|
);
|
||||||
|
self.session_id = Some(r.session_id);
|
||||||
|
eprint!("Waiting for participants to send their commitments...");
|
||||||
|
|
||||||
|
let r = loop {
|
||||||
|
let r = self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/get_commitments", self.host_port))
|
||||||
|
.json(&server::GetCommitmentsArgs {
|
||||||
|
session_id: r.session_id,
|
||||||
|
})
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
if r.status() != 200 {
|
||||||
|
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||||
|
eprint!(".");
|
||||||
|
} else {
|
||||||
|
break r.json::<server::GetCommitmentsOutput>().await?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
eprintln!();
|
||||||
|
|
||||||
|
Ok(r.commitments
|
||||||
|
.first()
|
||||||
|
.ok_or(eyre!("empty commitments"))
|
||||||
|
.cloned()?)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_signature_shares(
|
||||||
|
&mut self,
|
||||||
|
_input: &mut dyn BufRead,
|
||||||
|
_output: &mut dyn Write,
|
||||||
|
signing_package: &SigningPackage,
|
||||||
|
#[cfg(feature = "redpallas")] randomizer: frost::round2::Randomizer,
|
||||||
|
) -> Result<BTreeMap<Identifier, SignatureShare>, Box<dyn Error>> {
|
||||||
|
// Send SigningPackage to all participants
|
||||||
|
eprintln!("Sending SigningPackage to participants...");
|
||||||
|
|
||||||
|
let _r = self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/send_signing_package", self.host_port))
|
||||||
|
.json(&server::SendSigningPackageArgs {
|
||||||
|
aux_msg: Default::default(),
|
||||||
|
session_id: self.session_id.unwrap(),
|
||||||
|
signing_package: vec![signing_package.clone()],
|
||||||
|
#[cfg(feature = "redpallas")]
|
||||||
|
randomizer: vec![randomizer],
|
||||||
|
})
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.bytes()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
eprintln!("Waiting for participants to send their SignatureShares...");
|
||||||
|
|
||||||
|
let r = loop {
|
||||||
|
let r = self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/get_signature_shares", self.host_port))
|
||||||
|
.json(&server::GetSignatureSharesArgs {
|
||||||
|
session_id: self.session_id.unwrap(),
|
||||||
|
})
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
if r.status() != 200 {
|
||||||
|
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||||
|
eprint!(".");
|
||||||
|
} else {
|
||||||
|
break r.json::<server::GetSignatureSharesOutput>().await?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
eprintln!();
|
||||||
|
|
||||||
|
Ok(r.signature_shares
|
||||||
|
.first()
|
||||||
|
.ok_or(eyre!("empty signature shares"))?
|
||||||
|
.clone())
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,7 +17,12 @@ pub fn request_randomizer(
|
||||||
args: &Args,
|
args: &Args,
|
||||||
input: &mut impl BufRead,
|
input: &mut impl BufRead,
|
||||||
logger: &mut dyn Write,
|
logger: &mut dyn Write,
|
||||||
|
signing_package: &SigningPackage,
|
||||||
) -> Result<frost::round2::Randomizer, Box<dyn std::error::Error>> {
|
) -> Result<frost::round2::Randomizer, Box<dyn std::error::Error>> {
|
||||||
|
if args.randomizer.is_empty() {
|
||||||
|
let rng = rand::thread_rng();
|
||||||
|
return Ok(frost::round2::Randomizer::new(rng, signing_package)?);
|
||||||
|
};
|
||||||
let randomizer = if args.randomizer == "-" {
|
let randomizer = if args.randomizer == "-" {
|
||||||
writeln!(logger, "Enter the randomizer (hex string):")?;
|
writeln!(logger, "Enter the randomizer (hex string):")?;
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ axum = "0.7.3"
|
||||||
clap = { version = "4.5.2", features = ["derive"] }
|
clap = { version = "4.5.2", features = ["derive"] }
|
||||||
derivative = "2.2.0"
|
derivative = "2.2.0"
|
||||||
eyre = "0.6.11"
|
eyre = "0.6.11"
|
||||||
|
frost-ed25519 = { version = "1.0.0-rc.0", features = ["serde"] }
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
reddsa = { git = "https://github.com/ZcashFoundation/reddsa.git", rev = "81c649c412e5b6ba56d491d2857f91fbd28adbc7", features = [
|
reddsa = { git = "https://github.com/ZcashFoundation/reddsa.git", rev = "81c649c412e5b6ba56d491d2857f91fbd28adbc7", features = [
|
||||||
"frost",
|
"frost",
|
||||||
|
@ -24,5 +25,11 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
uuid = { version = "1.6.1", features = ["v4", "fast-rng", "serde"] }
|
uuid = { version = "1.6.1", features = ["v4", "fast-rng", "serde"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
axum-test = "14.4.0"
|
axum-test = "14.2.2"
|
||||||
reqwest = { version = "0.11.26", features = ["json"] }
|
coordinator = { path = "../coordinator" }
|
||||||
|
reqwest = { version = "0.11.26", features = ["json"] }
|
||||||
|
regex = "1.10.3"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
redpallas = ["coordinator/redpallas"]
|
||||||
|
default = []
|
||||||
|
|
|
@ -158,9 +158,14 @@ pub(crate) async fn send_signing_package(
|
||||||
|
|
||||||
match &mut session.state {
|
match &mut session.state {
|
||||||
SessionState::CommitmentsReady { commitments } => {
|
SessionState::CommitmentsReady { commitments } => {
|
||||||
if args.signing_package.len() != session.message_count as usize
|
if args.signing_package.len() != session.message_count as usize {
|
||||||
|| args.randomizer.len() != session.message_count as usize
|
return Err(AppError(
|
||||||
{
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
eyre!("wrong number of inputs"),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
#[cfg(feature = "redpallas")]
|
||||||
|
if args.randomizer.len() != session.message_count as usize {
|
||||||
return Err(AppError(
|
return Err(AppError(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
eyre!("wrong number of inputs"),
|
eyre!("wrong number of inputs"),
|
||||||
|
@ -170,6 +175,7 @@ pub(crate) async fn send_signing_package(
|
||||||
identifiers: commitments.keys().cloned().collect(),
|
identifiers: commitments.keys().cloned().collect(),
|
||||||
signing_package: args.signing_package,
|
signing_package: args.signing_package,
|
||||||
signature_shares: Default::default(),
|
signature_shares: Default::default(),
|
||||||
|
#[cfg(feature = "redpallas")]
|
||||||
randomizer: args.randomizer,
|
randomizer: args.randomizer,
|
||||||
aux_msg: args.aux_msg,
|
aux_msg: args.aux_msg,
|
||||||
};
|
};
|
||||||
|
@ -202,10 +208,12 @@ pub(crate) async fn get_signing_package(
|
||||||
identifiers: _,
|
identifiers: _,
|
||||||
signing_package,
|
signing_package,
|
||||||
signature_shares: _,
|
signature_shares: _,
|
||||||
|
#[cfg(feature = "redpallas")]
|
||||||
randomizer,
|
randomizer,
|
||||||
aux_msg,
|
aux_msg,
|
||||||
} => Ok(Json(GetSigningPackageOutput {
|
} => Ok(Json(GetSigningPackageOutput {
|
||||||
signing_package: signing_package.clone(),
|
signing_package: signing_package.clone(),
|
||||||
|
#[cfg(feature = "redpallas")]
|
||||||
randomizer: randomizer.clone(),
|
randomizer: randomizer.clone(),
|
||||||
aux_msg: aux_msg.clone(),
|
aux_msg: aux_msg.clone(),
|
||||||
})),
|
})),
|
||||||
|
@ -238,7 +246,8 @@ pub(crate) async fn send_signature_share(
|
||||||
identifiers,
|
identifiers,
|
||||||
signing_package: _,
|
signing_package: _,
|
||||||
signature_shares,
|
signature_shares,
|
||||||
randomizer: _,
|
#[cfg(feature = "redpallas")]
|
||||||
|
randomizer: _,
|
||||||
aux_msg: _,
|
aux_msg: _,
|
||||||
} => {
|
} => {
|
||||||
if !identifiers.contains(&args.identifier) {
|
if !identifiers.contains(&args.identifier) {
|
||||||
|
|
|
@ -3,10 +3,13 @@ use std::{
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
use uuid::Uuid;
|
#[cfg(not(feature = "redpallas"))]
|
||||||
|
use frost_ed25519 as frost;
|
||||||
|
#[cfg(feature = "redpallas")]
|
||||||
use reddsa::frost::redpallas as frost;
|
use reddsa::frost::redpallas as frost;
|
||||||
|
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
/// The current state of the server, and the required data for the state.
|
/// The current state of the server, and the required data for the state.
|
||||||
#[derive(derivative::Derivative)]
|
#[derive(derivative::Derivative)]
|
||||||
#[derivative(Debug)]
|
#[derivative(Debug)]
|
||||||
|
@ -35,7 +38,8 @@ pub enum SessionState {
|
||||||
/// Randomizer sent by coordinator to be sent to participants, for each
|
/// Randomizer sent by coordinator to be sent to participants, for each
|
||||||
/// message being signed.
|
/// message being signed.
|
||||||
/// (Rerandomized FROST only. TODO: make it optional?)
|
/// (Rerandomized FROST only. TODO: make it optional?)
|
||||||
#[derivative(Debug = "ignore")]
|
#[cfg(feature = "redpallas")]
|
||||||
|
#[cfg_attr(feature = "redpallas", derivative(Debug = "ignore"))]
|
||||||
randomizer: Vec<frost::round2::Randomizer>,
|
randomizer: Vec<frost::round2::Randomizer>,
|
||||||
/// Auxiliary (optional) message. A context-specific data that is
|
/// Auxiliary (optional) message. A context-specific data that is
|
||||||
/// supposed to be interpreted by the participants.
|
/// supposed to be interpreted by the participants.
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use uuid::Uuid;
|
pub use uuid::Uuid;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "redpallas"))]
|
||||||
|
use frost_ed25519 as frost;
|
||||||
|
#[cfg(feature = "redpallas")]
|
||||||
use reddsa::frost::redpallas as frost;
|
use reddsa::frost::redpallas as frost;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
@ -50,7 +53,8 @@ pub struct SendSigningPackageArgs {
|
||||||
pub session_id: Uuid,
|
pub session_id: Uuid,
|
||||||
pub signing_package: Vec<frost::SigningPackage>,
|
pub signing_package: Vec<frost::SigningPackage>,
|
||||||
pub aux_msg: Vec<u8>,
|
pub aux_msg: Vec<u8>,
|
||||||
#[derivative(Debug = "ignore")]
|
#[cfg(feature = "redpallas")]
|
||||||
|
#[cfg_attr(feature = "redpallas", derivative(Debug = "ignore"))]
|
||||||
pub randomizer: Vec<frost::round2::Randomizer>,
|
pub randomizer: Vec<frost::round2::Randomizer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +67,8 @@ pub struct GetSigningPackageArgs {
|
||||||
#[derivative(Debug)]
|
#[derivative(Debug)]
|
||||||
pub struct GetSigningPackageOutput {
|
pub struct GetSigningPackageOutput {
|
||||||
pub signing_package: Vec<frost::SigningPackage>,
|
pub signing_package: Vec<frost::SigningPackage>,
|
||||||
#[derivative(Debug = "ignore")]
|
#[cfg(feature = "redpallas")]
|
||||||
|
#[cfg_attr(feature = "redpallas", derivative(Debug = "ignore"))]
|
||||||
pub randomizer: Vec<frost::round2::Randomizer>,
|
pub randomizer: Vec<frost::round2::Randomizer>,
|
||||||
pub aux_msg: Vec<u8>,
|
pub aux_msg: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,9 @@ use axum_test::TestServer;
|
||||||
use rand::thread_rng;
|
use rand::thread_rng;
|
||||||
use server::{args::Args, router};
|
use server::{args::Args, router};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "redpallas"))]
|
||||||
|
use frost_ed25519 as frost;
|
||||||
|
#[cfg(feature = "redpallas")]
|
||||||
use reddsa::frost::redpallas as frost;
|
use reddsa::frost::redpallas as frost;
|
||||||
|
|
||||||
/// Test the entire FROST signing flow using axum_test.
|
/// Test the entire FROST signing flow using axum_test.
|
||||||
|
@ -110,6 +113,7 @@ async fn test_main_router() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, msg)| frost::SigningPackage::new(commitments[i].clone(), msg))
|
.map(|(i, msg)| frost::SigningPackage::new(commitments[i].clone(), msg))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
#[cfg(feature = "redpallas")]
|
||||||
let randomized_params = signing_packages
|
let randomized_params = signing_packages
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| frost::RandomizedParams::new(pubkeys.verifying_key(), p, &mut rng))
|
.map(|p| frost::RandomizedParams::new(pubkeys.verifying_key(), p, &mut rng))
|
||||||
|
@ -121,6 +125,7 @@ async fn test_main_router() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
.json(&server::SendSigningPackageArgs {
|
.json(&server::SendSigningPackageArgs {
|
||||||
session_id,
|
session_id,
|
||||||
signing_package: signing_packages.clone(),
|
signing_package: signing_packages.clone(),
|
||||||
|
#[cfg(feature = "redpallas")]
|
||||||
randomizer: randomized_params.iter().map(|p| *p.randomizer()).collect(),
|
randomizer: randomized_params.iter().map(|p| *p.randomizer()).collect(),
|
||||||
aux_msg: aux_msg.to_owned(),
|
aux_msg: aux_msg.to_owned(),
|
||||||
})
|
})
|
||||||
|
@ -141,6 +146,7 @@ async fn test_main_router() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let r: server::GetSigningPackageOutput = res.json();
|
let r: server::GetSigningPackageOutput = res.json();
|
||||||
|
|
||||||
// Generate SignatureShares for each SigningPackage
|
// Generate SignatureShares for each SigningPackage
|
||||||
|
#[cfg(feature = "redpallas")]
|
||||||
let signature_share = r
|
let signature_share = r
|
||||||
.signing_package
|
.signing_package
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -156,6 +162,16 @@ async fn test_main_router() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "redpallas"))]
|
||||||
|
let signature_share = r
|
||||||
|
.signing_package
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, signing_package)| {
|
||||||
|
frost::round2::sign(signing_package, &nonces_map[identifier][i], key_package)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
// Send SignatureShares to the server
|
// Send SignatureShares to the server
|
||||||
let res = server
|
let res = server
|
||||||
.post("/send_signature_share")
|
.post("/send_signature_share")
|
||||||
|
@ -177,11 +193,18 @@ async fn test_main_router() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let r: server::GetSignatureSharesOutput = res.json();
|
let r: server::GetSignatureSharesOutput = res.json();
|
||||||
|
|
||||||
// Generate the final Signature for each message
|
// Generate the final Signature for each message
|
||||||
|
#[cfg(feature = "redpallas")]
|
||||||
let signatures = signing_packages
|
let signatures = signing_packages
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, p)| frost::aggregate(p, &r.signature_shares[i], &pubkeys, &randomized_params[i]))
|
.map(|(i, p)| frost::aggregate(p, &r.signature_shares[i], &pubkeys, &randomized_params[i]))
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
#[cfg(not(feature = "redpallas"))]
|
||||||
|
let signatures = signing_packages
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, p)| frost::aggregate(p, &r.signature_shares[i], &pubkeys))
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
// Close the session
|
// Close the session
|
||||||
let res = server
|
let res = server
|
||||||
|
@ -191,10 +214,15 @@ async fn test_main_router() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
res.assert_status_ok();
|
res.assert_status_ok();
|
||||||
|
|
||||||
// Verify signatures to test if they were generated correctly
|
// Verify signatures to test if they were generated correctly
|
||||||
|
#[cfg(feature = "redpallas")]
|
||||||
for (i, p) in randomized_params.iter().enumerate() {
|
for (i, p) in randomized_params.iter().enumerate() {
|
||||||
p.randomized_verifying_key()
|
p.randomized_verifying_key()
|
||||||
.verify(messages[i], &signatures[i])?;
|
.verify(messages[i], &signatures[i])?;
|
||||||
}
|
}
|
||||||
|
#[cfg(not(feature = "redpallas"))]
|
||||||
|
for (i, m) in messages.iter().enumerate() {
|
||||||
|
pubkeys.verifying_key().verify(m, &signatures[i])?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue