-
Notifications
You must be signed in to change notification settings - Fork 83
Description
Hi,
I am part of a small team working on creating a FROST integration to provide multi-sig capabilities on Mina Protocol.
We ran into the issue in that Mina protocol Schnorr signatures require that the signature commitment (the group commitment within FROST) must have an even Y coordinate which FROST does not care about and therefore gives us a 50% chance that a valid FROST signature is valid on the Mina protocol.
As discussed already on the ZCash Forum, the solution to this is negating nonces and commitments when the group commitment within FROST has an odd Y value. However, the fix requires me to copy a large majority of code in order to modify a few lines.
I was wondering whether it is feasible to add pre_commitment_sign and pre_commitment_aggregate functions within frost-core:
frost::round2::sign
let binding_factor_list: BindingFactorList<C> =
compute_binding_factor_list(&signing_package, key_package.verifying_key(), &[])?;
let binding_factor: frost::BindingFactor<C> = binding_factor_list
.get(key_package.identifier())
.ok_or(Error::UnknownIdentifier)?
.clone();
// Perform pre_group_commitment to check if the group commitment is even
+ let (signing_package, signer_nonces) = pre_commitment_sign(&signing_package, &signer_nonces, &binding_factor_list)?;
// Compute the group commitment from signing commitments produced in round one.
let group_commitment = compute_group_commitment(&signing_package, &binding_factor_list)?;frost::aggregate
// Encodes the signing commitment list produced in round one as part of generating [`BindingFactor`], the
// binding factor.
let binding_factor_list: BindingFactorList<C> =
compute_binding_factor_list(&signing_package, pubkeys.verifying_key(), &[])?;
+ let signing_package = pre_commitment_aggregate(&signing_package, &binding_factor_list)?;
// Compute the group commitment from signing commitments produced in round one.
let group_commitment = compute_group_commitment(&signing_package, &binding_factor_list)?;Where the function signatures would look like:
pub fn pre_commitment_sign<'a, C: Ciphersuite>(
signing_package: &'a SigningPackage,
signing_nonces: &'a SigningNonces,
binding_factor_list: &'a BindingFactorList<C>,
) -> Result<(Cow<'a, SigningPackage>, Cow<'a, SigningNonces>), Error> {}pub fn pre_commitment_aggregate<'a, C: Ciphersuite>(
signing_package: &'a SigningPackage,
binding_factor_list: &'a BindingFactorList<C>,
) -> Result<Cow<'a, SigningPackage>, Error> {}This change should be backwards-incompatible and by default will act as no-ops.