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

Implementation of secp256k1 Group #844

Open
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

themicp
Copy link

@themicp themicp commented Oct 31, 2024

This PR implements the secp256k1 group by wrapping around the k256 crate. This enhancement enables the use of the DKG protocol in fastcrypto-tbls to produce shared keys on the secp256k1 curve.

Motivation: We would like to use the fastcrypto-tbls DKG protocol to produce shares for a key that can sign transactions on Bitcoin, which natively supports secp256k1. However, the DKG protocol implementation currently only supports the BLS12-381 curve. By implementing the secp256k1 group, we enable the DKG protocol to work in conjunction with a signature aggregation protocol (e.g., FROST) to produce aggregated signatures that can be natively verified on Bitcoin.

Changes:

  • Updated k256 to version 0.13.4
  • Implemented secp256k1 Group
  • Modified secp256k1 tests: Updated existing tests to align with the changes in the k256 interface
  • Enhanced dkg_v1 tests: Adjusted the tests to run with both BLS12381 and secp256k1 curves, ensuring that the DKG protocol functions correctly with the new implementation.

@benr-ml benr-ml self-requested a review October 31, 2024 12:45
Copy link
Contributor

@benr-ml benr-ml left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this contribution! Overall looks good:

  • I focused so far on the group related code, see comments
  • Please add tests similarly to the ones of bls12381_group_tests.rs
  • Note that I've sent [DKG] Clean up old versions of DKG & ECIES #845 to clean up the DKG code. I don't expect major changes needed because of that in the current PR, so mostly FYI.

@@ -76,6 +76,10 @@ where
proof,
}
}

pub fn as_element(&self) -> &G::ScalarType {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general the raw secret key should not be used not via APIs, do we really need this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My main use was from an external library that needed to convert the private key to a k256::ecdsa::SigningKey. But I can change the external library instead, and remove as_element() from here. Alternatively, we could also implement From<PrivateKey<G>> for k256::ecdsa::SigningKey, but it is not necessary for now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow - the ECIES private key is not related to the DKG private key/share, you can generate it independently when creating a party

fastcrypto/Cargo.toml Outdated Show resolved Hide resolved
fastcrypto/src/groups/mod.rs Show resolved Hide resolved
fastcrypto/src/groups/secp256k1.rs Outdated Show resolved Hide resolved
}

impl FromTrustedByteArray<SCALAR_BYTE_LENGTH> for Scalar {
fn from_trusted_byte_array(bytes: &[u8; SCALAR_BYTE_LENGTH]) -> FastCryptoResult<Self> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please document the expected format

}

impl FromTrustedByteArray<PROJECTIVE_POINT_BYTE_LENGTH> for ProjectivePoint {
fn from_trusted_byte_array(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document the format here


impl ToFromByteArray<PROJECTIVE_POINT_BYTE_LENGTH> for ProjectivePoint {
fn from_byte_array(bytes: &[u8; PROJECTIVE_POINT_BYTE_LENGTH]) -> FastCryptoResult<Self> {
Self::from_trusted_byte_array(bytes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will unwrap for invalid points? let's return error instead

fastcrypto/src/groups/secp256k1.rs Outdated Show resolved Hide resolved
fn hash_to_group_element(msg: &[u8]) -> Self {
let domain = "secp256k1_XMD:SHA-256_SSWU_RO_".as_bytes();
let mut u = [FieldElement::ZERO];
hash_to_field::<ExpandMsgXmd<Sha256>, FieldElement>(&[msg], &[domain], &mut u)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a link to the relevant standard this is based on

}

serialize_deserialize_with_to_from_byte_array!(ProjectivePoint);
generate_bytes_representation!(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that you don't need this - we mainly use XAsBytes for external interfaces

@benr-ml benr-ml requested a review from jonas-lj November 3, 2024 16:12
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

Successfully merging this pull request may close these issues.

2 participants