@noble/curves 0.8.2 → 0.9.0
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 +232 -176
- package/_shortw_utils.d.ts +3 -2
- package/_shortw_utils.d.ts.map +1 -1
- package/abstract/bls.d.ts +15 -15
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +9 -7
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +5 -1
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +4 -3
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/hash-to-curve.d.ts +6 -6
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts +24 -12
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +16 -3
- package/abstract/modular.js.map +1 -1
- package/abstract/montgomery.d.ts +3 -3
- package/abstract/montgomery.d.ts.map +1 -1
- package/abstract/poseidon.d.ts +4 -4
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js.map +1 -1
- package/abstract/utils.d.ts +7 -7
- package/abstract/utils.d.ts.map +1 -1
- package/abstract/weierstrass.d.ts +40 -18
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +20 -6
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +14 -14
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +2 -2
- package/bls12-381.js.map +1 -1
- package/bn.js +1 -1
- package/bn.js.map +1 -1
- package/ed25519.d.ts +1 -1
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +2 -2
- package/ed25519.js.map +1 -1
- package/ed448.js +1 -1
- package/ed448.js.map +1 -1
- package/esm/abstract/bls.js.map +1 -1
- package/esm/abstract/curve.js +5 -1
- package/esm/abstract/curve.js.map +1 -1
- package/esm/abstract/hash-to-curve.js.map +1 -1
- package/esm/abstract/modular.js +14 -1
- package/esm/abstract/modular.js.map +1 -1
- package/esm/abstract/poseidon.js.map +1 -1
- package/esm/abstract/weierstrass.js +20 -6
- package/esm/abstract/weierstrass.js.map +1 -1
- package/esm/bls12-381.js +2 -2
- package/esm/bls12-381.js.map +1 -1
- package/esm/bn.js +2 -2
- package/esm/bn.js.map +1 -1
- package/esm/ed25519.js +3 -2
- package/esm/ed25519.js.map +1 -1
- package/esm/ed448.js +1 -1
- package/esm/ed448.js.map +1 -1
- package/esm/jubjub.js +2 -2
- package/esm/jubjub.js.map +1 -1
- package/esm/p256.js +1 -1
- package/esm/p256.js.map +1 -1
- package/esm/p384.js +1 -1
- package/esm/p384.js.map +1 -1
- package/esm/p521.js +1 -1
- package/esm/p521.js.map +1 -1
- package/esm/pasta.js +2 -2
- package/esm/pasta.js.map +1 -1
- package/esm/secp256k1.js +1 -1
- package/esm/secp256k1.js.map +1 -1
- package/jubjub.js +1 -1
- package/jubjub.js.map +1 -1
- package/p256.d.ts +4 -2
- package/p256.d.ts.map +1 -1
- package/p256.js +1 -1
- package/p256.js.map +1 -1
- package/p384.d.ts +4 -2
- package/p384.d.ts.map +1 -1
- package/p384.js +1 -1
- package/p384.js.map +1 -1
- package/p521.d.ts +4 -2
- package/p521.d.ts.map +1 -1
- package/p521.js +1 -1
- package/p521.js.map +1 -1
- package/package.json +9 -9
- package/pasta.js +2 -2
- package/pasta.js.map +1 -1
- package/secp256k1.d.ts +2 -1
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +1 -1
- package/secp256k1.js.map +1 -1
- package/src/abstract/bls.ts +11 -11
- package/src/abstract/curve.ts +7 -3
- package/src/abstract/hash-to-curve.ts +2 -2
- package/src/abstract/modular.ts +28 -19
- package/src/abstract/poseidon.ts +2 -2
- package/src/abstract/weierstrass.ts +27 -11
- package/src/bls12-381.ts +5 -5
- package/src/bn.ts +2 -2
- package/src/ed25519.ts +1 -1
- package/src/ed448.ts +1 -1
- package/src/jubjub.ts +2 -2
- package/src/p256.ts +1 -1
- package/src/p384.ts +1 -1
- package/src/p521.ts +1 -1
- package/src/pasta.ts +2 -2
- package/src/secp256k1.ts +2 -3
package/README.md
CHANGED
|
@@ -1,28 +1,21 @@
|
|
|
1
1
|
# noble-curves
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Audited & minimal JS implementation of elliptic curve cryptography.
|
|
4
4
|
|
|
5
|
-
- **noble** family, zero dependencies
|
|
6
5
|
- Short Weierstrass, Edwards, Montgomery curves
|
|
7
6
|
- ECDSA, EdDSA, Schnorr, BLS signature schemes, ECDH key agreement
|
|
7
|
+
- 🔒 [**Audited**](#security) by an independent security firm
|
|
8
8
|
- #️⃣ [hash to curve](#abstracthash-to-curve-hashing-strings-to-curve-points)
|
|
9
9
|
for encoding or hashing an arbitrary string to an elliptic curve point
|
|
10
10
|
- 🧜♂️ [Poseidon](https://www.poseidon-hash.info) ZK-friendly hash
|
|
11
11
|
- 🏎 [Ultra-fast](#speed), hand-optimized for caveats of JS engines
|
|
12
|
-
- 🔍 Unique tests ensure correctness with Wycheproof vectors and
|
|
13
|
-
|
|
12
|
+
- 🔍 Unique tests ensure correctness with Wycheproof vectors and
|
|
13
|
+
[cryptofuzz](https://github.com/guidovranken/cryptofuzz) differential fuzzing
|
|
14
|
+
- 🔻 Tree-shaking-friendly: use only what's necessary, other code won't be included
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
2. [Implementations](#implementations), utilizing one dependency `@noble/hashes`, providing ready-to-use:
|
|
19
|
-
- NIST curves secp256r1/P256, secp384r1/P384, secp521r1/P521
|
|
20
|
-
- SECG curve secp256k1
|
|
21
|
-
- ed25519/curve25519/x25519/ristretto255, edwards448/curve448/x448 [RFC7748](https://www.rfc-editor.org/rfc/rfc7748) / [RFC8032](https://www.rfc-editor.org/rfc/rfc8032) / [ZIP215](https://zips.z.cash/zip-0215) stuff
|
|
22
|
-
- pairing-friendly curves bls12-381, bn254
|
|
23
|
-
|
|
24
|
-
Check out [Upgrading](#upgrading) if you've previously used single-feature noble packages
|
|
25
|
-
([secp256k1](https://github.com/paulmillr/noble-secp256k1), [ed25519](https://github.com/paulmillr/noble-ed25519)).
|
|
16
|
+
Check out [Upgrading](#upgrading) if you've previously used single-feature noble
|
|
17
|
+
packages ([secp256k1](https://github.com/paulmillr/noble-secp256k1),
|
|
18
|
+
[ed25519](https://github.com/paulmillr/noble-ed25519)).
|
|
26
19
|
See [Resources](#resources) for articles and real-world software that uses curves.
|
|
27
20
|
|
|
28
21
|
### This library belongs to _noble_ crypto
|
|
@@ -30,33 +23,50 @@ See [Resources](#resources) for articles and real-world software that uses curve
|
|
|
30
23
|
> **noble-crypto** — high-security, easily auditable set of contained cryptographic libraries and tools.
|
|
31
24
|
|
|
32
25
|
- No dependencies, protection against supply chain attacks
|
|
33
|
-
-
|
|
26
|
+
- Auditable TypeScript / JS code
|
|
34
27
|
- Supported in all major browsers and stable node.js versions
|
|
35
28
|
- All releases are signed with PGP keys
|
|
36
29
|
- Check out [homepage](https://paulmillr.com/noble/) & all libraries:
|
|
37
30
|
[curves](https://github.com/paulmillr/noble-curves)
|
|
38
|
-
([secp256k1](https://github.com/paulmillr/noble-secp256k1),
|
|
31
|
+
(4kb versions [secp256k1](https://github.com/paulmillr/noble-secp256k1),
|
|
39
32
|
[ed25519](https://github.com/paulmillr/noble-ed25519)),
|
|
40
33
|
[hashes](https://github.com/paulmillr/noble-hashes)
|
|
41
34
|
|
|
42
35
|
## Usage
|
|
43
36
|
|
|
44
|
-
|
|
37
|
+
Browser, deno and node.js are supported:
|
|
45
38
|
|
|
46
39
|
> npm install @noble/curves
|
|
47
40
|
|
|
48
|
-
For [Deno](https://deno.land), use it with
|
|
41
|
+
For [Deno](https://deno.land), use it with
|
|
42
|
+
[npm specifier](https://deno.land/manual@v1.28.0/node/npm_specifiers).
|
|
43
|
+
In browser, you could also include the single file from
|
|
49
44
|
[GitHub's releases page](https://github.com/paulmillr/noble-curves/releases).
|
|
50
45
|
|
|
51
|
-
The library is tree-shaking-friendly and does not expose root entry point as
|
|
52
|
-
Instead, you need to import specific primitives.
|
|
46
|
+
The library is tree-shaking-friendly and does not expose root entry point as
|
|
47
|
+
`import * from '@noble/curves'`. Instead, you need to import specific primitives.
|
|
48
|
+
This is done to ensure small size of your apps.
|
|
49
|
+
|
|
50
|
+
Package consists of two parts:
|
|
51
|
+
|
|
52
|
+
1. [Implementations](#implementations), utilizing one dependency `@noble/hashes`,
|
|
53
|
+
providing ready-to-use:
|
|
54
|
+
- NIST curves secp256r1/P256, secp384r1/P384, secp521r1/P521
|
|
55
|
+
- SECG curve secp256k1
|
|
56
|
+
- ed25519/curve25519/x25519/ristretto255, edwards448/curve448/x448
|
|
57
|
+
implementing
|
|
58
|
+
[RFC7748](https://www.rfc-editor.org/rfc/rfc7748) /
|
|
59
|
+
[RFC8032](https://www.rfc-editor.org/rfc/rfc8032) /
|
|
60
|
+
[ZIP215](https://zips.z.cash/zip-0215) standards
|
|
61
|
+
- pairing-friendly curves bls12-381, bn254
|
|
62
|
+
2. [Abstract](#abstract-api), zero-dependency EC algorithms
|
|
53
63
|
|
|
54
64
|
### Implementations
|
|
55
65
|
|
|
56
66
|
Each curve can be used in the following way:
|
|
57
67
|
|
|
58
68
|
```ts
|
|
59
|
-
import { secp256k1 } from '@noble/curves/secp256k1'; //
|
|
69
|
+
import { secp256k1 } from '@noble/curves/secp256k1'; // ESM and Common.js
|
|
60
70
|
// import { secp256k1 } from 'npm:@noble/curves@1.2.0/secp256k1'; // Deno
|
|
61
71
|
const priv = secp256k1.utils.randomPrivateKey();
|
|
62
72
|
const pub = secp256k1.getPublicKey(priv);
|
|
@@ -64,8 +74,9 @@ const msg = new Uint8Array(32).fill(1);
|
|
|
64
74
|
const sig = secp256k1.sign(msg, priv);
|
|
65
75
|
secp256k1.verify(sig, msg, pub) === true;
|
|
66
76
|
|
|
77
|
+
// hex strings are also supported besides Uint8Arrays:
|
|
67
78
|
const privHex = '46c930bc7bb4db7f55da20798697421b98c4175a52c630294d75a84b9c126236';
|
|
68
|
-
const pub2 = secp256k1.getPublicKey(privHex);
|
|
79
|
+
const pub2 = secp256k1.getPublicKey(privHex);
|
|
69
80
|
```
|
|
70
81
|
|
|
71
82
|
All curves:
|
|
@@ -90,7 +101,7 @@ Weierstrass curves feature recovering public keys from signatures and ECDH key a
|
|
|
90
101
|
const sigImprovedSecurity = secp256k1.sign(msg, priv, { extraEntropy: true });
|
|
91
102
|
sig.recoverPublicKey(msg) === pub; // public key recovery
|
|
92
103
|
const someonesPub = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey());
|
|
93
|
-
const shared = secp256k1.getSharedSecret(priv, someonesPub); // ECDH
|
|
104
|
+
const shared = secp256k1.getSharedSecret(priv, someonesPub); // ECDH
|
|
94
105
|
```
|
|
95
106
|
|
|
96
107
|
secp256k1 has schnorr signature implementation which follows
|
|
@@ -103,7 +114,6 @@ const pub = schnorr.getPublicKey(priv);
|
|
|
103
114
|
const msg = new TextEncoder().encode('hello');
|
|
104
115
|
const sig = schnorr.sign(msg, priv);
|
|
105
116
|
const isValid = schnorr.verify(sig, msg, pub);
|
|
106
|
-
console.log(isValid);
|
|
107
117
|
```
|
|
108
118
|
|
|
109
119
|
ed25519 module has ed25519ctx / ed25519ph variants,
|
|
@@ -134,18 +144,27 @@ RistrettoPoint.hashToCurve('Ristretto is traditionally a short shot of espresso
|
|
|
134
144
|
// also has add(), equals(), multiply(), toRawBytes() methods
|
|
135
145
|
```
|
|
136
146
|
|
|
137
|
-
ed448
|
|
147
|
+
ed448 is similar:
|
|
138
148
|
|
|
139
149
|
```ts
|
|
140
150
|
import { ed448, ed448ph, ed448ctx, x448 } from '@noble/curves/ed448';
|
|
141
151
|
import { hashToCurve, encodeToCurve } from '@noble/curves/ed448';
|
|
152
|
+
ed448.getPublicKey(ed448.utils.randomPrivateKey());
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Every curve has params:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
import { secp256k1 } from '@noble/curves/secp256k1'; // ESM and Common.js
|
|
159
|
+
console.log(secp256k1.CURVE.p, secp256k1.CURVE.n, secp256k1.CURVE.a, secp256k1.CURVE.b);
|
|
142
160
|
```
|
|
143
161
|
|
|
144
162
|
BLS12-381 pairing-friendly Barreto-Lynn-Scott elliptic curve construction allows to
|
|
145
163
|
construct [zk-SNARKs](https://z.cash/technology/zksnarks/) at the 128-bit security
|
|
146
164
|
and use aggregated, batch-verifiable
|
|
147
165
|
[threshold signatures](https://medium.com/snigirev.stepan/bls-signatures-better-than-schnorr-5a7fe30ea716),
|
|
148
|
-
using Boneh-Lynn-Shacham signature scheme.
|
|
166
|
+
using Boneh-Lynn-Shacham signature scheme. Compatible with ETH and others,
|
|
167
|
+
just make sure to provide correct DST (domain separation tag argument).
|
|
149
168
|
|
|
150
169
|
```ts
|
|
151
170
|
import { bls12_381 as bls } from '@noble/curves/bls12-381';
|
|
@@ -182,10 +201,13 @@ console.log({ publicKeys, signatures3, aggSignature3, isValid3 });
|
|
|
182
201
|
|
|
183
202
|
## Abstract API
|
|
184
203
|
|
|
185
|
-
Abstract API allows to define custom curves. All arithmetics is done with JS
|
|
186
|
-
which is defined from `modular` sub-module. For
|
|
187
|
-
|
|
188
|
-
|
|
204
|
+
Abstract API allows to define custom curves. All arithmetics is done with JS
|
|
205
|
+
bigints over finite fields, which is defined from `modular` sub-module. For
|
|
206
|
+
scalar multiplication, we use
|
|
207
|
+
[precomputed tables with w-ary non-adjacent form (wNAF)](https://paulmillr.com/posts/noble-secp256k1-fast-ecc/).
|
|
208
|
+
Precomputes are enabled for weierstrass and edwards BASE points of a curve. You
|
|
209
|
+
could precompute any other point (e.g. for ECDH) using `utils.precompute()`
|
|
210
|
+
method: check out examples.
|
|
189
211
|
|
|
190
212
|
There are following zero-dependency algorithms:
|
|
191
213
|
|
|
@@ -201,14 +223,36 @@ There are following zero-dependency algorithms:
|
|
|
201
223
|
|
|
202
224
|
```ts
|
|
203
225
|
import { weierstrass } from '@noble/curves/abstract/weierstrass';
|
|
226
|
+
import { Field } from '@noble/curves/abstract/modular'; // finite field for mod arithmetics
|
|
227
|
+
import { sha256 } from '@noble/hashes/sha256'; // 3rd-party sha256() of type utils.CHash
|
|
228
|
+
import { hmac } from '@noble/hashes/hmac'; // 3rd-party hmac() that will accept sha256()
|
|
229
|
+
import { concatBytes, randomBytes } from '@noble/hashes/utils'; // 3rd-party utilities
|
|
230
|
+
const secq256k1 = weierstrass({
|
|
231
|
+
// secq256k1: cycle of secp256k1 with Fp/N flipped.
|
|
232
|
+
// https://personaelabs.org/posts/spartan-ecdsa
|
|
233
|
+
// https://zcash.github.io/halo2/background/curves.html#cycles-of-curves
|
|
234
|
+
a: 0n,
|
|
235
|
+
b: 7n,
|
|
236
|
+
Fp: Field(2n ** 256n - 432420386565659656852420866394968145599n),
|
|
237
|
+
n: 2n ** 256n - 2n ** 32n - 2n ** 9n - 2n ** 8n - 2n ** 7n - 2n ** 6n - 2n ** 4n - 1n,
|
|
238
|
+
Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
|
|
239
|
+
Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
|
|
240
|
+
hash: sha256,
|
|
241
|
+
hmac: (key: Uint8Array, ...msgs: Uint8Array[]) => hmac(sha256, key, concatBytes(...msgs)),
|
|
242
|
+
randomBytes,
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// weierstrassPoints can also be used if you don't need ECDSA, hash, hmac, randomBytes
|
|
204
246
|
```
|
|
205
247
|
|
|
206
|
-
Short Weierstrass curve's formula is `y² = x³ + ax + b`. `weierstrass`
|
|
248
|
+
Short Weierstrass curve's formula is `y² = x³ + ax + b`. `weierstrass`
|
|
249
|
+
expects arguments `a`, `b`, field `Fp`, curve order `n`, cofactor `h`
|
|
207
250
|
and coordinates `Gx`, `Gy` of generator point.
|
|
208
251
|
|
|
209
|
-
**`k` generation** is done deterministically, following
|
|
210
|
-
For this you will need
|
|
211
|
-
|
|
252
|
+
**`k` generation** is done deterministically, following
|
|
253
|
+
[RFC6979](https://www.rfc-editor.org/rfc/rfc6979). For this you will need
|
|
254
|
+
`hmac` & `hash`, which in our implementations is provided by noble-hashes. If
|
|
255
|
+
you're using different hashing library, make sure to wrap it in the following interface:
|
|
212
256
|
|
|
213
257
|
```ts
|
|
214
258
|
type CHash = {
|
|
@@ -224,11 +268,36 @@ type CHash = {
|
|
|
224
268
|
1. Exported as `ProjectivePoint`
|
|
225
269
|
2. Represented in projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)
|
|
226
270
|
3. Use complete exception-free formulas for addition and doubling
|
|
227
|
-
4. Can be decoded/encoded from/to Uint8Array / hex strings using
|
|
271
|
+
4. Can be decoded/encoded from/to Uint8Array / hex strings using
|
|
272
|
+
`ProjectivePoint.fromHex` and `ProjectivePoint#toRawBytes()`
|
|
228
273
|
5. Have `assertValidity()` which checks for being on-curve
|
|
229
274
|
6. Have `toAffine()` and `x` / `y` getters which convert to 2d xy affine coordinates
|
|
230
275
|
|
|
231
276
|
```ts
|
|
277
|
+
// `weierstrassPoints()` returns `CURVE` and `ProjectivePoint`
|
|
278
|
+
// `weierstrass()` returns `CurveFn`
|
|
279
|
+
type SignOpts = { lowS?: boolean; prehash?: boolean; extraEntropy: boolean | Uint8Array };
|
|
280
|
+
type CurveFn = {
|
|
281
|
+
CURVE: ReturnType<typeof validateOpts>;
|
|
282
|
+
getPublicKey: (privateKey: PrivKey, isCompressed?: boolean) => Uint8Array;
|
|
283
|
+
getSharedSecret: (privateA: PrivKey, publicB: Hex, isCompressed?: boolean) => Uint8Array;
|
|
284
|
+
sign: (msgHash: Hex, privKey: PrivKey, opts?: SignOpts) => SignatureType;
|
|
285
|
+
verify: (
|
|
286
|
+
signature: Hex | SignatureType,
|
|
287
|
+
msgHash: Hex,
|
|
288
|
+
publicKey: Hex,
|
|
289
|
+
opts?: { lowS?: boolean; prehash?: boolean }
|
|
290
|
+
) => boolean;
|
|
291
|
+
ProjectivePoint: ProjectivePointConstructor;
|
|
292
|
+
Signature: SignatureConstructor;
|
|
293
|
+
utils: {
|
|
294
|
+
normPrivateKeyToScalar: (key: PrivKey) => bigint;
|
|
295
|
+
isValidPrivateKey(key: PrivKey): boolean;
|
|
296
|
+
randomPrivateKey: () => Uint8Array;
|
|
297
|
+
precompute: (windowSize?: number, point?: ProjPointType<bigint>) => ProjPointType<bigint>;
|
|
298
|
+
};
|
|
299
|
+
};
|
|
300
|
+
|
|
232
301
|
// T is usually bigint, but can be something else like complex numbers in BLS curves
|
|
233
302
|
interface ProjPointType<T> extends Group<ProjPointType<T>> {
|
|
234
303
|
readonly px: T;
|
|
@@ -254,7 +323,8 @@ interface ProjConstructor<T> extends GroupConstructor<ProjPointType<T>> {
|
|
|
254
323
|
}
|
|
255
324
|
```
|
|
256
325
|
|
|
257
|
-
**ECDSA signatures** are represented by `Signature` instances and can be
|
|
326
|
+
**ECDSA signatures** are represented by `Signature` instances and can be
|
|
327
|
+
described by the interface:
|
|
258
328
|
|
|
259
329
|
```ts
|
|
260
330
|
interface SignatureType {
|
|
@@ -279,28 +349,9 @@ type SignatureConstructor = {
|
|
|
279
349
|
};
|
|
280
350
|
```
|
|
281
351
|
|
|
282
|
-
|
|
283
|
-
[cycle](https://zcash.github.io/halo2/background/curves.html#cycles-of-curves) of secp256k1 with Fp/N flipped.
|
|
352
|
+
More examples:
|
|
284
353
|
|
|
285
354
|
```typescript
|
|
286
|
-
import { weierstrass } from '@noble/curves/abstract/weierstrass';
|
|
287
|
-
import { Field } from '@noble/curves/abstract/modular'; // finite field, mod arithmetics done over it
|
|
288
|
-
import { sha256 } from '@noble/hashes/sha256'; // 3rd-party sha256() of type utils.CHash, with blockLen/outputLen
|
|
289
|
-
import { hmac } from '@noble/hashes/hmac'; // 3rd-party hmac() that will accept sha256()
|
|
290
|
-
import { concatBytes, randomBytes } from '@noble/hashes/utils'; // 3rd-party utilities
|
|
291
|
-
const secq256k1 = weierstrass({
|
|
292
|
-
// secq256k1: cycle of secp256k1 with Fp/N flipped.
|
|
293
|
-
a: 0n,
|
|
294
|
-
b: 7n,
|
|
295
|
-
Fp: Field(2n ** 256n - 432420386565659656852420866394968145599n),
|
|
296
|
-
n: 2n ** 256n - 2n ** 32n - 2n ** 9n - 2n ** 8n - 2n ** 7n - 2n ** 6n - 2n ** 4n - 1n,
|
|
297
|
-
Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
|
|
298
|
-
Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
|
|
299
|
-
hash: sha256,
|
|
300
|
-
hmac: (key: Uint8Array, ...msgs: Uint8Array[]) => hmac(sha256, key, concatBytes(...msgs)),
|
|
301
|
-
randomBytes,
|
|
302
|
-
});
|
|
303
|
-
|
|
304
355
|
// All curves expose same generic interface.
|
|
305
356
|
const priv = secq256k1.utils.randomPrivateKey();
|
|
306
357
|
secq256k1.getPublicKey(priv); // Convert private key to public.
|
|
@@ -318,6 +369,7 @@ point.assertValidity(); // Checks for being on-curve
|
|
|
318
369
|
point.toAffine(); // Converts to 2d affine xy coordinates
|
|
319
370
|
|
|
320
371
|
secq256k1.CURVE.n;
|
|
372
|
+
secq256k1.CURVE.p;
|
|
321
373
|
secq256k1.CURVE.Fp.mod();
|
|
322
374
|
secq256k1.CURVE.hash();
|
|
323
375
|
|
|
@@ -326,84 +378,19 @@ const fast = secq256k1.utils.precompute(8, Point.fromHex(someonesPubKey));
|
|
|
326
378
|
fast.multiply(privKey); // much faster ECDH now
|
|
327
379
|
```
|
|
328
380
|
|
|
329
|
-
`weierstrass()` returns `CurveFn`:
|
|
330
|
-
|
|
331
|
-
```ts
|
|
332
|
-
type SignOpts = { lowS?: boolean; prehash?: boolean; extraEntropy: boolean | Uint8Array };
|
|
333
|
-
type CurveFn = {
|
|
334
|
-
CURVE: ReturnType<typeof validateOpts>;
|
|
335
|
-
getPublicKey: (privateKey: PrivKey, isCompressed?: boolean) => Uint8Array;
|
|
336
|
-
getSharedSecret: (privateA: PrivKey, publicB: Hex, isCompressed?: boolean) => Uint8Array;
|
|
337
|
-
sign: (msgHash: Hex, privKey: PrivKey, opts?: SignOpts) => SignatureType;
|
|
338
|
-
verify: (
|
|
339
|
-
signature: Hex | SignatureType,
|
|
340
|
-
msgHash: Hex,
|
|
341
|
-
publicKey: Hex,
|
|
342
|
-
opts?: { lowS?: boolean; prehash?: boolean }
|
|
343
|
-
) => boolean;
|
|
344
|
-
ProjectivePoint: ProjectivePointConstructor;
|
|
345
|
-
Signature: SignatureConstructor;
|
|
346
|
-
utils: {
|
|
347
|
-
normPrivateKeyToScalar: (key: PrivKey) => bigint;
|
|
348
|
-
isValidPrivateKey(key: PrivKey): boolean;
|
|
349
|
-
randomPrivateKey: () => Uint8Array;
|
|
350
|
-
precompute: (windowSize?: number, point?: ProjPointType<bigint>) => ProjPointType<bigint>;
|
|
351
|
-
};
|
|
352
|
-
};
|
|
353
|
-
```
|
|
354
|
-
|
|
355
381
|
### abstract/edwards: Twisted Edwards curve
|
|
356
382
|
|
|
357
|
-
Twisted Edwards curve's formula is `ax² + y² = 1 + dx²y²`. You must specify `a`, `d`, field `Fp`, order `n`, cofactor `h`
|
|
358
|
-
and coordinates `Gx`, `Gy` of generator point.
|
|
359
|
-
|
|
360
|
-
For EdDSA signatures, `hash` param required. `adjustScalarBytes` which instructs how to change private scalars could be specified.
|
|
361
|
-
|
|
362
|
-
**Edwards points:**
|
|
363
|
-
|
|
364
|
-
1. Exported as `ExtendedPoint`
|
|
365
|
-
2. Represented in extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z)
|
|
366
|
-
3. Use complete exception-free formulas for addition and doubling
|
|
367
|
-
4. Can be decoded/encoded from/to Uint8Array / hex strings using `ExtendedPoint.fromHex` and `ExtendedPoint#toRawBytes()`
|
|
368
|
-
5. Have `assertValidity()` which checks for being on-curve
|
|
369
|
-
6. Have `toAffine()` and `x` / `y` getters which convert to 2d xy affine coordinates
|
|
370
|
-
7. Have `isTorsionFree()`, `clearCofactor()` and `isSmallOrder()` utilities to handle torsions
|
|
371
|
-
|
|
372
|
-
```ts
|
|
373
|
-
interface ExtPointType extends Group<ExtPointType> {
|
|
374
|
-
readonly ex: bigint;
|
|
375
|
-
readonly ey: bigint;
|
|
376
|
-
readonly ez: bigint;
|
|
377
|
-
readonly et: bigint;
|
|
378
|
-
assertValidity(): void;
|
|
379
|
-
multiply(scalar: bigint): ExtPointType;
|
|
380
|
-
multiplyUnsafe(scalar: bigint): ExtPointType;
|
|
381
|
-
isSmallOrder(): boolean;
|
|
382
|
-
isTorsionFree(): boolean;
|
|
383
|
-
clearCofactor(): ExtPointType;
|
|
384
|
-
toAffine(iz?: bigint): AffinePoint<bigint>;
|
|
385
|
-
}
|
|
386
|
-
// Static methods of Extended Point with coordinates in X, Y, Z, T
|
|
387
|
-
interface ExtPointConstructor extends GroupConstructor<ExtPointType> {
|
|
388
|
-
new (x: bigint, y: bigint, z: bigint, t: bigint): ExtPointType;
|
|
389
|
-
fromAffine(p: AffinePoint<bigint>): ExtPointType;
|
|
390
|
-
fromHex(hex: Hex): ExtPointType;
|
|
391
|
-
fromPrivateKey(privateKey: Hex): ExtPointType;
|
|
392
|
-
}
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
Example implementing edwards25519:
|
|
396
|
-
|
|
397
383
|
```ts
|
|
398
384
|
import { twistedEdwards } from '@noble/curves/abstract/edwards';
|
|
399
|
-
import { Field
|
|
385
|
+
import { Field } from '@noble/curves/abstract/modular';
|
|
400
386
|
import { sha512 } from '@noble/hashes/sha512';
|
|
387
|
+
import { randomBytes } from '@noble/hashes/utils';
|
|
401
388
|
|
|
402
389
|
const Fp = Field(2n ** 255n - 19n);
|
|
403
390
|
const ed25519 = twistedEdwards({
|
|
404
391
|
a: -1n,
|
|
405
392
|
d: Fp.div(-121665n, 121666n), // -121665n/121666n mod p
|
|
406
|
-
Fp,
|
|
393
|
+
Fp: Fp,
|
|
407
394
|
n: 2n ** 252n + 27742317777372353535851937790883648493n,
|
|
408
395
|
h: 8n,
|
|
409
396
|
Gx: 15112221349535400772501151409588531511454012693041857206046113283949847762202n,
|
|
@@ -420,9 +407,23 @@ const ed25519 = twistedEdwards({
|
|
|
420
407
|
} as const);
|
|
421
408
|
```
|
|
422
409
|
|
|
423
|
-
`
|
|
410
|
+
Twisted Edwards curve's formula is `ax² + y² = 1 + dx²y²`. You must specify `a`, `d`, field `Fp`, order `n`, cofactor `h`
|
|
411
|
+
and coordinates `Gx`, `Gy` of generator point.
|
|
412
|
+
|
|
413
|
+
For EdDSA signatures, `hash` param required. `adjustScalarBytes` which instructs how to change private scalars could be specified.
|
|
414
|
+
|
|
415
|
+
**Edwards points:**
|
|
416
|
+
|
|
417
|
+
1. Exported as `ExtendedPoint`
|
|
418
|
+
2. Represented in extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z)
|
|
419
|
+
3. Use complete exception-free formulas for addition and doubling
|
|
420
|
+
4. Can be decoded/encoded from/to Uint8Array / hex strings using `ExtendedPoint.fromHex` and `ExtendedPoint#toRawBytes()`
|
|
421
|
+
5. Have `assertValidity()` which checks for being on-curve
|
|
422
|
+
6. Have `toAffine()` and `x` / `y` getters which convert to 2d xy affine coordinates
|
|
423
|
+
7. Have `isTorsionFree()`, `clearCofactor()` and `isSmallOrder()` utilities to handle torsions
|
|
424
424
|
|
|
425
425
|
```ts
|
|
426
|
+
// `twistedEdwards()` returns `CurveFn` of following type:
|
|
426
427
|
type CurveFn = {
|
|
427
428
|
CURVE: ReturnType<typeof validateOpts>;
|
|
428
429
|
getPublicKey: (privateKey: Hex) => Uint8Array;
|
|
@@ -440,21 +441,39 @@ type CurveFn = {
|
|
|
440
441
|
};
|
|
441
442
|
};
|
|
442
443
|
};
|
|
444
|
+
|
|
445
|
+
interface ExtPointType extends Group<ExtPointType> {
|
|
446
|
+
readonly ex: bigint;
|
|
447
|
+
readonly ey: bigint;
|
|
448
|
+
readonly ez: bigint;
|
|
449
|
+
readonly et: bigint;
|
|
450
|
+
assertValidity(): void;
|
|
451
|
+
multiply(scalar: bigint): ExtPointType;
|
|
452
|
+
multiplyUnsafe(scalar: bigint): ExtPointType;
|
|
453
|
+
isSmallOrder(): boolean;
|
|
454
|
+
isTorsionFree(): boolean;
|
|
455
|
+
clearCofactor(): ExtPointType;
|
|
456
|
+
toAffine(iz?: bigint): AffinePoint<bigint>;
|
|
457
|
+
}
|
|
458
|
+
// Static methods of Extended Point with coordinates in X, Y, Z, T
|
|
459
|
+
interface ExtPointConstructor extends GroupConstructor<ExtPointType> {
|
|
460
|
+
new (x: bigint, y: bigint, z: bigint, t: bigint): ExtPointType;
|
|
461
|
+
fromAffine(p: AffinePoint<bigint>): ExtPointType;
|
|
462
|
+
fromHex(hex: Hex): ExtPointType;
|
|
463
|
+
fromPrivateKey(privateKey: Hex): ExtPointType;
|
|
464
|
+
}
|
|
443
465
|
```
|
|
444
466
|
|
|
445
467
|
### abstract/montgomery: Montgomery curve
|
|
446
468
|
|
|
447
|
-
The module contains methods for x-only ECDH on Curve25519 / Curve448 from RFC7748. Proper Elliptic Curve Points are not implemented yet.
|
|
448
|
-
|
|
449
|
-
You must specify curve params `Fp`, `a`, `Gu` coordinate of u, `montgomeryBits` and `nByteLength`.
|
|
450
|
-
|
|
451
469
|
```typescript
|
|
452
470
|
import { montgomery } from '@noble/curves/abstract/montgomery';
|
|
471
|
+
import { Field } from '@noble/curves/abstract/modular';
|
|
453
472
|
|
|
454
473
|
const x25519 = montgomery({
|
|
455
|
-
Fp: Field(2n ** 255n - 19n),
|
|
456
474
|
a: 486662n,
|
|
457
475
|
Gu: 9n,
|
|
476
|
+
Fp: Field(2n ** 255n - 19n),
|
|
458
477
|
montgomeryBits: 255,
|
|
459
478
|
nByteLength: 32,
|
|
460
479
|
// Optional param
|
|
@@ -467,6 +486,11 @@ const x25519 = montgomery({
|
|
|
467
486
|
});
|
|
468
487
|
```
|
|
469
488
|
|
|
489
|
+
The module contains methods for x-only ECDH on Curve25519 / Curve448 from RFC7748.
|
|
490
|
+
Proper Elliptic Curve Points are not implemented yet.
|
|
491
|
+
|
|
492
|
+
You must specify curve params `Fp`, `a`, `Gu` coordinate of u, `montgomeryBits` and `nByteLength`.
|
|
493
|
+
|
|
470
494
|
### abstract/hash-to-curve: Hashing strings to curve points
|
|
471
495
|
|
|
472
496
|
The module allows to hash arbitrary strings to elliptic curve points. Implements [hash-to-curve v16](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16).
|
|
@@ -507,19 +531,37 @@ function expand_message_xof(
|
|
|
507
531
|
): Uint8Array;
|
|
508
532
|
```
|
|
509
533
|
|
|
510
|
-
`hash_to_field(msg, count, options)`
|
|
534
|
+
`hash_to_field(msg, count, options)`
|
|
535
|
+
[(spec)](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3)
|
|
511
536
|
hashes arbitrary-length byte strings to a list of one or more elements of a finite field F.
|
|
512
537
|
|
|
513
|
-
- `msg` a byte string containing the message to hash
|
|
514
|
-
- `count` the number of elements of F to output
|
|
515
|
-
- `options` `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}`.
|
|
516
|
-
- `p` is field prime, m=field extension (1 for prime fields)
|
|
517
|
-
- `k` is security target in bits (e.g. 128).
|
|
518
|
-
- `expand` should be `xmd` for SHA2, SHA3, BLAKE; `xof` for SHAKE, BLAKE-XOF
|
|
519
|
-
- `hash` conforming to `utils.CHash` interface, with `outputLen` / `blockLen` props
|
|
520
|
-
- Returns `[u_0, ..., u_(count - 1)]`, a list of field elements.
|
|
521
|
-
|
|
522
538
|
```ts
|
|
539
|
+
/**
|
|
540
|
+
* * `DST` is a domain separation tag, defined in section 2.2.5
|
|
541
|
+
* * `p` characteristic of F, where F is a finite field of characteristic p and order q = p^m
|
|
542
|
+
* * `m` is extension degree (1 for prime fields)
|
|
543
|
+
* * `k` is the target security target in bits (e.g. 128), from section 5.1
|
|
544
|
+
* * `expand` is `xmd` (SHA2, SHA3, BLAKE) or `xof` (SHAKE, BLAKE-XOF)
|
|
545
|
+
* * `hash` conforming to `utils.CHash` interface, with `outputLen` / `blockLen` props
|
|
546
|
+
*/
|
|
547
|
+
type UnicodeOrBytes = string | Uint8Array;
|
|
548
|
+
type Opts = {
|
|
549
|
+
DST: UnicodeOrBytes;
|
|
550
|
+
p: bigint;
|
|
551
|
+
m: number;
|
|
552
|
+
k: number;
|
|
553
|
+
expand?: 'xmd' | 'xof';
|
|
554
|
+
hash: CHash;
|
|
555
|
+
};
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Hashes arbitrary-length byte strings to a list of one or more elements of a finite field F
|
|
559
|
+
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3
|
|
560
|
+
* @param msg a byte string containing the message to hash
|
|
561
|
+
* @param count the number of elements of F to output
|
|
562
|
+
* @param options `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}`, see above
|
|
563
|
+
* @returns [u_0, ..., u_(count - 1)], a list of field elements.
|
|
564
|
+
*/
|
|
523
565
|
function hash_to_field(msg: Uint8Array, count: number, options: Opts): bigint[][];
|
|
524
566
|
```
|
|
525
567
|
|
|
@@ -704,6 +746,13 @@ hashToCurve
|
|
|
704
746
|
└─ed448 x 1,045 ops/sec @ 956μs/op
|
|
705
747
|
```
|
|
706
748
|
|
|
749
|
+
## Contributing & testing
|
|
750
|
+
|
|
751
|
+
1. Clone the repository
|
|
752
|
+
2. `npm install` to install build dependencies like TypeScript
|
|
753
|
+
3. `npm run build` to compile TypeScript code
|
|
754
|
+
4. `npm run test` will execute all main tests
|
|
755
|
+
|
|
707
756
|
## Resources
|
|
708
757
|
|
|
709
758
|
Article about some of library's features: [Learning fast elliptic-curve cryptography](https://paulmillr.com/posts/noble-secp256k1-fast-ecc/)
|
|
@@ -719,45 +768,52 @@ Projects using the library:
|
|
|
719
768
|
- Threshold sigs demo [genthresh.com](https://genthresh.com)
|
|
720
769
|
- BBS signatures [github.com/Wind4Greg/BBS-Draft-Checks](https://github.com/Wind4Greg/BBS-Draft-Checks) following [draft-irtf-cfrg-bbs-signatures-latest](https://identity.foundation/bbs-signature/draft-irtf-cfrg-bbs-signatures.html)
|
|
721
770
|
- Others
|
|
722
|
-
- All curves demo: Elliptic curve calculator [paulmillr.com/
|
|
771
|
+
- All curves demo: Elliptic curve calculator [paulmillr.com/noble](https://paulmillr.com/noble)
|
|
723
772
|
- [micro-starknet](https://github.com/paulmillr/micro-starknet) for stark-friendly elliptic curve.
|
|
773
|
+
|
|
724
774
|
## Upgrading
|
|
725
775
|
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
-
|
|
735
|
-
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
- `
|
|
741
|
-
|
|
742
|
-
- `
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
-
|
|
749
|
-
-
|
|
750
|
-
-
|
|
751
|
-
|
|
752
|
-
- `
|
|
776
|
+
Previously, the library was split into single-feature packages
|
|
777
|
+
noble-secp256k1 and noble-ed25519. curves can be thought as a continuation of their
|
|
778
|
+
original work. The libraries now changed their direction towards providing
|
|
779
|
+
minimal 4kb implementations of cryptography and are not as feature-complete.
|
|
780
|
+
|
|
781
|
+
Upgrading from [@noble/secp256k1](https://github.com/paulmillr/noble-secp256k1) 1.7:
|
|
782
|
+
|
|
783
|
+
- `getPublicKey`
|
|
784
|
+
- now produce 33-byte compressed signatures by default
|
|
785
|
+
- to use old behavior, which produced 65-byte uncompressed keys, set
|
|
786
|
+
argument `isCompressed` to `false`: `getPublicKey(priv, false)`
|
|
787
|
+
- `sign`
|
|
788
|
+
- is now sync; use `signAsync` for async version
|
|
789
|
+
- now returns `Signature` instance with `{ r, s, recovery }` properties
|
|
790
|
+
- `canonical` option was renamed to `lowS`
|
|
791
|
+
- `recovered` option has been removed because recovery bit is always returned now
|
|
792
|
+
- `der` option has been removed. There are 2 options:
|
|
793
|
+
1. Use compact encoding: `fromCompact`, `toCompactRawBytes`, `toCompactHex`.
|
|
794
|
+
Compact encoding is simply a concatenation of 32-byte r and 32-byte s.
|
|
795
|
+
2. If you must use DER encoding, switch to noble-curves (see above).
|
|
796
|
+
- `verify`
|
|
797
|
+
- `strict` option was renamed to `lowS`
|
|
798
|
+
- `getSharedSecret`
|
|
799
|
+
- now produce 33-byte compressed signatures by default
|
|
800
|
+
- to use old behavior, which produced 65-byte uncompressed keys, set
|
|
801
|
+
argument `isCompressed` to `false`: `getSharedSecret(a, b, false)`
|
|
802
|
+
- `recoverPublicKey(msg, sig, rec)` was changed to `sig.recoverPublicKey(msg)`
|
|
803
|
+
- `number` type for private keys have been removed: use `bigint` instead
|
|
804
|
+
- `Point` (2d xy) has been changed to `ProjectivePoint` (3d xyz)
|
|
805
|
+
- `utils` were split into `utils` (same api as in noble-curves) and
|
|
806
|
+
`etc` (`hmacSha256Sync` and others)
|
|
807
|
+
|
|
808
|
+
Upgrading from [@noble/ed25519](https://github.com/paulmillr/noble-ed25519) 1.7:
|
|
809
|
+
|
|
810
|
+
- Methods are now sync by default
|
|
753
811
|
- `bigint` is no longer allowed in `getPublicKey`, `sign`, `verify`. Reason: ed25519 is LE, can lead to bugs
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
3. `npm run build` to compile TypeScript code
|
|
760
|
-
4. `npm run test` will execute all main tests
|
|
812
|
+
- `Point` (2d xy) has been changed to `ExtendedPoint` (xyzt)
|
|
813
|
+
- `Signature` was removed: just use raw bytes or hex now
|
|
814
|
+
- `utils` were split into `utils` (same api as in noble-curves) and
|
|
815
|
+
`etc` (`sha512Sync` and others)
|
|
816
|
+
- `getSharedSecret` was moved to `x25519` module
|
|
761
817
|
|
|
762
818
|
## License
|
|
763
819
|
|
package/_shortw_utils.d.ts
CHANGED
|
@@ -6,13 +6,13 @@ export declare function getHash(hash: CHash): {
|
|
|
6
6
|
hmac: (key: Uint8Array, ...msgs: Uint8Array[]) => Uint8Array;
|
|
7
7
|
randomBytes: typeof randomBytes;
|
|
8
8
|
};
|
|
9
|
-
|
|
9
|
+
type CurveDef = Readonly<Omit<CurveType, 'hash' | 'hmac' | 'randomBytes'>>;
|
|
10
10
|
export declare function createCurve(curveDef: CurveDef, defHash: CHash): Readonly<{
|
|
11
11
|
create: (hash: CHash) => import("./abstract/weierstrass.js").CurveFn;
|
|
12
12
|
CURVE: Readonly<{
|
|
13
13
|
readonly nBitLength: number;
|
|
14
14
|
readonly nByteLength: number;
|
|
15
|
-
readonly Fp: import("./abstract/modular.js").
|
|
15
|
+
readonly Fp: import("./abstract/modular.js").IField<bigint>;
|
|
16
16
|
readonly n: bigint;
|
|
17
17
|
readonly h: bigint;
|
|
18
18
|
readonly hEff?: bigint | undefined;
|
|
@@ -40,6 +40,7 @@ export declare function createCurve(curveDef: CurveDef, defHash: CHash): Readonl
|
|
|
40
40
|
lowS: boolean;
|
|
41
41
|
readonly bits2int?: ((bytes: Uint8Array) => bigint) | undefined;
|
|
42
42
|
readonly bits2int_modN?: ((bytes: Uint8Array) => bigint) | undefined;
|
|
43
|
+
readonly p: bigint;
|
|
43
44
|
}>;
|
|
44
45
|
getPublicKey: (privateKey: import("./abstract/utils.js").PrivKey, isCompressed?: boolean | undefined) => Uint8Array;
|
|
45
46
|
getSharedSecret: (privateA: import("./abstract/utils.js").PrivKey, publicB: import("./abstract/utils.js").Hex, isCompressed?: boolean | undefined) => Uint8Array;
|
package/_shortw_utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_shortw_utils.d.ts","sourceRoot":"","sources":["src/_shortw_utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAe,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAG5C,wBAAgB,OAAO,CAAC,IAAI,EAAE,KAAK;;gBAGnB,UAAU,WAAW,UAAU,EAAE;;EAGhD;AAED,
|
|
1
|
+
{"version":3,"file":"_shortw_utils.d.ts","sourceRoot":"","sources":["src/_shortw_utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAe,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAG5C,wBAAgB,OAAO,CAAC,IAAI,EAAE,KAAK;;gBAGnB,UAAU,WAAW,UAAU,EAAE;;EAGhD;AAED,KAAK,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC;AAC3E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK;mBACtC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAE5B"}
|