Skip to content

Commit

Permalink
Not FROST since removing 1-round version
Browse files Browse the repository at this point in the history
  • Loading branch information
burdges committed Jul 30, 2024
1 parent 1cfc580 commit 6829d16
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 54 deletions.
46 changes: 23 additions & 23 deletions src/olaf/frost/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ use crate::{
};

/// A result for the SimplPedPoP protocol.
pub type FROSTResult<T> = Result<T, FROSTError>;
pub type MultiSigResult<T> = Result<T, MultiSigError>;

/// An error ocurred during the execution of the SimplPedPoP protocol.
#[derive(Debug)]
pub enum FROSTError {
pub enum MultiSigError {
/// The number of signing commitments must be at least equal to the threshold.
InvalidNumberOfSigningCommitments,
/// The participant's signing commitment is missing.
Expand Down Expand Up @@ -68,7 +68,7 @@ mod tests {
},
Keypair, PublicKey,
};
use super::FROSTError;
use super::MultiSigError;

#[test]
fn test_empty_signing_packages() {
Expand All @@ -79,9 +79,9 @@ mod tests {
match result {
Ok(_) => panic!("Expected an error, but got Ok."),
Err(e) => match e {
FROSTError::EmptySigningPackages => assert!(true),
MultiSigError::EmptySigningPackages => assert!(true),
_ => {
panic!("Expected FROSTError::EmptySigningPackages, but got {:?}", e)
panic!("Expected MultiSigError::EmptySigningPackages, but got {:?}", e)
},
},
}
Expand Down Expand Up @@ -148,7 +148,7 @@ mod tests {
match result {
Ok(_) => panic!("Expected an error, but got Ok."),
Err(e) => match e {
FROSTError::InvalidSignatureShare { culprit } => {
MultiSigError::InvalidSignatureShare { culprit } => {
assert_eq!(
culprit,
vec![
Expand All @@ -157,7 +157,7 @@ mod tests {
]
);
},
_ => panic!("Expected FROSTError::InvalidSignatureShare, but got {:?}", e),
_ => panic!("Expected MultiSigError::InvalidSignatureShare, but got {:?}", e),
},
}
}
Expand Down Expand Up @@ -222,9 +222,9 @@ mod tests {
match result {
Ok(_) => panic!("Expected an error, but got Ok."),
Err(e) => match e {
FROSTError::MismatchedSignatureSharesAndSigningCommitments => assert!(true),
MultiSigError::MismatchedSignatureSharesAndSigningCommitments => assert!(true),
_ => {
panic!("Expected FROSTError::MismatchedSignatureSharesAndSigningCommitments, but got {:?}", e)
panic!("Expected MultiSigError::MismatchedSignatureSharesAndSigningCommitments, but got {:?}", e)
},
},
}
Expand Down Expand Up @@ -290,9 +290,9 @@ mod tests {
match result {
Ok(_) => panic!("Expected an error, but got Ok."),
Err(e) => match e {
FROSTError::MismatchedCommonData => assert!(true),
MultiSigError::MismatchedCommonData => assert!(true),
_ => {
panic!("Expected FROSTError::MismatchedCommonData, but got {:?}", e)
panic!("Expected MultiSigError::MismatchedCommonData, but got {:?}", e)
},
},
}
Expand Down Expand Up @@ -354,9 +354,9 @@ mod tests {
match result {
Ok(_) => panic!("Expected an error, but got Ok."),
Err(e) => match e {
FROSTError::InvalidNumberOfSigningPackages => assert!(true),
MultiSigError::InvalidNumberOfSigningPackages => assert!(true),
_ => {
panic!("Expected FROSTError::InvalidNumberOfSigningPackages, but got {:?}", e)
panic!("Expected MultiSigError::InvalidNumberOfSigningPackages, but got {:?}", e)
},
},
}
Expand Down Expand Up @@ -411,9 +411,9 @@ mod tests {
match result {
Ok(_) => panic!("Expected an error, but got Ok."),
Err(e) => match e {
FROSTError::InvalidOwnVerifyingShare => assert!(true),
MultiSigError::InvalidOwnVerifyingShare => assert!(true),
_ => {
panic!("Expected FROSTError::InvalidOwnVerifyingShare, but got {:?}", e)
panic!("Expected MultiSigError::InvalidOwnVerifyingShare, but got {:?}", e)
},
},
}
Expand Down Expand Up @@ -468,9 +468,9 @@ mod tests {
match result {
Ok(_) => panic!("Expected an error, but got Ok."),
Err(e) => match e {
FROSTError::IncorrectNumberOfVerifyingShares => assert!(true),
MultiSigError::IncorrectNumberOfVerifyingShares => assert!(true),
_ => {
panic!("Expected FROSTError::IncorrectNumberOfVerifyingShares, but got {:?}", e)
panic!("Expected MultiSigError::IncorrectNumberOfVerifyingShares, but got {:?}", e)
},
},
}
Expand Down Expand Up @@ -528,9 +528,9 @@ mod tests {
match result {
Ok(_) => panic!("Expected an error, but got Ok."),
Err(e) => match e {
FROSTError::MissingOwnSigningCommitment => assert!(true),
MultiSigError::MissingOwnSigningCommitment => assert!(true),
_ => {
panic!("Expected FROSTError::MissingOwnSigningCommitment, but got {:?}", e)
panic!("Expected MultiSigError::MissingOwnSigningCommitment, but got {:?}", e)
},
},
}
Expand Down Expand Up @@ -585,9 +585,9 @@ mod tests {
match result {
Ok(_) => panic!("Expected an error, but got Ok."),
Err(e) => match e {
FROSTError::IdentitySigningCommitment => assert!(true),
MultiSigError::IdentitySigningCommitment => assert!(true),
_ => {
panic!("Expected FROSTError::IdentitySigningCommitment, but got {:?}", e)
panic!("Expected MultiSigError::IdentitySigningCommitment, but got {:?}", e)
},
},
}
Expand Down Expand Up @@ -644,10 +644,10 @@ mod tests {
match result {
Ok(_) => panic!("Expected an error, but got Ok."),
Err(e) => match e {
FROSTError::InvalidNumberOfSigningCommitments => assert!(true),
MultiSigError::InvalidNumberOfSigningCommitments => assert!(true),
_ => {
panic!(
"Expected FROSTError::InvalidNumberOfSigningCommitments, but got {:?}",
"Expected MultiSigError::InvalidNumberOfSigningCommitments, but got {:?}",
e
)
},
Expand Down
36 changes: 21 additions & 15 deletions src/olaf/frost/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
//! Implementation of the FROST protocol (<https://eprint.iacr.org/2020/852>).
//! Two-nonce non-deterministic MultiSig
//!
//! Intentionally prohibits the dangerous precomputed nonces
//! for which FROST was designed, but otherwise similar to
//! 2-round non-deterministic MultiSig protocols like
//! FROST, MuSig2, DWMS, etc.
//! See https://eprint.iacr.org/2020/852 or others
#![allow(non_snake_case)]
#![allow(clippy::result_large_err)]
Expand All @@ -16,7 +22,7 @@ use crate::{
Signature,
};
use self::{
errors::{FROSTError, FROSTResult},
errors::{MultiSigError, MultiSigResult},
types::{BindingFactor, BindingFactorList, GroupCommitment},
};
use super::{simplpedpop::SPPOutput, Identifier, SigningKeypair, ThresholdPublicKey, VerifyingShare};
Expand Down Expand Up @@ -83,20 +89,20 @@ impl SigningKeypair {
spp_output: SPPOutput,
all_signing_commitments: Vec<SigningCommitments>,
signer_nonces: &SigningNonces,
) -> FROSTResult<SigningPackage> {
) -> MultiSigResult<SigningPackage> {
let threshold_public_key = &spp_output.threshold_public_key;
let len = all_signing_commitments.len();

if len < spp_output.parameters.threshold as usize {
return Err(FROSTError::InvalidNumberOfSigningCommitments);
return Err(MultiSigError::InvalidNumberOfSigningCommitments);
}

if spp_output.verifying_keys.len() != len {
return Err(FROSTError::IncorrectNumberOfVerifyingShares);
return Err(MultiSigError::IncorrectNumberOfVerifyingShares);
}

if !all_signing_commitments.contains(&signer_nonces.commitments) {
return Err(FROSTError::MissingOwnSigningCommitment);
return Err(MultiSigError::MissingOwnSigningCommitment);
}

let mut identifiers = Vec::new();
Expand All @@ -116,11 +122,11 @@ impl SigningKeypair {
}

if !shares.contains(&&own_verifying_share) {
return Err(FROSTError::InvalidOwnVerifyingShare);
return Err(MultiSigError::InvalidOwnVerifyingShare);
}

if all_signing_commitments.len() < spp_output.parameters.threshold as usize {
return Err(FROSTError::InvalidNumberOfSigningCommitments);
return Err(MultiSigError::InvalidNumberOfSigningCommitments);
}

let binding_factor_list: BindingFactorList = BindingFactorList::compute(
Expand Down Expand Up @@ -229,15 +235,15 @@ pub(super) fn compute_lagrange_coefficient(
/// signature, if the coordinator themselves is a signer and misbehaves, they
/// can avoid that step. However, at worst, this results in a denial of
/// service attack due to publishing an invalid signature.
pub fn aggregate(signing_packages: &[SigningPackage]) -> Result<Signature, FROSTError> {
pub fn aggregate(signing_packages: &[SigningPackage]) -> Result<Signature, MultiSigError> {
if signing_packages.is_empty() {
return Err(FROSTError::EmptySigningPackages);
return Err(MultiSigError::EmptySigningPackages);
}

let parameters = &signing_packages[0].common_data.spp_output.parameters;

if signing_packages.len() < parameters.threshold as usize {
return Err(FROSTError::InvalidNumberOfSigningPackages);
return Err(MultiSigError::InvalidNumberOfSigningPackages);
}

let common_data = &signing_packages[0].common_data;
Expand All @@ -250,14 +256,14 @@ pub fn aggregate(signing_packages: &[SigningPackage]) -> Result<Signature, FROST

for signing_package in signing_packages.iter() {
if &signing_package.common_data != common_data {
return Err(FROSTError::MismatchedCommonData);
return Err(MultiSigError::MismatchedCommonData);
}

signature_shares.push(signing_package.signer_data.signature_share.clone());
}

if signature_shares.len() != signing_commitments.len() {
return Err(FROSTError::MismatchedSignatureSharesAndSigningCommitments);
return Err(MultiSigError::MismatchedSignatureSharesAndSigningCommitments);
}

let binding_factor_list: BindingFactorList =
Expand All @@ -276,7 +282,7 @@ pub fn aggregate(signing_packages: &[SigningPackage]) -> Result<Signature, FROST
let verification_result = threshold_public_key
.0
.verify_simple(context, message, &signature)
.map_err(FROSTError::InvalidSignature);
.map_err(MultiSigError::InvalidSignature);

let identifiers: Vec<Identifier> = spp_output.verifying_keys.iter().map(|x| x.0).collect();

Expand Down Expand Up @@ -317,7 +323,7 @@ pub fn aggregate(signing_packages: &[SigningPackage]) -> Result<Signature, FROST
}
}

return Err(FROSTError::InvalidSignatureShare { culprit: invalid_shares });
return Err(MultiSigError::InvalidSignatureShare { culprit: invalid_shares });
}

Ok(signature)
Expand Down
32 changes: 16 additions & 16 deletions src/olaf/frost/types.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Types of the FROST protocol.
//! Two-nonce non-deterministic MultiSig
use alloc::vec::Vec;
use curve25519_dalek::{
Expand All @@ -17,7 +17,7 @@ use crate::{
},
scalar_from_canonical_bytes, SecretKey,
};
use super::errors::{FROSTError, FROSTResult};
use super::errors::{MultiSigError, MultiSigResult};

/// A participant's signature share, which the coordinator will aggregate with all other signer's
/// shares into the joint signature.
Expand All @@ -32,11 +32,11 @@ impl SignatureShare {
self.share.to_bytes()
}

fn from_bytes(bytes: &[u8]) -> FROSTResult<SignatureShare> {
fn from_bytes(bytes: &[u8]) -> MultiSigResult<SignatureShare> {
let mut share_bytes = [0; SCALAR_LENGTH];
share_bytes.copy_from_slice(&bytes[..SCALAR_LENGTH]);
let share = scalar_from_canonical_bytes(share_bytes)
.ok_or(FROSTError::SignatureShareDeserializationError)?;
.ok_or(MultiSigError::SignatureShareDeserializationError)?;

Ok(SignatureShare { share })
}
Expand Down Expand Up @@ -186,11 +186,11 @@ impl NonceCommitment {
}

/// Deserializes the `NonceCommitment` from bytes.
fn from_bytes(bytes: &[u8]) -> FROSTResult<NonceCommitment> {
fn from_bytes(bytes: &[u8]) -> MultiSigResult<NonceCommitment> {
let compressed = CompressedRistretto::from_slice(&bytes[..COMPRESSED_RISTRETTO_LENGTH])
.map_err(FROSTError::DeserializationError)?;
.map_err(MultiSigError::DeserializationError)?;

let point = compressed.decompress().ok_or(FROSTError::InvalidNonceCommitment)?;
let point = compressed.decompress().ok_or(MultiSigError::InvalidNonceCommitment)?;

Ok(NonceCommitment(point))
}
Expand Down Expand Up @@ -246,7 +246,7 @@ impl SigningNonces {
}

/// Deserializes SigningNonces from bytes.
pub fn from_bytes(bytes: &[u8]) -> FROSTResult<Self> {
pub fn from_bytes(bytes: &[u8]) -> MultiSigResult<Self> {
let mut cursor = 0;

let mut hiding_bytes = [0; 32];
Expand Down Expand Up @@ -311,7 +311,7 @@ impl SigningCommitments {
}

/// Deserializes SigningCommitments from bytes.
pub fn from_bytes(bytes: &[u8]) -> FROSTResult<SigningCommitments> {
pub fn from_bytes(bytes: &[u8]) -> MultiSigResult<SigningCommitments> {
let hiding = NonceCommitment::from_bytes(&bytes[..COMPRESSED_RISTRETTO_LENGTH])?;
let binding = NonceCommitment::from_bytes(&bytes[COMPRESSED_RISTRETTO_LENGTH..])?;

Expand Down Expand Up @@ -362,7 +362,7 @@ impl CommonData {
}

/// Deserializes CommonData from bytes.
fn from_bytes(bytes: &[u8]) -> FROSTResult<Self> {
fn from_bytes(bytes: &[u8]) -> MultiSigResult<Self> {
let mut cursor = 0;

let message_len =
Expand All @@ -388,7 +388,7 @@ impl CommonData {
}

let spp_output = SPPOutput::from_bytes(&bytes[cursor..])
.map_err(FROSTError::SPPOutputDeserializationError)?;
.map_err(MultiSigError::SPPOutputDeserializationError)?;

Ok(CommonData { message, context, signing_commitments, spp_output })
}
Expand All @@ -410,15 +410,15 @@ impl SignerData {
}

/// Deserializes SignerData from bytes.
pub fn from_bytes(bytes: &[u8]) -> FROSTResult<Self> {
pub fn from_bytes(bytes: &[u8]) -> MultiSigResult<Self> {
let share_bytes = &bytes[..SCALAR_LENGTH];
let signature_share = SignatureShare::from_bytes(share_bytes)?;

Ok(SignerData { signature_share })
}
}

/// The signing package that each signer produces in the signing round of the FROST protocol and sends to the
/// The signing package that each signer produces in the signing round of the multi-signature protocol and sends to the
/// coordinator, which aggregates them into the final threshold signature.
#[derive(PartialEq, Eq)]
pub struct SigningPackage {
Expand All @@ -438,7 +438,7 @@ impl SigningPackage {
}

/// Deserializes SigningPackage from bytes.
pub fn from_bytes(bytes: &[u8]) -> FROSTResult<Self> {
pub fn from_bytes(bytes: &[u8]) -> MultiSigResult<Self> {
let signer_data = SignerData::from_bytes(&bytes[..SCALAR_LENGTH])?;

let common_data = CommonData::from_bytes(&bytes[SCALAR_LENGTH..])?;
Expand All @@ -455,7 +455,7 @@ impl GroupCommitment {
pub(super) fn compute(
signing_commitments: &[SigningCommitments],
binding_factor_list: &BindingFactorList,
) -> Result<GroupCommitment, FROSTError> {
) -> Result<GroupCommitment, MultiSigError> {
let identity = RistrettoPoint::identity();

let mut group_commitment = RistrettoPoint::identity();
Expand All @@ -471,7 +471,7 @@ impl GroupCommitment {
// The following check prevents a party from accidentally revealing their share.
// Note that the '&&' operator would be sufficient.
if identity == commitment.binding.0 || identity == commitment.hiding.0 {
return Err(FROSTError::IdentitySigningCommitment);
return Err(MultiSigError::IdentitySigningCommitment);
}

let binding_factor = &binding_factor_list.0[i];
Expand Down

0 comments on commit 6829d16

Please sign in to comment.