diff --git a/frost-core/src/lib.rs b/frost-core/src/lib.rs index 364beab..fe6d581 100644 --- a/frost-core/src/lib.rs +++ b/frost-core/src/lib.rs @@ -365,6 +365,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 @@ -377,6 +381,9 @@ pub struct SigningPackage { ) )] message: Vec, + + /// The adaptor for the signing operation. + adaptor: Option>, } impl SigningPackage @@ -393,7 +400,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, } } @@ -534,6 +574,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)) } @@ -656,6 +700,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 @@ -825,7 +874,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 b7a1e90..cfdfef2 100644 --- a/frost-core/src/round2.rs +++ b/frost-core/src/round2.rs @@ -160,7 +160,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 daa1960..8a1b596 100644 --- a/frost-secp256k1-tr/src/lib.rs +++ b/frost-secp256k1-tr/src/lib.rs @@ -915,3 +915,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, + ) +}