@noble/curves 0.5.1 → 0.6.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 +49 -8
- package/lib/_shortw_utils.d.ts +11 -26
- package/lib/abstract/bls.d.ts +51 -35
- package/lib/abstract/bls.js +77 -139
- package/lib/abstract/{group.d.ts → curve.d.ts} +31 -1
- package/lib/abstract/{group.js → curve.js} +39 -2
- package/lib/abstract/edwards.d.ts +30 -81
- package/lib/abstract/edwards.js +225 -420
- package/lib/abstract/hash-to-curve.d.ts +25 -6
- package/lib/abstract/hash-to-curve.js +40 -12
- package/lib/abstract/modular.d.ts +20 -7
- package/lib/abstract/modular.js +80 -51
- package/lib/abstract/montgomery.js +3 -4
- package/lib/abstract/poseidon.d.ts +29 -0
- package/lib/abstract/poseidon.js +115 -0
- package/lib/abstract/utils.d.ts +5 -34
- package/lib/abstract/utils.js +23 -63
- package/lib/abstract/weierstrass.d.ts +56 -79
- package/lib/abstract/weierstrass.js +509 -641
- package/lib/bls12-381.d.ts +1 -0
- package/lib/bls12-381.js +75 -65
- package/lib/bn.js +1 -1
- package/lib/ed25519.d.ts +7 -5
- package/lib/ed25519.js +87 -84
- package/lib/ed448.d.ts +3 -0
- package/lib/ed448.js +88 -84
- package/lib/esm/abstract/bls.js +77 -139
- package/lib/esm/abstract/{group.js → curve.js} +37 -1
- package/lib/esm/abstract/edwards.js +223 -418
- package/lib/esm/abstract/hash-to-curve.js +38 -11
- package/lib/esm/abstract/modular.js +77 -50
- package/lib/esm/abstract/montgomery.js +4 -7
- package/lib/esm/abstract/poseidon.js +109 -0
- package/lib/esm/abstract/utils.js +21 -59
- package/lib/esm/abstract/weierstrass.js +508 -640
- package/lib/esm/bls12-381.js +86 -76
- package/lib/esm/bn.js +1 -1
- package/lib/esm/ed25519.js +85 -83
- package/lib/esm/ed448.js +86 -83
- package/lib/esm/jubjub.js +6 -5
- package/lib/esm/p256.js +11 -9
- package/lib/esm/p384.js +11 -9
- package/lib/esm/p521.js +13 -12
- package/lib/esm/secp256k1.js +118 -157
- package/lib/esm/stark.js +104 -39
- package/lib/jubjub.d.ts +3 -2
- package/lib/jubjub.js +6 -5
- package/lib/p192.d.ts +22 -52
- package/lib/p224.d.ts +22 -52
- package/lib/p256.d.ts +25 -52
- package/lib/p256.js +13 -10
- package/lib/p384.d.ts +25 -52
- package/lib/p384.js +13 -10
- package/lib/p521.d.ts +25 -52
- package/lib/p521.js +15 -13
- package/lib/secp256k1.d.ts +26 -42
- package/lib/secp256k1.js +118 -157
- package/lib/stark.d.ts +36 -21
- package/lib/stark.js +107 -39
- package/package.json +14 -9
package/lib/stark.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ProjPointType } from './abstract/weierstrass.js';
|
|
2
2
|
import * as cutils from './abstract/utils.js';
|
|
3
|
-
|
|
3
|
+
import { Field } from './abstract/modular.js';
|
|
4
|
+
declare type ProjectivePoint = ProjPointType<bigint>;
|
|
4
5
|
export declare const starkCurve: import("./abstract/weierstrass.js").CurveFn;
|
|
5
6
|
declare function getPublicKey0x(privKey: Hex, isCompressed?: boolean): Uint8Array;
|
|
6
7
|
declare function getSharedSecret0x(privKeyA: Hex, pubKeyB: Hex): Uint8Array;
|
|
@@ -9,7 +10,7 @@ declare function verify0x(signature: Hex, msgHash: Hex, pubKey: Hex): boolean;
|
|
|
9
10
|
declare const CURVE: Readonly<{
|
|
10
11
|
readonly nBitLength: number;
|
|
11
12
|
readonly nByteLength: number;
|
|
12
|
-
readonly Fp:
|
|
13
|
+
readonly Fp: Field<bigint>;
|
|
13
14
|
readonly n: bigint;
|
|
14
15
|
readonly h: bigint;
|
|
15
16
|
readonly hEff?: bigint | undefined;
|
|
@@ -29,34 +30,22 @@ declare const CURVE: Readonly<{
|
|
|
29
30
|
k2: bigint;
|
|
30
31
|
};
|
|
31
32
|
} | undefined;
|
|
32
|
-
readonly isTorsionFree?: ((c: import("./abstract/weierstrass.js").
|
|
33
|
-
readonly clearCofactor?: ((c: import("./abstract/weierstrass.js").
|
|
34
|
-
readonly htfDefaults?: import("./abstract/hash-to-curve.js").htfOpts | undefined;
|
|
35
|
-
readonly mapToCurve?: ((scalar: bigint[]) => {
|
|
36
|
-
x: bigint;
|
|
37
|
-
y: bigint;
|
|
38
|
-
}) | undefined;
|
|
33
|
+
readonly isTorsionFree?: ((c: import("./abstract/weierstrass.js").ProjConstructor<bigint>, point: ProjPointType<bigint>) => boolean) | undefined;
|
|
34
|
+
readonly clearCofactor?: ((c: import("./abstract/weierstrass.js").ProjConstructor<bigint>, point: ProjPointType<bigint>) => ProjPointType<bigint>) | undefined;
|
|
39
35
|
lowS: boolean;
|
|
40
36
|
readonly hash: cutils.CHash;
|
|
41
37
|
readonly hmac: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
|
|
42
38
|
readonly randomBytes: (bytesLength?: number | undefined) => Uint8Array;
|
|
43
|
-
readonly
|
|
44
|
-
|
|
39
|
+
readonly bits2int?: ((bytes: Uint8Array) => bigint) | undefined;
|
|
40
|
+
readonly bits2int_modN?: ((bytes: Uint8Array) => bigint) | undefined;
|
|
41
|
+
}>, ProjectivePoint: import("./abstract/weierstrass.js").ProjConstructor<bigint>, Signature: import("./abstract/weierstrass.js").SignatureConstructor;
|
|
45
42
|
export declare const utils: {
|
|
46
|
-
mod: (a: bigint, b?: bigint | undefined) => bigint;
|
|
47
|
-
invert: (number: bigint, modulo?: bigint | undefined) => bigint;
|
|
48
|
-
_bigintToBytes: (num: bigint) => Uint8Array;
|
|
49
|
-
_bigintToString: (num: bigint) => string;
|
|
50
43
|
_normalizePrivateKey: (key: cutils.PrivKey) => bigint;
|
|
51
|
-
_normalizePublicKey: (publicKey: import("./abstract/weierstrass.js").PubKey) => import("./abstract/weierstrass.js").PointType<bigint>;
|
|
52
|
-
_isWithinCurveOrder: (num: bigint) => boolean;
|
|
53
|
-
_isValidFieldElement: (num: bigint) => boolean;
|
|
54
|
-
_weierstrassEquation: (x: bigint) => bigint;
|
|
55
44
|
isValidPrivateKey(privateKey: cutils.PrivKey): boolean;
|
|
56
45
|
hashToPrivateKey: (hash: cutils.Hex) => Uint8Array;
|
|
57
46
|
randomPrivateKey: () => Uint8Array;
|
|
58
47
|
};
|
|
59
|
-
export { CURVE,
|
|
48
|
+
export { CURVE, Signature, ProjectivePoint, getPublicKey0x as getPublicKey, getSharedSecret0x as getSharedSecret, sign0x as sign, verify0x as verify, };
|
|
60
49
|
export declare const bytesToHexEth: (uint8a: Uint8Array) => string;
|
|
61
50
|
export declare const strip0x: (hex: string) => string;
|
|
62
51
|
export declare const numberToHexEth: (num: bigint | number) => string;
|
|
@@ -70,3 +59,29 @@ export declare function pedersen(x: PedersenArg, y: PedersenArg): string;
|
|
|
70
59
|
export declare function hashChain(data: PedersenArg[], fn?: typeof pedersen): PedersenArg;
|
|
71
60
|
export declare const computeHashOnElements: (data: PedersenArg[], fn?: typeof pedersen) => PedersenArg;
|
|
72
61
|
export declare const keccak: (data: Uint8Array) => bigint;
|
|
62
|
+
export declare const Fp253: Readonly<Field<bigint> & Required<Pick<Field<bigint>, "isOdd">>>;
|
|
63
|
+
export declare const Fp251: Readonly<Field<bigint> & Required<Pick<Field<bigint>, "isOdd">>>;
|
|
64
|
+
export declare function _poseidonMDS(Fp: Field<bigint>, name: string, m: number, attempt?: number): bigint[][];
|
|
65
|
+
export declare type PoseidonOpts = {
|
|
66
|
+
Fp: Field<bigint>;
|
|
67
|
+
rate: number;
|
|
68
|
+
capacity: number;
|
|
69
|
+
roundsFull: number;
|
|
70
|
+
roundsPartial: number;
|
|
71
|
+
};
|
|
72
|
+
export declare function poseidonBasic(opts: PoseidonOpts, mds: bigint[][]): {
|
|
73
|
+
(values: bigint[]): bigint[];
|
|
74
|
+
roundConstants: bigint[][];
|
|
75
|
+
};
|
|
76
|
+
export declare function poseidonCreate(opts: PoseidonOpts, mdsAttempt?: number): {
|
|
77
|
+
(values: bigint[]): bigint[];
|
|
78
|
+
roundConstants: bigint[][];
|
|
79
|
+
};
|
|
80
|
+
export declare const poseidonSmall: {
|
|
81
|
+
(values: bigint[]): bigint[];
|
|
82
|
+
roundConstants: bigint[][];
|
|
83
|
+
};
|
|
84
|
+
export declare function poseidonHash(x: bigint, y: bigint, fn?: {
|
|
85
|
+
(values: bigint[]): bigint[];
|
|
86
|
+
roundConstants: bigint[][];
|
|
87
|
+
}): bigint;
|
package/lib/stark.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.keccak = exports.computeHashOnElements = exports.hashChain = exports.pedersen = exports.getAccountPath = exports.ethSigToPrivate = exports.getStarkKey = exports.grindKey = exports.numberToHexEth = exports.strip0x = exports.bytesToHexEth = exports.verify = exports.sign = exports.getSharedSecret = exports.getPublicKey = exports.ProjectivePoint = exports.Signature = exports.
|
|
3
|
+
exports.poseidonHash = exports.poseidonSmall = exports.poseidonCreate = exports.poseidonBasic = exports._poseidonMDS = exports.Fp251 = exports.Fp253 = exports.keccak = exports.computeHashOnElements = exports.hashChain = exports.pedersen = exports.getAccountPath = exports.ethSigToPrivate = exports.getStarkKey = exports.grindKey = exports.numberToHexEth = exports.strip0x = exports.bytesToHexEth = exports.verify = exports.sign = exports.getSharedSecret = exports.getPublicKey = exports.ProjectivePoint = exports.Signature = exports.CURVE = exports.utils = exports.starkCurve = void 0;
|
|
4
4
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
5
5
|
const sha3_1 = require("@noble/hashes/sha3");
|
|
6
6
|
const sha256_1 = require("@noble/hashes/sha256");
|
|
@@ -8,10 +8,21 @@ const weierstrass_js_1 = require("./abstract/weierstrass.js");
|
|
|
8
8
|
const cutils = require("./abstract/utils.js");
|
|
9
9
|
const modular_js_1 = require("./abstract/modular.js");
|
|
10
10
|
const _shortw_utils_js_1 = require("./_shortw_utils.js");
|
|
11
|
+
const poseidon = require("./abstract/poseidon.js");
|
|
12
|
+
const utils_1 = require("@noble/hashes/utils");
|
|
11
13
|
// Stark-friendly elliptic curve
|
|
12
14
|
// https://docs.starkware.co/starkex/stark-curve.html
|
|
13
15
|
const CURVE_N = BigInt('3618502788666131213697322783095070105526743751716087489154079457884512865583');
|
|
14
16
|
const nBitLength = 252;
|
|
17
|
+
// Copy-pasted from weierstrass.ts
|
|
18
|
+
function bits2int(bytes) {
|
|
19
|
+
const delta = bytes.length * 8 - nBitLength;
|
|
20
|
+
const num = cutils.bytesToNumberBE(bytes);
|
|
21
|
+
return delta > 0 ? num >> BigInt(delta) : num;
|
|
22
|
+
}
|
|
23
|
+
function bits2int_modN(bytes) {
|
|
24
|
+
return (0, modular_js_1.mod)(bits2int(bytes), CURVE_N);
|
|
25
|
+
}
|
|
15
26
|
exports.starkCurve = (0, weierstrass_js_1.weierstrass)({
|
|
16
27
|
// Params: a, b
|
|
17
28
|
a: BigInt(1),
|
|
@@ -29,33 +40,28 @@ exports.starkCurve = (0, weierstrass_js_1.weierstrass)({
|
|
|
29
40
|
// Default options
|
|
30
41
|
lowS: false,
|
|
31
42
|
...(0, _shortw_utils_js_1.getHash)(sha256_1.sha256),
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
// Custom truncation routines for stark curve
|
|
44
|
+
bits2int: (bytes) => {
|
|
45
|
+
while (bytes[0] === 0)
|
|
46
|
+
bytes = bytes.subarray(1);
|
|
47
|
+
return bits2int(bytes);
|
|
48
|
+
},
|
|
49
|
+
bits2int_modN: (bytes) => {
|
|
50
|
+
let hashS = cutils.bytesToNumberBE(bytes).toString(16);
|
|
51
|
+
if (hashS.length === 63) {
|
|
52
|
+
hashS += '0';
|
|
53
|
+
bytes = hexToBytes0x(hashS);
|
|
41
54
|
}
|
|
42
55
|
// Truncate zero bytes on left (compat with elliptic)
|
|
43
|
-
while (
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const delta = byteLength * 8 - nBitLength; // size of curve.n (252 bits)
|
|
47
|
-
let h = hash.length ? bytesToNumber0x(hash) : 0n;
|
|
48
|
-
if (delta > 0)
|
|
49
|
-
h = h >> BigInt(delta);
|
|
50
|
-
if (!truncateOnly && h >= CURVE_N)
|
|
51
|
-
h -= CURVE_N;
|
|
52
|
-
return h;
|
|
56
|
+
while (bytes[0] === 0)
|
|
57
|
+
bytes = bytes.subarray(1);
|
|
58
|
+
return bits2int_modN(bytes);
|
|
53
59
|
},
|
|
54
60
|
});
|
|
55
61
|
// Custom Starknet type conversion functions that can handle 0x and unpadded hex
|
|
56
62
|
function hexToBytes0x(hex) {
|
|
57
63
|
if (typeof hex !== 'string') {
|
|
58
|
-
throw new
|
|
64
|
+
throw new Error('hexToBytes: expected string, got ' + typeof hex);
|
|
59
65
|
}
|
|
60
66
|
hex = (0, exports.strip0x)(hex);
|
|
61
67
|
if (hex.length & 1)
|
|
@@ -75,7 +81,7 @@ function hexToBytes0x(hex) {
|
|
|
75
81
|
}
|
|
76
82
|
function hexToNumber0x(hex) {
|
|
77
83
|
if (typeof hex !== 'string') {
|
|
78
|
-
throw new
|
|
84
|
+
throw new Error('hexToNumber: expected string, got ' + typeof hex);
|
|
79
85
|
}
|
|
80
86
|
// Big Endian
|
|
81
87
|
// TODO: strip vs no strip?
|
|
@@ -90,7 +96,7 @@ function ensureBytes0x(hex) {
|
|
|
90
96
|
return hex instanceof Uint8Array ? Uint8Array.from(hex) : hexToBytes0x(hex);
|
|
91
97
|
}
|
|
92
98
|
function normalizePrivateKey(privKey) {
|
|
93
|
-
return cutils.bytesToHex(ensureBytes0x(privKey)).padStart(
|
|
99
|
+
return cutils.bytesToHex(ensureBytes0x(privKey)).padStart(64, '0');
|
|
94
100
|
}
|
|
95
101
|
function getPublicKey0x(privKey, isCompressed) {
|
|
96
102
|
return exports.starkCurve.getPublicKey(normalizePrivateKey(privKey), isCompressed);
|
|
@@ -111,9 +117,8 @@ function verify0x(signature, msgHash, pubKey) {
|
|
|
111
117
|
return exports.starkCurve.verify(sig, ensureBytes0x(msgHash), ensureBytes0x(pubKey));
|
|
112
118
|
}
|
|
113
119
|
exports.verify = verify0x;
|
|
114
|
-
const { CURVE,
|
|
120
|
+
const { CURVE, ProjectivePoint, Signature } = exports.starkCurve;
|
|
115
121
|
exports.CURVE = CURVE;
|
|
116
|
-
exports.Point = Point;
|
|
117
122
|
exports.ProjectivePoint = ProjectivePoint;
|
|
118
123
|
exports.Signature = Signature;
|
|
119
124
|
exports.utils = exports.starkCurve.utils;
|
|
@@ -129,17 +134,17 @@ function hashKeyWithIndex(key, index) {
|
|
|
129
134
|
let indexHex = cutils.numberToHexUnpadded(index);
|
|
130
135
|
if (indexHex.length & 1)
|
|
131
136
|
indexHex = '0' + indexHex;
|
|
132
|
-
return
|
|
137
|
+
return sha256Num(cutils.concatBytes(key, hexToBytes0x(indexHex)));
|
|
133
138
|
}
|
|
134
139
|
function grindKey(seed) {
|
|
135
140
|
const _seed = ensureBytes0x(seed);
|
|
136
141
|
const sha256mask = 2n ** 256n;
|
|
137
|
-
const limit = sha256mask -
|
|
142
|
+
const limit = sha256mask - (0, modular_js_1.mod)(sha256mask, CURVE_N);
|
|
138
143
|
for (let i = 0;; i++) {
|
|
139
144
|
const key = hashKeyWithIndex(_seed, i);
|
|
140
145
|
// key should be in [0, limit)
|
|
141
146
|
if (key < limit)
|
|
142
|
-
return
|
|
147
|
+
return (0, modular_js_1.mod)(key, CURVE_N).toString(16);
|
|
143
148
|
}
|
|
144
149
|
}
|
|
145
150
|
exports.grindKey = grindKey;
|
|
@@ -157,22 +162,22 @@ exports.ethSigToPrivate = ethSigToPrivate;
|
|
|
157
162
|
const MASK_31 = 2n ** 31n - 1n;
|
|
158
163
|
const int31 = (n) => Number(n & MASK_31);
|
|
159
164
|
function getAccountPath(layer, application, ethereumAddress, index) {
|
|
160
|
-
const layerNum = int31(
|
|
161
|
-
const applicationNum = int31(
|
|
165
|
+
const layerNum = int31(sha256Num(layer));
|
|
166
|
+
const applicationNum = int31(sha256Num(application));
|
|
162
167
|
const eth = hexToNumber0x(ethereumAddress);
|
|
163
168
|
return `m/2645'/${layerNum}'/${applicationNum}'/${int31(eth)}'/${int31(eth >> 31n)}'/${index}`;
|
|
164
169
|
}
|
|
165
170
|
exports.getAccountPath = getAccountPath;
|
|
166
171
|
// https://docs.starkware.co/starkex/pedersen-hash-function.html
|
|
167
172
|
const PEDERSEN_POINTS_AFFINE = [
|
|
168
|
-
new
|
|
169
|
-
new
|
|
170
|
-
new
|
|
171
|
-
new
|
|
172
|
-
new
|
|
173
|
+
new ProjectivePoint(2089986280348253421170679821480865132823066470938446095505822317253594081284n, 1713931329540660377023406109199410414810705867260802078187082345529207694986n, 1n),
|
|
174
|
+
new ProjectivePoint(996781205833008774514500082376783249102396023663454813447423147977397232763n, 1668503676786377725805489344771023921079126552019160156920634619255970485781n, 1n),
|
|
175
|
+
new ProjectivePoint(2251563274489750535117886426533222435294046428347329203627021249169616184184n, 1798716007562728905295480679789526322175868328062420237419143593021674992973n, 1n),
|
|
176
|
+
new ProjectivePoint(2138414695194151160943305727036575959195309218611738193261179310511854807447n, 113410276730064486255102093846540133784865286929052426931474106396135072156n, 1n),
|
|
177
|
+
new ProjectivePoint(2379962749567351885752724891227938183011949129833673362440656643086021394946n, 776496453633298175483985398648758586525933812536653089401905292063708816422n, 1n),
|
|
173
178
|
];
|
|
174
179
|
// for (const p of PEDERSEN_POINTS) p._setWindowSize(8);
|
|
175
|
-
const PEDERSEN_POINTS = PEDERSEN_POINTS_AFFINE
|
|
180
|
+
const PEDERSEN_POINTS = PEDERSEN_POINTS_AFFINE;
|
|
176
181
|
function pedersenPrecompute(p1, p2) {
|
|
177
182
|
const out = [];
|
|
178
183
|
let p = p1;
|
|
@@ -211,7 +216,7 @@ function pedersenSingle(point, value, constants) {
|
|
|
211
216
|
let x = pedersenArg(value);
|
|
212
217
|
for (let j = 0; j < 252; j++) {
|
|
213
218
|
const pt = constants[j];
|
|
214
|
-
if (pt.
|
|
219
|
+
if (pt.px === point.px)
|
|
215
220
|
throw new Error('Same point');
|
|
216
221
|
if ((x & 1n) !== 0n)
|
|
217
222
|
point = point.add(pt);
|
|
@@ -224,7 +229,7 @@ function pedersen(x, y) {
|
|
|
224
229
|
let point = PEDERSEN_POINTS[0];
|
|
225
230
|
point = pedersenSingle(point, x, PEDERSEN_POINTS1);
|
|
226
231
|
point = pedersenSingle(point, y, PEDERSEN_POINTS2);
|
|
227
|
-
return (0, exports.bytesToHexEth)(point.
|
|
232
|
+
return (0, exports.bytesToHexEth)(point.toRawBytes(true).slice(1));
|
|
228
233
|
}
|
|
229
234
|
exports.pedersen = pedersen;
|
|
230
235
|
function hashChain(data, fn = pedersen) {
|
|
@@ -240,6 +245,69 @@ exports.hashChain = hashChain;
|
|
|
240
245
|
// Same as hashChain, but computes hash even for single element and order is not revesed
|
|
241
246
|
const computeHashOnElements = (data, fn = pedersen) => [0, ...data, data.length].reduce((x, y) => fn(x, y));
|
|
242
247
|
exports.computeHashOnElements = computeHashOnElements;
|
|
243
|
-
const MASK_250 =
|
|
248
|
+
const MASK_250 = cutils.bitMask(250);
|
|
244
249
|
const keccak = (data) => bytesToNumber0x((0, sha3_1.keccak_256)(data)) & MASK_250;
|
|
245
250
|
exports.keccak = keccak;
|
|
251
|
+
const sha256Num = (data) => cutils.bytesToNumberBE((0, sha256_1.sha256)(data));
|
|
252
|
+
// Poseidon hash
|
|
253
|
+
exports.Fp253 = (0, modular_js_1.Fp)(BigInt('14474011154664525231415395255581126252639794253786371766033694892385558855681')); // 2^253 + 2^199 + 1
|
|
254
|
+
exports.Fp251 = (0, modular_js_1.Fp)(BigInt('3618502788666131213697322783095070105623107215331596699973092056135872020481')); // 2^251 + 17 * 2^192 + 1
|
|
255
|
+
function poseidonRoundConstant(Fp, name, idx) {
|
|
256
|
+
const val = Fp.fromBytes((0, sha256_1.sha256)((0, utils_1.utf8ToBytes)(`${name}${idx}`)));
|
|
257
|
+
return Fp.create(val);
|
|
258
|
+
}
|
|
259
|
+
// NOTE: doesn't check eiginvalues and possible can create unsafe matrix. But any filtration here will break compatibility with starknet
|
|
260
|
+
// Please use only if you really know what you doing.
|
|
261
|
+
// https://eprint.iacr.org/2019/458.pdf Section 2.3 (Avoiding Insecure Matrices)
|
|
262
|
+
function _poseidonMDS(Fp, name, m, attempt = 0) {
|
|
263
|
+
const x_values = [];
|
|
264
|
+
const y_values = [];
|
|
265
|
+
for (let i = 0; i < m; i++) {
|
|
266
|
+
x_values.push(poseidonRoundConstant(Fp, `${name}x`, attempt * m + i));
|
|
267
|
+
y_values.push(poseidonRoundConstant(Fp, `${name}y`, attempt * m + i));
|
|
268
|
+
}
|
|
269
|
+
if (new Set([...x_values, ...y_values]).size !== 2 * m)
|
|
270
|
+
throw new Error('X and Y values are not distinct');
|
|
271
|
+
return x_values.map((x) => y_values.map((y) => Fp.inv(Fp.sub(x, y))));
|
|
272
|
+
}
|
|
273
|
+
exports._poseidonMDS = _poseidonMDS;
|
|
274
|
+
const MDS_SMALL = [
|
|
275
|
+
[3, 1, 1],
|
|
276
|
+
[1, -1, 1],
|
|
277
|
+
[1, 1, -2],
|
|
278
|
+
].map((i) => i.map(BigInt));
|
|
279
|
+
function poseidonBasic(opts, mds) {
|
|
280
|
+
(0, modular_js_1.validateField)(opts.Fp);
|
|
281
|
+
if (!Number.isSafeInteger(opts.rate) || !Number.isSafeInteger(opts.capacity))
|
|
282
|
+
throw new Error(`Wrong poseidon opts: ${opts}`);
|
|
283
|
+
const m = opts.rate + opts.capacity;
|
|
284
|
+
const rounds = opts.roundsFull + opts.roundsPartial;
|
|
285
|
+
const roundConstants = [];
|
|
286
|
+
for (let i = 0; i < rounds; i++) {
|
|
287
|
+
const row = [];
|
|
288
|
+
for (let j = 0; j < m; j++)
|
|
289
|
+
row.push(poseidonRoundConstant(opts.Fp, 'Hades', m * i + j));
|
|
290
|
+
roundConstants.push(row);
|
|
291
|
+
}
|
|
292
|
+
return poseidon.poseidon({
|
|
293
|
+
...opts,
|
|
294
|
+
t: m,
|
|
295
|
+
sboxPower: 3,
|
|
296
|
+
reversePartialPowIdx: true,
|
|
297
|
+
mds,
|
|
298
|
+
roundConstants,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
exports.poseidonBasic = poseidonBasic;
|
|
302
|
+
function poseidonCreate(opts, mdsAttempt = 0) {
|
|
303
|
+
const m = opts.rate + opts.capacity;
|
|
304
|
+
if (!Number.isSafeInteger(mdsAttempt))
|
|
305
|
+
throw new Error(`Wrong mdsAttempt=${mdsAttempt}`);
|
|
306
|
+
return poseidonBasic(opts, _poseidonMDS(opts.Fp, 'HadesMDS', m, mdsAttempt));
|
|
307
|
+
}
|
|
308
|
+
exports.poseidonCreate = poseidonCreate;
|
|
309
|
+
exports.poseidonSmall = poseidonBasic({ Fp: exports.Fp251, rate: 2, capacity: 1, roundsFull: 8, roundsPartial: 83 }, MDS_SMALL);
|
|
310
|
+
function poseidonHash(x, y, fn = exports.poseidonSmall) {
|
|
311
|
+
return fn([x, y, 2n])[0];
|
|
312
|
+
}
|
|
313
|
+
exports.poseidonHash = poseidonHash;
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noble/curves",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Minimal, auditable JS implementation of elliptic curve cryptography",
|
|
5
5
|
"files": [
|
|
6
6
|
"lib"
|
|
7
7
|
],
|
|
8
8
|
"scripts": {
|
|
9
|
-
"bench": "node
|
|
9
|
+
"bench": "cd benchmark; node index.js",
|
|
10
10
|
"build": "tsc && tsc -p tsconfig.esm.json",
|
|
11
11
|
"build:release": "rollup -c rollup.config.js",
|
|
12
12
|
"lint": "prettier --check 'src/**/*.{js,ts}' 'test/*.js'",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"@types/node": "18.11.3",
|
|
32
32
|
"fast-check": "3.0.0",
|
|
33
33
|
"micro-bmark": "0.2.0",
|
|
34
|
-
"micro-should": "0.
|
|
35
|
-
"prettier": "2.
|
|
34
|
+
"micro-should": "0.3.0",
|
|
35
|
+
"prettier": "2.8.3",
|
|
36
36
|
"rollup": "2.75.5",
|
|
37
37
|
"typescript": "4.7.3"
|
|
38
38
|
},
|
|
@@ -73,16 +73,21 @@
|
|
|
73
73
|
"import": "./lib/esm/abstract/hash-to-curve.js",
|
|
74
74
|
"default": "./lib/abstract/hash-to-curve.js"
|
|
75
75
|
},
|
|
76
|
-
"./abstract/
|
|
77
|
-
"types": "./lib/abstract/
|
|
78
|
-
"import": "./lib/esm/abstract/
|
|
79
|
-
"default": "./lib/abstract/
|
|
76
|
+
"./abstract/curve": {
|
|
77
|
+
"types": "./lib/abstract/curve.d.ts",
|
|
78
|
+
"import": "./lib/esm/abstract/curve.js",
|
|
79
|
+
"default": "./lib/abstract/curve.js"
|
|
80
80
|
},
|
|
81
81
|
"./abstract/utils": {
|
|
82
82
|
"types": "./lib/abstract/utils.d.ts",
|
|
83
83
|
"import": "./lib/esm/abstract/utils.js",
|
|
84
84
|
"default": "./lib/abstract/utils.js"
|
|
85
85
|
},
|
|
86
|
+
"./abstract/poseidon": {
|
|
87
|
+
"types": "./lib/abstract/poseidon.d.ts",
|
|
88
|
+
"import": "./lib/esm/abstract/poseidon.js",
|
|
89
|
+
"default": "./lib/abstract/poseidon.js"
|
|
90
|
+
},
|
|
86
91
|
"./_shortw_utils": {
|
|
87
92
|
"types": "./lib/_shortw_utils.d.ts",
|
|
88
93
|
"import": "./lib/esm/_shortw_utils.js",
|
|
@@ -189,4 +194,4 @@
|
|
|
189
194
|
"url": "https://paulmillr.com/funding/"
|
|
190
195
|
}
|
|
191
196
|
]
|
|
192
|
-
}
|
|
197
|
+
}
|