@noble/curves 0.2.1 → 0.3.1
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 +14 -19
- package/lib/crypto.d.ts +4 -0
- package/lib/crypto.js +8 -0
- package/lib/cryptoBrowser.d.ts +4 -0
- package/lib/cryptoBrowser.js +7 -0
- package/lib/definitions/_shortw_utils.d.ts +63 -0
- package/lib/definitions/_shortw_utils.js +18 -0
- package/lib/definitions/bn.d.ts +7 -0
- package/lib/definitions/bn.js +23 -0
- package/lib/definitions/ed25519.d.ts +49 -0
- package/lib/definitions/ed25519.js +308 -0
- package/lib/definitions/ed448.d.ts +3 -0
- package/lib/definitions/ed448.js +127 -0
- package/lib/definitions/index.d.ts +0 -0
- package/lib/definitions/index.js +2 -0
- package/lib/definitions/jubjub.d.ts +7 -0
- package/lib/definitions/jubjub.js +55 -0
- package/lib/definitions/p192.d.ts +112 -0
- package/lib/definitions/p192.js +23 -0
- package/lib/definitions/p224.d.ts +112 -0
- package/lib/definitions/p224.js +24 -0
- package/lib/definitions/p256.d.ts +112 -0
- package/lib/definitions/p256.js +23 -0
- package/lib/definitions/p384.d.ts +112 -0
- package/lib/definitions/p384.js +24 -0
- package/lib/definitions/p521.d.ts +113 -0
- package/lib/definitions/p521.js +36 -0
- package/lib/definitions/pasta.d.ts +2 -0
- package/lib/definitions/pasta.js +32 -0
- package/lib/definitions/secp256k1.d.ts +87 -0
- package/lib/definitions/secp256k1.js +245 -0
- package/lib/definitions/stark.d.ts +62 -0
- package/lib/definitions/stark.js +248 -0
- package/lib/edwards.d.ts +2 -2
- package/lib/edwards.js +2 -6
- package/lib/esm/crypto.js +5 -0
- package/lib/esm/cryptoBrowser.js +4 -0
- package/lib/esm/definitions/_shortw_utils.js +13 -0
- package/lib/esm/definitions/bn.js +20 -0
- package/lib/esm/definitions/ed25519.js +304 -0
- package/lib/esm/definitions/ed448.js +124 -0
- package/lib/esm/definitions/index.js +2 -0
- package/lib/esm/definitions/jubjub.js +50 -0
- package/lib/esm/definitions/p192.js +20 -0
- package/lib/esm/definitions/p224.js +21 -0
- package/lib/esm/definitions/p256.js +20 -0
- package/lib/esm/definitions/p384.js +21 -0
- package/lib/esm/definitions/p521.js +33 -0
- package/lib/esm/definitions/pasta.js +29 -0
- package/lib/esm/definitions/secp256k1.js +241 -0
- package/lib/esm/definitions/stark.js +227 -0
- package/lib/esm/edwards.js +3 -7
- package/lib/esm/modular.js +14 -9
- package/lib/esm/utils.js +17 -0
- package/lib/esm/weierstrass.js +17 -9
- package/lib/modular.d.ts +8 -1
- package/lib/modular.js +14 -9
- package/lib/utils.d.ts +4 -0
- package/lib/utils.js +19 -1
- package/lib/weierstrass.d.ts +5 -3
- package/lib/weierstrass.js +16 -8
- package/package.json +38 -8
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { CHash } from '../weierstrass';
|
|
2
|
+
import * as cutils from '../utils';
|
|
3
|
+
export declare const starkCurve: import("../weierstrass").CurveFn;
|
|
4
|
+
declare function getPublicKey0x(privKey: Hex, isCompressed?: boolean): Uint8Array;
|
|
5
|
+
declare function getSharedSecret0x(privKeyA: Hex, pubKeyB: Hex): Uint8Array;
|
|
6
|
+
declare function sign0x(msgHash: Hex, privKey: Hex, opts: any): import("../weierstrass").SignatureType;
|
|
7
|
+
declare function verify0x(signature: Hex, msgHash: Hex, pubKey: Hex): boolean;
|
|
8
|
+
declare const CURVE: Readonly<{
|
|
9
|
+
readonly nBitLength: number;
|
|
10
|
+
readonly nByteLength: number;
|
|
11
|
+
readonly P: bigint;
|
|
12
|
+
readonly n: bigint;
|
|
13
|
+
readonly h: bigint;
|
|
14
|
+
readonly Gx: bigint;
|
|
15
|
+
readonly Gy: bigint;
|
|
16
|
+
readonly a: bigint;
|
|
17
|
+
readonly b: bigint;
|
|
18
|
+
lowS: boolean;
|
|
19
|
+
readonly hash: CHash;
|
|
20
|
+
readonly hmac: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
|
|
21
|
+
randomBytes: typeof cutils.randomBytes;
|
|
22
|
+
readonly truncateHash?: ((hash: Uint8Array, truncateOnly?: boolean | undefined) => bigint) | undefined;
|
|
23
|
+
readonly sqrtMod?: ((n: bigint) => bigint) | undefined;
|
|
24
|
+
readonly normalizePrivateKey?: ((key: cutils.PrivKey) => cutils.PrivKey) | undefined;
|
|
25
|
+
readonly endo?: {
|
|
26
|
+
beta: bigint;
|
|
27
|
+
splitScalar: (k: bigint) => {
|
|
28
|
+
k1neg: boolean;
|
|
29
|
+
k1: bigint;
|
|
30
|
+
k2neg: boolean;
|
|
31
|
+
k2: bigint;
|
|
32
|
+
};
|
|
33
|
+
} | undefined;
|
|
34
|
+
}>, Point: import("../weierstrass").PointConstructor, JacobianPoint: import("../weierstrass").JacobianPointConstructor, Signature: import("../weierstrass").SignatureConstructor;
|
|
35
|
+
export declare const utils: {
|
|
36
|
+
mod: (a: bigint, b?: bigint | undefined) => bigint;
|
|
37
|
+
invert: (number: bigint, modulo?: bigint | undefined) => bigint;
|
|
38
|
+
_bigintToBytes: (num: bigint) => Uint8Array;
|
|
39
|
+
_bigintToString: (num: bigint) => string;
|
|
40
|
+
_normalizePrivateKey: (key: cutils.PrivKey) => bigint;
|
|
41
|
+
_normalizePublicKey: (publicKey: import("../weierstrass").PubKey) => import("../weierstrass").PointType;
|
|
42
|
+
_isWithinCurveOrder: (num: bigint) => boolean;
|
|
43
|
+
_isValidFieldElement: (num: bigint) => boolean;
|
|
44
|
+
_weierstrassEquation: (x: bigint) => bigint;
|
|
45
|
+
isValidPrivateKey(privateKey: cutils.PrivKey): boolean;
|
|
46
|
+
hashToPrivateKey: (hash: cutils.Hex) => Uint8Array;
|
|
47
|
+
randomPrivateKey: () => Uint8Array;
|
|
48
|
+
};
|
|
49
|
+
export { CURVE, Point, Signature, JacobianPoint, getPublicKey0x as getPublicKey, getSharedSecret0x as getSharedSecret, sign0x as sign, verify0x as verify, };
|
|
50
|
+
export declare const bytesToHexEth: (uint8a: Uint8Array) => string;
|
|
51
|
+
export declare const strip0x: (hex: string) => string;
|
|
52
|
+
export declare const numberToHexEth: (num: bigint | number) => string;
|
|
53
|
+
declare type Hex = Uint8Array | string;
|
|
54
|
+
export declare function grindKey(seed: Hex): string;
|
|
55
|
+
export declare function getStarkKey(privateKey: Hex): string;
|
|
56
|
+
export declare function ethSigToPrivate(signature: string): string;
|
|
57
|
+
export declare function getAccountPath(layer: string, application: string, ethereumAddress: string, index: number): string;
|
|
58
|
+
declare type PedersenArg = Hex | bigint | number;
|
|
59
|
+
export declare function pedersen(x: PedersenArg, y: PedersenArg): string;
|
|
60
|
+
export declare function hashChain(data: PedersenArg[], fn?: typeof pedersen): PedersenArg;
|
|
61
|
+
export declare const computeHashOnElements: (data: PedersenArg[], fn?: typeof pedersen) => PedersenArg;
|
|
62
|
+
export declare const keccak: (data: Uint8Array) => bigint;
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
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.JacobianPoint = exports.Signature = exports.Point = exports.CURVE = exports.utils = exports.starkCurve = void 0;
|
|
4
|
+
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
5
|
+
const sha3_1 = require("@noble/hashes/sha3");
|
|
6
|
+
const sha256_1 = require("@noble/hashes/sha256");
|
|
7
|
+
const hmac_1 = require("@noble/hashes/hmac");
|
|
8
|
+
const utils_1 = require("@noble/hashes/utils");
|
|
9
|
+
const weierstrass_1 = require("../weierstrass");
|
|
10
|
+
const cutils = require("../utils");
|
|
11
|
+
// Stark-friendly elliptic curve
|
|
12
|
+
// https://docs.starkware.co/starkex/stark-curve.html
|
|
13
|
+
// TODO: clarify exports; it is exporting both starkCurve and sign() now, can be confusing
|
|
14
|
+
function getHash(hash) {
|
|
15
|
+
return {
|
|
16
|
+
hash,
|
|
17
|
+
hmac: (key, ...msgs) => (0, hmac_1.hmac)(hash, key, (0, utils_1.concatBytes)(...msgs)),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const CURVE_N = BigInt('3618502788666131213697322783095070105526743751716087489154079457884512865583');
|
|
21
|
+
const nBitLength = 252;
|
|
22
|
+
exports.starkCurve = (0, weierstrass_1.weierstrass)({
|
|
23
|
+
// Params: a, b
|
|
24
|
+
a: BigInt(1),
|
|
25
|
+
b: BigInt('3141592653589793238462643383279502884197169399375105820974944592307816406665'),
|
|
26
|
+
// Field over which we'll do calculations; 2n**251n + 17n * 2n**192n + 1n
|
|
27
|
+
// There is no efficient sqrt for field (P%4==1)
|
|
28
|
+
P: BigInt('0x800000000000011000000000000000000000000000000000000000000000001'),
|
|
29
|
+
// Curve order, total count of valid points in the field.
|
|
30
|
+
n: CURVE_N,
|
|
31
|
+
nBitLength: nBitLength,
|
|
32
|
+
// Base point (x, y) aka generator point
|
|
33
|
+
Gx: BigInt('874739451078007766457464989774322083649278607533249481151382481072868806602'),
|
|
34
|
+
Gy: BigInt('152666792071518830868575557812948353041420400780739481342941381225525861407'),
|
|
35
|
+
h: BigInt(1),
|
|
36
|
+
// Default options
|
|
37
|
+
lowS: false,
|
|
38
|
+
...getHash(sha256_1.sha256),
|
|
39
|
+
truncateHash: (hash, truncateOnly = false) => {
|
|
40
|
+
// TODO: cleanup, ugly code
|
|
41
|
+
// Fix truncation
|
|
42
|
+
if (!truncateOnly) {
|
|
43
|
+
let hashS = bytesToNumber0x(hash).toString(16);
|
|
44
|
+
if (hashS.length === 63) {
|
|
45
|
+
hashS += '0';
|
|
46
|
+
hash = hexToBytes0x(hashS);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Truncate zero bytes on left (compat with elliptic)
|
|
50
|
+
while (hash[0] === 0)
|
|
51
|
+
hash = hash.subarray(1);
|
|
52
|
+
const byteLength = hash.length;
|
|
53
|
+
const delta = byteLength * 8 - nBitLength; // size of curve.n (252 bits)
|
|
54
|
+
let h = hash.length ? bytesToNumber0x(hash) : 0n;
|
|
55
|
+
if (delta > 0)
|
|
56
|
+
h = h >> BigInt(delta);
|
|
57
|
+
if (!truncateOnly && h >= CURVE_N)
|
|
58
|
+
h -= CURVE_N;
|
|
59
|
+
return h;
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
// Custom Starknet type conversion functions that can handle 0x and unpadded hex
|
|
63
|
+
function hexToBytes0x(hex) {
|
|
64
|
+
if (typeof hex !== 'string') {
|
|
65
|
+
throw new TypeError('hexToBytes: expected string, got ' + typeof hex);
|
|
66
|
+
}
|
|
67
|
+
hex = (0, exports.strip0x)(hex);
|
|
68
|
+
if (hex.length & 1)
|
|
69
|
+
hex = '0' + hex; // padding
|
|
70
|
+
if (hex.length % 2)
|
|
71
|
+
throw new Error('hexToBytes: received invalid unpadded hex ' + hex.length);
|
|
72
|
+
const array = new Uint8Array(hex.length / 2);
|
|
73
|
+
for (let i = 0; i < array.length; i++) {
|
|
74
|
+
const j = i * 2;
|
|
75
|
+
const hexByte = hex.slice(j, j + 2);
|
|
76
|
+
const byte = Number.parseInt(hexByte, 16);
|
|
77
|
+
if (Number.isNaN(byte) || byte < 0)
|
|
78
|
+
throw new Error('Invalid byte sequence');
|
|
79
|
+
array[i] = byte;
|
|
80
|
+
}
|
|
81
|
+
return array;
|
|
82
|
+
}
|
|
83
|
+
function hexToNumber0x(hex) {
|
|
84
|
+
if (typeof hex !== 'string') {
|
|
85
|
+
throw new TypeError('hexToNumber: expected string, got ' + typeof hex);
|
|
86
|
+
}
|
|
87
|
+
// Big Endian
|
|
88
|
+
// TODO: strip vs no strip?
|
|
89
|
+
return BigInt(`0x${(0, exports.strip0x)(hex)}`);
|
|
90
|
+
}
|
|
91
|
+
function bytesToNumber0x(bytes) {
|
|
92
|
+
return hexToNumber0x(cutils.bytesToHex(bytes));
|
|
93
|
+
}
|
|
94
|
+
function ensureBytes0x(hex) {
|
|
95
|
+
// Uint8Array.from() instead of hash.slice() because node.js Buffer
|
|
96
|
+
// is instance of Uint8Array, and its slice() creates **mutable** copy
|
|
97
|
+
return hex instanceof Uint8Array ? Uint8Array.from(hex) : hexToBytes0x(hex);
|
|
98
|
+
}
|
|
99
|
+
function normalizePrivateKey(privKey) {
|
|
100
|
+
return cutils.bytesToHex(ensureBytes0x(privKey)).padStart(32 * 2, '0');
|
|
101
|
+
}
|
|
102
|
+
function getPublicKey0x(privKey, isCompressed) {
|
|
103
|
+
return exports.starkCurve.getPublicKey(normalizePrivateKey(privKey), isCompressed);
|
|
104
|
+
}
|
|
105
|
+
exports.getPublicKey = getPublicKey0x;
|
|
106
|
+
function getSharedSecret0x(privKeyA, pubKeyB) {
|
|
107
|
+
return exports.starkCurve.getSharedSecret(normalizePrivateKey(privKeyA), pubKeyB);
|
|
108
|
+
}
|
|
109
|
+
exports.getSharedSecret = getSharedSecret0x;
|
|
110
|
+
function sign0x(msgHash, privKey, opts) {
|
|
111
|
+
return exports.starkCurve.sign(ensureBytes0x(msgHash), normalizePrivateKey(privKey), opts);
|
|
112
|
+
}
|
|
113
|
+
exports.sign = sign0x;
|
|
114
|
+
function verify0x(signature, msgHash, pubKey) {
|
|
115
|
+
const sig = signature instanceof Signature ? signature : ensureBytes0x(signature);
|
|
116
|
+
return exports.starkCurve.verify(sig, ensureBytes0x(msgHash), ensureBytes0x(pubKey));
|
|
117
|
+
}
|
|
118
|
+
exports.verify = verify0x;
|
|
119
|
+
const { CURVE, Point, JacobianPoint, Signature } = exports.starkCurve;
|
|
120
|
+
exports.CURVE = CURVE;
|
|
121
|
+
exports.Point = Point;
|
|
122
|
+
exports.JacobianPoint = JacobianPoint;
|
|
123
|
+
exports.Signature = Signature;
|
|
124
|
+
exports.utils = exports.starkCurve.utils;
|
|
125
|
+
const stripLeadingZeros = (s) => s.replace(/^0+/gm, '');
|
|
126
|
+
const bytesToHexEth = (uint8a) => `0x${stripLeadingZeros(cutils.bytesToHex(uint8a))}`;
|
|
127
|
+
exports.bytesToHexEth = bytesToHexEth;
|
|
128
|
+
const strip0x = (hex) => hex.replace(/^0x/i, '');
|
|
129
|
+
exports.strip0x = strip0x;
|
|
130
|
+
const numberToHexEth = (num) => `0x${num.toString(16)}`;
|
|
131
|
+
exports.numberToHexEth = numberToHexEth;
|
|
132
|
+
// 1. seed generation
|
|
133
|
+
function hashKeyWithIndex(key, index) {
|
|
134
|
+
let indexHex = cutils.numberToHexUnpadded(index);
|
|
135
|
+
if (indexHex.length & 1)
|
|
136
|
+
indexHex = '0' + indexHex;
|
|
137
|
+
return bytesToNumber0x((0, sha256_1.sha256)(cutils.concatBytes(key, hexToBytes0x(indexHex))));
|
|
138
|
+
}
|
|
139
|
+
function grindKey(seed) {
|
|
140
|
+
const _seed = ensureBytes0x(seed);
|
|
141
|
+
const sha256mask = 2n ** 256n;
|
|
142
|
+
const limit = sha256mask - exports.starkCurve.utils.mod(sha256mask, exports.starkCurve.CURVE.n);
|
|
143
|
+
for (let i = 0;; i++) {
|
|
144
|
+
const key = hashKeyWithIndex(_seed, i);
|
|
145
|
+
// key should be in [0, limit)
|
|
146
|
+
if (key < limit)
|
|
147
|
+
return exports.starkCurve.utils.mod(key, exports.starkCurve.CURVE.n).toString(16);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
exports.grindKey = grindKey;
|
|
151
|
+
function getStarkKey(privateKey) {
|
|
152
|
+
return (0, exports.bytesToHexEth)(getPublicKey0x(privateKey, true).slice(1));
|
|
153
|
+
}
|
|
154
|
+
exports.getStarkKey = getStarkKey;
|
|
155
|
+
function ethSigToPrivate(signature) {
|
|
156
|
+
signature = (0, exports.strip0x)(signature.replace(/^0x/, ''));
|
|
157
|
+
if (signature.length !== 130)
|
|
158
|
+
throw new Error('Wrong ethereum signature');
|
|
159
|
+
return grindKey(signature.substring(0, 64));
|
|
160
|
+
}
|
|
161
|
+
exports.ethSigToPrivate = ethSigToPrivate;
|
|
162
|
+
const MASK_31 = 2n ** 31n - 1n;
|
|
163
|
+
const int31 = (n) => Number(n & MASK_31);
|
|
164
|
+
function getAccountPath(layer, application, ethereumAddress, index) {
|
|
165
|
+
const layerNum = int31(bytesToNumber0x((0, sha256_1.sha256)(layer)));
|
|
166
|
+
const applicationNum = int31(bytesToNumber0x((0, sha256_1.sha256)(application)));
|
|
167
|
+
const eth = hexToNumber0x(ethereumAddress);
|
|
168
|
+
return `m/2645'/${layerNum}'/${applicationNum}'/${int31(eth)}'/${int31(eth >> 31n)}'/${index}`;
|
|
169
|
+
}
|
|
170
|
+
exports.getAccountPath = getAccountPath;
|
|
171
|
+
// https://docs.starkware.co/starkex/pedersen-hash-function.html
|
|
172
|
+
const PEDERSEN_POINTS = [
|
|
173
|
+
new Point(2089986280348253421170679821480865132823066470938446095505822317253594081284n, 1713931329540660377023406109199410414810705867260802078187082345529207694986n),
|
|
174
|
+
new Point(996781205833008774514500082376783249102396023663454813447423147977397232763n, 1668503676786377725805489344771023921079126552019160156920634619255970485781n),
|
|
175
|
+
new Point(2251563274489750535117886426533222435294046428347329203627021249169616184184n, 1798716007562728905295480679789526322175868328062420237419143593021674992973n),
|
|
176
|
+
new Point(2138414695194151160943305727036575959195309218611738193261179310511854807447n, 113410276730064486255102093846540133784865286929052426931474106396135072156n),
|
|
177
|
+
new Point(2379962749567351885752724891227938183011949129833673362440656643086021394946n, 776496453633298175483985398648758586525933812536653089401905292063708816422n),
|
|
178
|
+
];
|
|
179
|
+
// for (const p of PEDERSEN_POINTS) p._setWindowSize(8);
|
|
180
|
+
const PEDERSEN_POINTS_JACOBIAN = PEDERSEN_POINTS.map(JacobianPoint.fromAffine);
|
|
181
|
+
function pedersenPrecompute(p1, p2) {
|
|
182
|
+
const out = [];
|
|
183
|
+
let p = p1;
|
|
184
|
+
for (let i = 0; i < 248; i++) {
|
|
185
|
+
out.push(p);
|
|
186
|
+
p = p.double();
|
|
187
|
+
}
|
|
188
|
+
p = p2;
|
|
189
|
+
for (let i = 0; i < 4; i++) {
|
|
190
|
+
out.push(p);
|
|
191
|
+
p = p.double();
|
|
192
|
+
}
|
|
193
|
+
return out;
|
|
194
|
+
}
|
|
195
|
+
const PEDERSEN_POINTS1 = pedersenPrecompute(PEDERSEN_POINTS_JACOBIAN[1], PEDERSEN_POINTS_JACOBIAN[2]);
|
|
196
|
+
const PEDERSEN_POINTS2 = pedersenPrecompute(PEDERSEN_POINTS_JACOBIAN[3], PEDERSEN_POINTS_JACOBIAN[4]);
|
|
197
|
+
function pedersenArg(arg) {
|
|
198
|
+
let value;
|
|
199
|
+
if (typeof arg === 'bigint')
|
|
200
|
+
value = arg;
|
|
201
|
+
else if (typeof arg === 'number') {
|
|
202
|
+
if (!Number.isSafeInteger(arg))
|
|
203
|
+
throw new Error(`Invalid pedersenArg: ${arg}`);
|
|
204
|
+
value = BigInt(arg);
|
|
205
|
+
}
|
|
206
|
+
else
|
|
207
|
+
value = bytesToNumber0x(ensureBytes0x(arg));
|
|
208
|
+
// [0..Fp)
|
|
209
|
+
if (!(0n <= value && value < exports.starkCurve.CURVE.P))
|
|
210
|
+
throw new Error(`PedersenArg should be 0 <= value < CURVE.P: ${value}`);
|
|
211
|
+
return value;
|
|
212
|
+
}
|
|
213
|
+
function pedersenSingle(point, value, constants) {
|
|
214
|
+
let x = pedersenArg(value);
|
|
215
|
+
for (let j = 0; j < 252; j++) {
|
|
216
|
+
const pt = constants[j];
|
|
217
|
+
if (pt.x === point.x)
|
|
218
|
+
throw new Error('Same point');
|
|
219
|
+
if ((x & 1n) !== 0n)
|
|
220
|
+
point = point.add(pt);
|
|
221
|
+
x >>= 1n;
|
|
222
|
+
}
|
|
223
|
+
return point;
|
|
224
|
+
}
|
|
225
|
+
// shift_point + x_low * P_0 + x_high * P1 + y_low * P2 + y_high * P3
|
|
226
|
+
function pedersen(x, y) {
|
|
227
|
+
let point = PEDERSEN_POINTS_JACOBIAN[0];
|
|
228
|
+
point = pedersenSingle(point, x, PEDERSEN_POINTS1);
|
|
229
|
+
point = pedersenSingle(point, y, PEDERSEN_POINTS2);
|
|
230
|
+
return (0, exports.bytesToHexEth)(point.toAffine().toRawBytes(true).slice(1));
|
|
231
|
+
}
|
|
232
|
+
exports.pedersen = pedersen;
|
|
233
|
+
function hashChain(data, fn = pedersen) {
|
|
234
|
+
if (!Array.isArray(data) || data.length < 1)
|
|
235
|
+
throw new Error('data should be array of at least 1 element');
|
|
236
|
+
if (data.length === 1)
|
|
237
|
+
return (0, exports.numberToHexEth)(pedersenArg(data[0]));
|
|
238
|
+
return Array.from(data)
|
|
239
|
+
.reverse()
|
|
240
|
+
.reduce((acc, i) => fn(i, acc));
|
|
241
|
+
}
|
|
242
|
+
exports.hashChain = hashChain;
|
|
243
|
+
// Same as hashChain, but computes hash even for single element and order is not revesed
|
|
244
|
+
const computeHashOnElements = (data, fn = pedersen) => [0, ...data, data.length].reduce((x, y) => fn(x, y));
|
|
245
|
+
exports.computeHashOnElements = computeHashOnElements;
|
|
246
|
+
const MASK_250 = 2n ** 250n - 1n;
|
|
247
|
+
const keccak = (data) => bytesToNumber0x((0, sha3_1.keccak_256)(data)) & MASK_250;
|
|
248
|
+
exports.keccak = keccak;
|
package/lib/edwards.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export declare type CurveType = BasicCurve & {
|
|
|
11
11
|
a: bigint;
|
|
12
12
|
d: bigint;
|
|
13
13
|
hash: CHash;
|
|
14
|
-
randomBytes
|
|
14
|
+
randomBytes?: (bytesLength?: number) => Uint8Array;
|
|
15
15
|
adjustScalarBytes?: (bytes: Uint8Array) => Uint8Array;
|
|
16
16
|
domain?: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array;
|
|
17
17
|
uvRatio?: (u: bigint, v: bigint) => {
|
|
@@ -31,7 +31,7 @@ declare function validateOpts(curve: CurveType): Readonly<{
|
|
|
31
31
|
readonly a: bigint;
|
|
32
32
|
readonly d: bigint;
|
|
33
33
|
readonly hash: CHash;
|
|
34
|
-
|
|
34
|
+
randomBytes: (bytesLength?: number | undefined) => Uint8Array;
|
|
35
35
|
readonly adjustScalarBytes?: ((bytes: Uint8Array) => Uint8Array) | undefined;
|
|
36
36
|
readonly domain?: ((data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array) | undefined;
|
|
37
37
|
readonly uvRatio?: ((u: bigint, v: bigint) => {
|
package/lib/edwards.js
CHANGED
|
@@ -27,18 +27,14 @@ function validateOpts(curve) {
|
|
|
27
27
|
if (typeof opts[i] !== 'bigint')
|
|
28
28
|
throw new Error(`Invalid curve param ${i}=${opts[i]} (${typeof opts[i]})`);
|
|
29
29
|
}
|
|
30
|
-
for (const fn of ['randomBytes']) {
|
|
31
|
-
if (typeof opts[fn] !== 'function')
|
|
32
|
-
throw new Error(`Invalid ${fn} function`);
|
|
33
|
-
}
|
|
34
|
-
for (const fn of ['adjustScalarBytes', 'domain', 'uvRatio']) {
|
|
30
|
+
for (const fn of ['adjustScalarBytes', 'domain', 'randomBytes', 'uvRatio']) {
|
|
35
31
|
if (opts[fn] === undefined)
|
|
36
32
|
continue; // Optional
|
|
37
33
|
if (typeof opts[fn] !== 'function')
|
|
38
34
|
throw new Error(`Invalid ${fn} function`);
|
|
39
35
|
}
|
|
40
36
|
// Set defaults
|
|
41
|
-
return Object.freeze({ ...opts });
|
|
37
|
+
return Object.freeze({ randomBytes: utils_js_1.randomBytes, ...opts });
|
|
42
38
|
}
|
|
43
39
|
// NOTE: it is not generic twisted curve for now, but ed25519/ed448 generic implementation
|
|
44
40
|
function twistedEdwards(curveDef) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { hmac } from '@noble/hashes/hmac';
|
|
2
|
+
import { concatBytes } from '@noble/hashes/utils';
|
|
3
|
+
import { weierstrass } from '../weierstrass';
|
|
4
|
+
export function getHash(hash) {
|
|
5
|
+
return {
|
|
6
|
+
hash,
|
|
7
|
+
hmac: (key, ...msgs) => hmac(hash, key, concatBytes(...msgs)),
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function createCurve(curveDef, defHash) {
|
|
11
|
+
const create = (hash) => weierstrass({ ...curveDef, ...getHash(hash) });
|
|
12
|
+
return Object.freeze({ ...create(defHash), create });
|
|
13
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2
|
+
import { weierstrass } from '../weierstrass';
|
|
3
|
+
import { sha256 } from '@noble/hashes/sha256';
|
|
4
|
+
import { getHash } from './_shortw_utils.js';
|
|
5
|
+
/**
|
|
6
|
+
* bn254 pairing-friendly curve.
|
|
7
|
+
* Previously known as alt_bn_128, when it had 128-bit security.
|
|
8
|
+
* Recent research shown it's weaker, the naming has been adjusted to its prime bit count.
|
|
9
|
+
* https://github.com/zcash/zcash/issues/2502
|
|
10
|
+
*/
|
|
11
|
+
export const bn254 = weierstrass({
|
|
12
|
+
a: BigInt(0),
|
|
13
|
+
b: BigInt(3),
|
|
14
|
+
P: BigInt('0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47'),
|
|
15
|
+
n: BigInt('0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001'),
|
|
16
|
+
Gx: BigInt(1),
|
|
17
|
+
Gy: BigInt(2),
|
|
18
|
+
h: BigInt(1),
|
|
19
|
+
...getHash(sha256),
|
|
20
|
+
});
|