@noble/curves 0.4.0 → 0.5.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 +254 -162
- package/lib/_shortw_utils.d.ts +75 -0
- package/lib/_shortw_utils.js +20 -0
- package/lib/{bls.d.ts → abstract/bls.d.ts} +2 -1
- package/lib/{bls.js → abstract/bls.js} +28 -27
- package/lib/{edwards.d.ts → abstract/edwards.d.ts} +17 -0
- package/lib/{edwards.js → abstract/edwards.js} +45 -4
- package/lib/{group.d.ts → abstract/group.d.ts} +2 -1
- package/lib/{group.js → abstract/group.js} +4 -3
- package/lib/abstract/hash-to-curve.d.ts +28 -0
- package/lib/{hashToCurve.js → abstract/hash-to-curve.js} +46 -11
- package/lib/{modular.d.ts → abstract/modular.d.ts} +13 -16
- package/lib/abstract/modular.js +337 -0
- package/lib/{montgomery.d.ts → abstract/montgomery.d.ts} +2 -1
- package/lib/{montgomery.js → abstract/montgomery.js} +17 -8
- package/lib/{utils.d.ts → abstract/utils.d.ts} +4 -2
- package/lib/{utils.js → abstract/utils.js} +1 -1
- package/lib/{weierstrass.d.ts → abstract/weierstrass.d.ts} +28 -16
- package/lib/{weierstrass.js → abstract/weierstrass.js} +261 -127
- package/lib/bls12-381.d.ts +66 -0
- package/lib/bls12-381.js +1132 -0
- package/lib/bn.d.ts +7 -0
- package/lib/bn.js +24 -0
- package/lib/ed25519.d.ts +48 -0
- package/lib/ed25519.js +385 -0
- package/lib/ed448.d.ts +3 -0
- package/lib/ed448.js +211 -0
- package/lib/esm/_shortw_utils.js +15 -0
- package/lib/esm/{bls.js → abstract/bls.js} +25 -24
- package/lib/esm/{edwards.js → abstract/edwards.js} +45 -4
- package/lib/esm/{group.js → abstract/group.js} +4 -3
- package/lib/esm/{hashToCurve.js → abstract/hash-to-curve.js} +43 -10
- package/lib/esm/abstract/modular.js +319 -0
- package/lib/esm/{montgomery.js → abstract/montgomery.js} +17 -8
- package/lib/esm/{utils.js → abstract/utils.js} +1 -1
- package/lib/esm/{weierstrass.js → abstract/weierstrass.js} +255 -123
- package/lib/esm/bls12-381.js +1129 -0
- package/lib/esm/bn.js +21 -0
- package/lib/esm/ed25519.js +381 -0
- package/lib/esm/ed448.js +208 -0
- package/lib/esm/index.js +2 -0
- package/lib/esm/jubjub.js +52 -0
- package/lib/esm/p192.js +21 -0
- package/lib/esm/p224.js +21 -0
- package/lib/esm/p256.js +39 -0
- package/lib/esm/p384.js +44 -0
- package/lib/esm/p521.js +58 -0
- package/lib/esm/pasta.js +29 -0
- package/lib/esm/secp256k1.js +293 -0
- package/lib/esm/stark.js +224 -0
- package/lib/index.d.ts +0 -0
- package/lib/index.js +2 -0
- package/lib/jubjub.d.ts +7 -0
- package/lib/jubjub.js +57 -0
- package/lib/p192.d.ts +130 -0
- package/lib/p192.js +24 -0
- package/lib/p224.d.ts +130 -0
- package/lib/p224.js +24 -0
- package/lib/p256.d.ts +130 -0
- package/lib/p256.js +42 -0
- package/lib/p384.d.ts +130 -0
- package/lib/p384.js +47 -0
- package/lib/p521.d.ts +131 -0
- package/lib/p521.js +61 -0
- package/lib/pasta.d.ts +4 -0
- package/lib/pasta.js +32 -0
- package/lib/secp256k1.d.ts +96 -0
- package/lib/secp256k1.js +297 -0
- package/lib/stark.d.ts +72 -0
- package/lib/stark.js +245 -0
- package/package.json +146 -50
- package/index.js +0 -1
- package/lib/esm/modular.js +0 -252
- package/lib/hashToCurve.d.ts +0 -13
- package/lib/modular.js +0 -267
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FpSqrtEven = exports.FpSqrtOdd = exports.Fp = exports.FpIsSquare = exports.FpDiv = exports.FpInvertBatch = exports.FpPow = exports.validateField = exports.isNegativeLE = exports.FpSqrt = exports.tonelliShanks = exports.invert = exports.pow2 = exports.pow = exports.mod = void 0;
|
|
4
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
5
|
+
// TODO: remove circular imports
|
|
6
|
+
const utils = require("./utils.js");
|
|
7
|
+
// Utilities for modular arithmetics and finite fields
|
|
8
|
+
// prettier-ignore
|
|
9
|
+
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);
|
|
10
|
+
// prettier-ignore
|
|
11
|
+
const _4n = BigInt(4), _5n = BigInt(5), _8n = BigInt(8);
|
|
12
|
+
// prettier-ignore
|
|
13
|
+
const _9n = BigInt(9), _16n = BigInt(16);
|
|
14
|
+
// Calculates a modulo b
|
|
15
|
+
function mod(a, b) {
|
|
16
|
+
const result = a % b;
|
|
17
|
+
return result >= _0n ? result : b + result;
|
|
18
|
+
}
|
|
19
|
+
exports.mod = mod;
|
|
20
|
+
/**
|
|
21
|
+
* Efficiently exponentiate num to power and do modular division.
|
|
22
|
+
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
|
23
|
+
* @example
|
|
24
|
+
* powMod(2n, 6n, 11n) // 64n % 11n == 9n
|
|
25
|
+
*/
|
|
26
|
+
// TODO: use field version && remove
|
|
27
|
+
function pow(num, power, modulo) {
|
|
28
|
+
if (modulo <= _0n || power < _0n)
|
|
29
|
+
throw new Error('Expected power/modulo > 0');
|
|
30
|
+
if (modulo === _1n)
|
|
31
|
+
return _0n;
|
|
32
|
+
let res = _1n;
|
|
33
|
+
while (power > _0n) {
|
|
34
|
+
if (power & _1n)
|
|
35
|
+
res = (res * num) % modulo;
|
|
36
|
+
num = (num * num) % modulo;
|
|
37
|
+
power >>= _1n;
|
|
38
|
+
}
|
|
39
|
+
return res;
|
|
40
|
+
}
|
|
41
|
+
exports.pow = pow;
|
|
42
|
+
// Does x ^ (2 ^ power) mod p. pow2(30, 4) == 30 ^ (2 ^ 4)
|
|
43
|
+
// TODO: Fp version?
|
|
44
|
+
function pow2(x, power, modulo) {
|
|
45
|
+
let res = x;
|
|
46
|
+
while (power-- > _0n) {
|
|
47
|
+
res *= res;
|
|
48
|
+
res %= modulo;
|
|
49
|
+
}
|
|
50
|
+
return res;
|
|
51
|
+
}
|
|
52
|
+
exports.pow2 = pow2;
|
|
53
|
+
// Inverses number over modulo
|
|
54
|
+
function invert(number, modulo) {
|
|
55
|
+
if (number === _0n || modulo <= _0n) {
|
|
56
|
+
throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
|
|
57
|
+
}
|
|
58
|
+
// Eucledian GCD https://brilliant.org/wiki/extended-euclidean-algorithm/
|
|
59
|
+
let a = mod(number, modulo);
|
|
60
|
+
let b = modulo;
|
|
61
|
+
// prettier-ignore
|
|
62
|
+
let x = _0n, y = _1n, u = _1n, v = _0n;
|
|
63
|
+
while (a !== _0n) {
|
|
64
|
+
const q = b / a;
|
|
65
|
+
const r = b % a;
|
|
66
|
+
const m = x - u * q;
|
|
67
|
+
const n = y - v * q;
|
|
68
|
+
// prettier-ignore
|
|
69
|
+
b = a, a = r, x = u, y = v, u = m, v = n;
|
|
70
|
+
}
|
|
71
|
+
const gcd = b;
|
|
72
|
+
if (gcd !== _1n)
|
|
73
|
+
throw new Error('invert: does not exist');
|
|
74
|
+
return mod(x, modulo);
|
|
75
|
+
}
|
|
76
|
+
exports.invert = invert;
|
|
77
|
+
// Tonelli-Shanks algorithm
|
|
78
|
+
// https://eprint.iacr.org/2012/685.pdf (page 12)
|
|
79
|
+
function tonelliShanks(P) {
|
|
80
|
+
// Legendre constant: used to calculate Legendre symbol (a | p),
|
|
81
|
+
// which denotes the value of a^((p-1)/2) (mod p).
|
|
82
|
+
// (a | p) ≡ 1 if a is a square (mod p)
|
|
83
|
+
// (a | p) ≡ -1 if a is not a square (mod p)
|
|
84
|
+
// (a | p) ≡ 0 if a ≡ 0 (mod p)
|
|
85
|
+
const legendreC = (P - _1n) / _2n;
|
|
86
|
+
let Q, S, Z;
|
|
87
|
+
// Step 1: By factoring out powers of 2 from p - 1,
|
|
88
|
+
// find q and s such that p - 1 = q2s with q odd
|
|
89
|
+
for (Q = P - _1n, S = 0; Q % _2n === _0n; Q /= _2n, S++)
|
|
90
|
+
;
|
|
91
|
+
// Step 2: Select a non-square z such that (z | p) ≡ -1 and set c ≡ zq
|
|
92
|
+
for (Z = _2n; Z < P && pow(Z, legendreC, P) !== P - _1n; Z++)
|
|
93
|
+
;
|
|
94
|
+
// Fast-path
|
|
95
|
+
if (S === 1) {
|
|
96
|
+
const p1div4 = (P + _1n) / _4n;
|
|
97
|
+
return function tonelliFast(Fp, n) {
|
|
98
|
+
const root = Fp.pow(n, p1div4);
|
|
99
|
+
if (!Fp.equals(Fp.square(root), n))
|
|
100
|
+
throw new Error('Cannot find square root');
|
|
101
|
+
return root;
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// Slow-path
|
|
105
|
+
const Q1div2 = (Q + _1n) / _2n;
|
|
106
|
+
return function tonelliSlow(Fp, n) {
|
|
107
|
+
// Step 0: Check that n is indeed a square: (n | p) must be ≡ 1
|
|
108
|
+
if (Fp.pow(n, legendreC) !== Fp.ONE)
|
|
109
|
+
throw new Error('Cannot find square root');
|
|
110
|
+
let s = S;
|
|
111
|
+
let c = pow(Z, Q, P);
|
|
112
|
+
let r = Fp.pow(n, Q1div2);
|
|
113
|
+
let t = Fp.pow(n, Q);
|
|
114
|
+
let t2 = Fp.ZERO;
|
|
115
|
+
while (!Fp.equals(Fp.sub(t, Fp.ONE), Fp.ZERO)) {
|
|
116
|
+
t2 = Fp.square(t);
|
|
117
|
+
let i;
|
|
118
|
+
for (i = 1; i < s; i++) {
|
|
119
|
+
// stop if t2-1 == 0
|
|
120
|
+
if (Fp.equals(Fp.sub(t2, Fp.ONE), Fp.ZERO))
|
|
121
|
+
break;
|
|
122
|
+
// t2 *= t2
|
|
123
|
+
t2 = Fp.square(t2);
|
|
124
|
+
}
|
|
125
|
+
let b = pow(c, BigInt(1 << (s - i - 1)), P);
|
|
126
|
+
r = Fp.mul(r, b);
|
|
127
|
+
c = mod(b * b, P);
|
|
128
|
+
t = Fp.mul(t, c);
|
|
129
|
+
s = i;
|
|
130
|
+
}
|
|
131
|
+
return r;
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
exports.tonelliShanks = tonelliShanks;
|
|
135
|
+
function FpSqrt(P) {
|
|
136
|
+
// NOTE: different algorithms can give different roots, it is up to user to decide which one they want.
|
|
137
|
+
// For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
|
|
138
|
+
// P ≡ 3 (mod 4)
|
|
139
|
+
// √n = n^((P+1)/4)
|
|
140
|
+
if (P % _4n === _3n) {
|
|
141
|
+
// Not all roots possible!
|
|
142
|
+
// const ORDER =
|
|
143
|
+
// 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn;
|
|
144
|
+
// const NUM = 72057594037927816n;
|
|
145
|
+
const p1div4 = (P + _1n) / _4n;
|
|
146
|
+
return function sqrt3mod4(Fp, n) {
|
|
147
|
+
const root = Fp.pow(n, p1div4);
|
|
148
|
+
// Throw if root**2 != n
|
|
149
|
+
if (!Fp.equals(Fp.square(root), n))
|
|
150
|
+
throw new Error('Cannot find square root');
|
|
151
|
+
return root;
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
// Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)
|
|
155
|
+
if (P % _8n === _5n) {
|
|
156
|
+
const c1 = (P - _5n) / _8n;
|
|
157
|
+
return function sqrt5mod8(Fp, n) {
|
|
158
|
+
const n2 = Fp.mul(n, _2n);
|
|
159
|
+
const v = Fp.pow(n2, c1);
|
|
160
|
+
const nv = Fp.mul(n, v);
|
|
161
|
+
const i = Fp.mul(Fp.mul(nv, _2n), v);
|
|
162
|
+
const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));
|
|
163
|
+
if (!Fp.equals(Fp.square(root), n))
|
|
164
|
+
throw new Error('Cannot find square root');
|
|
165
|
+
return root;
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
// P ≡ 9 (mod 16)
|
|
169
|
+
if (P % _16n === _9n) {
|
|
170
|
+
// NOTE: tonelli is too slow for bls-Fp2 calculations even on start
|
|
171
|
+
// Means we cannot use sqrt for constants at all!
|
|
172
|
+
//
|
|
173
|
+
// const c1 = Fp.sqrt(Fp.negate(Fp.ONE)); // 1. c1 = sqrt(-1) in F, i.e., (c1^2) == -1 in F
|
|
174
|
+
// const c2 = Fp.sqrt(c1); // 2. c2 = sqrt(c1) in F, i.e., (c2^2) == c1 in F
|
|
175
|
+
// const c3 = Fp.sqrt(Fp.negate(c1)); // 3. c3 = sqrt(-c1) in F, i.e., (c3^2) == -c1 in F
|
|
176
|
+
// const c4 = (P + _7n) / _16n; // 4. c4 = (q + 7) / 16 # Integer arithmetic
|
|
177
|
+
// sqrt = (x) => {
|
|
178
|
+
// let tv1 = Fp.pow(x, c4); // 1. tv1 = x^c4
|
|
179
|
+
// let tv2 = Fp.mul(c1, tv1); // 2. tv2 = c1 * tv1
|
|
180
|
+
// const tv3 = Fp.mul(c2, tv1); // 3. tv3 = c2 * tv1
|
|
181
|
+
// let tv4 = Fp.mul(c3, tv1); // 4. tv4 = c3 * tv1
|
|
182
|
+
// const e1 = Fp.equals(Fp.square(tv2), x); // 5. e1 = (tv2^2) == x
|
|
183
|
+
// const e2 = Fp.equals(Fp.square(tv3), x); // 6. e2 = (tv3^2) == x
|
|
184
|
+
// tv1 = Fp.cmov(tv1, tv2, e1); // 7. tv1 = CMOV(tv1, tv2, e1) # Select tv2 if (tv2^2) == x
|
|
185
|
+
// tv2 = Fp.cmov(tv4, tv3, e2); // 8. tv2 = CMOV(tv4, tv3, e2) # Select tv3 if (tv3^2) == x
|
|
186
|
+
// const e3 = Fp.equals(Fp.square(tv2), x); // 9. e3 = (tv2^2) == x
|
|
187
|
+
// return Fp.cmov(tv1, tv2, e3); // 10. z = CMOV(tv1, tv2, e3) # Select the sqrt from tv1 and tv2
|
|
188
|
+
// }
|
|
189
|
+
}
|
|
190
|
+
// Other cases: Tonelli-Shanks algorithm
|
|
191
|
+
return tonelliShanks(P);
|
|
192
|
+
}
|
|
193
|
+
exports.FpSqrt = FpSqrt;
|
|
194
|
+
// Little-endian check for first LE bit (last BE bit);
|
|
195
|
+
const isNegativeLE = (num, modulo) => (mod(num, modulo) & _1n) === _1n;
|
|
196
|
+
exports.isNegativeLE = isNegativeLE;
|
|
197
|
+
// prettier-ignore
|
|
198
|
+
const FIELD_FIELDS = [
|
|
199
|
+
'create', 'isValid', 'isZero', 'negate', 'invert', 'sqrt', 'square',
|
|
200
|
+
'equals', 'add', 'sub', 'mul', 'pow', 'div',
|
|
201
|
+
'addN', 'subN', 'mulN', 'squareN'
|
|
202
|
+
];
|
|
203
|
+
function validateField(field) {
|
|
204
|
+
for (const i of ['ORDER', 'MASK']) {
|
|
205
|
+
if (typeof field[i] !== 'bigint')
|
|
206
|
+
throw new Error(`Invalid field param ${i}=${field[i]} (${typeof field[i]})`);
|
|
207
|
+
}
|
|
208
|
+
for (const i of ['BYTES', 'BITS']) {
|
|
209
|
+
if (typeof field[i] !== 'number')
|
|
210
|
+
throw new Error(`Invalid field param ${i}=${field[i]} (${typeof field[i]})`);
|
|
211
|
+
}
|
|
212
|
+
for (const i of FIELD_FIELDS) {
|
|
213
|
+
if (typeof field[i] !== 'function')
|
|
214
|
+
throw new Error(`Invalid field param ${i}=${field[i]} (${typeof field[i]})`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
exports.validateField = validateField;
|
|
218
|
+
// Generic field functions
|
|
219
|
+
function FpPow(f, num, power) {
|
|
220
|
+
// Should have same speed as pow for bigints
|
|
221
|
+
// TODO: benchmark!
|
|
222
|
+
if (power < _0n)
|
|
223
|
+
throw new Error('Expected power > 0');
|
|
224
|
+
if (power === _0n)
|
|
225
|
+
return f.ONE;
|
|
226
|
+
if (power === _1n)
|
|
227
|
+
return num;
|
|
228
|
+
let p = f.ONE;
|
|
229
|
+
let d = num;
|
|
230
|
+
while (power > _0n) {
|
|
231
|
+
if (power & _1n)
|
|
232
|
+
p = f.mul(p, d);
|
|
233
|
+
d = f.square(d);
|
|
234
|
+
power >>= 1n;
|
|
235
|
+
}
|
|
236
|
+
return p;
|
|
237
|
+
}
|
|
238
|
+
exports.FpPow = FpPow;
|
|
239
|
+
function FpInvertBatch(f, nums) {
|
|
240
|
+
const tmp = new Array(nums.length);
|
|
241
|
+
// Walk from first to last, multiply them by each other MOD p
|
|
242
|
+
const lastMultiplied = nums.reduce((acc, num, i) => {
|
|
243
|
+
if (f.isZero(num))
|
|
244
|
+
return acc;
|
|
245
|
+
tmp[i] = acc;
|
|
246
|
+
return f.mul(acc, num);
|
|
247
|
+
}, f.ONE);
|
|
248
|
+
// Invert last element
|
|
249
|
+
const inverted = f.invert(lastMultiplied);
|
|
250
|
+
// Walk from last to first, multiply them by inverted each other MOD p
|
|
251
|
+
nums.reduceRight((acc, num, i) => {
|
|
252
|
+
if (f.isZero(num))
|
|
253
|
+
return acc;
|
|
254
|
+
tmp[i] = f.mul(acc, tmp[i]);
|
|
255
|
+
return f.mul(acc, num);
|
|
256
|
+
}, inverted);
|
|
257
|
+
return tmp;
|
|
258
|
+
}
|
|
259
|
+
exports.FpInvertBatch = FpInvertBatch;
|
|
260
|
+
function FpDiv(f, lhs, rhs) {
|
|
261
|
+
return f.mul(lhs, typeof rhs === 'bigint' ? invert(rhs, f.ORDER) : f.invert(rhs));
|
|
262
|
+
}
|
|
263
|
+
exports.FpDiv = FpDiv;
|
|
264
|
+
// This function returns True whenever the value x is a square in the field F.
|
|
265
|
+
function FpIsSquare(f) {
|
|
266
|
+
const legendreConst = (f.ORDER - _1n) / _2n; // Integer arithmetic
|
|
267
|
+
return (x) => {
|
|
268
|
+
const p = f.pow(x, legendreConst);
|
|
269
|
+
return f.equals(p, f.ZERO) || f.equals(p, f.ONE);
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
exports.FpIsSquare = FpIsSquare;
|
|
273
|
+
function Fp(ORDER, bitLen, isLE = false, redef = {}) {
|
|
274
|
+
if (ORDER <= _0n)
|
|
275
|
+
throw new Error(`Expected Fp ORDER > 0, got ${ORDER}`);
|
|
276
|
+
const { nBitLength: BITS, nByteLength: BYTES } = utils.nLength(ORDER, bitLen);
|
|
277
|
+
if (BYTES > 2048)
|
|
278
|
+
throw new Error('Field lengths over 2048 bytes are not supported');
|
|
279
|
+
const sqrtP = FpSqrt(ORDER);
|
|
280
|
+
const f = Object.freeze({
|
|
281
|
+
ORDER,
|
|
282
|
+
BITS,
|
|
283
|
+
BYTES,
|
|
284
|
+
MASK: utils.bitMask(BITS),
|
|
285
|
+
ZERO: _0n,
|
|
286
|
+
ONE: _1n,
|
|
287
|
+
create: (num) => mod(num, ORDER),
|
|
288
|
+
isValid: (num) => {
|
|
289
|
+
if (typeof num !== 'bigint')
|
|
290
|
+
throw new Error(`Invalid field element: expected bigint, got ${typeof num}`);
|
|
291
|
+
return _0n <= num && num < ORDER;
|
|
292
|
+
},
|
|
293
|
+
isZero: (num) => num === _0n,
|
|
294
|
+
isOdd: (num) => (num & _1n) === _1n,
|
|
295
|
+
negate: (num) => mod(-num, ORDER),
|
|
296
|
+
equals: (lhs, rhs) => lhs === rhs,
|
|
297
|
+
square: (num) => mod(num * num, ORDER),
|
|
298
|
+
add: (lhs, rhs) => mod(lhs + rhs, ORDER),
|
|
299
|
+
sub: (lhs, rhs) => mod(lhs - rhs, ORDER),
|
|
300
|
+
mul: (lhs, rhs) => mod(lhs * rhs, ORDER),
|
|
301
|
+
pow: (num, power) => FpPow(f, num, power),
|
|
302
|
+
div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),
|
|
303
|
+
// Same as above, but doesn't normalize
|
|
304
|
+
squareN: (num) => num * num,
|
|
305
|
+
addN: (lhs, rhs) => lhs + rhs,
|
|
306
|
+
subN: (lhs, rhs) => lhs - rhs,
|
|
307
|
+
mulN: (lhs, rhs) => lhs * rhs,
|
|
308
|
+
invert: (num) => invert(num, ORDER),
|
|
309
|
+
sqrt: redef.sqrt || ((n) => sqrtP(f, n)),
|
|
310
|
+
invertBatch: (lst) => FpInvertBatch(f, lst),
|
|
311
|
+
// TODO: do we really need constant cmov?
|
|
312
|
+
// We don't have const-time bigints anyway, so probably will be not very useful
|
|
313
|
+
cmov: (a, b, c) => (c ? b : a),
|
|
314
|
+
toBytes: (num) => isLE ? utils.numberToBytesLE(num, BYTES) : utils.numberToBytesBE(num, BYTES),
|
|
315
|
+
fromBytes: (bytes) => {
|
|
316
|
+
if (bytes.length !== BYTES)
|
|
317
|
+
throw new Error(`Fp.fromBytes: expected ${BYTES}, got ${bytes.length}`);
|
|
318
|
+
return isLE ? utils.bytesToNumberLE(bytes) : utils.bytesToNumberBE(bytes);
|
|
319
|
+
},
|
|
320
|
+
});
|
|
321
|
+
return Object.freeze(f);
|
|
322
|
+
}
|
|
323
|
+
exports.Fp = Fp;
|
|
324
|
+
function FpSqrtOdd(Fp, elm) {
|
|
325
|
+
if (!Fp.isOdd)
|
|
326
|
+
throw new Error(`Field doesn't have isOdd`);
|
|
327
|
+
const root = Fp.sqrt(elm);
|
|
328
|
+
return Fp.isOdd(root) ? root : Fp.negate(root);
|
|
329
|
+
}
|
|
330
|
+
exports.FpSqrtOdd = FpSqrtOdd;
|
|
331
|
+
function FpSqrtEven(Fp, elm) {
|
|
332
|
+
if (!Fp.isOdd)
|
|
333
|
+
throw new Error(`Field doesn't have isOdd`);
|
|
334
|
+
const root = Fp.sqrt(elm);
|
|
335
|
+
return Fp.isOdd(root) ? Fp.negate(root) : root;
|
|
336
|
+
}
|
|
337
|
+
exports.FpSqrtEven = FpSqrtEven;
|
|
@@ -11,8 +11,9 @@ export declare type CurveType = {
|
|
|
11
11
|
Gu: string;
|
|
12
12
|
};
|
|
13
13
|
export declare type CurveFn = {
|
|
14
|
-
scalarMult: (
|
|
14
|
+
scalarMult: (scalar: Hex, u: Hex) => Uint8Array;
|
|
15
15
|
scalarMultBase: (scalar: Hex) => Uint8Array;
|
|
16
|
+
getSharedSecret: (privateKeyA: Hex, publicKeyB: Hex) => Uint8Array;
|
|
16
17
|
getPublicKey: (privateKey: Hex) => Uint8Array;
|
|
17
18
|
Gu: string;
|
|
18
19
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.montgomery = void 0;
|
|
4
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
4
5
|
const mod = require("./modular.js");
|
|
5
6
|
const utils_js_1 = require("./utils.js");
|
|
6
7
|
const _0n = BigInt(0);
|
|
@@ -162,8 +163,14 @@ function montgomery(curveDef) {
|
|
|
162
163
|
throw new Error(`Expected ${montgomeryBytes} or ${fieldLen} bytes, got ${bytes.length}`);
|
|
163
164
|
return (0, utils_js_1.bytesToNumberLE)(adjustScalarBytes(bytes));
|
|
164
165
|
}
|
|
165
|
-
|
|
166
|
-
|
|
166
|
+
/**
|
|
167
|
+
* Computes shared secret between private key "scalar" and public key's "u" (x) coordinate.
|
|
168
|
+
* We can get 'y' coordinate from 'u',
|
|
169
|
+
* but Point.fromHex also wants 'x' coordinate oddity flag,
|
|
170
|
+
* and we cannot get 'x' without knowing 'v'.
|
|
171
|
+
* Need to add generic conversion between twisted edwards and complimentary curve for JubJub.
|
|
172
|
+
*/
|
|
173
|
+
function scalarMult(scalar, u) {
|
|
167
174
|
const pointU = decodeUCoordinate(u);
|
|
168
175
|
const _scalar = decodeScalar(scalar);
|
|
169
176
|
const pu = montgomeryLadder(pointU, _scalar);
|
|
@@ -173,17 +180,19 @@ function montgomery(curveDef) {
|
|
|
173
180
|
throw new Error('Invalid private or public key received');
|
|
174
181
|
return encodeUCoordinate(pu);
|
|
175
182
|
}
|
|
176
|
-
|
|
183
|
+
/**
|
|
184
|
+
* Computes public key from private.
|
|
185
|
+
* Executes scalar multiplication of curve's base point by scalar.
|
|
186
|
+
* @param scalar private key
|
|
187
|
+
* @returns new public key
|
|
188
|
+
*/
|
|
177
189
|
function scalarMultBase(scalar) {
|
|
178
|
-
return scalarMult(CURVE.Gu
|
|
190
|
+
return scalarMult(scalar, CURVE.Gu);
|
|
179
191
|
}
|
|
180
192
|
return {
|
|
181
|
-
// NOTE: we can get 'y' coordinate from 'u', but Point.fromHex also wants 'x' coordinate oddity flag, and we cannot get 'x' without knowing 'v'
|
|
182
|
-
// Need to add generic conversion between twisted edwards and complimentary curve for JubJub
|
|
183
193
|
scalarMult,
|
|
184
194
|
scalarMultBase,
|
|
185
|
-
|
|
186
|
-
// getSharedSecret: (privateKey: Hex, publicKey: Hex) => scalarMult(publicKey, privateKey),
|
|
195
|
+
getSharedSecret: (privateKey, publicKey) => scalarMult(privateKey, publicKey),
|
|
187
196
|
getPublicKey: (privateKey) => scalarMultBase(privateKey),
|
|
188
197
|
Gu: CURVE.Gu,
|
|
189
198
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*!
|
|
1
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2
2
|
import * as mod from './modular.js';
|
|
3
3
|
export declare type Hex = Uint8Array | string;
|
|
4
4
|
export declare type PrivKey = Hex | bigint | number;
|
|
@@ -6,7 +6,9 @@ export declare type CHash = {
|
|
|
6
6
|
(message: Uint8Array | string): Uint8Array;
|
|
7
7
|
blockLen: number;
|
|
8
8
|
outputLen: number;
|
|
9
|
-
create(
|
|
9
|
+
create(opts?: {
|
|
10
|
+
dkLen?: number;
|
|
11
|
+
}): any;
|
|
10
12
|
};
|
|
11
13
|
export declare type BasicCurve<T> = {
|
|
12
14
|
Fp: mod.Field<T>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.bitMask = exports.bitSet = exports.bitGet = exports.bitLen = exports.equalBytes = exports.hashToPrivateScalar = exports.nLength = exports.concatBytes = exports.ensureBytes = exports.numberToBytesLE = exports.numberToBytesBE = exports.bytesToNumberLE = exports.bytesToNumberBE = exports.hexToBytes = exports.hexToNumber = exports.numberToHexUnpadded = exports.bytesToHex = exports.validateOpts = void 0;
|
|
4
|
-
/*!
|
|
4
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
5
5
|
const mod = require("./modular.js");
|
|
6
6
|
const _0n = BigInt(0);
|
|
7
7
|
const _1n = BigInt(1);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import * as mod from './modular.js';
|
|
3
3
|
import { Hex, PrivKey } from './utils.js';
|
|
4
4
|
import * as utils from './utils.js';
|
|
5
|
-
import { htfOpts } from './
|
|
5
|
+
import { htfOpts } from './hash-to-curve.js';
|
|
6
6
|
import { Group, GroupConstructor } from './group.js';
|
|
7
7
|
declare type HmacFnSync = (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
|
|
8
8
|
declare type EndomorphismOpts = {
|
|
@@ -19,8 +19,8 @@ export declare type BasicCurve<T> = utils.BasicCurve<T> & {
|
|
|
19
19
|
b: T;
|
|
20
20
|
normalizePrivateKey?: (key: PrivKey) => PrivKey;
|
|
21
21
|
endo?: EndomorphismOpts;
|
|
22
|
-
isTorsionFree?: (c:
|
|
23
|
-
clearCofactor?: (c:
|
|
22
|
+
isTorsionFree?: (c: ProjectiveConstructor<T>, point: ProjectivePointType<T>) => boolean;
|
|
23
|
+
clearCofactor?: (c: ProjectiveConstructor<T>, point: ProjectivePointType<T>) => ProjectivePointType<T>;
|
|
24
24
|
htfDefaults?: htfOpts;
|
|
25
25
|
mapToCurve?: (scalar: bigint[]) => {
|
|
26
26
|
x: T;
|
|
@@ -53,19 +53,19 @@ declare type SignOpts = {
|
|
|
53
53
|
*
|
|
54
54
|
* TODO: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol
|
|
55
55
|
*/
|
|
56
|
-
export interface
|
|
56
|
+
export interface ProjectivePointType<T> extends Group<ProjectivePointType<T>> {
|
|
57
57
|
readonly x: T;
|
|
58
58
|
readonly y: T;
|
|
59
59
|
readonly z: T;
|
|
60
|
-
multiply(scalar: number | bigint, affinePoint?: PointType<T>):
|
|
61
|
-
multiplyUnsafe(scalar: bigint):
|
|
60
|
+
multiply(scalar: number | bigint, affinePoint?: PointType<T>): ProjectivePointType<T>;
|
|
61
|
+
multiplyUnsafe(scalar: bigint): ProjectivePointType<T>;
|
|
62
62
|
toAffine(invZ?: T): PointType<T>;
|
|
63
63
|
}
|
|
64
|
-
export interface
|
|
65
|
-
new (x: T, y: T, z: T):
|
|
66
|
-
fromAffine(p: PointType<T>):
|
|
67
|
-
toAffineBatch(points:
|
|
68
|
-
normalizeZ(points:
|
|
64
|
+
export interface ProjectiveConstructor<T> extends GroupConstructor<ProjectivePointType<T>> {
|
|
65
|
+
new (x: T, y: T, z: T): ProjectivePointType<T>;
|
|
66
|
+
fromAffine(p: PointType<T>): ProjectivePointType<T>;
|
|
67
|
+
toAffineBatch(points: ProjectivePointType<T>[]): PointType<T>[];
|
|
68
|
+
normalizeZ(points: ProjectivePointType<T>[]): ProjectivePointType<T>[];
|
|
69
69
|
}
|
|
70
70
|
export interface PointType<T> extends Group<PointType<T>> {
|
|
71
71
|
readonly x: T;
|
|
@@ -93,14 +93,14 @@ export declare type CurvePointsType<T> = BasicCurve<T> & {
|
|
|
93
93
|
};
|
|
94
94
|
export declare type CurvePointsRes<T> = {
|
|
95
95
|
Point: PointConstructor<T>;
|
|
96
|
-
|
|
96
|
+
ProjectivePoint: ProjectiveConstructor<T>;
|
|
97
97
|
normalizePrivateKey: (key: PrivKey) => bigint;
|
|
98
98
|
weierstrassEquation: (x: T) => T;
|
|
99
99
|
isWithinCurveOrder: (num: bigint) => boolean;
|
|
100
100
|
};
|
|
101
101
|
export declare function weierstrassPoints<T>(opts: CurvePointsType<T>): {
|
|
102
102
|
Point: PointConstructor<T>;
|
|
103
|
-
|
|
103
|
+
ProjectivePoint: ProjectiveConstructor<T>;
|
|
104
104
|
normalizePrivateKey: (key: PrivKey) => bigint;
|
|
105
105
|
weierstrassEquation: (x: T) => T;
|
|
106
106
|
isWithinCurveOrder: (num: bigint) => boolean;
|
|
@@ -147,8 +147,8 @@ declare function validateOpts(curve: CurveType): Readonly<{
|
|
|
147
147
|
readonly b: bigint;
|
|
148
148
|
readonly normalizePrivateKey?: ((key: PrivKey) => PrivKey) | undefined;
|
|
149
149
|
readonly endo?: EndomorphismOpts | undefined;
|
|
150
|
-
readonly isTorsionFree?: ((c:
|
|
151
|
-
readonly clearCofactor?: ((c:
|
|
150
|
+
readonly isTorsionFree?: ((c: ProjectiveConstructor<bigint>, point: ProjectivePointType<bigint>) => boolean) | undefined;
|
|
151
|
+
readonly clearCofactor?: ((c: ProjectiveConstructor<bigint>, point: ProjectivePointType<bigint>) => ProjectivePointType<bigint>) | undefined;
|
|
152
152
|
readonly htfDefaults?: htfOpts | undefined;
|
|
153
153
|
readonly mapToCurve?: ((scalar: bigint[]) => {
|
|
154
154
|
x: bigint;
|
|
@@ -169,7 +169,7 @@ export declare type CurveFn = {
|
|
|
169
169
|
lowS?: boolean;
|
|
170
170
|
}) => boolean;
|
|
171
171
|
Point: PointConstructor<bigint>;
|
|
172
|
-
|
|
172
|
+
ProjectivePoint: ProjectiveConstructor<bigint>;
|
|
173
173
|
Signature: SignatureConstructor;
|
|
174
174
|
utils: {
|
|
175
175
|
mod: (a: bigint, b?: bigint) => bigint;
|
|
@@ -187,4 +187,16 @@ export declare type CurveFn = {
|
|
|
187
187
|
};
|
|
188
188
|
};
|
|
189
189
|
export declare function weierstrass(curveDef: CurveType): CurveFn;
|
|
190
|
+
export declare function SWUFpSqrtRatio<T>(Fp: mod.Field<T>, Z: T): (u: T, v: T) => {
|
|
191
|
+
isValid: boolean;
|
|
192
|
+
value: T;
|
|
193
|
+
};
|
|
194
|
+
export declare function mapToCurveSimpleSWU<T>(Fp: mod.Field<T>, opts: {
|
|
195
|
+
A: T;
|
|
196
|
+
B: T;
|
|
197
|
+
Z: T;
|
|
198
|
+
}): (u: T) => {
|
|
199
|
+
x: T;
|
|
200
|
+
y: T;
|
|
201
|
+
};
|
|
190
202
|
export {};
|