diff --git a/frost-core/src/lib.rs b/frost-core/src/lib.rs index 76078d9..4727545 100644 --- a/frost-core/src/lib.rs +++ b/frost-core/src/lib.rs @@ -367,6 +367,10 @@ pub struct SigningPackage { /// The set of commitments participants published in the first round of the /// protocol. signing_commitments: BTreeMap, round1::SigningCommitments>, + + /// The set of participants that are signing. + signing_participants_groups: Option>>>, + /// Message which each participant will sign. /// /// Each signer should perform protocol-specific verification on the @@ -379,6 +383,9 @@ pub struct SigningPackage { ) )] message: Vec, + + /// The adaptor for the signing operation. + adaptor: Option>, } impl SigningPackage @@ -395,7 +402,40 @@ where SigningPackage { header: Header::default(), signing_commitments, + signing_participants_groups: None, message: message.to_vec(), + adaptor: None, + } + } + + /// Create a new `SigningPackage` with a set of signing participants. + pub fn new_with_participants_groups( + signing_commitments: BTreeMap, round1::SigningCommitments>, + signing_participants_groups: Option>>>, + message: &[u8], + ) -> SigningPackage { + SigningPackage { + header: Header::default(), + signing_commitments, + signing_participants_groups: signing_participants_groups, + message: message.to_vec(), + adaptor: None, + } + } + + /// Create a new `SigningPackage` with a set of signing participants and an adaptor. + pub fn new_with_adaptor( + signing_commitments: BTreeMap, round1::SigningCommitments>, + signing_participants_groups: Option>>>, + message: &[u8], + adaptor: Option>, + ) -> SigningPackage { + SigningPackage { + header: Header::default(), + signing_commitments, + signing_participants_groups: signing_participants_groups, + message: message.to_vec(), + adaptor: adaptor, } } @@ -536,6 +576,10 @@ where group_commitment = group_commitment + accumulated_binding_commitment; + if let Some(adaptor) = signing_package.adaptor { + group_commitment = group_commitment + adaptor.to_element(); + } + Ok(GroupCommitment(group_commitment)) } @@ -611,6 +655,11 @@ where z, }; + if signing_package.adaptor.is_some() { + // If there is an adaptor, we skip the verification step. + return Ok(signature); + } + // Verify the aggregate signature let verification_result = pubkeys .verifying_key @@ -749,7 +798,23 @@ fn verify_signature_share_precomputed( verifying_share: &keys::VerifyingShare, challenge: Challenge, ) -> Result<(), Error> { - let lambda_i = derive_interpolating_value(&signature_share_identifier, signing_package)?; + let lambda_i = match signing_package.signing_participants_groups.clone() { + Some(signing_participants_groups) => { + let mut result: Result, Error> = Err(Error::UnknownIdentifier); + for signing_participants_group in signing_participants_groups { + if signing_participants_group.contains(&signature_share_identifier) { + result = compute_lagrange_coefficient( + &signing_participants_group, + None, + signature_share_identifier, + ); + break; + } + } + result? + } + None => derive_interpolating_value(&signature_share_identifier, signing_package)?, + }; let binding_factor = binding_factor_list .get(&signature_share_identifier) diff --git a/frost-core/src/round2.rs b/frost-core/src/round2.rs index d3147db..9d819a6 100644 --- a/frost-core/src/round2.rs +++ b/frost-core/src/round2.rs @@ -158,7 +158,23 @@ pub fn sign( let group_commitment = compute_group_commitment(&signing_package, &binding_factor_list)?; // Compute Lagrange coefficient. - let lambda_i = frost::derive_interpolating_value(key_package.identifier(), &signing_package)?; + let lambda_i = match signing_package.signing_participants_groups.clone() { + Some(signing_participants_groups) => { + let mut result: Result, Error> = Err(Error::UnknownIdentifier); + for signing_participants_group in signing_participants_groups { + if signing_participants_group.contains(&key_package.identifier()) { + result = frost::compute_lagrange_coefficient( + &signing_participants_group, + None, + *key_package.identifier(), + ); + break; + } + } + result? + } + None => frost::derive_interpolating_value(key_package.identifier(), &signing_package)?, + }; // Compute the per-message challenge. let challenge = ::challenge( diff --git a/frost-secp256k1-tr/src/lib.rs b/frost-secp256k1-tr/src/lib.rs index f566f72..fa93d84 100644 --- a/frost-secp256k1-tr/src/lib.rs +++ b/frost-secp256k1-tr/src/lib.rs @@ -912,3 +912,20 @@ pub type SigningKey = frost_core::SigningKey; /// A valid verifying key for Schnorr signatures on FROST(secp256k1, SHA-256). pub type VerifyingKey = frost_core::VerifyingKey; + +/// Verifies a signature share for the given participant `identifier`, +pub fn verify_signature_share( + identifier: Identifier, + verifying_share: &keys::VerifyingShare, + signature_share: &round2::SignatureShare, + signing_package: &SigningPackage, + verifying_key: &VerifyingKey, +) -> Result<(), Error> { + frost_core::verify_signature_share( + identifier, + verifying_share, + signature_share, + signing_package, + verifying_key, + ) +}