Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

curve-p256

atypiape180MIT1.0.2TypeScript support: included

The secp256r1 (p-256) elliptic curve for ECDH & ECDSA

elliptic, curve, cryptography, p256, P-256, secp256r1, RFC6979, noble, ecdh, ecdsa, crypto, wechat, wx, miniprogram, 小程序, 密钥交换, 密钥协商

readme

curve-p256

This 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.

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 中提取出来的。

另外,我对微信小程序做了支持。由于 @noble/curves 依赖了 Web Crypto APICrypto 的实例方法,但小程序尚未支持,所以我实现了这些方法。

Usage

NPM:

npm i curve-p256

YARN:

yarn add curve-p256

Example:

ECDH: Diffie-Hellman shared secrets

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

ECDSA signatures over secp256r1 and others

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

Public key recovery

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 available

const pub2 = sig.recoverPublicKey(msg).toRawBytes(); // public key recovery
console.log(pub === pub2); // true

Utils

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/op

ecdh
p256 x 511 ops/sec @ 1ms/op