@noble/curves
Advanced tools
Comparing version 0.4.0 to 0.5.0
182
package.json
{ | ||
"name": "@noble/curves", | ||
"version": "0.4.0", | ||
"description": "Minimal, zero-dependency JS implementation of elliptic curve cryptography", | ||
"version": "0.5.0", | ||
"description": "Minimal, auditable JS implementation of elliptic curve cryptography", | ||
"files": [ | ||
"index.js", | ||
"lib", | ||
"lib/esm" | ||
"lib" | ||
], | ||
"scripts": { | ||
"bench": "node curve-definitions/benchmark/index.js", | ||
"bench": "node benchmark/index.js", | ||
"build": "tsc && tsc -p tsconfig.esm.json", | ||
"build:release": "rollup -c rollup.config.js", | ||
"lint": "prettier --check 'src/**/*.{js,ts}' 'curve-definitions/src/**/*.{js,ts}'", | ||
"format": "prettier --write 'src/**/*.{js,ts}' 'curve-definitions/src/**/*.{js,ts}'", | ||
"test": "cd curve-definitions; node test/index.test.js" | ||
"lint": "prettier --check 'src/**/*.{js,ts}' 'test/*.js'", | ||
"format": "prettier --write 'src/**/*.{js,ts}' 'test/*.js'", | ||
"test": "node test/index.test.js" | ||
}, | ||
@@ -25,4 +23,12 @@ "author": "Paul Miller (https://paulmillr.com)", | ||
"license": "MIT", | ||
"dependencies": { | ||
"@noble/hashes": "1.1.5" | ||
}, | ||
"devDependencies": { | ||
"@rollup/plugin-node-resolve": "13.3.0", | ||
"@scure/base": "~1.1.1", | ||
"@scure/bip32": "~1.1.1", | ||
"@scure/bip39": "~1.1.0", | ||
"@types/node": "18.11.3", | ||
"fast-check": "3.0.0", | ||
"micro-bmark": "0.2.0", | ||
@@ -36,41 +42,121 @@ "micro-should": "0.2.0", | ||
"exports": { | ||
"./edwards": { | ||
"types": "./lib/edwards.d.ts", | ||
"import": "./lib/esm/edwards.js", | ||
"default": "./lib/edwards.js" | ||
".": { | ||
"types": "./lib/index.d.ts", | ||
"import": "./lib/esm/index.js", | ||
"default": "./lib/index.js" | ||
}, | ||
"./modular": { | ||
"types": "./lib/modular.d.ts", | ||
"import": "./lib/esm/modular.js", | ||
"default": "./lib/modular.js" | ||
"./abstract/edwards": { | ||
"types": "./lib/abstract/edwards.d.ts", | ||
"import": "./lib/esm/abstract/edwards.js", | ||
"default": "./lib/abstract/edwards.js" | ||
}, | ||
"./montgomery": { | ||
"types": "./lib/montgomery.d.ts", | ||
"import": "./lib/esm/montgomery.js", | ||
"default": "./lib/montgomery.js" | ||
"./abstract/modular": { | ||
"types": "./lib/abstract/modular.d.ts", | ||
"import": "./lib/esm/abstract/modular.js", | ||
"default": "./lib/abstract/modular.js" | ||
}, | ||
"./weierstrass": { | ||
"types": "./lib/weierstrass.d.ts", | ||
"import": "./lib/esm/weierstrass.js", | ||
"default": "./lib/weierstrass.js" | ||
"./abstract/montgomery": { | ||
"types": "./lib/abstract/montgomery.d.ts", | ||
"import": "./lib/esm/abstract/montgomery.js", | ||
"default": "./lib/abstract/montgomery.js" | ||
}, | ||
"./bls": { | ||
"types": "./lib/bls.d.ts", | ||
"import": "./lib/esm/bls.js", | ||
"default": "./lib/bls.js" | ||
"./abstract/weierstrass": { | ||
"types": "./lib/abstract/weierstrass.d.ts", | ||
"import": "./lib/esm/abstract/weierstrass.js", | ||
"default": "./lib/abstract/weierstrass.js" | ||
}, | ||
"./hashToCurve": { | ||
"types": "./lib/hashToCurve.d.ts", | ||
"import": "./lib/esm/hashToCurve.js", | ||
"default": "./lib/hashToCurve.js" | ||
"./abstract/bls": { | ||
"types": "./lib/abstract/bls.d.ts", | ||
"import": "./lib/esm/abstract/bls.js", | ||
"default": "./lib/abstract/bls.js" | ||
}, | ||
"./group": { | ||
"types": "./lib/group.d.ts", | ||
"import": "./lib/esm/group.js", | ||
"default": "./lib/group.js" | ||
"./abstract/hash-to-curve": { | ||
"types": "./lib/abstract/hash-to-curve.d.ts", | ||
"import": "./lib/esm/abstract/hash-to-curve.js", | ||
"default": "./lib/abstract/hash-to-curve.js" | ||
}, | ||
"./utils": { | ||
"types": "./lib/utils.d.ts", | ||
"import": "./lib/esm/utils.js", | ||
"default": "./lib/utils.js" | ||
"./abstract/group": { | ||
"types": "./lib/abstract/group.d.ts", | ||
"import": "./lib/esm/abstract/group.js", | ||
"default": "./lib/abstract/group.js" | ||
}, | ||
"./abstract/utils": { | ||
"types": "./lib/abstract/utils.d.ts", | ||
"import": "./lib/esm/abstract/utils.js", | ||
"default": "./lib/abstract/utils.js" | ||
}, | ||
"./_shortw_utils": { | ||
"types": "./lib/_shortw_utils.d.ts", | ||
"import": "./lib/esm/_shortw_utils.js", | ||
"default": "./lib/_shortw_utils.js" | ||
}, | ||
"./bls12-381": { | ||
"types": "./lib/bls12-381.d.ts", | ||
"import": "./lib/esm/bls12-381.js", | ||
"default": "./lib/bls12-381.js" | ||
}, | ||
"./bn": { | ||
"types": "./lib/bn.d.ts", | ||
"import": "./lib/esm/bn.js", | ||
"default": "./lib/bn.js" | ||
}, | ||
"./ed25519": { | ||
"types": "./lib/ed25519.d.ts", | ||
"import": "./lib/esm/ed25519.js", | ||
"default": "./lib/ed25519.js" | ||
}, | ||
"./ed448": { | ||
"types": "./lib/ed448.d.ts", | ||
"import": "./lib/esm/ed448.js", | ||
"default": "./lib/ed448.js" | ||
}, | ||
"./index": { | ||
"types": "./lib/index.d.ts", | ||
"import": "./lib/esm/index.js", | ||
"default": "./lib/index.js" | ||
}, | ||
"./jubjub": { | ||
"types": "./lib/jubjub.d.ts", | ||
"import": "./lib/esm/jubjub.js", | ||
"default": "./lib/jubjub.js" | ||
}, | ||
"./p192": { | ||
"types": "./lib/p192.d.ts", | ||
"import": "./lib/esm/p192.js", | ||
"default": "./lib/p192.js" | ||
}, | ||
"./p224": { | ||
"types": "./lib/p224.d.ts", | ||
"import": "./lib/esm/p224.js", | ||
"default": "./lib/p224.js" | ||
}, | ||
"./p256": { | ||
"types": "./lib/p256.d.ts", | ||
"import": "./lib/esm/p256.js", | ||
"default": "./lib/p256.js" | ||
}, | ||
"./p384": { | ||
"types": "./lib/p384.d.ts", | ||
"import": "./lib/esm/p384.js", | ||
"default": "./lib/p384.js" | ||
}, | ||
"./p521": { | ||
"types": "./lib/p521.d.ts", | ||
"import": "./lib/esm/p521.js", | ||
"default": "./lib/p521.js" | ||
}, | ||
"./pasta": { | ||
"types": "./lib/pasta.d.ts", | ||
"import": "./lib/esm/pasta.js", | ||
"default": "./lib/pasta.js" | ||
}, | ||
"./secp256k1": { | ||
"types": "./lib/secp256k1.d.ts", | ||
"import": "./lib/esm/secp256k1.js", | ||
"default": "./lib/secp256k1.js" | ||
}, | ||
"./stark": { | ||
"types": "./lib/stark.d.ts", | ||
"import": "./lib/esm/stark.js", | ||
"default": "./lib/stark.js" | ||
} | ||
@@ -82,6 +168,16 @@ }, | ||
"cryptography", | ||
"hyperelliptic", | ||
"weierstrass", | ||
"montgomery", | ||
"edwards", | ||
"p256", | ||
"p384", | ||
"p521", | ||
"secp256r1", | ||
"secp256k1", | ||
"ed25519", | ||
"ed448", | ||
"bls12-381", | ||
"bn254", | ||
"pasta", | ||
"bls", | ||
"nist", | ||
@@ -99,2 +195,2 @@ "ecc", | ||
] | ||
} | ||
} |
357
README.md
# noble-curves | ||
Minimal, zero-dependency JS implementation of elliptic curve cryptography. | ||
Minimal, auditable JS implementation of elliptic curve cryptography. | ||
- Short Weierstrass curve with ECDSA signatures | ||
- Twisted Edwards curve with EdDSA signatures | ||
- Montgomery curve for ECDH key agreement | ||
- Short Weierstrass, Edwards, Montgomery curves | ||
- ECDSA, EdDSA, Schnorr, BLS signature schemes, ECDH key agreement | ||
- [hash to curve](https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/) | ||
for encoding or hashing an arbitrary string to a point on an elliptic curve | ||
- Auditable, [fast](#speed) | ||
- 🔻 Tree-shaking-friendly: there is no entry point, which ensures small size of your app | ||
- 🔍 Unique tests ensure correctness. Wycheproof vectors included | ||
To keep the package minimal, no curve definitions are provided out-of-box. Use `micro-curve-definitions` module: | ||
There are two parts of the package: | ||
- It provides P192, P224, P256, P384, P521, secp256k1, stark curve, bn254, pasta (pallas/vesta) short weierstrass curves | ||
- It also provides ed25519 and ed448 twisted edwards curves | ||
- Main reason for separate package is the fact hashing library (like `@noble/hashes`) is required for full functionality | ||
- We may reconsider merging packages in future, when a stable version would be ready | ||
1. `abstract/` directory specifies zero-dependency EC algorithms | ||
2. root directory utilizes one dependency `@noble/hashes` and provides ready-to-use: | ||
- NIST curves secp192r1/P192, secp224r1/P224, secp256r1/P256, secp384r1/P384, secp521r1/P521 | ||
- SECG curve secp256k1 | ||
- pairing-friendly curves bls12-381, bn254 | ||
- ed25519/curve25519/x25519/ristretto, edwards448/curve448/x448 RFC7748 / RFC8032 / ZIP215 stuff | ||
Future plans: | ||
Curves incorporate work from previous noble packages | ||
([secp256k1](https://github.com/paulmillr/noble-secp256k1), | ||
[ed25519](https://github.com/paulmillr/noble-ed25519), | ||
[bls12-381](https://github.com/paulmillr/noble-bls12-381)), | ||
which had security audits and were developed from 2019 to 2022. | ||
The goal is to replace them with lean UMD builds based on single-codebase noble-curves. | ||
- hash to curve standard | ||
- point indistinguishability | ||
- pairings | ||
### This library belongs to _noble_ crypto | ||
@@ -26,3 +33,3 @@ | ||
- No dependencies, small files | ||
- Minimal dependencies, small files | ||
- Easily auditable TypeScript/JS code | ||
@@ -32,7 +39,6 @@ - Supported in all major browsers and stable node.js versions | ||
- Check out [homepage](https://paulmillr.com/noble/) & all libraries: | ||
[secp256k1](https://github.com/paulmillr/noble-secp256k1), | ||
[curves](https://github.com/paulmillr/noble-curves) ([secp256k1](https://github.com/paulmillr/noble-secp256k1), | ||
[ed25519](https://github.com/paulmillr/noble-ed25519), | ||
[bls12-381](https://github.com/paulmillr/noble-bls12-381), | ||
[hashes](https://github.com/paulmillr/noble-hashes), | ||
[curves](https://github.com/paulmillr/noble-curves) | ||
[bls12-381](https://github.com/paulmillr/noble-bls12-381)), | ||
[hashes](https://github.com/paulmillr/noble-hashes) | ||
@@ -49,5 +55,62 @@ ## Usage | ||
```ts | ||
import { weierstrass } from '@noble/curves/weierstrass'; // Short Weierstrass curve | ||
// Common.js and ECMAScript Modules (ESM) | ||
import { secp256k1 } from '@noble/curves/secp256k1'; | ||
const key = secp256k1.utils.randomPrivateKey(); | ||
const pub = secp256k1.getPublicKey(key); | ||
const msg = new Uint8Array(32).fill(1); | ||
const sig = secp256k1.sign(msg, key); | ||
secp256k1.verify(sig, msg, pub) === true; | ||
sig.recoverPublicKey(msg) === pub; | ||
const someonesPub = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey()); | ||
const shared = secp256k1.getSharedSecret(key, someonesPub); | ||
``` | ||
All curves: | ||
```ts | ||
import { secp256k1 } from '@noble/curves/secp256k1'; | ||
import { ed25519, ed25519ph, ed25519ctx, x25519, RistrettoPoint } from '@noble/curves/ed25519'; | ||
import { ed448, ed448ph, ed448ctx, x448 } from '@noble/curves/ed448'; | ||
import { p256 } from '@noble/curves/p256'; | ||
import { p384 } from '@noble/curves/p384'; | ||
import { p521 } from '@noble/curves/p521'; | ||
import { pallas, vesta } from '@noble/curves/pasta'; | ||
import * as stark from '@noble/curves/stark'; | ||
import { bls12_381 } from '@noble/curves/bls12-381'; | ||
import { bn254 } from '@noble/curves/bn'; | ||
import { jubjub } from '@noble/curves/jubjub'; | ||
``` | ||
To define a custom curve, check out API below. | ||
## API | ||
- [Overview](#overview) | ||
- [abstract/edwards: Twisted Edwards curve](#abstract/edwards-twisted-edwards-curve) | ||
- [abstract/montgomery: Montgomery curve](#abstract/montgomery-montgomery-curve) | ||
- [abstract/weierstrass: Short Weierstrass curve](#abstract/weierstrass-short-weierstrass-curve) | ||
- [abstract/modular](#abstract/modular) | ||
- [abstract/utils](#abstract/utils) | ||
### Overview | ||
There are following zero-dependency abstract algorithms: | ||
```ts | ||
import { bls } from '@noble/curves/abstract/bls'; | ||
import { twistedEdwards } from '@noble/curves/abstract/edwards'; | ||
import { montgomery } from '@noble/curves/abstract/montgomery'; | ||
import { weierstrass } from '@noble/curves/abstract/weierstrass'; | ||
import * as mod from '@noble/curves/abstract/modular'; | ||
import * as utils from '@noble/curves/abstract/utils'; | ||
``` | ||
They allow to define a new curve in a few lines of code: | ||
```ts | ||
import { Fp } from '@noble/curves/abstract/modular'; | ||
import { weierstrass } from '@noble/curves/abstract/weierstrass'; | ||
import { hmac } from '@noble/hashes/hmac'; | ||
import { sha256 } from '@noble/hashes/sha256'; | ||
import { hmac } from '@noble/hashes/hmac'; | ||
import { concatBytes, randomBytes } from '@noble/hashes/utils'; | ||
@@ -58,70 +121,53 @@ | ||
b: 7n, | ||
P: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn, | ||
n: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n, | ||
Fp: Fp(2n ** 256n - 2n ** 32n - 2n ** 9n - 2n ** 8n - 2n ** 7n - 2n ** 6n - 2n ** 4n - 1n), | ||
n: 2n ** 256n - 432420386565659656852420866394968145599n, | ||
Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n, | ||
Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n, | ||
hash: sha256, | ||
hmac: (k: Uint8Array, ...msgs: Uint8Array[]) => hmac(sha256, key, concatBytes(...msgs)), | ||
hmac: (key: Uint8Array, ...msgs: Uint8Array[]) => hmac(sha256, key, concatBytes(...msgs)), | ||
randomBytes, | ||
}); | ||
const key = secp256k1.utils.randomPrivateKey(); | ||
const pub = secp256k1.getPublicKey(key); | ||
const msg = randomBytes(32); | ||
const sig = secp256k1.sign(msg, key); | ||
secp256k1.verify(sig, msg, pub); // true | ||
sig.recoverPublicKey(msg); // == pub | ||
const someonesPubkey = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey()); | ||
const shared = secp256k1.getSharedSecret(key, someonesPubkey); | ||
``` | ||
## API | ||
- [Overview](#overview) | ||
- [edwards: Twisted Edwards curve](#edwards-twisted-edwards-curve) | ||
- [montgomery: Montgomery curve](#montgomery-montgomery-curve) | ||
- [weierstrass: Short Weierstrass curve](#weierstrass-short-weierstrass-curve) | ||
- [modular](#modular) | ||
- [utils](#utils) | ||
### Overview | ||
* To initialize new curve, you must specify its variables, order (number of points on curve), field prime (over which the modular division would be done) | ||
* All curves expose same generic interface: | ||
* `getPublicKey()`, `sign()`, `verify()` functions | ||
* `Point` conforming to `Group` interface with add/multiply/double/negate/add/equals methods | ||
* `CURVE` object with curve variables like `Gx`, `Gy`, `P` (field), `n` (order) | ||
* `utils` object with `randomPrivateKey()`, `mod()`, `invert()` methods (`mod CURVE.P`) | ||
* All arithmetics is done with JS bigints over finite fields | ||
* Many features require hashing, which is not provided. `@noble/hashes` can be used for this purpose. | ||
- To initialize new curve, you must specify its variables, order (number of points on curve), field prime (over which the modular division would be done) | ||
- All curves expose same generic interface: | ||
- `getPublicKey()`, `sign()`, `verify()` functions | ||
- `Point` conforming to `Group` interface with add/multiply/double/negate/add/equals methods | ||
- `CURVE` object with curve variables like `Gx`, `Gy`, `Fp` (field), `n` (order) | ||
- `utils` object with `randomPrivateKey()`, `mod()`, `invert()` methods (`mod CURVE.P`) | ||
- All arithmetics is done with JS bigints over finite fields, which is defined from `modular` sub-module | ||
- Many features require hashing, which is not provided. `@noble/hashes` can be used for this purpose. | ||
Any other library must conform to the CHash interface: | ||
```ts | ||
export type CHash = { | ||
(message: Uint8Array): Uint8Array; | ||
blockLen: number; outputLen: number; create(): any; | ||
}; | ||
``` | ||
* w-ary non-adjacent form (wNAF) method with constant-time adjustments is used for point multiplication. | ||
```ts | ||
export type CHash = { | ||
(message: Uint8Array): Uint8Array; | ||
blockLen: number; | ||
outputLen: number; | ||
create(): any; | ||
}; | ||
``` | ||
- w-ary non-adjacent form (wNAF) method with constant-time adjustments is used for point multiplication. | ||
It is possible to enable precomputes for edwards & weierstrass curves. | ||
Precomputes are calculated once (takes ~20-40ms), after that most `G` multiplications | ||
- for example, `getPublicKey()`, `sign()` and similar methods - would be much faster. | ||
Use `curve.utils.precompute()` | ||
* Special params that tune performance can be optionally provided. For example: | ||
* `sqrtMod` square root calculation, used for point decompression | ||
* `endo` endomorphism options for Koblitz curves | ||
Precomputes are calculated once (takes ~20-40ms), after that most `G` base point multiplications: | ||
for example, `getPublicKey()`, `sign()` and similar methods - would be much faster. | ||
Use `curve.utils.precompute()` to adjust precomputation window size | ||
- You could use optional special params to tune performance: | ||
- `Fp({sqrt})` square root calculation, used for point decompression | ||
- `endo` endomorphism options for Koblitz curves | ||
### edwards: Twisted Edwards curve | ||
### abstract/edwards: Twisted Edwards curve | ||
Twisted Edwards curve's formula is: ax² + y² = 1 + dx²y². | ||
* You must specify curve params `a`, `d`, field `P`, order `n`, cofactor `h`, and coordinates `Gx`, `Gy` of generator point. | ||
* For EdDSA signatures, params `hash` is also required. `adjustScalarBytes` which instructs how to change private scalars could be specified. | ||
- You must specify curve params `a`, `d`, field `Fp`, order `n`, cofactor `h` and coordinates `Gx`, `Gy` of generator point | ||
- For EdDSA signatures, params `hash` is also required. `adjustScalarBytes` which instructs how to change private scalars could be specified | ||
```typescript | ||
import { twistedEdwards } from '@noble/curves/edwards'; // Twisted Edwards curve | ||
import { twistedEdwards } from '@noble/curves/abstract/edwards'; | ||
import { div } from '@noble/curves/abstract/modular'; | ||
import { sha512 } from '@noble/hashes/sha512'; | ||
import * as mod from '@noble/curves/modular'; | ||
const ed25519 = twistedEdwards({ | ||
a: -1n, | ||
d: mod.div(-121665n, 121666n, 2n ** 255n - 19n), // -121665n/121666n | ||
d: div(-121665n, 121666n, 2n ** 255n - 19n), // -121665n/121666n | ||
P: 2n ** 255n - 19n, | ||
@@ -134,3 +180,4 @@ n: 2n ** 252n + 27742317777372353535851937790883648493n, | ||
randomBytes, | ||
adjustScalarBytes(bytes) { // optional | ||
adjustScalarBytes(bytes) { | ||
// optional in general, mandatory in ed25519 | ||
bytes[0] &= 248; | ||
@@ -142,3 +189,7 @@ bytes[31] &= 127; | ||
} as const); | ||
ed25519.getPublicKey(ed25519.utils.randomPrivateKey()); | ||
const key = ed25519.utils.randomPrivateKey(); | ||
const pub = ed25519.getPublicKey(key); | ||
const msg = new TextEncoder().encode('hello world'); // strings not accepted, must be Uint8Array | ||
const sig = ed25519.sign(msg, key); | ||
ed25519.verify(sig, msg, pub) === true; | ||
``` | ||
@@ -172,3 +223,3 @@ | ||
### montgomery: Montgomery curve | ||
### abstract/montgomery: Montgomery curve | ||
@@ -182,2 +233,4 @@ For now the module only contains methods for x-only ECDH on Curve25519 / Curve448 from RFC7748. | ||
```typescript | ||
import { montgomery } from '@noble/curves/abstract/montgomery'; | ||
const x25519 = montgomery({ | ||
@@ -191,3 +244,5 @@ P: 2n ** 255n - 19n, | ||
// Optional params | ||
powPminus2: (x: bigint): bigint => { return mod.pow(x, P-2, P); }, | ||
powPminus2: (x: bigint): bigint => { | ||
return mod.pow(x, P - 2, P); | ||
}, | ||
adjustScalarBytes(bytes) { | ||
@@ -202,13 +257,14 @@ bytes[0] &= 248; | ||
### weierstrass: Short Weierstrass curve | ||
### abstract/weierstrass: Short Weierstrass curve | ||
Short Weierstrass curve's formula is: y² = x³ + ax + b. Uses deterministic ECDSA from RFC6979. You can also specify `extraEntropy` in `sign()`. | ||
* You must specify curve params: `a`, `b`; field `P`; curve order `n`; coordinates `Gx`, `Gy` of generator point | ||
* For ECDSA, you must specify `hash`, `hmac`. It is also possible to recover keys from signatures | ||
* For ECDH, use `getSharedSecret(privKeyA, pubKeyB)` | ||
* Optional params are `lowS` (default value), `sqrtMod` (square root chain) and `endo` (endomorphism) | ||
- You must specify curve params: `a`, `b`, field `Fp`, order `n`, cofactor `h` and coordinates `Gx`, `Gy` of generator point | ||
- For ECDSA, you must specify `hash`, `hmac`. It is also possible to recover keys from signatures | ||
- For ECDH, use `getSharedSecret(privKeyA, pubKeyB)` | ||
- Optional params are `lowS` (default value) and `endo` (endomorphism) | ||
```typescript | ||
import { weierstrass } from '@noble/curves/weierstrass'; // Short Weierstrass curve | ||
import { Fp } from '@noble/curves/abstract/modular'; | ||
import { weierstrass } from '@noble/curves/abstract/weierstrass'; // Short Weierstrass curve | ||
import { sha256 } from '@noble/hashes/sha256'; | ||
@@ -219,7 +275,6 @@ import { hmac } from '@noble/hashes/hmac'; | ||
const secp256k1 = weierstrass({ | ||
// Required params | ||
a: 0n, | ||
b: 7n, | ||
P: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn, | ||
n: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n, | ||
Fp: Fp(2n ** 256n - 2n ** 32n - 2n ** 9n - 2n ** 8n - 2n ** 7n - 2n ** 6n - 2n ** 4n - 1n), | ||
n: 2n ** 256n - 432420386565659656852420866394968145599n, | ||
Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n, | ||
@@ -232,15 +287,11 @@ Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n, | ||
// Optional params | ||
// Cofactor | ||
h: BigInt(1), | ||
// Allow only low-S signatures by default in sign() and verify() | ||
lowS: true, | ||
// More efficient curve-specific implementation of square root | ||
sqrtMod(y: bigint) { return sqrt(y); }, | ||
// Endomorphism options | ||
h: 1n, // Cofactor | ||
lowS: true, // Allow only low-S signatures by default in sign() and verify() | ||
endo: { | ||
// Endomorphism options for Koblitz curve | ||
// Beta param | ||
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'), | ||
beta: 0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501een, | ||
// Split scalar k into k1, k2 | ||
splitScalar: (k: bigint) => { | ||
return { k1neg: true, k1: 512n, k2neg: false, k2: 448n }; | ||
// return { k1neg: true, k1: 512n, k2neg: false, k2: 448n }; | ||
}, | ||
@@ -270,10 +321,13 @@ }, | ||
verify: ( | ||
signature: Hex | SignatureType, msgHash: Hex, publicKey: PubKey, opts?: {lowS?: boolean;} | ||
signature: Hex | SignatureType, | ||
msgHash: Hex, | ||
publicKey: PubKey, | ||
opts?: { lowS?: boolean } | ||
) => boolean; | ||
Point: PointConstructor; | ||
JacobianPoint: JacobianPointConstructor; | ||
ProjectivePoint: ProjectivePointConstructor; | ||
Signature: SignatureConstructor; | ||
utils: { | ||
mod: (a: bigint, b?: bigint) => bigint; | ||
invert: (number: bigint, modulo?: bigint) => bigint; | ||
mod: (a: bigint) => bigint; | ||
invert: (number: bigint) => bigint; | ||
isValidPrivateKey(privateKey: PrivKey): boolean; | ||
@@ -286,3 +340,3 @@ hashToPrivateKey: (hash: Hex) => Uint8Array; | ||
### modular | ||
### abstract/modular | ||
@@ -292,14 +346,17 @@ Modular arithmetics utilities. | ||
```typescript | ||
import * as mod from '@noble/curves/modular'; | ||
mod.mod(21n, 10n); // 21 mod 10 == 1n; fixed version of 21 % 10 | ||
mod.invert(17n, 10n); // invert(17) mod 10; modular multiplicative inverse | ||
mod.div(5n, 17n, 10n); // 5/17 mod 10 == 5 * invert(17) mod 10; division | ||
mod.invertBatch([1n, 2n, 4n], 21n); // => [1n, 11n, 16n] in one inversion | ||
mod.sqrt(21n, 73n); // sqrt(21) mod 73; square root | ||
import { mod, invert, div, invertBatch, sqrt, Fp } from '@noble/curves/abstract/modular'; | ||
mod(21n, 10n); // 21 mod 10 == 1n; fixed version of 21 % 10 | ||
invert(17n, 10n); // invert(17) mod 10; modular multiplicative inverse | ||
div(5n, 17n, 10n); // 5/17 mod 10 == 5 * invert(17) mod 10; division | ||
invertBatch([1n, 2n, 4n], 21n); // => [1n, 11n, 16n] in one inversion | ||
sqrt(21n, 73n); // √21 mod 73; square root | ||
const fp = Fp(2n ** 255n - 19n); // Finite field over 2^255-19 | ||
fp.mul(591n, 932n); | ||
fp.pow(481n, 11024858120n); | ||
``` | ||
### utils | ||
### abstract/utils | ||
```typescript | ||
import * as utils from '@noble/curves/utils'; | ||
import * as utils from '@noble/curves/abstract/utils'; | ||
@@ -333,55 +390,39 @@ utils.bytesToHex(Uint8Array.from([0xde, 0xad, 0xbe, 0xef])); | ||
``` | ||
==== secp256k1 ==== | ||
- getPublicKey1 (samples: 10000) | ||
noble_old x 8,131 ops/sec @ 122μs/op | ||
secp256k1 x 7,374 ops/sec @ 135μs/op | ||
- getPublicKey255 (samples: 10000) | ||
noble_old x 7,894 ops/sec @ 126μs/op | ||
secp256k1 x 7,327 ops/sec @ 136μs/op | ||
- sign (samples: 5000) | ||
noble_old x 5,243 ops/sec @ 190μs/op | ||
secp256k1 x 4,834 ops/sec @ 206μs/op | ||
- getSharedSecret (samples: 1000) | ||
noble_old x 653 ops/sec @ 1ms/op | ||
secp256k1 x 634 ops/sec @ 1ms/op | ||
- verify (samples: 1000) | ||
secp256k1_old x 1,038 ops/sec @ 962μs/op | ||
secp256k1 x 1,009 ops/sec @ 990μs/op | ||
==== ed25519 ==== | ||
- getPublicKey (samples: 10000) | ||
old x 8,632 ops/sec @ 115μs/op | ||
noble x 8,390 ops/sec @ 119μs/op | ||
- sign (samples: 5000) | ||
old x 4,376 ops/sec @ 228μs/op | ||
noble x 4,233 ops/sec @ 236μs/op | ||
- verify (samples: 1000) | ||
old x 865 ops/sec @ 1ms/op | ||
noble x 860 ops/sec @ 1ms/op | ||
==== ed448 ==== | ||
- getPublicKey (samples: 5000) | ||
noble x 3,224 ops/sec @ 310μs/op | ||
- sign (samples: 2500) | ||
noble x 1,561 ops/sec @ 640μs/op | ||
- verify (samples: 500) | ||
noble x 313 ops/sec @ 3ms/op | ||
==== nist ==== | ||
- getPublicKey (samples: 2500) | ||
P256 x 7,993 ops/sec @ 125μs/op | ||
P384 x 3,819 ops/sec @ 261μs/op | ||
P521 x 2,074 ops/sec @ 481μs/op | ||
- sign (samples: 1000) | ||
P256 x 5,327 ops/sec @ 187μs/op | ||
P384 x 2,728 ops/sec @ 366μs/op | ||
P521 x 1,594 ops/sec @ 626μs/op | ||
- verify (samples: 250) | ||
P256 x 806 ops/sec @ 1ms/op | ||
P384 x 353 ops/sec @ 2ms/op | ||
P521 x 171 ops/sec @ 5ms/op | ||
getPublicKey | ||
secp256k1 x 5,241 ops/sec @ 190μs/op | ||
P256 x 7,993 ops/sec @ 125μs/op | ||
P384 x 3,819 ops/sec @ 261μs/op | ||
P521 x 2,074 ops/sec @ 481μs/op | ||
ed25519 x 8,390 ops/sec @ 119μs/op | ||
ed448 x 3,224 ops/sec @ 310μs/op | ||
sign | ||
secp256k1 x 3,934 ops/sec @ 254μs/op | ||
P256 x 5,327 ops/sec @ 187μs/op | ||
P384 x 2,728 ops/sec @ 366μs/op | ||
P521 x 1,594 ops/sec @ 626μs/op | ||
ed25519 x 4,233 ops/sec @ 236μs/op | ||
ed448 x 1,561 ops/sec @ 640μs/op | ||
verify | ||
secp256k1 x 731 ops/sec @ 1ms/op | ||
P256 x 806 ops/sec @ 1ms/op | ||
P384 x 353 ops/sec @ 2ms/op | ||
P521 x 171 ops/sec @ 5ms/op | ||
ed25519 x 860 ops/sec @ 1ms/op | ||
ed448 x 313 ops/sec @ 3ms/op | ||
getSharedSecret | ||
secp256k1 x 445 ops/sec @ 2ms/op | ||
recoverPublicKey | ||
secp256k1 x 732 ops/sec @ 1ms/op | ||
==== bls12-381 ==== | ||
getPublicKey x 817 ops/sec @ 1ms/op | ||
sign x 50 ops/sec @ 19ms/op | ||
verify x 34 ops/sec @ 28ms/op | ||
pairing x 89 ops/sec @ 11ms/op | ||
==== stark ==== | ||
- pedersen (samples: 500) | ||
old x 85 ops/sec @ 11ms/op | ||
noble x 1,216 ops/sec @ 822μs/op | ||
- verify (samples: 500) | ||
old x 302 ops/sec @ 3ms/op | ||
noble x 698 ops/sec @ 1ms/op | ||
pedersen | ||
old x 85 ops/sec @ 11ms/op | ||
noble x 1,216 ops/sec @ 822μs/op | ||
verify | ||
old x 302 ops/sec @ 3ms/op | ||
noble x 698 ops/sec @ 1ms/op | ||
``` | ||
@@ -388,0 +429,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
578641
73
12546
428
1
11
+ Added@noble/hashes@1.1.5
+ Added@noble/hashes@1.1.5(transitive)