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

Add ES256K sign and verify test vectors #104

Merged
merged 1 commit into from
Jan 16, 2024
Merged

Conversation

frankhinek
Copy link
Contributor

This PR will:

  • Add test vectors for Crypto - ES256K - sign and verify operations
  • Test vectors extracted from web5-js, where they are currently being used.
  • README includes a link to reference implementations of the functions being tested so that other SDK implementers can re-implement in other languages.

Note

This test vector was intentionally named ES256K and not Secp256k1 as it tests the sign and verify operations of a concrete implementation of the ECDSA algorithm with the secp256k1 curve and SHA-256 hash function.

The ES256K algorithm identifier is defined in RFC8812, which specifies the use of ECDSA with the secp256k1 curve and the SHA-256 cryptographic hash function. This provides a succinct and unambiguous identifier for this combination of signature algorithm (ECDSA), curve (secp256k1), and hash function (SHA-256). The same algorithm identifiers are used broadly across JSON Object Signing and Encryption (JOSE) standards and when working with DIDs and VCs.

There are other non-signature algorithms (e.g., ECDH, ECIES, etc.) that the secp256k1 curve can be used with and other hash functions (e.g., SHA-384 or SHA-512) that can be used with ECDSA+secp256k1. There are even other signature algorithms (e.g., Schnorr) that can use both secp256k1 and SHA-256.

closes #84

Copy link
Member

@mistermoe mistermoe left a comment

Choose a reason for hiding this comment

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

Love the detailed docs!

Comment on lines +38 to +43
### Reference Implementations

Reference implementations for the sign operation can be found in the following SDK repositories:

- TypeScript: [`Secp256k1.sign()`](https://github.com/TBD54566975/web5-js/blob/44c38a116dec0b357ca15d807eb513f819341e50/packages/crypto/src/primitives/secp256k1.ts#L547-L595)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm a little confused by this reference after reading the PR description here.

Both the sign and verify references are simply Secp256k1.sign() or Secp256k1.verify(). But in the same token, this PR description has a note with the following opening line:

This test vector was intentionally named ES256K and not Secp256k1 as it tests the sign and verify operations of a concrete implementation of the ECDSA algorithm with the secp256k1 curve and SHA-256 hash function.

Does this mean that the implementation of secp256k1 does an ES256K signature by default? Why isn't it passed in as a parameter to the reference implementation?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Follow up to clarify this part of the note:

There are other non-signature algorithms (e.g., ECDH, ECIES, etc.) that the secp256k1 curve can be used with and other hash functions (e.g., SHA-384 or SHA-512) that can be used with ECDSA+secp256k1. There are even other signature algorithms (e.g., Schnorr) that can use both secp256k1 and SHA-256.

How does Secp256k1.sign() or Secp256k1.verify() differentiate between the different algorithms?

Copy link
Contributor Author

@frankhinek frankhinek Jan 16, 2024

Choose a reason for hiding this comment

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

Good questions @amika-sq

Does this mean that the implementation of secp256k1 does an ES256K signature by default? Why isn't it passed in as a parameter to the reference implementation?

How does Secp256k1.sign() or Secp256k1.verify() differentiate between the different algorithms?

The test vector doesn't dictate how the implementation is constructed at that level of granularity. There are slight differences in implementation design (e.g., method signatures, return values, error handling, etc.) across the SDKs, largely due to idiomatic differences (which team consensus has viewed as a positive for dev ex).

Instead, the test vector validates that an implementation of ECDSA + secp256k1 + SHA-256 produces the expected output given the input. For example, the following data (hex string) and private key:

{
  "data": "333435",
  "key": {
    "crv": "secp256k1",
    "d": "lZqISvM7R1S7zBgZ5JjUuOppZuYKXuCbYWBkqgwX88c",
    "kid": "JOeO0oJDLMaXibhJBpsHVvskK47qq0k8uaLozxTtNhk",
    "kty": "EC",
    "x": "npaD6WyM4AZIxwPmieND_gdnYuROitnyDfskXwpv-J0",
    "y": "y5_uOFRRNOCWAJPD-Ly1ENJd908lWJ0-0KGnTwxWzNM"
  }
}

should result in a signature matching the hex string 95b9c99642a5765b4f5f4648671dbad2ad107f7507f1e538eb4ad365caf76a4d321db3e3682f5124d37c597b6f2b489171c6b7d90e82f67a87a7e4d8783f4d63

Whether or not a particular implementation provides an argument in sign or verify to specify the hash function or uses a Result<> return type, this vector can be used without modification. It could also be used by an implementation of ECDSA that supports multiple elliptic curve and hash functions as it would only be used for testing in the secp256k1 + SHA-256 case (and we can add vectors for ES256, ES384, secp256k1+SHA-512, etc. if there's a practical reason to).

In general, the idea was to map the vector naming to the algorithm identifiers we're using, which are JOSE algorithm identifiers unless one does not exist.

@frankhinek frankhinek merged commit 736eae6 into main Jan 16, 2024
6 checks passed
@frankhinek frankhinek deleted the vector-crypto-es256k branch January 16, 2024 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crypto cryptographic primitives
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Produce test vectors for secp256k1 signing and verification
4 participants