Overview
This proposal suggests adding support for the secp256k1 curve using the algorithm identifier "ES256K", following Coze's existing ECDSA implementations.
Algorithm Properties
ES256K has these properties:
{
"Name":"ES256K",
"Genus":"ECDSA",
"Family":"EC",
"Use":"sig",
"Hash":"SHA-256",
"HashSize":32,
"HashSizeB64":43,
"XSize":64,
"XSizeB64":86,
"DSize":32,
"DSizeB64":43,
"Curve":"secp256k1",
"SigSize":64,
"SigSizeB64":86
}
This follows the form for existing algorithms: https://github.com/Cyphrme/Coze/blob/c2298862110f552ed0cc21a90d4fd76dadb4846f/alg_test.go#L159C1-L193C1
The curve "secp256k1" will also be added.
Signature Canonicalization
Secp256k1, like other ECDSA curves, has signature malleability concerns. Each signature (r,s) has a complementary valid signature (r,-s mod n). To prevent malleability, Coze should enforce low-S values in signatures, similar to how Bitcoin and other cryptocurrencies handle this issue.
The first formal proposal in the industry was Bitcoin's work: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki
Bitcoin's work (they call it "lower-S form"): https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1.h
This is a problem for most blockchains using ECDSA, making them a good source for prior work. For example, XRP's work on the issue: https://xrpl.org/docs/concepts/transactions/finality-of-results/transaction-malleability
Go Considerations
Decred
Decred has developed a native Go implementation:
https://github.com/decred/dcrd/tree/master/dcrec/secp256k1
It's also used by btcd: https://github.com/btcsuite/btcd/blob/09ba026580f4041bae30d732f26fa1a2036af003/go.mod#L12C2-L12C50
It appears that Decred's library generates only canonicalized signatures: https://github.com/decred/dcrd/blob/172eeb5fe1493e1d5cff6dc304c94de5befd0d21/dcrec/secp256k1/ecdsa/signature.go#L558
Ethereum
Ethereum has a C wrapper: https://pkg.go.dev/github.com/ethereum/go-ethereum/crypto/secp256k1?utm_source=godoc
After taking a quick look, I would recommend using Decred's library. The library is already battle-tested through btcd, is a pure Go implementation (no C dependencies), and Decred has active maintenance and strong security track record.
JavaScript Considerations
Paul's library has zero dependencies, as constant-time as possible with JavaScript, and is well-reviewed and widely used.
https://github.com/paulmillr/noble-secp256k1
Other considerations
The name "ES256K" is also used by JOSE: https://www.iana.org/assignments/jose/jose.xhtml
Overview
This proposal suggests adding support for the secp256k1 curve using the algorithm identifier "ES256K", following Coze's existing ECDSA implementations.
Algorithm Properties
ES256K has these properties:
{ "Name":"ES256K", "Genus":"ECDSA", "Family":"EC", "Use":"sig", "Hash":"SHA-256", "HashSize":32, "HashSizeB64":43, "XSize":64, "XSizeB64":86, "DSize":32, "DSizeB64":43, "Curve":"secp256k1", "SigSize":64, "SigSizeB64":86 }This follows the form for existing algorithms: https://github.com/Cyphrme/Coze/blob/c2298862110f552ed0cc21a90d4fd76dadb4846f/alg_test.go#L159C1-L193C1
The curve "secp256k1" will also be added.
Signature Canonicalization
Secp256k1, like other ECDSA curves, has signature malleability concerns. Each signature (r,s) has a complementary valid signature (r,-s mod n). To prevent malleability, Coze should enforce low-S values in signatures, similar to how Bitcoin and other cryptocurrencies handle this issue.
The first formal proposal in the industry was Bitcoin's work: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki
Bitcoin's work (they call it "lower-S form"): https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1.h
This is a problem for most blockchains using ECDSA, making them a good source for prior work. For example, XRP's work on the issue: https://xrpl.org/docs/concepts/transactions/finality-of-results/transaction-malleability
Go Considerations
Decred
Decred has developed a native Go implementation:
https://github.com/decred/dcrd/tree/master/dcrec/secp256k1
It's also used by btcd: https://github.com/btcsuite/btcd/blob/09ba026580f4041bae30d732f26fa1a2036af003/go.mod#L12C2-L12C50
It appears that Decred's library generates only canonicalized signatures: https://github.com/decred/dcrd/blob/172eeb5fe1493e1d5cff6dc304c94de5befd0d21/dcrec/secp256k1/ecdsa/signature.go#L558
Ethereum
Ethereum has a C wrapper: https://pkg.go.dev/github.com/ethereum/go-ethereum/crypto/secp256k1?utm_source=godoc
After taking a quick look, I would recommend using Decred's library. The library is already battle-tested through btcd, is a pure Go implementation (no C dependencies), and Decred has active maintenance and strong security track record.
JavaScript Considerations
Paul's library has zero dependencies, as constant-time as possible with JavaScript, and is well-reviewed and widely used.
https://github.com/paulmillr/noble-secp256k1
Other considerations
The name "ES256K" is also used by JOSE: https://www.iana.org/assignments/jose/jose.xhtml