@noble/curves 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -71
- package/lib/abstract/curve.d.ts +9 -5
- package/lib/abstract/curve.js +21 -8
- package/lib/abstract/edwards.js +24 -1
- package/lib/abstract/hash-to-curve.d.ts +0 -1
- package/lib/abstract/hash-to-curve.js +10 -17
- package/lib/abstract/modular.d.ts +1 -1
- package/lib/abstract/montgomery.js +3 -1
- package/lib/abstract/utils.d.ts +15 -2
- package/lib/abstract/utils.js +24 -16
- package/lib/abstract/weierstrass.js +3 -0
- package/lib/esm/abstract/curve.js +21 -8
- package/lib/esm/abstract/edwards.js +24 -1
- package/lib/esm/abstract/hash-to-curve.js +10 -16
- package/lib/esm/abstract/montgomery.js +3 -1
- package/lib/esm/abstract/utils.js +24 -16
- package/lib/esm/abstract/weierstrass.js +3 -0
- package/package.json +4 -6
package/README.md
CHANGED
|
@@ -22,8 +22,7 @@ Package consists of two parts:
|
|
|
22
22
|
|
|
23
23
|
Curves incorporate work from previous noble packages
|
|
24
24
|
([secp256k1](https://github.com/paulmillr/noble-secp256k1),
|
|
25
|
-
[ed25519](https://github.com/paulmillr/noble-ed25519),
|
|
26
|
-
[bls12-381](https://github.com/paulmillr/noble-bls12-381)),
|
|
25
|
+
[ed25519](https://github.com/paulmillr/noble-ed25519)),
|
|
27
26
|
which had security audits and were developed from 2019 to 2022.
|
|
28
27
|
Check out [Upgrading](#upgrading) section if you've used them before.
|
|
29
28
|
|
|
@@ -31,14 +30,14 @@ Check out [Upgrading](#upgrading) section if you've used them before.
|
|
|
31
30
|
|
|
32
31
|
> **noble-crypto** — high-security, easily auditable set of contained cryptographic libraries and tools.
|
|
33
32
|
|
|
34
|
-
-
|
|
33
|
+
- Protection against supply chain attacks
|
|
35
34
|
- Easily auditable TypeScript/JS code
|
|
36
35
|
- Supported in all major browsers and stable node.js versions
|
|
37
36
|
- All releases are signed with PGP keys
|
|
38
37
|
- Check out [homepage](https://paulmillr.com/noble/) & all libraries:
|
|
39
|
-
[curves](https://github.com/paulmillr/noble-curves)
|
|
40
|
-
[
|
|
41
|
-
[
|
|
38
|
+
[curves](https://github.com/paulmillr/noble-curves)
|
|
39
|
+
([secp256k1](https://github.com/paulmillr/noble-secp256k1),
|
|
40
|
+
[ed25519](https://github.com/paulmillr/noble-ed25519)),
|
|
42
41
|
[hashes](https://github.com/paulmillr/noble-hashes)
|
|
43
42
|
|
|
44
43
|
## Usage
|
|
@@ -48,23 +47,7 @@ Use NPM in node.js / browser, or include single file from
|
|
|
48
47
|
|
|
49
48
|
> npm install @noble/curves
|
|
50
49
|
|
|
51
|
-
The library does not have an entry point. It allows you to select specific primitives and drop everything else. If you only want to use secp256k1, just use the library with rollup or other bundlers. This is done to make your bundles tiny.
|
|
52
|
-
|
|
53
|
-
```ts
|
|
54
|
-
// Common.js and ECMAScript Modules (ESM)
|
|
55
|
-
import { secp256k1 } from '@noble/curves/secp256k1';
|
|
56
|
-
|
|
57
|
-
const key = secp256k1.utils.randomPrivateKey();
|
|
58
|
-
const pub = secp256k1.getPublicKey(key);
|
|
59
|
-
const msg = new Uint8Array(32).fill(1);
|
|
60
|
-
const sig = secp256k1.sign(msg, key);
|
|
61
|
-
secp256k1.verify(sig, msg, pub) === true;
|
|
62
|
-
sig.recoverPublicKey(msg) === pub;
|
|
63
|
-
const someonesPub = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey());
|
|
64
|
-
const shared = secp256k1.getSharedSecret(key, someonesPub);
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
All curves:
|
|
50
|
+
The library does not have an entry point. It allows you to select specific primitives and drop everything else. If you only want to use secp256k1, just use the library with rollup or other bundlers. This is done to make your bundles tiny. All curves:
|
|
68
51
|
|
|
69
52
|
```ts
|
|
70
53
|
import { secp256k1 } from '@noble/curves/secp256k1';
|
|
@@ -80,7 +63,25 @@ import { bn254 } from '@noble/curves/bn';
|
|
|
80
63
|
import { jubjub } from '@noble/curves/jubjub';
|
|
81
64
|
```
|
|
82
65
|
|
|
83
|
-
|
|
66
|
+
Every curve can be used in the following way:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { secp256k1 } from '@noble/curves/secp256k1'; // Common.js and ECMAScript Modules (ESM)
|
|
70
|
+
|
|
71
|
+
const key = secp256k1.utils.randomPrivateKey();
|
|
72
|
+
const pub = secp256k1.getPublicKey(key);
|
|
73
|
+
const msg = new Uint8Array(32).fill(1);
|
|
74
|
+
const sig = secp256k1.sign(msg, key);
|
|
75
|
+
// weierstrass curves should use extraEntropy: https://moderncrypto.org/mail-archive/curves/2017/000925.html
|
|
76
|
+
const sigImprovedSecurity = secp256k1.sign(msg, key, { extraEntropy: true });
|
|
77
|
+
secp256k1.verify(sig, msg, pub) === true;
|
|
78
|
+
// secp, p*, pasta curves allow pub recovery
|
|
79
|
+
sig.recoverPublicKey(msg) === pub;
|
|
80
|
+
const someonesPub = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey());
|
|
81
|
+
const shared = secp256k1.getSharedSecret(key, someonesPub);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
To define a custom curve, check out docs below.
|
|
84
85
|
|
|
85
86
|
## API
|
|
86
87
|
|
|
@@ -109,17 +110,20 @@ import * as utils from '@noble/curves/abstract/utils';
|
|
|
109
110
|
They allow to define a new curve in a few lines of code:
|
|
110
111
|
|
|
111
112
|
```ts
|
|
112
|
-
import {
|
|
113
|
+
import { Field } from '@noble/curves/abstract/modular';
|
|
113
114
|
import { weierstrass } from '@noble/curves/abstract/weierstrass';
|
|
114
115
|
import { hmac } from '@noble/hashes/hmac';
|
|
115
116
|
import { sha256 } from '@noble/hashes/sha256';
|
|
116
117
|
import { concatBytes, randomBytes } from '@noble/hashes/utils';
|
|
117
118
|
|
|
118
|
-
|
|
119
|
+
// secq (NOT secp) 256k1: cycle of secp256k1 with Fp/N flipped.
|
|
120
|
+
// https://zcash.github.io/halo2/background/curves.html#cycles-of-curves
|
|
121
|
+
// https://personaelabs.org/posts/spartan-ecdsa
|
|
122
|
+
const secq256k1 = weierstrass({
|
|
119
123
|
a: 0n,
|
|
120
124
|
b: 7n,
|
|
121
|
-
Fp:
|
|
122
|
-
n: 2n ** 256n -
|
|
125
|
+
Fp: Field(2n ** 256n - 432420386565659656852420866394968145599n),
|
|
126
|
+
n: 2n ** 256n - 2n ** 32n - 2n ** 9n - 2n ** 8n - 2n ** 7n - 2n ** 6n - 2n ** 4n - 1n,
|
|
123
127
|
Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
|
|
124
128
|
Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
|
|
125
129
|
hash: sha256,
|
|
@@ -329,47 +333,54 @@ The module allows to hash arbitrary strings to elliptic curve points.
|
|
|
329
333
|
|
|
330
334
|
- `expand_message_xmd` [(spec)](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.4.1) produces a uniformly random byte string using a cryptographic hash function H that outputs b bits..
|
|
331
335
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
336
|
+
```ts
|
|
337
|
+
function expand_message_xmd(
|
|
338
|
+
msg: Uint8Array,
|
|
339
|
+
DST: Uint8Array,
|
|
340
|
+
lenInBytes: number,
|
|
341
|
+
H: CHash
|
|
342
|
+
): Uint8Array;
|
|
343
|
+
function expand_message_xof(
|
|
344
|
+
msg: Uint8Array,
|
|
345
|
+
DST: Uint8Array,
|
|
346
|
+
lenInBytes: number,
|
|
347
|
+
k: number,
|
|
348
|
+
H: CHash
|
|
349
|
+
): Uint8Array;
|
|
350
|
+
```
|
|
340
351
|
|
|
341
352
|
- `hash_to_field(msg, count, options)` [(spec)](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3)
|
|
342
|
-
hashes arbitrary-length byte strings to a list of one or more elements of a finite field F.
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
353
|
+
hashes arbitrary-length byte strings to a list of one or more elements of a finite field F.
|
|
354
|
+
_ `msg` a byte string containing the message to hash
|
|
355
|
+
_ `count` the number of elements of F to output
|
|
356
|
+
_ `options` `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}`
|
|
357
|
+
_ Returns `[u_0, ..., u_(count - 1)]`, a list of field elements.
|
|
358
|
+
|
|
359
|
+
```ts
|
|
360
|
+
function hash_to_field(msg: Uint8Array, count: number, options: htfOpts): bigint[][];
|
|
361
|
+
type htfOpts = {
|
|
362
|
+
// DST: a domain separation tag
|
|
363
|
+
// defined in section 2.2.5
|
|
364
|
+
DST: string;
|
|
365
|
+
// p: the characteristic of F
|
|
366
|
+
// where F is a finite field of characteristic p and order q = p^m
|
|
367
|
+
p: bigint;
|
|
368
|
+
// m: the extension degree of F, m >= 1
|
|
369
|
+
// where F is a finite field of characteristic p and order q = p^m
|
|
370
|
+
m: number;
|
|
371
|
+
// k: the target security level for the suite in bits
|
|
372
|
+
// defined in section 5.1
|
|
373
|
+
k: number;
|
|
374
|
+
// option to use a message that has already been processed by
|
|
375
|
+
// expand_message_xmd
|
|
376
|
+
expand?: 'xmd' | 'xof';
|
|
377
|
+
// Hash functions for: expand_message_xmd is appropriate for use with a
|
|
378
|
+
// wide range of hash functions, including SHA-2, SHA-3, BLAKE2, and others.
|
|
379
|
+
// BBS+ uses blake2: https://github.com/hyperledger/aries-framework-go/issues/2247
|
|
380
|
+
// TODO: verify that hash is shake if expand==='xof' via types
|
|
381
|
+
hash: CHash;
|
|
382
|
+
};
|
|
383
|
+
```
|
|
373
384
|
|
|
374
385
|
### abstract/poseidon: Poseidon hash
|
|
375
386
|
|
|
@@ -516,11 +527,11 @@ Upgrading from @noble/secp256k1 1.7:
|
|
|
516
527
|
- Compressed (33-byte) public keys are now returned by default, instead of uncompressed
|
|
517
528
|
- Methods are now synchronous. Setting `secp.utils.hmacSha256` is no longer required
|
|
518
529
|
- `sign()`
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
530
|
+
- `der`, `recovered` options were removed
|
|
531
|
+
- `canonical` was renamed to `lowS`
|
|
532
|
+
- Return type is now `{ r: bigint, s: bigint, recovery: number }` instance of `Signature`
|
|
522
533
|
- `verify()`
|
|
523
|
-
|
|
534
|
+
- `strict` was renamed to `lowS`
|
|
524
535
|
- `recoverPublicKey()`: moved to sig instance `Signature#recoverPublicKey(msgHash)`
|
|
525
536
|
- `Point` was removed: use `ProjectivePoint` in xyz coordinates
|
|
526
537
|
- `utils`: Many methods were removed, others were moved to `schnorr` namespace
|
|
@@ -532,6 +543,7 @@ Upgrading from @noble/ed25519 1.7:
|
|
|
532
543
|
- `Point` was removed: use `ExtendedPoint` in xyzt coordinates
|
|
533
544
|
- `Signature` was removed
|
|
534
545
|
- `getSharedSecret` was removed: use separate x25519 sub-module
|
|
546
|
+
- `bigint` is no longer allowed in `getPublicKey`, `sign`, `verify`. Reason: ed25519 is LE, can lead to bugs
|
|
535
547
|
|
|
536
548
|
## Contributing & testing
|
|
537
549
|
|
package/lib/abstract/curve.d.ts
CHANGED
|
@@ -26,15 +26,19 @@ export declare function wNAF<T extends Group<T>>(c: GroupConstructor<T>, bits: n
|
|
|
26
26
|
/**
|
|
27
27
|
* Creates a wNAF precomputation window. Used for caching.
|
|
28
28
|
* Default window size is set by `utils.precompute()` and is equal to 8.
|
|
29
|
-
*
|
|
30
|
-
*
|
|
29
|
+
* Number of precomputed points depends on the curve size:
|
|
30
|
+
* 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
|
|
31
|
+
* - 𝑊 is the window size
|
|
32
|
+
* - 𝑛 is the bitlength of the curve order.
|
|
33
|
+
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
|
34
|
+
* @returns precomputed point tables flattened to a single array
|
|
31
35
|
*/
|
|
32
36
|
precomputeWindow(elm: T, W: number): Group<T>[];
|
|
33
37
|
/**
|
|
34
|
-
* Implements w-ary non-adjacent form
|
|
38
|
+
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
|
35
39
|
* @param W window size
|
|
36
|
-
* @param
|
|
37
|
-
* @param n
|
|
40
|
+
* @param precomputes precomputed tables
|
|
41
|
+
* @param n scalar (we don't check here, but should be less than curve order)
|
|
38
42
|
* @returns real and fake (for const-time) points
|
|
39
43
|
*/
|
|
40
44
|
wNAF(W: number, precomputes: T[], n: bigint): {
|
package/lib/abstract/curve.js
CHANGED
|
@@ -7,8 +7,17 @@ const modular_js_1 = require("./modular.js");
|
|
|
7
7
|
const utils_js_1 = require("./utils.js");
|
|
8
8
|
const _0n = BigInt(0);
|
|
9
9
|
const _1n = BigInt(1);
|
|
10
|
-
// Elliptic curve multiplication of Point by scalar.
|
|
11
|
-
//
|
|
10
|
+
// Elliptic curve multiplication of Point by scalar. Fragile.
|
|
11
|
+
// Scalars should always be less than curve order: this should be checked inside of a curve itself.
|
|
12
|
+
// Creates precomputation tables for fast multiplication:
|
|
13
|
+
// - private scalar is split by fixed size windows of W bits
|
|
14
|
+
// - every window point is collected from window's table & added to accumulator
|
|
15
|
+
// - since windows are different, same point inside tables won't be accessed more than once per calc
|
|
16
|
+
// - each multiplication is 'Math.ceil(CURVE_ORDER / 𝑊) + 1' point additions (fixed for any scalar)
|
|
17
|
+
// - +1 window is neccessary for wNAF
|
|
18
|
+
// - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication
|
|
19
|
+
// TODO: Research returning 2d JS array of windows, instead of a single window. This would allow
|
|
20
|
+
// windows to be in different memory locations
|
|
12
21
|
function wNAF(c, bits) {
|
|
13
22
|
const constTimeNegate = (condition, item) => {
|
|
14
23
|
const neg = item.negate();
|
|
@@ -36,8 +45,12 @@ function wNAF(c, bits) {
|
|
|
36
45
|
/**
|
|
37
46
|
* Creates a wNAF precomputation window. Used for caching.
|
|
38
47
|
* Default window size is set by `utils.precompute()` and is equal to 8.
|
|
39
|
-
*
|
|
40
|
-
*
|
|
48
|
+
* Number of precomputed points depends on the curve size:
|
|
49
|
+
* 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
|
|
50
|
+
* - 𝑊 is the window size
|
|
51
|
+
* - 𝑛 is the bitlength of the curve order.
|
|
52
|
+
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
|
53
|
+
* @returns precomputed point tables flattened to a single array
|
|
41
54
|
*/
|
|
42
55
|
precomputeWindow(elm, W) {
|
|
43
56
|
const { windows, windowSize } = opts(W);
|
|
@@ -57,14 +70,14 @@ function wNAF(c, bits) {
|
|
|
57
70
|
return points;
|
|
58
71
|
},
|
|
59
72
|
/**
|
|
60
|
-
* Implements w-ary non-adjacent form
|
|
73
|
+
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
|
61
74
|
* @param W window size
|
|
62
|
-
* @param
|
|
63
|
-
* @param n
|
|
75
|
+
* @param precomputes precomputed tables
|
|
76
|
+
* @param n scalar (we don't check here, but should be less than curve order)
|
|
64
77
|
* @returns real and fake (for const-time) points
|
|
65
78
|
*/
|
|
66
79
|
wNAF(W, precomputes, n) {
|
|
67
|
-
// TODO: maybe check that scalar is less than group order? wNAF
|
|
80
|
+
// TODO: maybe check that scalar is less than group order? wNAF behavious is undefined otherwise
|
|
68
81
|
// But need to carefully remove other checks before wNAF. ORDER == bits here
|
|
69
82
|
const { windows, windowSize } = opts(W);
|
|
70
83
|
let p = c.ZERO;
|
package/lib/abstract/edwards.js
CHANGED
|
@@ -109,7 +109,30 @@ function twistedEdwards(curveDef) {
|
|
|
109
109
|
this._WINDOW_SIZE = windowSize;
|
|
110
110
|
pointPrecomputes.delete(this);
|
|
111
111
|
}
|
|
112
|
-
|
|
112
|
+
// Not required for fromHex(), which always creates valid points.
|
|
113
|
+
// Could be useful for fromAffine().
|
|
114
|
+
assertValidity() {
|
|
115
|
+
const { a, d } = CURVE;
|
|
116
|
+
if (this.is0())
|
|
117
|
+
throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
|
|
118
|
+
// Equation in affine coordinates: ax² + y² = 1 + dx²y²
|
|
119
|
+
// Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
|
|
120
|
+
const { ex: X, ey: Y, ez: Z, et: T } = this;
|
|
121
|
+
const X2 = modP(X * X); // X²
|
|
122
|
+
const Y2 = modP(Y * Y); // Y²
|
|
123
|
+
const Z2 = modP(Z * Z); // Z²
|
|
124
|
+
const Z4 = modP(Z2 * Z2); // Z⁴
|
|
125
|
+
const aX2 = modP(X2 * a); // aX²
|
|
126
|
+
const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
|
|
127
|
+
const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
|
|
128
|
+
if (left !== right)
|
|
129
|
+
throw new Error('bad point: equation left != right (1)');
|
|
130
|
+
// In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
|
|
131
|
+
const XY = modP(X * Y);
|
|
132
|
+
const ZT = modP(Z * T);
|
|
133
|
+
if (XY !== ZT)
|
|
134
|
+
throw new Error('bad point: equation left != right (2)');
|
|
135
|
+
}
|
|
113
136
|
// Compare one point to another.
|
|
114
137
|
equals(other) {
|
|
115
138
|
isPoint(other);
|
|
@@ -11,7 +11,6 @@ export declare type Opts = {
|
|
|
11
11
|
expand?: 'xmd' | 'xof';
|
|
12
12
|
hash: CHash;
|
|
13
13
|
};
|
|
14
|
-
export declare function validateOpts(opts: Opts): void;
|
|
15
14
|
export declare function stringToBytes(str: string): Uint8Array;
|
|
16
15
|
export declare function expand_message_xmd(msg: Uint8Array, DST: Uint8Array, lenInBytes: number, H: CHash): Uint8Array;
|
|
17
16
|
export declare function expand_message_xof(msg: Uint8Array, DST: Uint8Array, lenInBytes: number, k: number, H: CHash): Uint8Array;
|
|
@@ -1,23 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.hashToCurve = exports.isogenyMap = exports.hash_to_field = exports.expand_message_xof = exports.expand_message_xmd = exports.stringToBytes =
|
|
3
|
+
exports.hashToCurve = exports.isogenyMap = exports.hash_to_field = exports.expand_message_xof = exports.expand_message_xmd = exports.stringToBytes = void 0;
|
|
4
4
|
const modular_js_1 = require("./modular.js");
|
|
5
5
|
const utils_js_1 = require("./utils.js");
|
|
6
|
-
function validateOpts(opts) {
|
|
7
|
-
if (typeof opts.DST !== 'string')
|
|
8
|
-
throw new Error('Invalid htf/DST');
|
|
9
|
-
if (typeof opts.p !== 'bigint')
|
|
10
|
-
throw new Error('Invalid htf/p');
|
|
11
|
-
if (typeof opts.m !== 'number')
|
|
12
|
-
throw new Error('Invalid htf/m');
|
|
13
|
-
if (typeof opts.k !== 'number')
|
|
14
|
-
throw new Error('Invalid htf/k');
|
|
15
|
-
if (opts.expand !== 'xmd' && opts.expand !== 'xof' && opts.expand !== undefined)
|
|
16
|
-
throw new Error('Invalid htf/expand');
|
|
17
|
-
if (typeof opts.hash !== 'function' || !Number.isSafeInteger(opts.hash.outputLen))
|
|
18
|
-
throw new Error('Invalid htf/hash function');
|
|
19
|
-
}
|
|
20
|
-
exports.validateOpts = validateOpts;
|
|
21
6
|
function stringToBytes(str) {
|
|
22
7
|
if (typeof str !== 'string') {
|
|
23
8
|
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
|
@@ -143,7 +128,15 @@ function isogenyMap(field, map) {
|
|
|
143
128
|
}
|
|
144
129
|
exports.isogenyMap = isogenyMap;
|
|
145
130
|
function hashToCurve(Point, mapToCurve, def) {
|
|
146
|
-
|
|
131
|
+
(0, utils_js_1.validateObject)(def, {
|
|
132
|
+
DST: 'string',
|
|
133
|
+
p: 'bigint',
|
|
134
|
+
m: 'isSafeInteger',
|
|
135
|
+
k: 'isSafeInteger',
|
|
136
|
+
hash: 'hash',
|
|
137
|
+
});
|
|
138
|
+
if (def.expand !== 'xmd' && def.expand !== 'xof' && def.expand !== undefined)
|
|
139
|
+
throw new Error('Invalid htf/expand');
|
|
147
140
|
if (typeof mapToCurve !== 'function')
|
|
148
141
|
throw new Error('hashToCurve: mapToCurve() has not been defined');
|
|
149
142
|
return {
|
|
@@ -42,7 +42,7 @@ export interface Field<T> {
|
|
|
42
42
|
fromBytes(bytes: Uint8Array): T;
|
|
43
43
|
cmov(a: T, b: T, c: boolean): T;
|
|
44
44
|
}
|
|
45
|
-
export declare function validateField<T>(field: Field<T>):
|
|
45
|
+
export declare function validateField<T>(field: Field<T>): Field<T>;
|
|
46
46
|
export declare function FpPow<T>(f: Field<T>, num: T, power: bigint): T;
|
|
47
47
|
export declare function FpInvertBatch<T>(f: Field<T>, nums: T[]): T[];
|
|
48
48
|
export declare function FpDiv<T>(f: Field<T>, lhs: T, rhs: T | bigint): T;
|
|
@@ -121,7 +121,9 @@ function montgomery(curveDef) {
|
|
|
121
121
|
// This is very ugly way, but it works because fieldLen-1 is outside of bounds for X448, so this becomes NOOP
|
|
122
122
|
// fieldLen - scalaryBytes = 1 for X448 and = 0 for X25519
|
|
123
123
|
const u = (0, utils_js_1.ensureBytes)(uEnc, montgomeryBytes);
|
|
124
|
-
u[fieldLen
|
|
124
|
+
// u[fieldLen-1] crashes QuickJS (TypeError: out-of-bound numeric index)
|
|
125
|
+
if (fieldLen === montgomeryBytes)
|
|
126
|
+
u[fieldLen - 1] &= 127; // 0b0111_1111
|
|
125
127
|
return (0, utils_js_1.bytesToNumberLE)(u);
|
|
126
128
|
}
|
|
127
129
|
function decodeScalar(n) {
|
package/lib/abstract/utils.d.ts
CHANGED
|
@@ -25,6 +25,19 @@ export declare function bitLen(n: bigint): number;
|
|
|
25
25
|
export declare const bitGet: (n: bigint, pos: number) => bigint;
|
|
26
26
|
export declare const bitSet: (n: bigint, pos: number, value: boolean) => bigint;
|
|
27
27
|
export declare const bitMask: (n: number) => bigint;
|
|
28
|
-
declare
|
|
29
|
-
|
|
28
|
+
declare const validatorFns: {
|
|
29
|
+
readonly bigint: (val: any) => boolean;
|
|
30
|
+
readonly function: (val: any) => boolean;
|
|
31
|
+
readonly boolean: (val: any) => boolean;
|
|
32
|
+
readonly string: (val: any) => boolean;
|
|
33
|
+
readonly isSafeInteger: (val: any) => boolean;
|
|
34
|
+
readonly array: (val: any) => boolean;
|
|
35
|
+
readonly field: (val: any, object: any) => any;
|
|
36
|
+
readonly hash: (val: any) => boolean;
|
|
37
|
+
};
|
|
38
|
+
declare type Validator = keyof typeof validatorFns;
|
|
39
|
+
declare type ValMap<T extends Record<string, any>> = {
|
|
40
|
+
[K in keyof T]?: Validator;
|
|
41
|
+
};
|
|
42
|
+
export declare function validateObject<T extends Record<string, any>>(object: T, validators: ValMap<T>, optValidators?: ValMap<T>): T;
|
|
30
43
|
export {};
|
package/lib/abstract/utils.js
CHANGED
|
@@ -27,7 +27,7 @@ function hexToNumber(hex) {
|
|
|
27
27
|
if (typeof hex !== 'string')
|
|
28
28
|
throw new Error('string expected, got ' + typeof hex);
|
|
29
29
|
// Big Endian
|
|
30
|
-
return BigInt(`0x${hex}`);
|
|
30
|
+
return BigInt(hex === '' ? '0' : `0x${hex}`);
|
|
31
31
|
}
|
|
32
32
|
exports.hexToNumber = hexToNumber;
|
|
33
33
|
// Caching slows it down 2-3x
|
|
@@ -118,18 +118,18 @@ exports.bitSet = bitSet;
|
|
|
118
118
|
// Not using ** operator with bigints for old engines.
|
|
119
119
|
const bitMask = (n) => (_2n << BigInt(n - 1)) - _1n;
|
|
120
120
|
exports.bitMask = bitMask;
|
|
121
|
+
const validatorFns = {
|
|
122
|
+
bigint: (val) => typeof val === 'bigint',
|
|
123
|
+
function: (val) => typeof val === 'function',
|
|
124
|
+
boolean: (val) => typeof val === 'boolean',
|
|
125
|
+
string: (val) => typeof val === 'string',
|
|
126
|
+
isSafeInteger: (val) => Number.isSafeInteger(val),
|
|
127
|
+
array: (val) => Array.isArray(val),
|
|
128
|
+
field: (val, object) => object.Fp.isValid(val),
|
|
129
|
+
hash: (val) => typeof val === 'function' && Number.isSafeInteger(val.outputLen),
|
|
130
|
+
};
|
|
131
|
+
// type Record<K extends string | number | symbol, T> = { [P in K]: T; }
|
|
121
132
|
function validateObject(object, validators, optValidators = {}) {
|
|
122
|
-
const validatorFns = {
|
|
123
|
-
bigint: (val) => typeof val === 'bigint',
|
|
124
|
-
function: (val) => typeof val === 'function',
|
|
125
|
-
boolean: (val) => typeof val === 'boolean',
|
|
126
|
-
string: (val) => typeof val === 'string',
|
|
127
|
-
isSafeInteger: (val) => Number.isSafeInteger(val),
|
|
128
|
-
array: (val) => Array.isArray(val),
|
|
129
|
-
field: (val) => object.Fp.isValid(val),
|
|
130
|
-
hash: (val) => typeof val === 'function' && Number.isSafeInteger(val.outputLen),
|
|
131
|
-
};
|
|
132
|
-
// type Key = keyof typeof validators;
|
|
133
133
|
const checkField = (fieldName, type, isOptional) => {
|
|
134
134
|
const checkVal = validatorFns[type];
|
|
135
135
|
if (typeof checkVal !== 'function')
|
|
@@ -137,14 +137,22 @@ function validateObject(object, validators, optValidators = {}) {
|
|
|
137
137
|
const val = object[fieldName];
|
|
138
138
|
if (isOptional && val === undefined)
|
|
139
139
|
return;
|
|
140
|
-
if (!checkVal(val)) {
|
|
141
|
-
throw new Error(`Invalid param ${fieldName}=${val} (${typeof val}), expected ${type}`);
|
|
140
|
+
if (!checkVal(val, object)) {
|
|
141
|
+
throw new Error(`Invalid param ${String(fieldName)}=${val} (${typeof val}), expected ${type}`);
|
|
142
142
|
}
|
|
143
143
|
};
|
|
144
|
-
for (
|
|
144
|
+
for (const [fieldName, type] of Object.entries(validators))
|
|
145
145
|
checkField(fieldName, type, false);
|
|
146
|
-
for (
|
|
146
|
+
for (const [fieldName, type] of Object.entries(optValidators))
|
|
147
147
|
checkField(fieldName, type, true);
|
|
148
148
|
return object;
|
|
149
149
|
}
|
|
150
150
|
exports.validateObject = validateObject;
|
|
151
|
+
// validate type tests
|
|
152
|
+
// const o: { a: number; b: number; c: number } = { a: 1, b: 5, c: 6 };
|
|
153
|
+
// const z0 = validateObject(o, { a: 'isSafeInteger' }, { c: 'bigint' }); // Ok!
|
|
154
|
+
// // Should fail type-check
|
|
155
|
+
// const z1 = validateObject(o, { a: 'tmp' }, { c: 'zz' });
|
|
156
|
+
// const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });
|
|
157
|
+
// const z3 = validateObject(o, { test: 'boolean', z: 'bug' });
|
|
158
|
+
// const z4 = validateObject(o, { a: 'boolean', z: 'bug' });
|
|
@@ -19,6 +19,7 @@ function validatePointOpts(curve) {
|
|
|
19
19
|
wrapPrivateKey: 'boolean',
|
|
20
20
|
isTorsionFree: 'function',
|
|
21
21
|
clearCofactor: 'function',
|
|
22
|
+
allowInfinityPoint: 'boolean',
|
|
22
23
|
});
|
|
23
24
|
const { endo, Fp, a } = opts;
|
|
24
25
|
if (endo) {
|
|
@@ -157,6 +158,8 @@ function weierstrassPoints(opts) {
|
|
|
157
158
|
if (pz == null || !Fp.isValid(pz))
|
|
158
159
|
throw new Error('z required');
|
|
159
160
|
}
|
|
161
|
+
// Does not validate if the point is on-curve.
|
|
162
|
+
// Use fromHex instead, or call assertValidity() later.
|
|
160
163
|
static fromAffine(p) {
|
|
161
164
|
const { x, y } = p || {};
|
|
162
165
|
if (!p || !Fp.isValid(x) || !Fp.isValid(y))
|
|
@@ -4,8 +4,17 @@ import { validateField, nLength } from './modular.js';
|
|
|
4
4
|
import { validateObject } from './utils.js';
|
|
5
5
|
const _0n = BigInt(0);
|
|
6
6
|
const _1n = BigInt(1);
|
|
7
|
-
// Elliptic curve multiplication of Point by scalar.
|
|
8
|
-
//
|
|
7
|
+
// Elliptic curve multiplication of Point by scalar. Fragile.
|
|
8
|
+
// Scalars should always be less than curve order: this should be checked inside of a curve itself.
|
|
9
|
+
// Creates precomputation tables for fast multiplication:
|
|
10
|
+
// - private scalar is split by fixed size windows of W bits
|
|
11
|
+
// - every window point is collected from window's table & added to accumulator
|
|
12
|
+
// - since windows are different, same point inside tables won't be accessed more than once per calc
|
|
13
|
+
// - each multiplication is 'Math.ceil(CURVE_ORDER / 𝑊) + 1' point additions (fixed for any scalar)
|
|
14
|
+
// - +1 window is neccessary for wNAF
|
|
15
|
+
// - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication
|
|
16
|
+
// TODO: Research returning 2d JS array of windows, instead of a single window. This would allow
|
|
17
|
+
// windows to be in different memory locations
|
|
9
18
|
export function wNAF(c, bits) {
|
|
10
19
|
const constTimeNegate = (condition, item) => {
|
|
11
20
|
const neg = item.negate();
|
|
@@ -33,8 +42,12 @@ export function wNAF(c, bits) {
|
|
|
33
42
|
/**
|
|
34
43
|
* Creates a wNAF precomputation window. Used for caching.
|
|
35
44
|
* Default window size is set by `utils.precompute()` and is equal to 8.
|
|
36
|
-
*
|
|
37
|
-
*
|
|
45
|
+
* Number of precomputed points depends on the curve size:
|
|
46
|
+
* 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
|
|
47
|
+
* - 𝑊 is the window size
|
|
48
|
+
* - 𝑛 is the bitlength of the curve order.
|
|
49
|
+
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
|
50
|
+
* @returns precomputed point tables flattened to a single array
|
|
38
51
|
*/
|
|
39
52
|
precomputeWindow(elm, W) {
|
|
40
53
|
const { windows, windowSize } = opts(W);
|
|
@@ -54,14 +67,14 @@ export function wNAF(c, bits) {
|
|
|
54
67
|
return points;
|
|
55
68
|
},
|
|
56
69
|
/**
|
|
57
|
-
* Implements w-ary non-adjacent form
|
|
70
|
+
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
|
58
71
|
* @param W window size
|
|
59
|
-
* @param
|
|
60
|
-
* @param n
|
|
72
|
+
* @param precomputes precomputed tables
|
|
73
|
+
* @param n scalar (we don't check here, but should be less than curve order)
|
|
61
74
|
* @returns real and fake (for const-time) points
|
|
62
75
|
*/
|
|
63
76
|
wNAF(W, precomputes, n) {
|
|
64
|
-
// TODO: maybe check that scalar is less than group order? wNAF
|
|
77
|
+
// TODO: maybe check that scalar is less than group order? wNAF behavious is undefined otherwise
|
|
65
78
|
// But need to carefully remove other checks before wNAF. ORDER == bits here
|
|
66
79
|
const { windows, windowSize } = opts(W);
|
|
67
80
|
let p = c.ZERO;
|
|
@@ -106,7 +106,30 @@ export function twistedEdwards(curveDef) {
|
|
|
106
106
|
this._WINDOW_SIZE = windowSize;
|
|
107
107
|
pointPrecomputes.delete(this);
|
|
108
108
|
}
|
|
109
|
-
|
|
109
|
+
// Not required for fromHex(), which always creates valid points.
|
|
110
|
+
// Could be useful for fromAffine().
|
|
111
|
+
assertValidity() {
|
|
112
|
+
const { a, d } = CURVE;
|
|
113
|
+
if (this.is0())
|
|
114
|
+
throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
|
|
115
|
+
// Equation in affine coordinates: ax² + y² = 1 + dx²y²
|
|
116
|
+
// Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
|
|
117
|
+
const { ex: X, ey: Y, ez: Z, et: T } = this;
|
|
118
|
+
const X2 = modP(X * X); // X²
|
|
119
|
+
const Y2 = modP(Y * Y); // Y²
|
|
120
|
+
const Z2 = modP(Z * Z); // Z²
|
|
121
|
+
const Z4 = modP(Z2 * Z2); // Z⁴
|
|
122
|
+
const aX2 = modP(X2 * a); // aX²
|
|
123
|
+
const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
|
|
124
|
+
const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
|
|
125
|
+
if (left !== right)
|
|
126
|
+
throw new Error('bad point: equation left != right (1)');
|
|
127
|
+
// In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
|
|
128
|
+
const XY = modP(X * Y);
|
|
129
|
+
const ZT = modP(Z * T);
|
|
130
|
+
if (XY !== ZT)
|
|
131
|
+
throw new Error('bad point: equation left != right (2)');
|
|
132
|
+
}
|
|
110
133
|
// Compare one point to another.
|
|
111
134
|
equals(other) {
|
|
112
135
|
isPoint(other);
|
|
@@ -1,19 +1,5 @@
|
|
|
1
1
|
import { mod } from './modular.js';
|
|
2
|
-
import { concatBytes, ensureBytes } from './utils.js';
|
|
3
|
-
export function validateOpts(opts) {
|
|
4
|
-
if (typeof opts.DST !== 'string')
|
|
5
|
-
throw new Error('Invalid htf/DST');
|
|
6
|
-
if (typeof opts.p !== 'bigint')
|
|
7
|
-
throw new Error('Invalid htf/p');
|
|
8
|
-
if (typeof opts.m !== 'number')
|
|
9
|
-
throw new Error('Invalid htf/m');
|
|
10
|
-
if (typeof opts.k !== 'number')
|
|
11
|
-
throw new Error('Invalid htf/k');
|
|
12
|
-
if (opts.expand !== 'xmd' && opts.expand !== 'xof' && opts.expand !== undefined)
|
|
13
|
-
throw new Error('Invalid htf/expand');
|
|
14
|
-
if (typeof opts.hash !== 'function' || !Number.isSafeInteger(opts.hash.outputLen))
|
|
15
|
-
throw new Error('Invalid htf/hash function');
|
|
16
|
-
}
|
|
2
|
+
import { concatBytes, ensureBytes, validateObject } from './utils.js';
|
|
17
3
|
export function stringToBytes(str) {
|
|
18
4
|
if (typeof str !== 'string') {
|
|
19
5
|
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
|
@@ -134,7 +120,15 @@ export function isogenyMap(field, map) {
|
|
|
134
120
|
};
|
|
135
121
|
}
|
|
136
122
|
export function hashToCurve(Point, mapToCurve, def) {
|
|
137
|
-
|
|
123
|
+
validateObject(def, {
|
|
124
|
+
DST: 'string',
|
|
125
|
+
p: 'bigint',
|
|
126
|
+
m: 'isSafeInteger',
|
|
127
|
+
k: 'isSafeInteger',
|
|
128
|
+
hash: 'hash',
|
|
129
|
+
});
|
|
130
|
+
if (def.expand !== 'xmd' && def.expand !== 'xof' && def.expand !== undefined)
|
|
131
|
+
throw new Error('Invalid htf/expand');
|
|
138
132
|
if (typeof mapToCurve !== 'function')
|
|
139
133
|
throw new Error('hashToCurve: mapToCurve() has not been defined');
|
|
140
134
|
return {
|
|
@@ -118,7 +118,9 @@ export function montgomery(curveDef) {
|
|
|
118
118
|
// This is very ugly way, but it works because fieldLen-1 is outside of bounds for X448, so this becomes NOOP
|
|
119
119
|
// fieldLen - scalaryBytes = 1 for X448 and = 0 for X25519
|
|
120
120
|
const u = ensureBytes(uEnc, montgomeryBytes);
|
|
121
|
-
u[fieldLen
|
|
121
|
+
// u[fieldLen-1] crashes QuickJS (TypeError: out-of-bound numeric index)
|
|
122
|
+
if (fieldLen === montgomeryBytes)
|
|
123
|
+
u[fieldLen - 1] &= 127; // 0b0111_1111
|
|
122
124
|
return bytesToNumberLE(u);
|
|
123
125
|
}
|
|
124
126
|
function decodeScalar(n) {
|
|
@@ -22,7 +22,7 @@ export function hexToNumber(hex) {
|
|
|
22
22
|
if (typeof hex !== 'string')
|
|
23
23
|
throw new Error('string expected, got ' + typeof hex);
|
|
24
24
|
// Big Endian
|
|
25
|
-
return BigInt(`0x${hex}`);
|
|
25
|
+
return BigInt(hex === '' ? '0' : `0x${hex}`);
|
|
26
26
|
}
|
|
27
27
|
// Caching slows it down 2-3x
|
|
28
28
|
export function hexToBytes(hex) {
|
|
@@ -99,18 +99,18 @@ export const bitSet = (n, pos, value) => n | ((value ? _1n : _0n) << BigInt(pos)
|
|
|
99
99
|
// Return mask for N bits (Same as BigInt(`0b${Array(i).fill('1').join('')}`))
|
|
100
100
|
// Not using ** operator with bigints for old engines.
|
|
101
101
|
export const bitMask = (n) => (_2n << BigInt(n - 1)) - _1n;
|
|
102
|
+
const validatorFns = {
|
|
103
|
+
bigint: (val) => typeof val === 'bigint',
|
|
104
|
+
function: (val) => typeof val === 'function',
|
|
105
|
+
boolean: (val) => typeof val === 'boolean',
|
|
106
|
+
string: (val) => typeof val === 'string',
|
|
107
|
+
isSafeInteger: (val) => Number.isSafeInteger(val),
|
|
108
|
+
array: (val) => Array.isArray(val),
|
|
109
|
+
field: (val, object) => object.Fp.isValid(val),
|
|
110
|
+
hash: (val) => typeof val === 'function' && Number.isSafeInteger(val.outputLen),
|
|
111
|
+
};
|
|
112
|
+
// type Record<K extends string | number | symbol, T> = { [P in K]: T; }
|
|
102
113
|
export function validateObject(object, validators, optValidators = {}) {
|
|
103
|
-
const validatorFns = {
|
|
104
|
-
bigint: (val) => typeof val === 'bigint',
|
|
105
|
-
function: (val) => typeof val === 'function',
|
|
106
|
-
boolean: (val) => typeof val === 'boolean',
|
|
107
|
-
string: (val) => typeof val === 'string',
|
|
108
|
-
isSafeInteger: (val) => Number.isSafeInteger(val),
|
|
109
|
-
array: (val) => Array.isArray(val),
|
|
110
|
-
field: (val) => object.Fp.isValid(val),
|
|
111
|
-
hash: (val) => typeof val === 'function' && Number.isSafeInteger(val.outputLen),
|
|
112
|
-
};
|
|
113
|
-
// type Key = keyof typeof validators;
|
|
114
114
|
const checkField = (fieldName, type, isOptional) => {
|
|
115
115
|
const checkVal = validatorFns[type];
|
|
116
116
|
if (typeof checkVal !== 'function')
|
|
@@ -118,13 +118,21 @@ export function validateObject(object, validators, optValidators = {}) {
|
|
|
118
118
|
const val = object[fieldName];
|
|
119
119
|
if (isOptional && val === undefined)
|
|
120
120
|
return;
|
|
121
|
-
if (!checkVal(val)) {
|
|
122
|
-
throw new Error(`Invalid param ${fieldName}=${val} (${typeof val}), expected ${type}`);
|
|
121
|
+
if (!checkVal(val, object)) {
|
|
122
|
+
throw new Error(`Invalid param ${String(fieldName)}=${val} (${typeof val}), expected ${type}`);
|
|
123
123
|
}
|
|
124
124
|
};
|
|
125
|
-
for (
|
|
125
|
+
for (const [fieldName, type] of Object.entries(validators))
|
|
126
126
|
checkField(fieldName, type, false);
|
|
127
|
-
for (
|
|
127
|
+
for (const [fieldName, type] of Object.entries(optValidators))
|
|
128
128
|
checkField(fieldName, type, true);
|
|
129
129
|
return object;
|
|
130
130
|
}
|
|
131
|
+
// validate type tests
|
|
132
|
+
// const o: { a: number; b: number; c: number } = { a: 1, b: 5, c: 6 };
|
|
133
|
+
// const z0 = validateObject(o, { a: 'isSafeInteger' }, { c: 'bigint' }); // Ok!
|
|
134
|
+
// // Should fail type-check
|
|
135
|
+
// const z1 = validateObject(o, { a: 'tmp' }, { c: 'zz' });
|
|
136
|
+
// const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });
|
|
137
|
+
// const z3 = validateObject(o, { test: 'boolean', z: 'bug' });
|
|
138
|
+
// const z4 = validateObject(o, { a: 'boolean', z: 'bug' });
|
|
@@ -16,6 +16,7 @@ function validatePointOpts(curve) {
|
|
|
16
16
|
wrapPrivateKey: 'boolean',
|
|
17
17
|
isTorsionFree: 'function',
|
|
18
18
|
clearCofactor: 'function',
|
|
19
|
+
allowInfinityPoint: 'boolean',
|
|
19
20
|
});
|
|
20
21
|
const { endo, Fp, a } = opts;
|
|
21
22
|
if (endo) {
|
|
@@ -154,6 +155,8 @@ export function weierstrassPoints(opts) {
|
|
|
154
155
|
if (pz == null || !Fp.isValid(pz))
|
|
155
156
|
throw new Error('z required');
|
|
156
157
|
}
|
|
158
|
+
// Does not validate if the point is on-curve.
|
|
159
|
+
// Use fromHex instead, or call assertValidity() later.
|
|
157
160
|
static fromAffine(p) {
|
|
158
161
|
const { x, y } = p || {};
|
|
159
162
|
if (!p || !Fp.isValid(x) || !Fp.isValid(y))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noble/curves",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "Minimal, auditable JS implementation of elliptic curve cryptography",
|
|
5
5
|
"files": [
|
|
6
6
|
"lib"
|
|
@@ -21,19 +21,17 @@
|
|
|
21
21
|
},
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@noble/hashes": "1.
|
|
24
|
+
"@noble/hashes": "1.2.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@rollup/plugin-node-resolve": "13.3.0",
|
|
28
27
|
"@scure/base": "~1.1.1",
|
|
29
|
-
"@scure/bip32": "~1.1.
|
|
30
|
-
"@scure/bip39": "~1.1.
|
|
28
|
+
"@scure/bip32": "~1.1.5",
|
|
29
|
+
"@scure/bip39": "~1.1.1",
|
|
31
30
|
"@types/node": "18.11.3",
|
|
32
31
|
"fast-check": "3.0.0",
|
|
33
32
|
"micro-bmark": "0.3.0",
|
|
34
33
|
"micro-should": "0.4.0",
|
|
35
34
|
"prettier": "2.8.3",
|
|
36
|
-
"rollup": "2.75.5",
|
|
37
35
|
"typescript": "4.7.3"
|
|
38
36
|
},
|
|
39
37
|
"main": "index.js",
|