Skip to content

Add secp256k1 ECDSA support via aws-lc-rs#6689

Closed
ibremseth wants to merge 4 commits into
cloudflare:mainfrom
ibremseth:ibremseth/secp256k1-aws
Closed

Add secp256k1 ECDSA support via aws-lc-rs#6689
ibremseth wants to merge 4 commits into
cloudflare:mainfrom
ibremseth:ibremseth/secp256k1-aws

Conversation

@ibremseth

Copy link
Copy Markdown

Summary

Adds support for namedCurve: "secp256k1" to the WebCrypto ECDSA algorithm, gated behind the new secp256k1_ecdsa_curve flag. secp256k1 is the curve used by Bitcoin, Ethereum, and related ecosystems.

BoringSSL doesn't include secp256k1, so this PR vendors aws-lc-rs and routes secp256k1 operations through it. aws-lc-rs wraps AWS-LC, a BoringSSL fork that includes secp256k1.

Scope

  • Supported formats: raw and jwk
  • Hash: SHA-256 only
  • Signatures: 64-byte r || s compact, random nonces
    • NOTE: signatures are not normalized to low-s; both forms verify

Follow-ups

  • SPKI / PKCS8 import/export
  • Keccak-256 hashing (would let ECDSA work for Ethereum-style message signing)

@github-actions

Copy link
Copy Markdown


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

Comment thread src/workerd/api/crypto/ec.c++ Outdated
// Overload that adds secp256k1 to the table when the compat flag is set.
EllipticCurveInfo lookupEllipticCurve(jsg::Lock& js, kj::StringPtr curveName) {
if (FeatureFlags::get(js).getSecp256k1EcdsaCurve() &&
strcasecmp(curveName.cStr(), "secp256k1") == 0) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

(note to self) we need to add equalsIgnoreCase to StringPtr.

Comment thread src/workerd/api/crypto/ec.c++ Outdated
Comment thread src/workerd/api/crypto/secp256k1-key.c++ Outdated
Comment thread src/workerd/api/crypto/secp256k1-key.c++ Outdated
Comment thread src/workerd/api/crypto/secp256k1-key.c++ Outdated
Comment thread src/workerd/api/crypto/secp256k1-key.c++ Outdated
Comment thread src/workerd/api/crypto/secp256k1-key.c++ Outdated
Comment thread src/workerd/api/crypto/secp256k1-key.c++ Outdated
Comment thread src/workerd/api/crypto/secp256k1-key.c++ Outdated
Comment thread src/workerd/api/crypto/secp256k1-key.c++ Outdated
Comment thread src/workerd/api/crypto/secp256k1-key.c++ Outdated

@kentonv kentonv left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hold on here.

This is adding a non-standard crypto algorithm to our WebCrypto implementation, requiring a new dependency on a third-party library.

Sorry but this isn't something we can do on a whim. Once landed we'll have to support this forever. This has long-term maintenance and binary bloat costs for us. We need some sort of argument for why this is worthwihle.

@kentonv

kentonv commented Apr 29, 2026

Copy link
Copy Markdown
Member

@mikea informed me that @ibremseth is a Cloudflare employee, which I would never have guessed from the profile and PR description.

@kentonv kentonv dismissed their stale review April 29, 2026 01:58

Discussed with @mikea, seems like there was context elsewhere that was just missing from the PR description.

@ibremseth ibremseth force-pushed the ibremseth/secp256k1-aws branch from 0733892 to e36815d Compare April 29, 2026 14:14
@jasnell

jasnell commented Apr 29, 2026

Copy link
Copy Markdown
Collaborator

Will need to weigh this carefully relative to #6403 as well. We need to carefully consider the additional dependency on the new rust libraries relative to what boringssl provides and settle the question of which (if any) additional dependencies we want to accept. I understand there's other work depending on this but let's be sure to settle the dependency questions before merging this.

EllipticCurveInfo lookupEllipticCurve(jsg::Lock& js, kj::StringPtr curveName) {
if (FeatureFlags::get(js).getSecp256k1EcdsaCurve() && isSecp256k1(curveName)) {
return {"secp256k1", 0, 32};
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If we add this, it likely should be with an autogate and not a compat flag. Once we're sure it's ready, it should just be there, rather than made conditional on an autogate. That said, we might want to consider using a namespaced name for it just in case the WebCrypto standard adds the algorithm later with the same name but potentially conflicting details.

@danlapid

danlapid commented May 1, 2026

Copy link
Copy Markdown
Collaborator

Will need to weigh this carefully relative to #6403 as well. We need to carefully consider the additional dependency on the new rust libraries relative to what boringssl provides and settle the question of which (if any) additional dependencies we want to accept. I understand there's other work depending on this but let's be sure to settle the dependency questions before merging this.

aws-lc-rs is the chosen second library to use in addition to the existing boringssl

@ibremseth ibremseth force-pushed the ibremseth/secp256k1-aws branch from e36815d to b3e8124 Compare May 1, 2026 15:25
@ibremseth ibremseth force-pushed the ibremseth/secp256k1-aws branch from 7630bce to 60c901d Compare May 1, 2026 18:41
@panva

panva commented May 4, 2026

Copy link
Copy Markdown
Contributor

I'm not aware of any extension to Web Cryptography that defines these (or the mentioned followups). I feel compelled to suggest that it should use vendor prefix for the namedCurve value (not the JWK crv itself, that's already in IANA).

https://w3c.github.io/webcrypto/#extensibility
Vendor-specific proprietary extensions to this specification are strongly discouraged. Authors must not use such extensions, as doing so reduces interoperability and fragments the user base, allowing only users of specific user agents to access the content in question.
If vendor-specific extensions are needed, the members should be prefixed by vendor-specific strings to prevent clashes with future versions of this specification. Extensions must be defined so that the use of extensions neither contradicts nor causes the non-conformance of functionality defined in the specification.

As far as this and all followups go, i'd suggest finding a home for this in an existing SDO such that a) you don't need a vendor prefix, b) get feedback from other implementers, and c) stand a chance of other (server) runtimes picking it up as well.

@ibremseth

Copy link
Copy Markdown
Author

After some discussion we've decided to add secp256k1 as a WASM module directly in a worker! Closing this, appreciate everyones time and thoughts

@ibremseth ibremseth closed this May 5, 2026
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.

6 participants