@bsv/sdk 1.6.18 → 1.6.20
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 +11 -11
- package/dist/cjs/package.json +5 -9
- package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js +39 -39
- package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
- package/dist/cjs/src/primitives/ECDSA.js +69 -167
- package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
- package/dist/cjs/src/primitives/Hash.js +660 -436
- package/dist/cjs/src/primitives/Hash.js.map +1 -1
- package/dist/cjs/src/primitives/Point.js +285 -293
- package/dist/cjs/src/primitives/Point.js.map +1 -1
- package/dist/cjs/src/script/ScriptEvaluationError.js +27 -0
- package/dist/cjs/src/script/ScriptEvaluationError.js.map +1 -0
- package/dist/cjs/src/script/Spend.js +13 -7
- package/dist/cjs/src/script/Spend.js.map +1 -1
- package/dist/cjs/src/script/index.js +3 -1
- package/dist/cjs/src/script/index.js.map +1 -1
- package/dist/cjs/src/transaction/Beef.js +4 -4
- package/dist/cjs/src/transaction/Transaction.js +3 -3
- package/dist/cjs/src/transaction/Transaction.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js +39 -39
- package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
- package/dist/esm/src/primitives/ECDSA.js +69 -167
- package/dist/esm/src/primitives/ECDSA.js.map +1 -1
- package/dist/esm/src/primitives/Hash.js +672 -444
- package/dist/esm/src/primitives/Hash.js.map +1 -1
- package/dist/esm/src/primitives/Point.js +268 -293
- package/dist/esm/src/primitives/Point.js.map +1 -1
- package/dist/esm/src/script/ScriptEvaluationError.js +33 -0
- package/dist/esm/src/script/ScriptEvaluationError.js.map +1 -0
- package/dist/esm/src/script/Spend.js +14 -8
- package/dist/esm/src/script/Spend.js.map +1 -1
- package/dist/esm/src/script/index.js +1 -0
- package/dist/esm/src/script/index.js.map +1 -1
- package/dist/esm/src/transaction/Beef.js +4 -4
- package/dist/esm/src/transaction/Transaction.js +3 -3
- package/dist/esm/src/transaction/Transaction.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/auth/transports/SimplifiedFetchTransport.d.ts +1 -1
- package/dist/types/src/auth/transports/SimplifiedFetchTransport.d.ts.map +1 -1
- package/dist/types/src/primitives/ECDSA.d.ts.map +1 -1
- package/dist/types/src/primitives/Hash.d.ts +12 -19
- package/dist/types/src/primitives/Hash.d.ts.map +1 -1
- package/dist/types/src/primitives/Point.d.ts +37 -5
- package/dist/types/src/primitives/Point.d.ts.map +1 -1
- package/dist/types/src/script/ScriptEvaluationError.d.ts +24 -0
- package/dist/types/src/script/ScriptEvaluationError.d.ts.map +1 -0
- package/dist/types/src/script/Spend.d.ts.map +1 -1
- package/dist/types/src/script/index.d.ts +1 -0
- package/dist/types/src/script/index.d.ts.map +1 -1
- package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +20 -1
- package/dist/umd/bundle.js.map +1 -0
- package/package.json +5 -9
- package/src/auth/transports/SimplifiedFetchTransport.ts +64 -67
- package/src/primitives/ECDSA.ts +80 -222
- package/src/primitives/Hash.ts +752 -589
- package/src/primitives/Point.ts +277 -336
- package/src/script/ScriptEvaluationError.ts +44 -0
- package/src/script/Spend.ts +14 -12
- package/src/script/index.ts +1 -0
- package/src/transaction/Beef.ts +4 -4
- package/src/transaction/Transaction.ts +11 -3
|
@@ -3,11 +3,216 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.modInvN = exports.modMulN = exports.modN = exports.scalarMultiplyWNAF = exports.jpNeg = exports.jpAdd = exports.jpDouble = exports.GY_BIGINT = exports.GX_BIGINT = exports.biModSqrt = exports.P_PLUS1_DIV4 = exports.biModPow = exports.biModSqr = exports.biModInv = exports.biModAdd = exports.biModMul = exports.biModSub = exports.biMod = exports.red = exports.MASK_256 = exports.N_BIGINT = exports.P_BIGINT = exports.BI_EIGHT = exports.BI_FOUR = exports.BI_THREE = exports.BI_TWO = exports.BI_ONE = exports.BI_ZERO = void 0;
|
|
6
7
|
const BasePoint_js_1 = __importDefault(require("./BasePoint.js"));
|
|
7
8
|
const JacobianPoint_js_1 = __importDefault(require("./JacobianPoint.js"));
|
|
8
9
|
const BigNumber_js_1 = __importDefault(require("./BigNumber.js"));
|
|
9
10
|
const utils_js_1 = require("./utils.js");
|
|
10
|
-
|
|
11
|
+
// -----------------------------------------------------------------------------
|
|
12
|
+
// BigInt helpers & constants (secp256k1) – hoisted so we don't recreate them on
|
|
13
|
+
// every Point.mul() call.
|
|
14
|
+
// -----------------------------------------------------------------------------
|
|
15
|
+
exports.BI_ZERO = 0n;
|
|
16
|
+
exports.BI_ONE = 1n;
|
|
17
|
+
exports.BI_TWO = 2n;
|
|
18
|
+
exports.BI_THREE = 3n;
|
|
19
|
+
exports.BI_FOUR = 4n;
|
|
20
|
+
exports.BI_EIGHT = 8n;
|
|
21
|
+
exports.P_BIGINT = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn;
|
|
22
|
+
exports.N_BIGINT = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n;
|
|
23
|
+
exports.MASK_256 = (1n << 256n) - 1n; // 0xffff…ffff (256 sones)
|
|
24
|
+
function red(x) {
|
|
25
|
+
// first fold
|
|
26
|
+
let hi = x >> 256n;
|
|
27
|
+
x = (x & exports.MASK_256) + (hi << 32n) + hi * 977n;
|
|
28
|
+
// second fold (hi ≤ 2³² + 977 here, so one more pass is enough)
|
|
29
|
+
hi = x >> 256n;
|
|
30
|
+
x = (x & exports.MASK_256) + (hi << 32n) + hi * 977n;
|
|
31
|
+
// final conditional subtraction
|
|
32
|
+
if (x >= exports.P_BIGINT)
|
|
33
|
+
x -= exports.P_BIGINT;
|
|
34
|
+
return x;
|
|
35
|
+
}
|
|
36
|
+
exports.red = red;
|
|
37
|
+
const biMod = (a) => red((a % exports.P_BIGINT + exports.P_BIGINT) % exports.P_BIGINT);
|
|
38
|
+
exports.biMod = biMod;
|
|
39
|
+
const biModSub = (a, b) => (a >= b ? a - b : exports.P_BIGINT - (b - a));
|
|
40
|
+
exports.biModSub = biModSub;
|
|
41
|
+
const biModMul = (a, b) => red(a * b);
|
|
42
|
+
exports.biModMul = biModMul;
|
|
43
|
+
const biModAdd = (a, b) => red(a + b);
|
|
44
|
+
exports.biModAdd = biModAdd;
|
|
45
|
+
const biModInv = (a) => {
|
|
46
|
+
let lm = exports.BI_ONE;
|
|
47
|
+
let hm = exports.BI_ZERO;
|
|
48
|
+
let low = (0, exports.biMod)(a);
|
|
49
|
+
let high = exports.P_BIGINT;
|
|
50
|
+
while (low > exports.BI_ONE) {
|
|
51
|
+
const r = high / low;
|
|
52
|
+
[lm, hm] = [hm - lm * r, lm];
|
|
53
|
+
[low, high] = [high - low * r, low];
|
|
54
|
+
}
|
|
55
|
+
return (0, exports.biMod)(lm);
|
|
56
|
+
};
|
|
57
|
+
exports.biModInv = biModInv;
|
|
58
|
+
const biModSqr = (a) => (0, exports.biModMul)(a, a);
|
|
59
|
+
exports.biModSqr = biModSqr;
|
|
60
|
+
const biModPow = (base, exp) => {
|
|
61
|
+
let result = exports.BI_ONE;
|
|
62
|
+
base = (0, exports.biMod)(base);
|
|
63
|
+
let e = exp;
|
|
64
|
+
while (e > exports.BI_ZERO) {
|
|
65
|
+
if ((e & exports.BI_ONE) === exports.BI_ONE)
|
|
66
|
+
result = (0, exports.biModMul)(result, base);
|
|
67
|
+
base = (0, exports.biModMul)(base, base);
|
|
68
|
+
e >>= exports.BI_ONE;
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
};
|
|
72
|
+
exports.biModPow = biModPow;
|
|
73
|
+
exports.P_PLUS1_DIV4 = (exports.P_BIGINT + 1n) >> 2n;
|
|
74
|
+
const biModSqrt = (a) => {
|
|
75
|
+
const r = (0, exports.biModPow)(a, exports.P_PLUS1_DIV4);
|
|
76
|
+
return (0, exports.biModMul)(r, r) === (0, exports.biMod)(a) ? r : null;
|
|
77
|
+
};
|
|
78
|
+
exports.biModSqrt = biModSqrt;
|
|
79
|
+
const toBigInt = (x) => {
|
|
80
|
+
if (BigNumber_js_1.default.isBN(x))
|
|
81
|
+
return BigInt('0x' + x.toString(16));
|
|
82
|
+
if (typeof x === 'string')
|
|
83
|
+
return BigInt('0x' + x);
|
|
84
|
+
if (Array.isArray(x))
|
|
85
|
+
return BigInt('0x' + (0, utils_js_1.toHex)(x));
|
|
86
|
+
return BigInt(x);
|
|
87
|
+
};
|
|
88
|
+
// Generator point coordinates as bigint constants
|
|
89
|
+
exports.GX_BIGINT = BigInt('0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798');
|
|
90
|
+
exports.GY_BIGINT = BigInt('0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8');
|
|
91
|
+
// Cache for precomputed windowed tables keyed by 'window:x:y'
|
|
92
|
+
const WNAF_TABLE_CACHE = new Map();
|
|
93
|
+
const jpDouble = (P) => {
|
|
94
|
+
const { X: X1, Y: Y1, Z: Z1 } = P;
|
|
95
|
+
if (Y1 === exports.BI_ZERO)
|
|
96
|
+
return { X: exports.BI_ZERO, Y: exports.BI_ONE, Z: exports.BI_ZERO };
|
|
97
|
+
const Y1sq = (0, exports.biModMul)(Y1, Y1);
|
|
98
|
+
const S = (0, exports.biModMul)(exports.BI_FOUR, (0, exports.biModMul)(X1, Y1sq));
|
|
99
|
+
const M = (0, exports.biModMul)(exports.BI_THREE, (0, exports.biModMul)(X1, X1));
|
|
100
|
+
const X3 = (0, exports.biModSub)((0, exports.biModMul)(M, M), (0, exports.biModMul)(exports.BI_TWO, S));
|
|
101
|
+
const Y3 = (0, exports.biModSub)((0, exports.biModMul)(M, (0, exports.biModSub)(S, X3)), (0, exports.biModMul)(exports.BI_EIGHT, (0, exports.biModMul)(Y1sq, Y1sq)));
|
|
102
|
+
const Z3 = (0, exports.biModMul)(exports.BI_TWO, (0, exports.biModMul)(Y1, Z1));
|
|
103
|
+
return { X: X3, Y: Y3, Z: Z3 };
|
|
104
|
+
};
|
|
105
|
+
exports.jpDouble = jpDouble;
|
|
106
|
+
const jpAdd = (P, Q) => {
|
|
107
|
+
if (P.Z === exports.BI_ZERO)
|
|
108
|
+
return Q;
|
|
109
|
+
if (Q.Z === exports.BI_ZERO)
|
|
110
|
+
return P;
|
|
111
|
+
const Z1Z1 = (0, exports.biModMul)(P.Z, P.Z);
|
|
112
|
+
const Z2Z2 = (0, exports.biModMul)(Q.Z, Q.Z);
|
|
113
|
+
const U1 = (0, exports.biModMul)(P.X, Z2Z2);
|
|
114
|
+
const U2 = (0, exports.biModMul)(Q.X, Z1Z1);
|
|
115
|
+
const S1 = (0, exports.biModMul)(P.Y, (0, exports.biModMul)(Z2Z2, Q.Z));
|
|
116
|
+
const S2 = (0, exports.biModMul)(Q.Y, (0, exports.biModMul)(Z1Z1, P.Z));
|
|
117
|
+
const H = (0, exports.biModSub)(U2, U1);
|
|
118
|
+
const r = (0, exports.biModSub)(S2, S1);
|
|
119
|
+
if (H === exports.BI_ZERO) {
|
|
120
|
+
if (r === exports.BI_ZERO)
|
|
121
|
+
return (0, exports.jpDouble)(P);
|
|
122
|
+
return { X: exports.BI_ZERO, Y: exports.BI_ONE, Z: exports.BI_ZERO }; // Infinity
|
|
123
|
+
}
|
|
124
|
+
const HH = (0, exports.biModMul)(H, H);
|
|
125
|
+
const HHH = (0, exports.biModMul)(H, HH);
|
|
126
|
+
const V = (0, exports.biModMul)(U1, HH);
|
|
127
|
+
const X3 = (0, exports.biModSub)((0, exports.biModSub)((0, exports.biModMul)(r, r), HHH), (0, exports.biModMul)(exports.BI_TWO, V));
|
|
128
|
+
const Y3 = (0, exports.biModSub)((0, exports.biModMul)(r, (0, exports.biModSub)(V, X3)), (0, exports.biModMul)(S1, HHH));
|
|
129
|
+
const Z3 = (0, exports.biModMul)(H, (0, exports.biModMul)(P.Z, Q.Z));
|
|
130
|
+
return { X: X3, Y: Y3, Z: Z3 };
|
|
131
|
+
};
|
|
132
|
+
exports.jpAdd = jpAdd;
|
|
133
|
+
const jpNeg = (P) => {
|
|
134
|
+
if (P.Z === exports.BI_ZERO)
|
|
135
|
+
return P;
|
|
136
|
+
return { X: P.X, Y: exports.P_BIGINT - P.Y, Z: P.Z };
|
|
137
|
+
};
|
|
138
|
+
exports.jpNeg = jpNeg;
|
|
139
|
+
// Fast windowed-NAF scalar multiplication (default window = 5) in Jacobian
|
|
140
|
+
// coordinates. Returns Q = k * P0 as a JacobianPoint.
|
|
141
|
+
const scalarMultiplyWNAF = (k, P0, window = 5) => {
|
|
142
|
+
const key = `${window}:${P0.x.toString(16)}:${P0.y.toString(16)}`;
|
|
143
|
+
let tbl = WNAF_TABLE_CACHE.get(key);
|
|
144
|
+
let P;
|
|
145
|
+
if (tbl === undefined) {
|
|
146
|
+
// Convert affine to Jacobian and pre-compute odd multiples
|
|
147
|
+
const tblSize = 1 << (window - 1); // e.g. w=5 → 16 entries
|
|
148
|
+
tbl = new Array(tblSize);
|
|
149
|
+
P = { X: P0.x, Y: P0.y, Z: exports.BI_ONE };
|
|
150
|
+
tbl[0] = P;
|
|
151
|
+
const twoP = (0, exports.jpDouble)(P);
|
|
152
|
+
for (let i = 1; i < tblSize; i++) {
|
|
153
|
+
tbl[i] = (0, exports.jpAdd)(tbl[i - 1], twoP);
|
|
154
|
+
}
|
|
155
|
+
WNAF_TABLE_CACHE.set(key, tbl);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
P = tbl[0];
|
|
159
|
+
}
|
|
160
|
+
// Build wNAF representation of k
|
|
161
|
+
const wnaf = [];
|
|
162
|
+
const wBig = 1n << BigInt(window);
|
|
163
|
+
const wHalf = wBig >> 1n;
|
|
164
|
+
let kTmp = k;
|
|
165
|
+
while (kTmp > 0n) {
|
|
166
|
+
if ((kTmp & exports.BI_ONE) === exports.BI_ZERO) {
|
|
167
|
+
wnaf.push(0);
|
|
168
|
+
kTmp >>= exports.BI_ONE;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
let z = kTmp & (wBig - 1n); // kTmp mod 2^w
|
|
172
|
+
if (z > wHalf)
|
|
173
|
+
z -= wBig; // make it odd & within (-2^{w-1}, 2^{w-1})
|
|
174
|
+
wnaf.push(Number(z));
|
|
175
|
+
kTmp -= z;
|
|
176
|
+
kTmp >>= exports.BI_ONE;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Accumulate from MSB to LSB
|
|
180
|
+
let Q = { X: exports.BI_ZERO, Y: exports.BI_ONE, Z: exports.BI_ZERO }; // infinity
|
|
181
|
+
for (let i = wnaf.length - 1; i >= 0; i--) {
|
|
182
|
+
Q = (0, exports.jpDouble)(Q);
|
|
183
|
+
const di = wnaf[i];
|
|
184
|
+
if (di !== 0) {
|
|
185
|
+
const idx = Math.abs(di) >> 1; // (|di|-1)/2 because di is odd
|
|
186
|
+
const addend = di > 0 ? tbl[idx] : (0, exports.jpNeg)(tbl[idx]);
|
|
187
|
+
Q = (0, exports.jpAdd)(Q, addend);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return Q;
|
|
191
|
+
};
|
|
192
|
+
exports.scalarMultiplyWNAF = scalarMultiplyWNAF;
|
|
193
|
+
const modN = (a) => {
|
|
194
|
+
let r = a % exports.N_BIGINT;
|
|
195
|
+
if (r < 0n)
|
|
196
|
+
r += exports.N_BIGINT;
|
|
197
|
+
return r;
|
|
198
|
+
};
|
|
199
|
+
exports.modN = modN;
|
|
200
|
+
const modMulN = (a, b) => (0, exports.modN)(a * b);
|
|
201
|
+
exports.modMulN = modMulN;
|
|
202
|
+
/** modular inverse modulo n with plain extended‑gcd (not constant‑time) */
|
|
203
|
+
const modInvN = (a) => {
|
|
204
|
+
let lm = 1n;
|
|
205
|
+
let hm = 0n;
|
|
206
|
+
let low = (0, exports.modN)(a);
|
|
207
|
+
let high = exports.N_BIGINT;
|
|
208
|
+
while (low > 1n) {
|
|
209
|
+
const q = high / low;
|
|
210
|
+
[lm, hm] = [hm - lm * q, lm];
|
|
211
|
+
[low, high] = [high - low * q, low];
|
|
212
|
+
}
|
|
213
|
+
return (0, exports.modN)(lm);
|
|
214
|
+
};
|
|
215
|
+
exports.modInvN = modInvN;
|
|
11
216
|
/**
|
|
12
217
|
* `Point` class is a representation of an elliptic curve point with affine coordinates.
|
|
13
218
|
* It extends the functionality of BasePoint and carries x, y coordinates of point on the curve.
|
|
@@ -82,12 +287,6 @@ class Point extends BasePoint_js_1.default {
|
|
|
82
287
|
const bytes = (0, utils_js_1.toArray)(str, 'hex');
|
|
83
288
|
return Point.fromDER(bytes);
|
|
84
289
|
}
|
|
85
|
-
static redSqrtOptimized(y2) {
|
|
86
|
-
const red = Point.red;
|
|
87
|
-
const p = red.m; // The modulus
|
|
88
|
-
const exponent = p.addn(1).iushrn(2); // (p + 1) / 4
|
|
89
|
-
return y2.redPow(exponent);
|
|
90
|
-
}
|
|
91
290
|
/**
|
|
92
291
|
* Generates a point from an x coordinate and a boolean indicating whether the corresponding
|
|
93
292
|
* y coordinate is odd.
|
|
@@ -104,62 +303,18 @@ class Point extends BasePoint_js_1.default {
|
|
|
104
303
|
* const point = Point.fromX(xCoordinate, true);
|
|
105
304
|
*/
|
|
106
305
|
static fromX(x, odd) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
base = mod(base, modulus);
|
|
113
|
-
while (exponent > BigInt(0)) {
|
|
114
|
-
if ((exponent & BigInt(1)) === BigInt(1)) {
|
|
115
|
-
result = mod(result * base, modulus);
|
|
116
|
-
}
|
|
117
|
-
exponent >>= BigInt(1);
|
|
118
|
-
base = mod(base * base, modulus);
|
|
119
|
-
}
|
|
120
|
-
return result;
|
|
121
|
-
}
|
|
122
|
-
function sqrtMod(a, p) {
|
|
123
|
-
const exponent = (p + BigInt(1)) >> BigInt(2);
|
|
124
|
-
const sqrtCandidate = modPow(a, exponent, p);
|
|
125
|
-
if (mod(sqrtCandidate * sqrtCandidate, p) === mod(a, p)) {
|
|
126
|
-
return sqrtCandidate;
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
return null;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
// Curve parameters for secp256k1
|
|
133
|
-
const p = BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F');
|
|
134
|
-
const b = BigInt(7);
|
|
135
|
-
let xBigInt;
|
|
136
|
-
if (x instanceof BigNumber_js_1.default) {
|
|
137
|
-
xBigInt = BigInt('0x' + x.toString(16));
|
|
138
|
-
}
|
|
139
|
-
else if (typeof x === 'string') {
|
|
140
|
-
xBigInt = BigInt('0x' + x);
|
|
141
|
-
}
|
|
142
|
-
else if (Array.isArray(x)) {
|
|
143
|
-
xBigInt = BigInt('0x' + (0, utils_js_1.toHex)(x).padStart(64, '0'));
|
|
144
|
-
}
|
|
145
|
-
else if (typeof x === 'number') {
|
|
146
|
-
xBigInt = BigInt(x);
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
throw new Error('Invalid x-coordinate type');
|
|
150
|
-
}
|
|
151
|
-
xBigInt = mod(xBigInt, p);
|
|
152
|
-
const y2 = mod(modPow(xBigInt, BigInt(3), p) + b, p);
|
|
153
|
-
let y = sqrtMod(y2, p);
|
|
154
|
-
if (y === null) {
|
|
306
|
+
let xBigInt = toBigInt(x);
|
|
307
|
+
xBigInt = (0, exports.biMod)(xBigInt);
|
|
308
|
+
const y2 = (0, exports.biModAdd)((0, exports.biModMul)((0, exports.biModSqr)(xBigInt), xBigInt), 7n);
|
|
309
|
+
const y = (0, exports.biModSqrt)(y2);
|
|
310
|
+
if (y === null)
|
|
155
311
|
throw new Error('Invalid point');
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
y = p - y;
|
|
312
|
+
let yBig = y;
|
|
313
|
+
if ((yBig & exports.BI_ONE) !== (odd ? exports.BI_ONE : exports.BI_ZERO)) {
|
|
314
|
+
yBig = (0, exports.biModSub)(exports.P_BIGINT, yBig);
|
|
160
315
|
}
|
|
161
316
|
const xBN = new BigNumber_js_1.default(xBigInt.toString(16), 16);
|
|
162
|
-
const yBN = new BigNumber_js_1.default(
|
|
317
|
+
const yBN = new BigNumber_js_1.default(yBig.toString(16), 16);
|
|
163
318
|
return new Point(xBN, yBN);
|
|
164
319
|
}
|
|
165
320
|
/**
|
|
@@ -401,21 +556,30 @@ class Point extends BasePoint_js_1.default {
|
|
|
401
556
|
}
|
|
402
557
|
// P + (-P) = O
|
|
403
558
|
if (this.neg().eq(p)) {
|
|
404
|
-
return new Point(
|
|
559
|
+
return new Point(null, null);
|
|
405
560
|
}
|
|
406
561
|
// P + Q = O
|
|
407
562
|
if (this.x?.cmp(p.x ?? new BigNumber_js_1.default(0)) === 0) {
|
|
408
|
-
return new Point(
|
|
409
|
-
}
|
|
410
|
-
let c = this.y?.redSub(p.y ?? new BigNumber_js_1.default(0)) ?? new BigNumber_js_1.default(0);
|
|
411
|
-
if (c.cmpn(0) !== 0) {
|
|
412
|
-
c = c.redMul(this.x?.redSub(p.x ?? new BigNumber_js_1.default(0)).redInvm() ?? new BigNumber_js_1.default(1));
|
|
563
|
+
return new Point(null, null);
|
|
413
564
|
}
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
565
|
+
const P1 = {
|
|
566
|
+
X: BigInt('0x' + this.x.fromRed().toString(16)),
|
|
567
|
+
Y: BigInt('0x' + this.y.fromRed().toString(16)),
|
|
568
|
+
Z: exports.BI_ONE
|
|
569
|
+
};
|
|
570
|
+
const Q1 = {
|
|
571
|
+
X: BigInt('0x' + p.x.fromRed().toString(16)),
|
|
572
|
+
Y: BigInt('0x' + p.y.fromRed().toString(16)),
|
|
573
|
+
Z: exports.BI_ONE
|
|
574
|
+
};
|
|
575
|
+
const R = (0, exports.jpAdd)(P1, Q1);
|
|
576
|
+
if (R.Z === exports.BI_ZERO)
|
|
577
|
+
return new Point(null, null);
|
|
578
|
+
const zInv = (0, exports.biModInv)(R.Z);
|
|
579
|
+
const zInv2 = (0, exports.biModMul)(zInv, zInv);
|
|
580
|
+
const xRes = (0, exports.biModMul)(R.X, zInv2);
|
|
581
|
+
const yRes = (0, exports.biModMul)(R.Y, (0, exports.biModMul)(zInv2, zInv));
|
|
582
|
+
return new Point(xRes.toString(16), yRes.toString(16));
|
|
419
583
|
}
|
|
420
584
|
/**
|
|
421
585
|
* Doubles the current point.
|
|
@@ -427,21 +591,21 @@ class Point extends BasePoint_js_1.default {
|
|
|
427
591
|
* const result = P.dbl();
|
|
428
592
|
* */
|
|
429
593
|
dbl() {
|
|
430
|
-
if (this.inf)
|
|
594
|
+
if (this.inf)
|
|
431
595
|
return this;
|
|
596
|
+
if (this.x === null || this.y === null) {
|
|
597
|
+
throw new Error('Point coordinates cannot be null');
|
|
432
598
|
}
|
|
433
|
-
|
|
434
|
-
const
|
|
435
|
-
if (
|
|
436
|
-
return new Point(
|
|
437
|
-
}
|
|
438
|
-
const
|
|
439
|
-
const
|
|
440
|
-
const
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
const ny = c.redMul((this.x ?? new BigNumber_js_1.default(0)).redSub(nx)).redISub(this.y ?? new BigNumber_js_1.default(0));
|
|
444
|
-
return new Point(nx, ny);
|
|
599
|
+
const X = BigInt('0x' + this.x.fromRed().toString(16));
|
|
600
|
+
const Y = BigInt('0x' + this.y.fromRed().toString(16));
|
|
601
|
+
if (Y === exports.BI_ZERO)
|
|
602
|
+
return new Point(null, null);
|
|
603
|
+
const R = (0, exports.jpDouble)({ X, Y, Z: exports.BI_ONE });
|
|
604
|
+
const zInv = (0, exports.biModInv)(R.Z);
|
|
605
|
+
const zInv2 = (0, exports.biModMul)(zInv, zInv);
|
|
606
|
+
const xRes = (0, exports.biModMul)(R.X, zInv2);
|
|
607
|
+
const yRes = (0, exports.biModMul)(R.Y, (0, exports.biModMul)(zInv2, zInv));
|
|
608
|
+
return new Point(xRes.toString(16), yRes.toString(16));
|
|
445
609
|
}
|
|
446
610
|
/**
|
|
447
611
|
* Returns X coordinate of point
|
|
@@ -479,86 +643,45 @@ class Point extends BasePoint_js_1.default {
|
|
|
479
643
|
k = new BigNumber_js_1.default(k, 16);
|
|
480
644
|
}
|
|
481
645
|
k = k;
|
|
482
|
-
if (
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
let Px;
|
|
502
|
-
let Py;
|
|
503
|
-
if (this === this.curve.g) {
|
|
504
|
-
Px = GX_BIGINT;
|
|
505
|
-
Py = GY_BIGINT;
|
|
506
|
-
}
|
|
507
|
-
else {
|
|
508
|
-
Px = BigInt('0x' + this.x.fromRed().toString(16));
|
|
509
|
-
Py = BigInt('0x' + this.y.fromRed().toString(16));
|
|
510
|
-
}
|
|
511
|
-
const mod = (a, m) => ((a % m) + m) % m;
|
|
512
|
-
const modMul = (a, b, m) => mod(a * b, m);
|
|
513
|
-
const modInv = (a, m) => {
|
|
514
|
-
let lm = one;
|
|
515
|
-
let hm = zero;
|
|
516
|
-
let low = mod(a, m);
|
|
517
|
-
let high = m;
|
|
518
|
-
while (low > one) {
|
|
519
|
-
const r = high / low;
|
|
520
|
-
const nm = hm - lm * r;
|
|
521
|
-
const neww = high - low * r;
|
|
522
|
-
hm = lm;
|
|
523
|
-
lm = nm;
|
|
524
|
-
high = low;
|
|
525
|
-
low = neww;
|
|
526
|
-
}
|
|
527
|
-
return mod(lm, m);
|
|
528
|
-
};
|
|
529
|
-
const scalarMultiply = (kVal, P0) => {
|
|
530
|
-
// Delegate to the hoisted windowed-NAF implementation above. We
|
|
531
|
-
// keep the wrapper so that the rest of the mul() code remains
|
|
532
|
-
// untouched while providing a massive speed-up (≈4-6×).
|
|
533
|
-
return scalarMultiplyWNAF(kVal, P0);
|
|
534
|
-
};
|
|
535
|
-
const R = scalarMultiply(kBig, { x: Px, y: Py });
|
|
536
|
-
if (R.Z === zero) {
|
|
537
|
-
return new Point(null, null);
|
|
538
|
-
}
|
|
539
|
-
const zInv = modInv(R.Z, p);
|
|
540
|
-
const zInv2 = modMul(zInv, zInv, p);
|
|
541
|
-
const xRes = modMul(R.X, zInv2, p);
|
|
542
|
-
const yRes = modMul(R.Y, modMul(zInv2, zInv, p), p);
|
|
543
|
-
const xBN = new BigNumber_js_1.default(xRes.toString(16), 16);
|
|
544
|
-
const yBN = new BigNumber_js_1.default(yRes.toString(16), 16);
|
|
545
|
-
const result = new Point(xBN, yBN);
|
|
546
|
-
if (isNeg) {
|
|
547
|
-
return result.neg();
|
|
548
|
-
}
|
|
549
|
-
return result;
|
|
646
|
+
if (this.inf) {
|
|
647
|
+
return this;
|
|
648
|
+
}
|
|
649
|
+
let kBig = BigInt('0x' + k.toString(16));
|
|
650
|
+
const isNeg = kBig < exports.BI_ZERO;
|
|
651
|
+
if (isNeg)
|
|
652
|
+
kBig = -kBig;
|
|
653
|
+
kBig = (0, exports.biMod)(kBig);
|
|
654
|
+
if (kBig === exports.BI_ZERO) {
|
|
655
|
+
return new Point(null, null);
|
|
656
|
+
}
|
|
657
|
+
if (this.x === null || this.y === null) {
|
|
658
|
+
throw new Error('Point coordinates cannot be null');
|
|
659
|
+
}
|
|
660
|
+
let Px;
|
|
661
|
+
let Py;
|
|
662
|
+
if (this === this.curve.g) {
|
|
663
|
+
Px = exports.GX_BIGINT;
|
|
664
|
+
Py = exports.GY_BIGINT;
|
|
550
665
|
}
|
|
551
666
|
else {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
else {
|
|
559
|
-
return this._endoWnafMulAdd([this], [k]);
|
|
560
|
-
}
|
|
667
|
+
Px = BigInt('0x' + this.x.fromRed().toString(16));
|
|
668
|
+
Py = BigInt('0x' + this.y.fromRed().toString(16));
|
|
669
|
+
}
|
|
670
|
+
const R = (0, exports.scalarMultiplyWNAF)(kBig, { x: Px, y: Py });
|
|
671
|
+
if (R.Z === exports.BI_ZERO) {
|
|
672
|
+
return new Point(null, null);
|
|
561
673
|
}
|
|
674
|
+
const zInv = (0, exports.biModInv)(R.Z);
|
|
675
|
+
const zInv2 = (0, exports.biModMul)(zInv, zInv);
|
|
676
|
+
const xRes = (0, exports.biModMul)(R.X, zInv2);
|
|
677
|
+
const yRes = (0, exports.biModMul)(R.Y, (0, exports.biModMul)(zInv2, zInv));
|
|
678
|
+
const xBN = new BigNumber_js_1.default(xRes.toString(16), 16);
|
|
679
|
+
const yBN = new BigNumber_js_1.default(yRes.toString(16), 16);
|
|
680
|
+
const result = new Point(xBN, yBN);
|
|
681
|
+
if (isNeg) {
|
|
682
|
+
return result.neg();
|
|
683
|
+
}
|
|
684
|
+
return result;
|
|
562
685
|
}
|
|
563
686
|
/**
|
|
564
687
|
* Performs a multiplication and addition operation in a single step.
|
|
@@ -892,7 +1015,7 @@ class Point extends BasePoint_js_1.default {
|
|
|
892
1015
|
for (i = 0; i < points.length; i++) {
|
|
893
1016
|
const split = this.curve._endoSplit(coeffs[i]);
|
|
894
1017
|
let p = points[i];
|
|
895
|
-
let beta = p._getBeta() ?? new Point(
|
|
1018
|
+
let beta = p._getBeta() ?? new Point(null, null);
|
|
896
1019
|
if (split.k1.negative !== 0) {
|
|
897
1020
|
split.k1.ineg();
|
|
898
1021
|
p = p.neg(true);
|
|
@@ -966,136 +1089,5 @@ class Point extends BasePoint_js_1.default {
|
|
|
966
1089
|
};
|
|
967
1090
|
}
|
|
968
1091
|
}
|
|
969
|
-
Point.red = new ReductionContext_js_1.default('k256');
|
|
970
|
-
Point.a = new BigNumber_js_1.default(0).toRed(Point.red);
|
|
971
|
-
Point.b = new BigNumber_js_1.default(7).toRed(Point.red);
|
|
972
|
-
Point.zero = new BigNumber_js_1.default(0).toRed(Point.red);
|
|
973
1092
|
exports.default = Point;
|
|
974
|
-
// -----------------------------------------------------------------------------
|
|
975
|
-
// BigInt helpers & constants (secp256k1) – hoisted so we don't recreate them on
|
|
976
|
-
// every Point.mul() call.
|
|
977
|
-
// -----------------------------------------------------------------------------
|
|
978
|
-
const BI_ZERO = 0n;
|
|
979
|
-
const BI_ONE = 1n;
|
|
980
|
-
const BI_TWO = 2n;
|
|
981
|
-
const BI_THREE = 3n;
|
|
982
|
-
const BI_FOUR = 4n;
|
|
983
|
-
const BI_EIGHT = 8n;
|
|
984
|
-
const P_BIGINT = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn;
|
|
985
|
-
const MASK_256 = (1n << 256n) - 1n; // 0xffff…ffff (256 sones)
|
|
986
|
-
function red(x) {
|
|
987
|
-
// first fold
|
|
988
|
-
let hi = x >> 256n;
|
|
989
|
-
x = (x & MASK_256) + (hi << 32n) + hi * 977n;
|
|
990
|
-
// second fold (hi ≤ 2³² + 977 here, so one more pass is enough)
|
|
991
|
-
hi = x >> 256n;
|
|
992
|
-
x = (x & MASK_256) + (hi << 32n) + hi * 977n;
|
|
993
|
-
// final conditional subtraction
|
|
994
|
-
if (x >= P_BIGINT)
|
|
995
|
-
x -= P_BIGINT;
|
|
996
|
-
return x;
|
|
997
|
-
}
|
|
998
|
-
const biModSub = (a, b) => (a >= b ? a - b : P_BIGINT - (b - a));
|
|
999
|
-
const biModMul = (a, b) => red(a * b);
|
|
1000
|
-
// Generator point coordinates as bigint constants
|
|
1001
|
-
const GX_BIGINT = BigInt('0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798');
|
|
1002
|
-
const GY_BIGINT = BigInt('0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8');
|
|
1003
|
-
// Cache for precomputed windowed tables keyed by 'window:x:y'
|
|
1004
|
-
const WNAF_TABLE_CACHE = new Map();
|
|
1005
|
-
const jpDouble = (P) => {
|
|
1006
|
-
const { X: X1, Y: Y1, Z: Z1 } = P;
|
|
1007
|
-
if (Y1 === BI_ZERO)
|
|
1008
|
-
return { X: BI_ZERO, Y: BI_ONE, Z: BI_ZERO };
|
|
1009
|
-
const Y1sq = biModMul(Y1, Y1);
|
|
1010
|
-
const S = biModMul(BI_FOUR, biModMul(X1, Y1sq));
|
|
1011
|
-
const M = biModMul(BI_THREE, biModMul(X1, X1));
|
|
1012
|
-
const X3 = biModSub(biModMul(M, M), biModMul(BI_TWO, S));
|
|
1013
|
-
const Y3 = biModSub(biModMul(M, biModSub(S, X3)), biModMul(BI_EIGHT, biModMul(Y1sq, Y1sq)));
|
|
1014
|
-
const Z3 = biModMul(BI_TWO, biModMul(Y1, Z1));
|
|
1015
|
-
return { X: X3, Y: Y3, Z: Z3 };
|
|
1016
|
-
};
|
|
1017
|
-
const jpAdd = (P, Q) => {
|
|
1018
|
-
if (P.Z === BI_ZERO)
|
|
1019
|
-
return Q;
|
|
1020
|
-
if (Q.Z === BI_ZERO)
|
|
1021
|
-
return P;
|
|
1022
|
-
const Z1Z1 = biModMul(P.Z, P.Z);
|
|
1023
|
-
const Z2Z2 = biModMul(Q.Z, Q.Z);
|
|
1024
|
-
const U1 = biModMul(P.X, Z2Z2);
|
|
1025
|
-
const U2 = biModMul(Q.X, Z1Z1);
|
|
1026
|
-
const S1 = biModMul(P.Y, biModMul(Z2Z2, Q.Z));
|
|
1027
|
-
const S2 = biModMul(Q.Y, biModMul(Z1Z1, P.Z));
|
|
1028
|
-
const H = biModSub(U2, U1);
|
|
1029
|
-
const r = biModSub(S2, S1);
|
|
1030
|
-
if (H === BI_ZERO) {
|
|
1031
|
-
if (r === BI_ZERO)
|
|
1032
|
-
return jpDouble(P);
|
|
1033
|
-
return { X: BI_ZERO, Y: BI_ONE, Z: BI_ZERO }; // Infinity
|
|
1034
|
-
}
|
|
1035
|
-
const HH = biModMul(H, H);
|
|
1036
|
-
const HHH = biModMul(H, HH);
|
|
1037
|
-
const V = biModMul(U1, HH);
|
|
1038
|
-
const X3 = biModSub(biModSub(biModMul(r, r), HHH), biModMul(BI_TWO, V));
|
|
1039
|
-
const Y3 = biModSub(biModMul(r, biModSub(V, X3)), biModMul(S1, HHH));
|
|
1040
|
-
const Z3 = biModMul(H, biModMul(P.Z, Q.Z));
|
|
1041
|
-
return { X: X3, Y: Y3, Z: Z3 };
|
|
1042
|
-
};
|
|
1043
|
-
const jpNeg = (P) => {
|
|
1044
|
-
if (P.Z === BI_ZERO)
|
|
1045
|
-
return P;
|
|
1046
|
-
return { X: P.X, Y: P_BIGINT - P.Y, Z: P.Z };
|
|
1047
|
-
};
|
|
1048
|
-
// Fast windowed-NAF scalar multiplication (default window = 5) in Jacobian
|
|
1049
|
-
// coordinates. Returns Q = k * P0 as a JacobianPoint.
|
|
1050
|
-
const scalarMultiplyWNAF = (k, P0, window = 5) => {
|
|
1051
|
-
const key = `${window}:${P0.x.toString(16)}:${P0.y.toString(16)}`;
|
|
1052
|
-
let tbl = WNAF_TABLE_CACHE.get(key);
|
|
1053
|
-
let P;
|
|
1054
|
-
if (tbl === undefined) {
|
|
1055
|
-
// Convert affine to Jacobian and pre-compute odd multiples
|
|
1056
|
-
const tblSize = 1 << (window - 1); // e.g. w=5 → 16 entries
|
|
1057
|
-
tbl = new Array(tblSize);
|
|
1058
|
-
P = { X: P0.x, Y: P0.y, Z: BI_ONE };
|
|
1059
|
-
tbl[0] = P;
|
|
1060
|
-
const twoP = jpDouble(P);
|
|
1061
|
-
for (let i = 1; i < tblSize; i++) {
|
|
1062
|
-
tbl[i] = jpAdd(tbl[i - 1], twoP);
|
|
1063
|
-
}
|
|
1064
|
-
WNAF_TABLE_CACHE.set(key, tbl);
|
|
1065
|
-
}
|
|
1066
|
-
else {
|
|
1067
|
-
P = tbl[0];
|
|
1068
|
-
}
|
|
1069
|
-
// Build wNAF representation of k
|
|
1070
|
-
const wnaf = [];
|
|
1071
|
-
const wBig = 1n << BigInt(window);
|
|
1072
|
-
const wHalf = wBig >> 1n;
|
|
1073
|
-
let kTmp = k;
|
|
1074
|
-
while (kTmp > 0n) {
|
|
1075
|
-
if ((kTmp & BI_ONE) === BI_ZERO) {
|
|
1076
|
-
wnaf.push(0);
|
|
1077
|
-
kTmp >>= BI_ONE;
|
|
1078
|
-
}
|
|
1079
|
-
else {
|
|
1080
|
-
let z = kTmp & (wBig - 1n); // kTmp mod 2^w
|
|
1081
|
-
if (z > wHalf)
|
|
1082
|
-
z -= wBig; // make it odd & within (-2^{w-1}, 2^{w-1})
|
|
1083
|
-
wnaf.push(Number(z));
|
|
1084
|
-
kTmp -= z;
|
|
1085
|
-
kTmp >>= BI_ONE;
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
// Accumulate from MSB to LSB
|
|
1089
|
-
let Q = { X: BI_ZERO, Y: BI_ONE, Z: BI_ZERO }; // infinity
|
|
1090
|
-
for (let i = wnaf.length - 1; i >= 0; i--) {
|
|
1091
|
-
Q = jpDouble(Q);
|
|
1092
|
-
const di = wnaf[i];
|
|
1093
|
-
if (di !== 0) {
|
|
1094
|
-
const idx = Math.abs(di) >> 1; // (|di|-1)/2 because di is odd
|
|
1095
|
-
const addend = di > 0 ? tbl[idx] : jpNeg(tbl[idx]);
|
|
1096
|
-
Q = jpAdd(Q, addend);
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
return Q;
|
|
1100
|
-
};
|
|
1101
1093
|
//# sourceMappingURL=Point.js.map
|