Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49a659b248 | ||
|
|
9d0a2e25dc | ||
|
|
7c461af2b2 | ||
|
|
4a8f447c8d | ||
|
|
4b2d31ce7f | ||
|
|
16115f27a6 | ||
|
|
0e0d0f530d | ||
|
|
fa5105aef2 | ||
|
|
11f1626ecc | ||
|
|
53ff287bf7 | ||
|
|
214c9aa553 | ||
|
|
ec2c3e1248 | ||
|
|
e64a9d654c | ||
|
|
088edd0fbb | ||
|
|
3e90930e9d |
12
README.md
12
README.md
@@ -56,7 +56,7 @@ Instead, you need to import specific primitives. This is done to ensure small si
|
|||||||
Each curve can be used in the following way:
|
Each curve can be used in the following way:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { secp256k1 } from '@noble/curves/secp256k1'; // ECMAScript Modules (ESM) and Common.js
|
import { secp256k1 } from '@noble/curves/secp256k1'; // ECMAScript Modules (ESM)
|
||||||
// import { secp256k1 } from 'npm:@noble/curves@1.2.0/secp256k1'; // Deno
|
// import { secp256k1 } from 'npm:@noble/curves@1.2.0/secp256k1'; // Deno
|
||||||
const priv = secp256k1.utils.randomPrivateKey();
|
const priv = secp256k1.utils.randomPrivateKey();
|
||||||
const pub = secp256k1.getPublicKey(priv);
|
const pub = secp256k1.getPublicKey(priv);
|
||||||
@@ -472,7 +472,7 @@ const x25519 = montgomery({
|
|||||||
|
|
||||||
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).
|
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).
|
||||||
|
|
||||||
Every curve has exported `hashToCurve` and `encodeToCurve` methods:
|
Every curve has exported `hashToCurve` and `encodeToCurve` methods. You should always prefer `hashToCurve` for security:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { hashToCurve, encodeToCurve } from '@noble/curves/secp256k1';
|
import { hashToCurve, encodeToCurve } from '@noble/curves/secp256k1';
|
||||||
@@ -711,10 +711,14 @@ hashToCurve
|
|||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
|
|
||||||
Article about some of library's features: [Learning fast elliptic-curve cryptography](https://paulmillr.com/posts/noble-secp256k1-fast-ecc/). Elliptic curve calculator: [paulmillr.com/ecc](https://paulmillr.com/ecc)
|
Article about some of library's features: [Learning fast elliptic-curve cryptography](https://paulmillr.com/posts/noble-secp256k1-fast-ecc/)
|
||||||
|
|
||||||
|
Demo: Elliptic curve calculator [paulmillr.com/ecc](https://paulmillr.com/ecc).
|
||||||
|
|
||||||
|
Projects using the library:
|
||||||
|
|
||||||
- secp256k1
|
- secp256k1
|
||||||
- [btc-signer](https://github.com/paulmillr/micro-btc-signer), [eth-signer](https://github.com/paulmillr/micro-eth-signer)
|
- [btc-signer](https://github.com/paulmillr/scure-btc-signer), [eth-signer](https://github.com/paulmillr/micro-eth-signer)
|
||||||
- ed25519
|
- ed25519
|
||||||
- [sol-signer](https://github.com/paulmillr/micro-sol-signer)
|
- [sol-signer](https://github.com/paulmillr/micro-sol-signer)
|
||||||
- BLS12-381
|
- BLS12-381
|
||||||
|
|||||||
13
benchmark/modular.js
Normal file
13
benchmark/modular.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { run, mark } from 'micro-bmark';
|
||||||
|
import { secp256k1 } from '../secp256k1.js';
|
||||||
|
import { Fp } from '../abstract/modular.js';
|
||||||
|
|
||||||
|
run(async () => {
|
||||||
|
console.log(`\x1b[36mmodular, secp256k1 field\x1b[0m`);
|
||||||
|
const { Fp: secpFp } = secp256k1.CURVE;
|
||||||
|
await mark('invert a', 300000, () => secpFp.inv(2n ** 232n - 5910n));
|
||||||
|
await mark('invert b', 300000, () => secpFp.inv(2n ** 231n - 5910n));
|
||||||
|
await mark('sqrt p = 3 mod 4', 15000, () => secpFp.sqrt(2n ** 231n - 5910n));
|
||||||
|
const FpStark = Fp(BigInt('0x800000000000011000000000000000000000000000000000000000000000001'));
|
||||||
|
await mark('sqrt tonneli-shanks', 500, () => FpStark.sqrt(2n ** 231n - 5909n))
|
||||||
|
});
|
||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@noble/curves",
|
"name": "@noble/curves",
|
||||||
"version": "0.7.2",
|
"version": "0.8.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@noble/curves",
|
"name": "@noble/curves",
|
||||||
"version": "0.7.2",
|
"version": "0.8.0",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
|
|||||||
30
package.json
30
package.json
@@ -1,10 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "@noble/curves",
|
"name": "@noble/curves",
|
||||||
"version": "0.7.3",
|
"version": "0.8.0",
|
||||||
"description": "Minimal, auditable JS implementation of elliptic curve cryptography",
|
"description": "Minimal, auditable JS implementation of elliptic curve cryptography",
|
||||||
"files": [
|
"files": [
|
||||||
"abstract",
|
"abstract",
|
||||||
"esm",
|
|
||||||
"src",
|
"src",
|
||||||
"*.js",
|
"*.js",
|
||||||
"*.js.map",
|
"*.js.map",
|
||||||
@@ -13,7 +12,8 @@
|
|||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"bench": "cd benchmark; node secp256k1.js; node curves.js; node ecdh.js; node stark.js; node bls.js",
|
"bench": "cd benchmark; node secp256k1.js; node curves.js; node ecdh.js; node stark.js; node bls.js",
|
||||||
"build": "tsc && tsc -p tsconfig.esm.json",
|
"build": "tsc",
|
||||||
|
"build:clean": "rm *.{js,d.ts,js.map} esm/*.{js,js.map} 2> /dev/null",
|
||||||
"build:release": "rollup -c rollup.config.js",
|
"build:release": "rollup -c rollup.config.js",
|
||||||
"lint": "prettier --check 'src/**/*.{js,ts}' 'test/*.js'",
|
"lint": "prettier --check 'src/**/*.{js,ts}' 'test/*.js'",
|
||||||
"format": "prettier --write 'src/**/*.{js,ts}' 'test/*.js'",
|
"format": "prettier --write 'src/**/*.{js,ts}' 'test/*.js'",
|
||||||
@@ -40,120 +40,98 @@
|
|||||||
"typescript": "4.7.3"
|
"typescript": "4.7.3"
|
||||||
},
|
},
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
"types": "./index.d.ts",
|
"types": "./index.d.ts",
|
||||||
"import": "./esm/index.js",
|
|
||||||
"default": "./index.js"
|
"default": "./index.js"
|
||||||
},
|
},
|
||||||
"./abstract/edwards": {
|
"./abstract/edwards": {
|
||||||
"types": "./abstract/edwards.d.ts",
|
"types": "./abstract/edwards.d.ts",
|
||||||
"import": "./esm/abstract/edwards.js",
|
|
||||||
"default": "./abstract/edwards.js"
|
"default": "./abstract/edwards.js"
|
||||||
},
|
},
|
||||||
"./abstract/modular": {
|
"./abstract/modular": {
|
||||||
"types": "./abstract/modular.d.ts",
|
"types": "./abstract/modular.d.ts",
|
||||||
"import": "./esm/abstract/modular.js",
|
|
||||||
"default": "./abstract/modular.js"
|
"default": "./abstract/modular.js"
|
||||||
},
|
},
|
||||||
"./abstract/montgomery": {
|
"./abstract/montgomery": {
|
||||||
"types": "./abstract/montgomery.d.ts",
|
"types": "./abstract/montgomery.d.ts",
|
||||||
"import": "./esm/abstract/montgomery.js",
|
|
||||||
"default": "./abstract/montgomery.js"
|
"default": "./abstract/montgomery.js"
|
||||||
},
|
},
|
||||||
"./abstract/weierstrass": {
|
"./abstract/weierstrass": {
|
||||||
"types": "./abstract/weierstrass.d.ts",
|
"types": "./abstract/weierstrass.d.ts",
|
||||||
"import": "./esm/abstract/weierstrass.js",
|
|
||||||
"default": "./abstract/weierstrass.js"
|
"default": "./abstract/weierstrass.js"
|
||||||
},
|
},
|
||||||
"./abstract/bls": {
|
"./abstract/bls": {
|
||||||
"types": "./abstract/bls.d.ts",
|
"types": "./abstract/bls.d.ts",
|
||||||
"import": "./esm/abstract/bls.js",
|
|
||||||
"default": "./abstract/bls.js"
|
"default": "./abstract/bls.js"
|
||||||
},
|
},
|
||||||
"./abstract/hash-to-curve": {
|
"./abstract/hash-to-curve": {
|
||||||
"types": "./abstract/hash-to-curve.d.ts",
|
"types": "./abstract/hash-to-curve.d.ts",
|
||||||
"import": "./esm/abstract/hash-to-curve.js",
|
|
||||||
"default": "./abstract/hash-to-curve.js"
|
"default": "./abstract/hash-to-curve.js"
|
||||||
},
|
},
|
||||||
"./abstract/curve": {
|
"./abstract/curve": {
|
||||||
"types": "./abstract/curve.d.ts",
|
"types": "./abstract/curve.d.ts",
|
||||||
"import": "./esm/abstract/curve.js",
|
|
||||||
"default": "./abstract/curve.js"
|
"default": "./abstract/curve.js"
|
||||||
},
|
},
|
||||||
"./abstract/utils": {
|
"./abstract/utils": {
|
||||||
"types": "./abstract/utils.d.ts",
|
"types": "./abstract/utils.d.ts",
|
||||||
"import": "./esm/abstract/utils.js",
|
|
||||||
"default": "./abstract/utils.js"
|
"default": "./abstract/utils.js"
|
||||||
},
|
},
|
||||||
"./abstract/poseidon": {
|
"./abstract/poseidon": {
|
||||||
"types": "./abstract/poseidon.d.ts",
|
"types": "./abstract/poseidon.d.ts",
|
||||||
"import": "./esm/abstract/poseidon.js",
|
|
||||||
"default": "./abstract/poseidon.js"
|
"default": "./abstract/poseidon.js"
|
||||||
},
|
},
|
||||||
"./_shortw_utils": {
|
"./_shortw_utils": {
|
||||||
"types": "./_shortw_utils.d.ts",
|
"types": "./_shortw_utils.d.ts",
|
||||||
"import": "./esm/_shortw_utils.js",
|
|
||||||
"default": "./_shortw_utils.js"
|
"default": "./_shortw_utils.js"
|
||||||
},
|
},
|
||||||
"./bls12-381": {
|
"./bls12-381": {
|
||||||
"types": "./bls12-381.d.ts",
|
"types": "./bls12-381.d.ts",
|
||||||
"import": "./esm/bls12-381.js",
|
|
||||||
"default": "./bls12-381.js"
|
"default": "./bls12-381.js"
|
||||||
},
|
},
|
||||||
"./bn": {
|
"./bn": {
|
||||||
"types": "./bn.d.ts",
|
"types": "./bn.d.ts",
|
||||||
"import": "./esm/bn.js",
|
|
||||||
"default": "./bn.js"
|
"default": "./bn.js"
|
||||||
},
|
},
|
||||||
"./ed25519": {
|
"./ed25519": {
|
||||||
"types": "./ed25519.d.ts",
|
"types": "./ed25519.d.ts",
|
||||||
"import": "./esm/ed25519.js",
|
|
||||||
"default": "./ed25519.js"
|
"default": "./ed25519.js"
|
||||||
},
|
},
|
||||||
"./ed448": {
|
"./ed448": {
|
||||||
"types": "./ed448.d.ts",
|
"types": "./ed448.d.ts",
|
||||||
"import": "./esm/ed448.js",
|
|
||||||
"default": "./ed448.js"
|
"default": "./ed448.js"
|
||||||
},
|
},
|
||||||
"./index": {
|
"./index": {
|
||||||
"types": "./index.d.ts",
|
"types": "./index.d.ts",
|
||||||
"import": "./esm/index.js",
|
|
||||||
"default": "./index.js"
|
"default": "./index.js"
|
||||||
},
|
},
|
||||||
"./jubjub": {
|
"./jubjub": {
|
||||||
"types": "./jubjub.d.ts",
|
"types": "./jubjub.d.ts",
|
||||||
"import": "./esm/jubjub.js",
|
|
||||||
"default": "./jubjub.js"
|
"default": "./jubjub.js"
|
||||||
},
|
},
|
||||||
"./p256": {
|
"./p256": {
|
||||||
"types": "./p256.d.ts",
|
"types": "./p256.d.ts",
|
||||||
"import": "./esm/p256.js",
|
|
||||||
"default": "./p256.js"
|
"default": "./p256.js"
|
||||||
},
|
},
|
||||||
"./p384": {
|
"./p384": {
|
||||||
"types": "./p384.d.ts",
|
"types": "./p384.d.ts",
|
||||||
"import": "./esm/p384.js",
|
|
||||||
"default": "./p384.js"
|
"default": "./p384.js"
|
||||||
},
|
},
|
||||||
"./p521": {
|
"./p521": {
|
||||||
"types": "./p521.d.ts",
|
"types": "./p521.d.ts",
|
||||||
"import": "./esm/p521.js",
|
|
||||||
"default": "./p521.js"
|
"default": "./p521.js"
|
||||||
},
|
},
|
||||||
"./pasta": {
|
"./pasta": {
|
||||||
"types": "./pasta.d.ts",
|
"types": "./pasta.d.ts",
|
||||||
"import": "./esm/pasta.js",
|
|
||||||
"default": "./pasta.js"
|
"default": "./pasta.js"
|
||||||
},
|
},
|
||||||
"./secp256k1": {
|
"./secp256k1": {
|
||||||
"types": "./secp256k1.d.ts",
|
"types": "./secp256k1.d.ts",
|
||||||
"import": "./esm/secp256k1.js",
|
|
||||||
"default": "./secp256k1.js"
|
"default": "./secp256k1.js"
|
||||||
},
|
},
|
||||||
"./stark": {
|
"./stark": {
|
||||||
"types": "./stark.d.ts",
|
"types": "./stark.d.ts",
|
||||||
"import": "./esm/stark.js",
|
|
||||||
"default": "./stark.js"
|
"default": "./stark.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ import { bytesToNumberBE, CHash, concatBytes, utf8ToBytes, validateObject } from
|
|||||||
* * `expand` is `xmd` (SHA2, SHA3, BLAKE) or `xof` (SHAKE, BLAKE-XOF)
|
* * `expand` is `xmd` (SHA2, SHA3, BLAKE) or `xof` (SHAKE, BLAKE-XOF)
|
||||||
* * `hash` conforming to `utils.CHash` interface, with `outputLen` / `blockLen` props
|
* * `hash` conforming to `utils.CHash` interface, with `outputLen` / `blockLen` props
|
||||||
*/
|
*/
|
||||||
|
type UnicodeOrBytes = string | Uint8Array;
|
||||||
export type Opts = {
|
export type Opts = {
|
||||||
DST: string | Uint8Array;
|
DST: UnicodeOrBytes;
|
||||||
p: bigint;
|
p: bigint;
|
||||||
m: number;
|
m: number;
|
||||||
k: number;
|
k: number;
|
||||||
@@ -20,7 +21,7 @@ export type Opts = {
|
|||||||
hash: CHash;
|
hash: CHash;
|
||||||
};
|
};
|
||||||
|
|
||||||
function validateDST(dst: string | Uint8Array): Uint8Array {
|
function validateDST(dst: UnicodeOrBytes): Uint8Array {
|
||||||
if (dst instanceof Uint8Array) return dst;
|
if (dst instanceof Uint8Array) return dst;
|
||||||
if (typeof dst === 'string') return utf8ToBytes(dst);
|
if (typeof dst === 'string') return utf8ToBytes(dst);
|
||||||
throw new Error('DST must be Uint8Array or string');
|
throw new Error('DST must be Uint8Array or string');
|
||||||
@@ -125,6 +126,13 @@ export function expand_message_xof(
|
|||||||
* @returns [u_0, ..., u_(count - 1)], a list of field elements.
|
* @returns [u_0, ..., u_(count - 1)], a list of field elements.
|
||||||
*/
|
*/
|
||||||
export function hash_to_field(msg: Uint8Array, count: number, options: Opts): bigint[][] {
|
export function hash_to_field(msg: Uint8Array, count: number, options: Opts): bigint[][] {
|
||||||
|
validateObject(options, {
|
||||||
|
DST: 'string',
|
||||||
|
p: 'bigint',
|
||||||
|
m: 'isSafeInteger',
|
||||||
|
k: 'isSafeInteger',
|
||||||
|
hash: 'hash',
|
||||||
|
});
|
||||||
const { p, k, m, hash, expand, DST: _DST } = options;
|
const { p, k, m, hash, expand, DST: _DST } = options;
|
||||||
isBytes(msg);
|
isBytes(msg);
|
||||||
isNum(count);
|
isNum(count);
|
||||||
@@ -183,24 +191,17 @@ export type MapToCurve<T> = (scalar: bigint[]) => AffinePoint<T>;
|
|||||||
|
|
||||||
// Separated from initialization opts, so users won't accidentally change per-curve parameters
|
// Separated from initialization opts, so users won't accidentally change per-curve parameters
|
||||||
// (changing DST is ok!)
|
// (changing DST is ok!)
|
||||||
export type htfBasicOpts = { DST: string };
|
export type htfBasicOpts = { DST: UnicodeOrBytes };
|
||||||
|
|
||||||
export function createHasher<T>(
|
export function createHasher<T>(
|
||||||
Point: H2CPointConstructor<T>,
|
Point: H2CPointConstructor<T>,
|
||||||
mapToCurve: MapToCurve<T>,
|
mapToCurve: MapToCurve<T>,
|
||||||
def: Opts & { encodeDST?: string }
|
def: Opts & { encodeDST?: UnicodeOrBytes }
|
||||||
) {
|
) {
|
||||||
validateObject(def, {
|
|
||||||
DST: 'string',
|
|
||||||
p: 'bigint',
|
|
||||||
m: 'isSafeInteger',
|
|
||||||
k: 'isSafeInteger',
|
|
||||||
hash: 'hash',
|
|
||||||
});
|
|
||||||
if (typeof mapToCurve !== 'function') throw new Error('mapToCurve() must be defined');
|
if (typeof mapToCurve !== 'function') throw new Error('mapToCurve() must be defined');
|
||||||
return {
|
return {
|
||||||
// Encodes byte string to elliptic curve
|
// Encodes byte string to elliptic curve
|
||||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3
|
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-3
|
||||||
hashToCurve(msg: Uint8Array, options?: htfBasicOpts) {
|
hashToCurve(msg: Uint8Array, options?: htfBasicOpts) {
|
||||||
const u = hash_to_field(msg, 2, { ...def, DST: def.DST, ...options } as Opts);
|
const u = hash_to_field(msg, 2, { ...def, DST: def.DST, ...options } as Opts);
|
||||||
const u0 = Point.fromAffine(mapToCurve(u[0]));
|
const u0 = Point.fromAffine(mapToCurve(u[0]));
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export function invert(number: bigint, modulo: bigint): bigint {
|
|||||||
throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
|
throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
|
||||||
}
|
}
|
||||||
// Eucledian GCD https://brilliant.org/wiki/extended-euclidean-algorithm/
|
// Eucledian GCD https://brilliant.org/wiki/extended-euclidean-algorithm/
|
||||||
|
// Fermat's little theorem "CT-like" version inv(n) = n^(m-2) mod m is 30x slower.
|
||||||
let a = mod(number, modulo);
|
let a = mod(number, modulo);
|
||||||
let b = modulo;
|
let b = modulo;
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
|
|||||||
@@ -943,16 +943,10 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
|||||||
const q = Point.BASE.multiply(k).toAffine(); // q = Gk
|
const q = Point.BASE.multiply(k).toAffine(); // q = Gk
|
||||||
const r = modN(q.x); // r = q.x mod n
|
const r = modN(q.x); // r = q.x mod n
|
||||||
if (r === _0n) return;
|
if (r === _0n) return;
|
||||||
// X blinding according to https://tches.iacr.org/index.php/TCHES/article/view/7337/6509
|
// Can use scalar blinding b^-1(bm + bdr) where b ∈ [1,q−1] according to
|
||||||
// b * m + b * r * d ∈ [0,q−1] exposed via side-channel, but d (private scalar) is not.
|
// https://tches.iacr.org/index.php/TCHES/article/view/7337/6509. We've decided against it:
|
||||||
// NOTE: there is still probable some leak in multiplication, since it is not constant-time
|
// a) dependency on CSPRNG b) 15% slowdown c) doesn't really help since bigints are not CT
|
||||||
const b = ut.bytesToNumberBE(utils.randomPrivateKey()); // random scalar, b ∈ [1,q−1]
|
const s = modN(ik * modN(m + r * d)); // Not using blinding here
|
||||||
const bi = invN(b); // b^-1
|
|
||||||
const bdr = modN(b * d * r); // b * d * r
|
|
||||||
const bm = modN(b * m); // b * m
|
|
||||||
const mrx = modN(bi * modN(bdr + bm)); // b^-1(bm + bdr) -> m + rd
|
|
||||||
|
|
||||||
const s = modN(ik * mrx); // s = k^-1(m + rd) mod n
|
|
||||||
if (s === _0n) return;
|
if (s === _0n) return;
|
||||||
let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n); // recovery bit (2 or 3, when q.x > n)
|
let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n); // recovery bit (2 or 3, when q.x > n)
|
||||||
let normS = s;
|
let normS = s;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
ensureBytes,
|
ensureBytes,
|
||||||
} from './abstract/utils.js';
|
} from './abstract/utils.js';
|
||||||
import * as htf from './abstract/hash-to-curve.js';
|
import * as htf from './abstract/hash-to-curve.js';
|
||||||
|
import { AffinePoint } from './abstract/curve.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ed25519 Twisted Edwards curve with following addons:
|
* ed25519 Twisted Edwards curve with following addons:
|
||||||
@@ -309,6 +310,11 @@ export class RistrettoPoint {
|
|||||||
// Private property to discourage combining ExtendedPoint + RistrettoPoint
|
// Private property to discourage combining ExtendedPoint + RistrettoPoint
|
||||||
// Always use Ristretto encoding/decoding instead.
|
// Always use Ristretto encoding/decoding instead.
|
||||||
constructor(private readonly ep: ExtendedPoint) {}
|
constructor(private readonly ep: ExtendedPoint) {}
|
||||||
|
|
||||||
|
static fromAffine(ap: AffinePoint<bigint>) {
|
||||||
|
return new RistrettoPoint(ed25519.ExtendedPoint.fromAffine(ap));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes uniform output of 64-bit hash function like sha512 and converts it to `RistrettoPoint`.
|
* Takes uniform output of 64-bit hash function like sha512 and converts it to `RistrettoPoint`.
|
||||||
* The hash-to-group operation applies Elligator twice and adds the results.
|
* The hash-to-group operation applies Elligator twice and adds the results.
|
||||||
@@ -401,7 +407,7 @@ export class RistrettoPoint {
|
|||||||
equals(other: RistrettoPoint): boolean {
|
equals(other: RistrettoPoint): boolean {
|
||||||
assertRstPoint(other);
|
assertRstPoint(other);
|
||||||
const { ex: X1, ey: Y1 } = this.ep;
|
const { ex: X1, ey: Y1 } = this.ep;
|
||||||
const { ex: X2, ey: Y2 } = this.ep;
|
const { ex: X2, ey: Y2 } = other.ep;
|
||||||
const mod = ed25519.CURVE.Fp.create;
|
const mod = ed25519.CURVE.Fp.create;
|
||||||
// (x1 * y2 == y1 * x2) | (y1 * y2 == x1 * x2)
|
// (x1 * y2 == y1 * x2) | (y1 * y2 == x1 * x2)
|
||||||
const one = mod(X1 * Y2) === mod(Y1 * X2);
|
const one = mod(X1 * Y2) === mod(Y1 * X2);
|
||||||
@@ -427,3 +433,13 @@ export class RistrettoPoint {
|
|||||||
return new RistrettoPoint(this.ep.multiplyUnsafe(scalar));
|
return new RistrettoPoint(this.ep.multiplyUnsafe(scalar));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/14/
|
||||||
|
// Appendix B. Hashing to ristretto255
|
||||||
|
export const hash_to_ristretto255 = (msg: Uint8Array, options: htf.htfBasicOpts) => {
|
||||||
|
const d = options.DST;
|
||||||
|
const DST = typeof d === 'string' ? utf8ToBytes(d) : d;
|
||||||
|
const uniform_bytes = htf.expand_message_xmd(msg, DST, 64, sha512);
|
||||||
|
const P = RistrettoPoint.hashToCurve(uniform_bytes);
|
||||||
|
return P;
|
||||||
|
};
|
||||||
|
|||||||
@@ -115,12 +115,13 @@ const modN = (x: bigint) => mod(x, secp256k1N);
|
|||||||
const Point = secp256k1.ProjectivePoint;
|
const Point = secp256k1.ProjectivePoint;
|
||||||
const GmulAdd = (Q: PointType<bigint>, a: bigint, b: bigint) =>
|
const GmulAdd = (Q: PointType<bigint>, a: bigint, b: bigint) =>
|
||||||
Point.BASE.multiplyAndAddUnsafe(Q, a, b);
|
Point.BASE.multiplyAndAddUnsafe(Q, a, b);
|
||||||
|
|
||||||
// Calculate point, scalar and bytes
|
// Calculate point, scalar and bytes
|
||||||
function schnorrGetExtPubKey(priv: PrivKey) {
|
function schnorrGetExtPubKey(priv: PrivKey) {
|
||||||
const d = secp256k1.utils.normPrivateKeyToScalar(priv); // same method executed in fromPrivateKey
|
let d_ = secp256k1.utils.normPrivateKeyToScalar(priv); // same method executed in fromPrivateKey
|
||||||
const point = Point.fromPrivateKey(d); // P = d'⋅G; 0 < d' < n check is done inside
|
let p = Point.fromPrivateKey(d_); // P = d'⋅G; 0 < d' < n check is done inside
|
||||||
const scalar = point.hasEvenY() ? d : modN(-d); // d = d' if has_even_y(P), otherwise d = n-d'
|
const scalar = p.hasEvenY() ? d_ : modN(-d_);
|
||||||
return { point, scalar, bytes: pointToBytes(point) };
|
return { scalar: scalar, bytes: pointToBytes(p) };
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* lift_x from BIP340. Convert 32-byte x coordinate to elliptic curve point.
|
* lift_x from BIP340. Convert 32-byte x coordinate to elliptic curve point.
|
||||||
@@ -166,10 +167,10 @@ function schnorrSign(
|
|||||||
const rand = taggedHash('BIP0340/nonce', t, px, m); // Let rand = hash/nonce(t || bytes(P) || m)
|
const rand = taggedHash('BIP0340/nonce', t, px, m); // Let rand = hash/nonce(t || bytes(P) || m)
|
||||||
const k_ = modN(bytesToNumberBE(rand)); // Let k' = int(rand) mod n
|
const k_ = modN(bytesToNumberBE(rand)); // Let k' = int(rand) mod n
|
||||||
if (k_ === _0n) throw new Error('sign failed: k is zero'); // Fail if k' = 0.
|
if (k_ === _0n) throw new Error('sign failed: k is zero'); // Fail if k' = 0.
|
||||||
const { point: R, bytes: rx, scalar: k } = schnorrGetExtPubKey(k_); // Let R = k'⋅G.
|
const { bytes: rx, scalar: k } = schnorrGetExtPubKey(k_); // Let R = k'⋅G.
|
||||||
const e = challenge(rx, px, m); // Let e = int(hash/challenge(bytes(R) || bytes(P) || m)) mod n.
|
const e = challenge(rx, px, m); // Let e = int(hash/challenge(bytes(R) || bytes(P) || m)) mod n.
|
||||||
const sig = new Uint8Array(64); // Let sig = bytes(R) || bytes((k + ed) mod n).
|
const sig = new Uint8Array(64); // Let sig = bytes(R) || bytes((k + ed) mod n).
|
||||||
sig.set(numTo32b(R.px), 0);
|
sig.set(rx, 0);
|
||||||
sig.set(numTo32b(modN(k + e * d)), 32);
|
sig.set(numTo32b(modN(k + e * d)), 32);
|
||||||
// If Verify(bytes(P), m, sig) (see below) returns failure, abort
|
// If Verify(bytes(P), m, sig) (see below) returns failure, abort
|
||||||
if (!schnorrVerify(sig, m, px)) throw new Error('sign: Invalid signature produced');
|
if (!schnorrVerify(sig, m, px)) throw new Error('sign: Invalid signature produced');
|
||||||
@@ -205,7 +206,6 @@ export const schnorr = {
|
|||||||
verify: schnorrVerify,
|
verify: schnorrVerify,
|
||||||
utils: {
|
utils: {
|
||||||
randomPrivateKey: secp256k1.utils.randomPrivateKey,
|
randomPrivateKey: secp256k1.utils.randomPrivateKey,
|
||||||
getExtendedPublicKey: schnorrGetExtPubKey,
|
|
||||||
lift_x,
|
lift_x,
|
||||||
pointToBytes,
|
pointToBytes,
|
||||||
numberToBytesBE,
|
numberToBytesBE,
|
||||||
|
|||||||
77
src/stark.ts
77
src/stark.ts
@@ -5,17 +5,8 @@ import { utf8ToBytes } from '@noble/hashes/utils';
|
|||||||
import { Fp, mod, Field, validateField } from './abstract/modular.js';
|
import { Fp, mod, Field, validateField } from './abstract/modular.js';
|
||||||
import { poseidon } from './abstract/poseidon.js';
|
import { poseidon } from './abstract/poseidon.js';
|
||||||
import { weierstrass, ProjPointType, SignatureType } from './abstract/weierstrass.js';
|
import { weierstrass, ProjPointType, SignatureType } from './abstract/weierstrass.js';
|
||||||
import {
|
import * as u from './abstract/utils.js';
|
||||||
Hex,
|
import type { Hex } from './abstract/utils.js';
|
||||||
bitMask,
|
|
||||||
bytesToHex,
|
|
||||||
bytesToNumberBE,
|
|
||||||
concatBytes,
|
|
||||||
ensureBytes as ensureBytesOrig,
|
|
||||||
hexToBytes,
|
|
||||||
hexToNumber,
|
|
||||||
numberToVarBytesBE,
|
|
||||||
} from './abstract/utils.js';
|
|
||||||
import { getHash } from './_shortw_utils.js';
|
import { getHash } from './_shortw_utils.js';
|
||||||
|
|
||||||
// Stark-friendly elliptic curve
|
// Stark-friendly elliptic curve
|
||||||
@@ -30,7 +21,7 @@ function bits2int(bytes: Uint8Array): bigint {
|
|||||||
while (bytes[0] === 0) bytes = bytes.subarray(1); // strip leading 0s
|
while (bytes[0] === 0) bytes = bytes.subarray(1); // strip leading 0s
|
||||||
// Copy-pasted from weierstrass.ts
|
// Copy-pasted from weierstrass.ts
|
||||||
const delta = bytes.length * 8 - nBitLength;
|
const delta = bytes.length * 8 - nBitLength;
|
||||||
const num = bytesToNumberBE(bytes);
|
const num = u.bytesToNumberBE(bytes);
|
||||||
return delta > 0 ? num >> BigInt(delta) : num;
|
return delta > 0 ? num >> BigInt(delta) : num;
|
||||||
}
|
}
|
||||||
function hex0xToBytes(hex: string): Uint8Array {
|
function hex0xToBytes(hex: string): Uint8Array {
|
||||||
@@ -38,7 +29,7 @@ function hex0xToBytes(hex: string): Uint8Array {
|
|||||||
hex = strip0x(hex); // allow 0x prefix
|
hex = strip0x(hex); // allow 0x prefix
|
||||||
if (hex.length & 1) hex = '0' + hex; // allow unpadded hex
|
if (hex.length & 1) hex = '0' + hex; // allow unpadded hex
|
||||||
}
|
}
|
||||||
return hexToBytes(hex);
|
return u.hexToBytes(hex);
|
||||||
}
|
}
|
||||||
const curve = weierstrass({
|
const curve = weierstrass({
|
||||||
a: BigInt(1), // Params: a, b
|
a: BigInt(1), // Params: a, b
|
||||||
@@ -59,7 +50,7 @@ const curve = weierstrass({
|
|||||||
bits2int_modN: (bytes: Uint8Array): bigint => {
|
bits2int_modN: (bytes: Uint8Array): bigint => {
|
||||||
// 2102820b232636d200cb21f1d330f20d096cae09d1bf3edb1cc333ddee11318 =>
|
// 2102820b232636d200cb21f1d330f20d096cae09d1bf3edb1cc333ddee11318 =>
|
||||||
// 2102820b232636d200cb21f1d330f20d096cae09d1bf3edb1cc333ddee113180
|
// 2102820b232636d200cb21f1d330f20d096cae09d1bf3edb1cc333ddee113180
|
||||||
const hex = bytesToNumberBE(bytes).toString(16); // toHex unpadded
|
const hex = u.bytesToNumberBE(bytes).toString(16); // toHex unpadded
|
||||||
if (hex.length === 63) bytes = hex0xToBytes(hex + '0'); // append trailing 0
|
if (hex.length === 63) bytes = hex0xToBytes(hex + '0'); // append trailing 0
|
||||||
return mod(bits2int(bytes), CURVE_ORDER);
|
return mod(bits2int(bytes), CURVE_ORDER);
|
||||||
},
|
},
|
||||||
@@ -67,11 +58,11 @@ const curve = weierstrass({
|
|||||||
export const _starkCurve = curve;
|
export const _starkCurve = curve;
|
||||||
|
|
||||||
function ensureBytes(hex: Hex): Uint8Array {
|
function ensureBytes(hex: Hex): Uint8Array {
|
||||||
return ensureBytesOrig('', typeof hex === 'string' ? hex0xToBytes(hex) : hex);
|
return u.ensureBytes('', typeof hex === 'string' ? hex0xToBytes(hex) : hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
function normPrivKey(privKey: Hex): string {
|
function normPrivKey(privKey: Hex): string {
|
||||||
return bytesToHex(ensureBytes(privKey)).padStart(64, '0');
|
return u.bytesToHex(ensureBytes(privKey)).padStart(64, '0');
|
||||||
}
|
}
|
||||||
export function getPublicKey(privKey: Hex, isCompressed = false): Uint8Array {
|
export function getPublicKey(privKey: Hex, isCompressed = false): Uint8Array {
|
||||||
return curve.getPublicKey(normPrivKey(privKey), isCompressed);
|
return curve.getPublicKey(normPrivKey(privKey), isCompressed);
|
||||||
@@ -91,7 +82,7 @@ const { CURVE, ProjectivePoint, Signature, utils } = curve;
|
|||||||
export { CURVE, ProjectivePoint, Signature, utils };
|
export { CURVE, ProjectivePoint, Signature, utils };
|
||||||
|
|
||||||
function extractX(bytes: Uint8Array): string {
|
function extractX(bytes: Uint8Array): string {
|
||||||
const hex = bytesToHex(bytes.subarray(1));
|
const hex = u.bytesToHex(bytes.subarray(1));
|
||||||
const stripped = hex.replace(/^0+/gm, ''); // strip leading 0s
|
const stripped = hex.replace(/^0+/gm, ''); // strip leading 0s
|
||||||
return `0x${stripped}`;
|
return `0x${stripped}`;
|
||||||
}
|
}
|
||||||
@@ -109,7 +100,7 @@ export function grindKey(seed: Hex) {
|
|||||||
const sha256mask = 2n ** 256n;
|
const sha256mask = 2n ** 256n;
|
||||||
const limit = sha256mask - mod(sha256mask, CURVE_ORDER);
|
const limit = sha256mask - mod(sha256mask, CURVE_ORDER);
|
||||||
for (let i = 0; ; i++) {
|
for (let i = 0; ; i++) {
|
||||||
const key = sha256Num(concatBytes(_seed, numberToVarBytesBE(BigInt(i))));
|
const key = sha256Num(u.concatBytes(_seed, u.numberToVarBytesBE(BigInt(i))));
|
||||||
if (key < limit) return mod(key, CURVE_ORDER).toString(16); // key should be in [0, limit)
|
if (key < limit) return mod(key, CURVE_ORDER).toString(16); // key should be in [0, limit)
|
||||||
if (i === 100000) throw new Error('grindKey is broken: tried 100k vals'); // prevent dos
|
if (i === 100000) throw new Error('grindKey is broken: tried 100k vals'); // prevent dos
|
||||||
}
|
}
|
||||||
@@ -135,7 +126,7 @@ export function getAccountPath(
|
|||||||
): string {
|
): string {
|
||||||
const layerNum = int31(sha256Num(layer));
|
const layerNum = int31(sha256Num(layer));
|
||||||
const applicationNum = int31(sha256Num(application));
|
const applicationNum = int31(sha256Num(application));
|
||||||
const eth = hexToNumber(strip0x(ethereumAddress));
|
const eth = u.hexToNumber(strip0x(ethereumAddress));
|
||||||
return `m/2645'/${layerNum}'/${applicationNum}'/${int31(eth)}'/${int31(eth >> 31n)}'/${index}`;
|
return `m/2645'/${layerNum}'/${applicationNum}'/${int31(eth)}'/${int31(eth >> 31n)}'/${index}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,7 +187,7 @@ function pedersenArg(arg: PedersenArg): bigint {
|
|||||||
if (!Number.isSafeInteger(arg)) throw new Error(`Invalid pedersenArg: ${arg}`);
|
if (!Number.isSafeInteger(arg)) throw new Error(`Invalid pedersenArg: ${arg}`);
|
||||||
value = BigInt(arg);
|
value = BigInt(arg);
|
||||||
} else {
|
} else {
|
||||||
value = bytesToNumberBE(ensureBytes(arg));
|
value = u.bytesToNumberBE(ensureBytes(arg));
|
||||||
}
|
}
|
||||||
if (!(0n <= value && value < curve.CURVE.Fp.ORDER))
|
if (!(0n <= value && value < curve.CURVE.Fp.ORDER))
|
||||||
throw new Error(`PedersenArg should be 0 <= value < CURVE.P: ${value}`); // [0..Fp)
|
throw new Error(`PedersenArg should be 0 <= value < CURVE.P: ${value}`); // [0..Fp)
|
||||||
@@ -207,7 +198,7 @@ function pedersenSingle(point: ProjectivePoint, value: PedersenArg, constants: P
|
|||||||
let x = pedersenArg(value);
|
let x = pedersenArg(value);
|
||||||
for (let j = 0; j < 252; j++) {
|
for (let j = 0; j < 252; j++) {
|
||||||
const pt = constants[j];
|
const pt = constants[j];
|
||||||
if (pt.px === point.px) throw new Error('Same point');
|
if (pt.equals(point)) throw new Error('Same point');
|
||||||
if ((x & 1n) !== 0n) point = point.add(pt);
|
if ((x & 1n) !== 0n) point = point.add(pt);
|
||||||
x >>= 1n;
|
x >>= 1n;
|
||||||
}
|
}
|
||||||
@@ -234,9 +225,9 @@ export function hashChain(data: PedersenArg[], fn = pedersen) {
|
|||||||
export const computeHashOnElements = (data: PedersenArg[], fn = pedersen) =>
|
export const computeHashOnElements = (data: PedersenArg[], fn = pedersen) =>
|
||||||
[0, ...data, data.length].reduce((x, y) => fn(x, y));
|
[0, ...data, data.length].reduce((x, y) => fn(x, y));
|
||||||
|
|
||||||
const MASK_250 = bitMask(250);
|
const MASK_250 = u.bitMask(250);
|
||||||
export const keccak = (data: Uint8Array): bigint => bytesToNumberBE(keccak_256(data)) & MASK_250;
|
export const keccak = (data: Uint8Array): bigint => u.bytesToNumberBE(keccak_256(data)) & MASK_250;
|
||||||
const sha256Num = (data: Uint8Array | string): bigint => bytesToNumberBE(sha256(data));
|
const sha256Num = (data: Uint8Array | string): bigint => u.bytesToNumberBE(sha256(data));
|
||||||
|
|
||||||
// Poseidon hash
|
// Poseidon hash
|
||||||
export const Fp253 = Fp(
|
export const Fp253 = Fp(
|
||||||
@@ -280,7 +271,13 @@ export type PoseidonOpts = {
|
|||||||
roundsPartial: number;
|
roundsPartial: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function poseidonBasic(opts: PoseidonOpts, mds: bigint[][]) {
|
export type PoseidonFn = ReturnType<typeof poseidon> & {
|
||||||
|
m: number;
|
||||||
|
rate: number;
|
||||||
|
capacity: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function poseidonBasic(opts: PoseidonOpts, mds: bigint[][]): PoseidonFn {
|
||||||
validateField(opts.Fp);
|
validateField(opts.Fp);
|
||||||
if (!Number.isSafeInteger(opts.rate) || !Number.isSafeInteger(opts.capacity))
|
if (!Number.isSafeInteger(opts.rate) || !Number.isSafeInteger(opts.capacity))
|
||||||
throw new Error(`Wrong poseidon opts: ${opts}`);
|
throw new Error(`Wrong poseidon opts: ${opts}`);
|
||||||
@@ -292,7 +289,7 @@ export function poseidonBasic(opts: PoseidonOpts, mds: bigint[][]) {
|
|||||||
for (let j = 0; j < m; j++) row.push(poseidonRoundConstant(opts.Fp, 'Hades', m * i + j));
|
for (let j = 0; j < m; j++) row.push(poseidonRoundConstant(opts.Fp, 'Hades', m * i + j));
|
||||||
roundConstants.push(row);
|
roundConstants.push(row);
|
||||||
}
|
}
|
||||||
return poseidon({
|
const res: Partial<PoseidonFn> = poseidon({
|
||||||
...opts,
|
...opts,
|
||||||
t: m,
|
t: m,
|
||||||
sboxPower: 3,
|
sboxPower: 3,
|
||||||
@@ -300,6 +297,10 @@ export function poseidonBasic(opts: PoseidonOpts, mds: bigint[][]) {
|
|||||||
mds,
|
mds,
|
||||||
roundConstants,
|
roundConstants,
|
||||||
});
|
});
|
||||||
|
res.m = m;
|
||||||
|
res.rate = opts.rate;
|
||||||
|
res.capacity = opts.capacity;
|
||||||
|
return res as PoseidonFn;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function poseidonCreate(opts: PoseidonOpts, mdsAttempt = 0) {
|
export function poseidonCreate(opts: PoseidonOpts, mdsAttempt = 0) {
|
||||||
@@ -313,6 +314,28 @@ export const poseidonSmall = poseidonBasic(
|
|||||||
MDS_SMALL
|
MDS_SMALL
|
||||||
);
|
);
|
||||||
|
|
||||||
export function poseidonHash(x: bigint, y: bigint, fn = poseidonSmall) {
|
export function poseidonHash(x: bigint, y: bigint, fn = poseidonSmall): bigint {
|
||||||
return fn([x, y, 2n])[0];
|
return fn([x, y, 2n])[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function poseidonHashFunc(x: Uint8Array, y: Uint8Array, fn = poseidonSmall): Uint8Array {
|
||||||
|
return u.numberToVarBytesBE(poseidonHash(u.bytesToNumberBE(x), u.bytesToNumberBE(y), fn));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function poseidonHashSingle(x: bigint, fn = poseidonSmall): bigint {
|
||||||
|
return fn([x, 0n, 1n])[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function poseidonHashMany(values: bigint[], fn = poseidonSmall): bigint {
|
||||||
|
const { m, rate } = fn;
|
||||||
|
if (!Array.isArray(values)) throw new Error('bigint array expected in values');
|
||||||
|
const padded = Array.from(values); // copy
|
||||||
|
padded.push(1n);
|
||||||
|
while (padded.length % rate !== 0) padded.push(0n);
|
||||||
|
let state: bigint[] = new Array(m).fill(0n);
|
||||||
|
for (let i = 0; i < padded.length; i += rate) {
|
||||||
|
for (let j = 0; j < rate; j++) state[j] += padded[i + j];
|
||||||
|
state = fn(state);
|
||||||
|
}
|
||||||
|
return state[0];
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
import { deepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, throws } from 'assert';
|
||||||
import { should, describe } from 'micro-should';
|
import { should, describe } from 'micro-should';
|
||||||
import * as fc from 'fast-check';
|
import * as fc from 'fast-check';
|
||||||
import * as mod from '../esm/abstract/modular.js';
|
import * as mod from '../abstract/modular.js';
|
||||||
import { bytesToHex as toHex } from '../esm/abstract/utils.js';
|
import { bytesToHex as toHex } from '../abstract/utils.js';
|
||||||
// Generic tests for all curves in package
|
// Generic tests for all curves in package
|
||||||
import { secp192r1, secp224r1 } from './_more-curves.helpers.js';
|
import { secp192r1, secp224r1 } from './_more-curves.helpers.js';
|
||||||
import { secp256r1 } from '../esm/p256.js';
|
import { secp256r1 } from '../p256.js';
|
||||||
import { secp384r1 } from '../esm/p384.js';
|
import { secp384r1 } from '../p384.js';
|
||||||
import { secp521r1 } from '../esm/p521.js';
|
import { secp521r1 } from '../p521.js';
|
||||||
import { secp256k1 } from '../esm/secp256k1.js';
|
import { secp256k1 } from '../secp256k1.js';
|
||||||
import { ed25519, ed25519ctx, ed25519ph, x25519 } from '../esm/ed25519.js';
|
import { ed25519, ed25519ctx, ed25519ph, x25519 } from '../ed25519.js';
|
||||||
import { ed448, ed448ph } from '../esm/ed448.js';
|
import { ed448, ed448ph } from '../ed448.js';
|
||||||
import { _starkCurve as starkCurve } from '../esm/stark.js';
|
import { _starkCurve as starkCurve } from '../stark.js';
|
||||||
import { pallas, vesta } from '../esm/pasta.js';
|
import { pallas, vesta } from '../pasta.js';
|
||||||
import { bn254 } from '../esm/bn.js';
|
import { bn254 } from '../bn.js';
|
||||||
import { jubjub } from '../esm/jubjub.js';
|
import { jubjub } from '../jubjub.js';
|
||||||
import { bls12_381 } from '../esm/bls12-381.js';
|
import { bls12_381 } from '../bls12-381.js';
|
||||||
|
|
||||||
// Fields tests
|
// Fields tests
|
||||||
const FIELDS = {
|
const FIELDS = {
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import { deepStrictEqual, notDeepStrictEqual, throws } from 'assert';
|
|||||||
import * as fc from 'fast-check';
|
import * as fc from 'fast-check';
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { describe, should } from 'micro-should';
|
import { describe, should } from 'micro-should';
|
||||||
import { wNAF } from '../esm/abstract/curve.js';
|
import { wNAF } from '../abstract/curve.js';
|
||||||
import { bytesToHex, utf8ToBytes } from '../esm/abstract/utils.js';
|
import { bytesToHex, utf8ToBytes } from '../abstract/utils.js';
|
||||||
import { hash_to_field } from '../esm/abstract/hash-to-curve.js';
|
import { hash_to_field } from '../abstract/hash-to-curve.js';
|
||||||
import { bls12_381 as bls } from '../esm/bls12-381.js';
|
import { bls12_381 as bls } from '../bls12-381.js';
|
||||||
|
|
||||||
import zkVectors from './bls12-381/zkcrypto/converted.json' assert { type: 'json' };
|
import zkVectors from './bls12-381/zkcrypto/converted.json' assert { type: 'json' };
|
||||||
import pairingVectors from './bls12-381/go_pairing_vectors/pairing.json' assert { type: 'json' };
|
import pairingVectors from './bls12-381/go_pairing_vectors/pairing.json' assert { type: 'json' };
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import { sha512 } from '@noble/hashes/sha512';
|
|||||||
import { hexToBytes, bytesToHex, randomBytes } from '@noble/hashes/utils';
|
import { hexToBytes, bytesToHex, randomBytes } from '@noble/hashes/utils';
|
||||||
import { deepStrictEqual, strictEqual, throws } from 'assert';
|
import { deepStrictEqual, strictEqual, throws } from 'assert';
|
||||||
import { describe, should } from 'micro-should';
|
import { describe, should } from 'micro-should';
|
||||||
import { numberToBytesLE } from '../esm/abstract/utils.js';
|
import { bytesToNumberLE, numberToBytesLE } from '../abstract/utils.js';
|
||||||
import { default as x25519vectors } from './wycheproof/x25519_test.json' assert { type: 'json' };
|
import { default as x25519vectors } from './wycheproof/x25519_test.json' assert { type: 'json' };
|
||||||
import { ed25519ctx, ed25519ph, RistrettoPoint, x25519 } from '../esm/ed25519.js';
|
import { ed25519ctx, ed25519ph, RistrettoPoint, x25519 } from '../ed25519.js';
|
||||||
|
|
||||||
// const ed = ed25519;
|
// const ed = ed25519;
|
||||||
const hex = bytesToHex;
|
const hex = bytesToHex;
|
||||||
@@ -281,10 +281,23 @@ describe('ristretto255', () => {
|
|||||||
deepStrictEqual(point.toHex(), encodedHashToPoints[i]);
|
deepStrictEqual(point.toHex(), encodedHashToPoints[i]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
should('have proper equality testing', () => {
|
||||||
|
const MAX_255B = BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
||||||
|
const bytes255ToNumberLE = (bytes) =>
|
||||||
|
ed25519ctx.CURVE.Fp.create(bytesToNumberLE(bytes) & MAX_255B);
|
||||||
|
|
||||||
|
const priv = new Uint8Array([
|
||||||
|
198, 101, 65, 165, 93, 120, 37, 238, 16, 133, 10, 35, 253, 243, 161, 246, 229, 135, 12, 137,
|
||||||
|
202, 114, 222, 139, 146, 123, 4, 125, 152, 173, 1, 7,
|
||||||
|
]);
|
||||||
|
const pub = RistrettoPoint.BASE.multiply(bytes255ToNumberLE(priv));
|
||||||
|
deepStrictEqual(pub.equals(RistrettoPoint.ZERO), false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// ESM is broken.
|
// ESM is broken.
|
||||||
import url from 'url';
|
import url from 'url';
|
||||||
|
import { assert } from 'console';
|
||||||
if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
|
if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
|
||||||
should.run();
|
should.run();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
export { ed25519, ED25519_TORSION_SUBGROUP } from '../esm/ed25519.js';
|
export { ed25519, ED25519_TORSION_SUBGROUP } from '../ed25519.js';
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { deepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, throws } from 'assert';
|
||||||
import { describe, should } from 'micro-should';
|
import { describe, should } from 'micro-should';
|
||||||
import * as fc from 'fast-check';
|
import * as fc from 'fast-check';
|
||||||
import { ed448, ed448ph, x448 } from '../esm/ed448.js';
|
import { ed448, ed448ph, x448 } from '../ed448.js';
|
||||||
import { hexToBytes, bytesToHex, randomBytes } from '@noble/hashes/utils';
|
import { hexToBytes, bytesToHex, randomBytes } from '@noble/hashes/utils';
|
||||||
import { numberToBytesLE } from '../esm/abstract/utils.js';
|
import { numberToBytesLE } from '../abstract/utils.js';
|
||||||
import { default as ed448vectors } from './wycheproof/ed448_test.json' assert { type: 'json' };
|
import { default as ed448vectors } from './wycheproof/ed448_test.json' assert { type: 'json' };
|
||||||
import { default as x448vectors } from './wycheproof/x448_test.json' assert { type: 'json' };
|
import { default as x448vectors } from './wycheproof/x448_test.json' assert { type: 'json' };
|
||||||
|
|
||||||
|
|||||||
@@ -5,15 +5,15 @@ import { bytesToHex } from '@noble/hashes/utils';
|
|||||||
import { sha256 } from '@noble/hashes/sha256';
|
import { sha256 } from '@noble/hashes/sha256';
|
||||||
import { sha512 } from '@noble/hashes/sha512';
|
import { sha512 } from '@noble/hashes/sha512';
|
||||||
import { shake128, shake256 } from '@noble/hashes/sha3';
|
import { shake128, shake256 } from '@noble/hashes/sha3';
|
||||||
import * as secp256r1 from '../esm/p256.js';
|
import * as secp256r1 from '../p256.js';
|
||||||
import * as secp384r1 from '../esm/p384.js';
|
import * as secp384r1 from '../p384.js';
|
||||||
import * as secp521r1 from '../esm/p521.js';
|
import * as secp521r1 from '../p521.js';
|
||||||
import * as ed25519 from '../esm/ed25519.js';
|
import * as ed25519 from '../ed25519.js';
|
||||||
import * as ed448 from '../esm/ed448.js';
|
import * as ed448 from '../ed448.js';
|
||||||
import * as secp256k1 from '../esm/secp256k1.js';
|
import * as secp256k1 from '../secp256k1.js';
|
||||||
import { bls12_381 } from '../esm/bls12-381.js';
|
import { bls12_381 } from '../bls12-381.js';
|
||||||
import { expand_message_xmd, expand_message_xof } from '../esm/abstract/hash-to-curve.js';
|
import { expand_message_xmd, expand_message_xof } from '../abstract/hash-to-curve.js';
|
||||||
import { utf8ToBytes } from '../esm/abstract/utils.js';
|
import { utf8ToBytes } from '../abstract/utils.js';
|
||||||
// XMD
|
// XMD
|
||||||
import { default as xmd_sha256_38 } from './hash-to-curve/expand_message_xmd_SHA256_38.json' assert { type: 'json' };
|
import { default as xmd_sha256_38 } from './hash-to-curve/expand_message_xmd_SHA256_38.json' assert { type: 'json' };
|
||||||
import { default as xmd_sha256_256 } from './hash-to-curve/expand_message_xmd_SHA256_256.json' assert { type: 'json' };
|
import { default as xmd_sha256_256 } from './hash-to-curve/expand_message_xmd_SHA256_256.json' assert { type: 'json' };
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { jubjub, findGroupHash } from '../esm/jubjub.js';
|
import { jubjub, findGroupHash } from '../jubjub.js';
|
||||||
import { describe, should } from 'micro-should';
|
import { describe, should } from 'micro-should';
|
||||||
import { deepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, throws } from 'assert';
|
||||||
const Point = jubjub.ExtendedPoint;
|
const Point = jubjub.ExtendedPoint;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { deepStrictEqual } from 'assert';
|
import { deepStrictEqual } from 'assert';
|
||||||
import { describe, should } from 'micro-should';
|
import { describe, should } from 'micro-should';
|
||||||
import { secp192r1, secp224r1, P192, P224 } from './_more-curves.helpers.js';
|
import { secp192r1, secp224r1, P192, P224 } from './_more-curves.helpers.js';
|
||||||
import { secp256r1, P256 } from '../esm/p256.js';
|
import { secp256r1, P256 } from '../p256.js';
|
||||||
import { secp384r1, P384 } from '../esm/p384.js';
|
import { secp384r1, P384 } from '../p384.js';
|
||||||
import { secp521r1, P521 } from '../esm/p521.js';
|
import { secp521r1, P521 } from '../p521.js';
|
||||||
import { secp256k1 } from '../esm/secp256k1.js';
|
import { secp256k1 } from '../secp256k1.js';
|
||||||
import { hexToBytes, bytesToHex } from '../esm/abstract/utils.js';
|
import { hexToBytes, bytesToHex } from '../abstract/utils.js';
|
||||||
import { default as ecdsa } from './wycheproof/ecdsa_test.json' assert { type: 'json' };
|
import { default as ecdsa } from './wycheproof/ecdsa_test.json' assert { type: 'json' };
|
||||||
import { default as ecdh } from './wycheproof/ecdh_test.json' assert { type: 'json' };
|
import { default as ecdh } from './wycheproof/ecdh_test.json' assert { type: 'json' };
|
||||||
import { default as rfc6979 } from './fixtures/rfc6979.json' assert { type: 'json' };
|
import { default as rfc6979 } from './fixtures/rfc6979.json' assert { type: 'json' };
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { deepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, throws } from 'assert';
|
||||||
import { should, describe } from 'micro-should';
|
import { should, describe } from 'micro-should';
|
||||||
import * as poseidon from '../esm/abstract/poseidon.js';
|
import * as poseidon from '../abstract/poseidon.js';
|
||||||
import * as stark from '../esm/stark.js';
|
import * as stark from '../stark.js';
|
||||||
import * as mod from '../esm/abstract/modular.js';
|
import * as mod from '../abstract/modular.js';
|
||||||
import { default as pvectors } from './vectors/poseidon.json' assert { type: 'json' };
|
import { default as pvectors } from './vectors/poseidon.json' assert { type: 'json' };
|
||||||
const { st1, st2, st3, st4 } = pvectors;
|
const { st1, st2, st3, st4 } = pvectors;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { deepStrictEqual, throws } from 'assert';
|
|||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { should, describe } from 'micro-should';
|
import { should, describe } from 'micro-should';
|
||||||
import { bytesToHex as hex } from '@noble/hashes/utils';
|
import { bytesToHex as hex } from '@noble/hashes/utils';
|
||||||
import { schnorr } from '../esm/secp256k1.js';
|
import { schnorr } from '../secp256k1.js';
|
||||||
const schCsv = readFileSync('./test/vectors/schnorr.csv', 'utf-8');
|
const schCsv = readFileSync('./test/vectors/schnorr.csv', 'utf-8');
|
||||||
|
|
||||||
describe('schnorr.sign()', () => {
|
describe('schnorr.sign()', () => {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
export { secp256k1 as secp } from '../esm/secp256k1.js';
|
export { secp256k1 as secp } from '../secp256k1.js';
|
||||||
import { secp256k1 as _secp } from '../esm/secp256k1.js';
|
import { secp256k1 as _secp } from '../secp256k1.js';
|
||||||
export { bytesToNumberBE, numberToBytesBE } from '../esm/abstract/utils.js';
|
export { bytesToNumberBE, numberToBytesBE } from '../abstract/utils.js';
|
||||||
export { mod } from '../esm/abstract/modular.js';
|
export { mod } from '../abstract/modular.js';
|
||||||
export const sigFromDER = (der) => {
|
export const sigFromDER = (der) => {
|
||||||
return _secp.Signature.fromDER(der);
|
return _secp.Signature.fromDER(der);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { deepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, throws } from 'assert';
|
||||||
import { describe, should } from 'micro-should';
|
import { describe, should } from 'micro-should';
|
||||||
import * as starknet from '../../esm/stark.js';
|
import * as starknet from '../../stark.js';
|
||||||
import { default as issue2 } from './fixtures/issue2.json' assert { type: 'json' };
|
import { default as issue2 } from './fixtures/issue2.json' assert { type: 'json' };
|
||||||
import * as bip32 from '@scure/bip32';
|
import * as bip32 from '@scure/bip32';
|
||||||
import * as bip39 from '@scure/bip39';
|
import * as bip39 from '@scure/bip39';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as microStark from '../../../esm/stark.js';
|
import * as microStark from '../../../stark.js';
|
||||||
import * as starkwareCrypto from '@starkware-industries/starkware-crypto-utils';
|
import * as starkwareCrypto from '@starkware-industries/starkware-crypto-utils';
|
||||||
import * as bench from 'micro-bmark';
|
import * as bench from 'micro-bmark';
|
||||||
const { run, mark } = bench; // or bench.mark
|
const { run, mark } = bench; // or bench.mark
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { deepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, throws } from 'assert';
|
||||||
import { describe, should } from 'micro-should';
|
import { describe, should } from 'micro-should';
|
||||||
import * as starknet from '../../esm/stark.js';
|
import * as starknet from '../../stark.js';
|
||||||
|
import { bytesToHex as hex } from '@noble/hashes/utils';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
function parseTest(path) {
|
function parseTest(path) {
|
||||||
@@ -107,6 +108,96 @@ should('Poseidon examples', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
should('Poseidon 2', () => {
|
||||||
|
// Cross-test with cairo-lang 0.11
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHash(1n, 1n),
|
||||||
|
315729444126170353286530004158376771769107830460625027134495740547491428733n
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHash(123n, 123n),
|
||||||
|
3149184350054566761517315875549307360045573205732410509163060794402900549639n
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHash(1231231231231231231231231312312n, 1231231231231231231231231312312n),
|
||||||
|
2544250291965936388474000136445328679708604225006461780180655815882994563864n
|
||||||
|
);
|
||||||
|
// poseidonHashSingle
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHashSingle(1n),
|
||||||
|
3085182978037364507644541379307921604860861694664657935759708330416374536741n
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHashSingle(123n),
|
||||||
|
2751345659320901472675327541550911744303539407817894466726181731796247467344n
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHashSingle(1231231231231231231231231312312n),
|
||||||
|
3083085683696942145160394401206391098729120397175152900096470498748103599322n
|
||||||
|
);
|
||||||
|
// poseidonHashMany
|
||||||
|
throws(() => starknet.poseidonHash(new Uint8Array([1, 2, 3])));
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHashMany([1n]),
|
||||||
|
154809849725474173771833689306955346864791482278938452209165301614543497938n
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHashMany([1n, 2n]),
|
||||||
|
1557996165160500454210437319447297236715335099509187222888255133199463084263n
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHashMany([1n, 2n, 3n, 4n, 5n, 6n, 7n, 8n, 9n, 1n, 2n, 3n, 4n, 5n, 6n, 7n, 8n]),
|
||||||
|
976552833909388839716191681593200982850734838655927116322079791360264131378n
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHashMany([1n, 2n, 3n, 4n, 5n, 6n, 7n, 8n, 9n, 1n, 2n, 3n, 4n, 5n, 6n, 7n]),
|
||||||
|
1426681430756292883765769449684978541173830451959857824597431064948702170774n
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHashMany([1n, 2n, 3n, 4n, 5n, 6n, 7n, 8n, 9n, 1n, 2n, 3n, 4n, 5n, 6n]),
|
||||||
|
3578895185591466904832617962452140411216018208734547126302182794057260630783n
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHashMany([1n, 2n, 3n, 4n, 5n, 6n, 7n, 8n, 9n, 1n, 2n, 3n, 4n, 5n]),
|
||||||
|
2047942584693618630610564708884241243670450597197937863619828684896211911953n
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHashMany([1n, 2n, 3n, 4n, 5n, 6n, 7n, 8n, 9n, 1n, 2n, 3n, 4n]),
|
||||||
|
717812721730784692894550948559585317289413466140233907962980309405694367376n
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHashMany([1n, 2n, 3n, 4n, 5n, 6n, 7n, 8n, 9n, 1n, 2n, 3n]),
|
||||||
|
2926122208425648133778911655767364584769133265503722614793281770361723147648n
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
starknet.poseidonHashMany([
|
||||||
|
154809849725474173771833689306955346864791482278938452209165301614543497938n,
|
||||||
|
1557996165160500454210437319447297236715335099509187222888255133199463084263n,
|
||||||
|
976552833909388839716191681593200982850734838655927116322079791360264131378n,
|
||||||
|
1426681430756292883765769449684978541173830451959857824597431064948702170774n,
|
||||||
|
3578895185591466904832617962452140411216018208734547126302182794057260630783n,
|
||||||
|
]),
|
||||||
|
1019392520709073131437410341528874594624843119359955302374885123884546721410n
|
||||||
|
);
|
||||||
|
// poseidon_hash_func
|
||||||
|
deepStrictEqual(
|
||||||
|
hex(starknet.poseidonHashFunc(new Uint8Array([1, 2]), new Uint8Array([3, 4]))),
|
||||||
|
'01f87cbb9c58139605384d0f0df49b446600af020aa9dac92301d45c96d78c0a'
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
hex(starknet.poseidonHashFunc(new Uint8Array(32).fill(255), new Uint8Array(32).fill(255))),
|
||||||
|
'05fd546b5ee3bcbbcbb733ed90bfc33033169d6765ac37bba71794a11cbb51a6'
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
hex(starknet.poseidonHashFunc(new Uint8Array(64).fill(255), new Uint8Array(64).fill(255))),
|
||||||
|
'07dba6b4d94b3e32697afe0825d6dac2dccafd439f7806a9575693c93735596b'
|
||||||
|
);
|
||||||
|
deepStrictEqual(
|
||||||
|
hex(starknet.poseidonHashFunc(new Uint8Array(256).fill(255), new Uint8Array(256).fill(255))),
|
||||||
|
'02f048581901865201dad701a5653d946b961748ec770fc11139aa7c06a9432a'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// ESM is broken.
|
// ESM is broken.
|
||||||
import url from 'url';
|
import url from 'url';
|
||||||
if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
|
if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { deepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, throws } from 'assert';
|
||||||
import { describe, should } from 'micro-should';
|
import { describe, should } from 'micro-should';
|
||||||
import * as starknet from '../../esm/stark.js';
|
import * as starknet from '../../stark.js';
|
||||||
import * as fc from 'fast-check';
|
import * as fc from 'fast-check';
|
||||||
|
|
||||||
const FC_BIGINT = fc.bigInt(1n + 1n, starknet.CURVE.n - 1n);
|
const FC_BIGINT = fc.bigInt(1n + 1n, starknet.CURVE.n - 1n);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { describe, should } from 'micro-should';
|
|||||||
import { utf8ToBytes } from '@noble/hashes/utils';
|
import { utf8ToBytes } from '@noble/hashes/utils';
|
||||||
import * as bip32 from '@scure/bip32';
|
import * as bip32 from '@scure/bip32';
|
||||||
import * as bip39 from '@scure/bip39';
|
import * as bip39 from '@scure/bip39';
|
||||||
import * as starknet from '../../esm/stark.js';
|
import * as starknet from '../../stark.js';
|
||||||
import { default as sigVec } from './fixtures/rfc6979_signature_test_vector.json' assert { type: 'json' };
|
import { default as sigVec } from './fixtures/rfc6979_signature_test_vector.json' assert { type: 'json' };
|
||||||
import { default as precomputedKeys } from './fixtures/keys_precomputed.json' assert { type: 'json' };
|
import { default as precomputedKeys } from './fixtures/keys_precomputed.json' assert { type: 'json' };
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"strict": true,
|
|
||||||
"outDir": "esm",
|
|
||||||
"target": "es2020",
|
|
||||||
"module": "es6",
|
|
||||||
"moduleResolution": "node16",
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"sourceMap": true,
|
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
|
||||||
"@noble/hashes/crypto": [ "src/crypto" ]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"include": ["src"],
|
|
||||||
"exclude": [
|
|
||||||
"node_modules",
|
|
||||||
"lib",
|
|
||||||
],
|
|
||||||
}
|
|
||||||
@@ -3,12 +3,12 @@
|
|||||||
"strict": true,
|
"strict": true,
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"declarationMap": true,
|
"declarationMap": true,
|
||||||
|
"sourceMap": true,
|
||||||
"outDir": ".",
|
"outDir": ".",
|
||||||
"target": "es2020",
|
"target": "es2020",
|
||||||
"lib": ["es2020"], // Set explicitly to remove DOM
|
"lib": ["es2020"], // Set explicitly to remove DOM
|
||||||
"sourceMap": true,
|
"module": "es6",
|
||||||
"module": "commonjs",
|
"moduleResolution": "node16",
|
||||||
"moduleResolution": "node",
|
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user