The secp256r1 (p-256) elliptic curve for ECDH & ECDSA
npm install curve-p256This is a JS implementation of secp256r1 (P-256) elliptic curve encryption algorithm library, used for ECDH key exchange & ECDSA signing. This library is extract from @noble/curves.
- ✍️ ECDSA
signatures compliant with RFC6979
- 🤝 Elliptic Curve Diffie-Hellman ECDH
- 🔒 Supports hedged signatures guarding against fault attacks
In addition, I have added support for Wechat Mini Programs. Since @noble/curves depends on the instance methods of Crypto in the Web Crypto API, which are not yet supported by Mini Programs, I have implemented these methods myself.
-----
这是一个 JS 实现的 secp256r1 (P-256) 椭圆曲线加密算法库,用于 ECDH 密钥交换和 ECDSA 签名。这个库是从@noble/curves 中提取出来的。
- ✍️ 符合 RFC6979 标准的 ECDSA 签名
- 🤝 椭圆曲线迪菲-赫尔曼 ECDH 密钥交换
- 🔒 支持防护性签名,可抵御故障攻击
另外,我对微信小程序做了支持。由于 @noble/curves 依赖了 Web Crypto API 中 Crypto 的实例方法,但小程序尚未支持,所以我实现了这些方法。
NPM:
``bash`
npm i curve-p256
YARN:
`bash`
yarn add curve-p256
`js
import { p256 } from 'curve-p256';
const privBob = p256.utils.randomPrivateKey();
const pubBob = p256.getPublicKey(privBob);
const privAlice = p256.utils.randomPrivateKey();
const pubAlice = p256.getPublicKey(privAlice);
const shared1 = p256.getSharedSecret(privBob, pubAlice);
const shared2 = p256.getSharedSecret(privAlice, pubBob);
console.log(shared1 === shared2); // true
`
`js
import { p256 } from 'curve-p256';
const priv = p256.utils.randomPrivateKey();
const pub = p256.getPublicKey(priv); // Convert private key to public.
const msg = new TextEncoder().encode('Hello world!');
const sig = p256.sign(msg, priv); // Sign msg with private key.
const isValid = p256.verify(sig, msg, pub);
console.log(isValid); // true
`
js
import { p256 } from 'curve-p256';const priv = p256.utils.randomPrivateKey();
const pub = p256.getPublicKey(priv);
const msg = new TextEncoder().encode('Hello world!');
const sig = p256.sign(msg, priv); //
{prehash: true} option is availableconst pub2 = sig.recoverPublicKey(msg).toRawBytes(); // public key recovery
console.log(pub === pub2); // true
`$3
`js
import { bytesToHex, hexToBytes, concatBytes } from 'curve-p256';// hex = 'deadbeef'
const hex = bytesToHex(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));
// bytes = Uint8Array.from([0xde, 0xad, 0xbe, 0xef])
const bytes = hexToBytes('deadbeef');
// bytes = Uint8Array.from([0xde, 0xad, 0xbe, 0xef])
const concated = concatBytes(Uint8Array.from([0xde, 0xad]), Uint8Array.from([0xbe, 0xef]));
`Speed
Benchmark results on Apple M2 with node v20:
`
p256
init x 38 ops/sec @ 26ms/op
getPublicKey x 6,530 ops/sec @ 153μs/op
sign x 5,074 ops/sec @ 197μs/op
verify x 626 ops/sec @ 1ms/opecdh
p256 x 511 ops/sec @ 1ms/op
``