Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intercompatibility with k256 #60

Open
tbraun96 opened this issue Mar 28, 2024 · 2 comments
Open

Intercompatibility with k256 #60

tbraun96 opened this issue Mar 28, 2024 · 2 comments

Comments

@tbraun96
Copy link

tbraun96 commented Mar 28, 2024

We are using the frost-secp256k1 crate for verification of WSTS-generated signatures: frost-secp256k1 { git = "https://github.com/LIT-Protocol/frost" }.

In theory, the math should be identical to this repo's use of Schnorr. Signatures in both crates use R and z values. This is how we convert from a WSTS signature to a ZCash FROST signature:

    let wsts_sig = sig_agg
        .sign(&msg, &party_nonces, &signature_shares, &party_key_ids)
        .map_err(|err| JobError {
            reason: err.to_string(),
        })?;

    // Convert the signature to a FROST-compatible format for pallet-verification
    let z_scalar_p = ScalarPrimitive::from_slice(&wsts_sig.z.to_bytes())
        .expect("Should be a valid 32-byte scalar");
    let z = k256::Scalar::from(&z_scalar_p);
    let x_generic_array = GenericArray::from(wsts_sig.R.x().to_bytes());
    let y_generic_array = GenericArray::from(wsts_sig.R.y().to_bytes());
    let R_encoded_point =
        EncodedPoint::from_affine_coordinates(&x_generic_array, &y_generic_array, true);
    let R = k256::ProjectivePoint::from_encoded_point(&R_encoded_point)
        .expect("Should be a valid encoded point");
    let frost_signature = frost_secp256k1::Signature::new(R, z);

And, this is how we convert from a WSTS group public key to a ZCash FROST group public key:

    let party: PartyState = party.save();

    // Convert the WSTS group key into a FROST-compatible format
    let group_point = party.group_key;
    let x_generic_array = GenericArray::from(group_point.x().to_bytes());
    let y_generic_array = GenericArray::from(group_point.y().to_bytes());
    let encoded_point =
        EncodedPoint::from_affine_coordinates(&x_generic_array, &y_generic_array, true);
    let projective_point = k256::ProjectivePoint::from_encoded_point(&encoded_point)
        .expect("Should be a valid encoded point");
    let verifying_key = VerifyingKey::new(projective_point);
    let public_key_frost_format = verifying_key.serialize().as_ref().to_vec();

Note: We are using wsts=3.0.0.

The to_bytes() function returns in big-endian. All functions that receive these big-endian bytes also expect a big-endian input. I have verified that the sizes are all correct, and, that none of this code panics.

However, when we attempt to verify using ZCash FROST, we get an invalid signature. I know this question may be outside of the scope of this repo, however, we do need to use wsts for our DKG and later use a no-std friendly crate for Schnorr signature verifications (specifically over secp256k1). Are there any ideas as to what we're doing wrong, or, if this is even possible? Thanks!

@tbraun96 tbraun96 changed the title Intercompatibility with ZCash FROST Secp256k1 Intercompatibility with k256 Mar 28, 2024
@shekohex
Copy link

shekohex commented Apr 4, 2024

Using frost_taproot instead of frost_secp256k1 works, since wsts and frsot_secp256k1 does use different challenge strings

@xoloki
Copy link
Collaborator

xoloki commented Apr 13, 2024

Using frost_taproot instead of frost_secp256k1 works, since wsts and frsot_secp256k1 does use different challenge strings

Yeah we use taproot compatible challenge strings in many (maybe all) contexts.

I always planned on offering a nostd build feature, would you like me to do that sooner rather than later? I actually did that for the dalek crates years ago, it was my first PRs for them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants