@bsv/sdk 1.6.16 → 1.6.18

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.
Files changed (111) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/auth/Peer.js +16 -25
  3. package/dist/cjs/src/auth/Peer.js.map +1 -1
  4. package/dist/cjs/src/auth/SessionManager.js +2 -4
  5. package/dist/cjs/src/auth/SessionManager.js.map +1 -1
  6. package/dist/cjs/src/auth/certificates/Certificate.js +2 -4
  7. package/dist/cjs/src/auth/certificates/Certificate.js.map +1 -1
  8. package/dist/cjs/src/auth/certificates/MasterCertificate.js +1 -1
  9. package/dist/cjs/src/auth/certificates/MasterCertificate.js.map +1 -1
  10. package/dist/cjs/src/auth/clients/AuthFetch.js +2 -4
  11. package/dist/cjs/src/auth/clients/AuthFetch.js.map +1 -1
  12. package/dist/cjs/src/compat/ECIES.js +1 -1
  13. package/dist/cjs/src/compat/ECIES.js.map +1 -1
  14. package/dist/cjs/src/compat/Mnemonic.js +2 -2
  15. package/dist/cjs/src/compat/Mnemonic.js.map +1 -1
  16. package/dist/cjs/src/identity/IdentityClient.js +1 -1
  17. package/dist/cjs/src/identity/IdentityClient.js.map +1 -1
  18. package/dist/cjs/src/kvstore/LocalKVStore.js +1 -2
  19. package/dist/cjs/src/kvstore/LocalKVStore.js.map +1 -1
  20. package/dist/cjs/src/overlay-tools/LookupResolver.js +10 -8
  21. package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
  22. package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js +9 -10
  23. package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js.map +1 -1
  24. package/dist/cjs/src/primitives/AESGCM.js +1 -2
  25. package/dist/cjs/src/primitives/AESGCM.js.map +1 -1
  26. package/dist/cjs/src/primitives/BigNumber.js +2 -3
  27. package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
  28. package/dist/cjs/src/primitives/Curve.js +2 -3
  29. package/dist/cjs/src/primitives/Curve.js.map +1 -1
  30. package/dist/cjs/src/primitives/ECDSA.js +174 -396
  31. package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
  32. package/dist/cjs/src/primitives/JacobianPoint.js +1 -2
  33. package/dist/cjs/src/primitives/JacobianPoint.js.map +1 -1
  34. package/dist/cjs/src/primitives/Point.js +217 -181
  35. package/dist/cjs/src/primitives/Point.js.map +1 -1
  36. package/dist/cjs/src/primitives/Polynomial.js +1 -1
  37. package/dist/cjs/src/primitives/Polynomial.js.map +1 -1
  38. package/dist/cjs/src/primitives/Random.js +1 -2
  39. package/dist/cjs/src/primitives/Random.js.map +1 -1
  40. package/dist/cjs/src/primitives/TransactionSignature.js +5 -7
  41. package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
  42. package/dist/cjs/src/primitives/utils.js +1 -2
  43. package/dist/cjs/src/primitives/utils.js.map +1 -1
  44. package/dist/cjs/src/registry/RegistryClient.js +2 -4
  45. package/dist/cjs/src/registry/RegistryClient.js.map +1 -1
  46. package/dist/cjs/src/script/Spend.js +1 -2
  47. package/dist/cjs/src/script/Spend.js.map +1 -1
  48. package/dist/cjs/src/script/templates/P2PKH.js +4 -4
  49. package/dist/cjs/src/script/templates/P2PKH.js.map +1 -1
  50. package/dist/cjs/src/script/templates/PushDrop.js +7 -8
  51. package/dist/cjs/src/script/templates/PushDrop.js.map +1 -1
  52. package/dist/cjs/src/script/templates/RPuzzle.js +7 -6
  53. package/dist/cjs/src/script/templates/RPuzzle.js.map +1 -1
  54. package/dist/cjs/src/storage/StorageDownloader.js +1 -1
  55. package/dist/cjs/src/storage/StorageDownloader.js.map +1 -1
  56. package/dist/cjs/src/storage/StorageUploader.js +6 -9
  57. package/dist/cjs/src/storage/StorageUploader.js.map +1 -1
  58. package/dist/cjs/src/transaction/Beef.js +2 -3
  59. package/dist/cjs/src/transaction/Beef.js.map +1 -1
  60. package/dist/cjs/src/transaction/MerklePath.js +9 -12
  61. package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
  62. package/dist/cjs/src/transaction/Transaction.js +15 -22
  63. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  64. package/dist/cjs/src/transaction/broadcasters/ARC.js +3 -3
  65. package/dist/cjs/src/transaction/broadcasters/ARC.js.map +1 -1
  66. package/dist/cjs/src/transaction/broadcasters/Teranode.js +2 -3
  67. package/dist/cjs/src/transaction/broadcasters/Teranode.js.map +1 -1
  68. package/dist/cjs/src/transaction/broadcasters/WhatsOnChainBroadcaster.js +2 -3
  69. package/dist/cjs/src/transaction/broadcasters/WhatsOnChainBroadcaster.js.map +1 -1
  70. package/dist/cjs/src/transaction/chaintrackers/BlockHeadersService.js +2 -2
  71. package/dist/cjs/src/transaction/chaintrackers/BlockHeadersService.js.map +1 -1
  72. package/dist/cjs/src/transaction/chaintrackers/WhatsOnChain.js +2 -2
  73. package/dist/cjs/src/transaction/chaintrackers/WhatsOnChain.js.map +1 -1
  74. package/dist/cjs/src/transaction/http/FetchHttpClient.js +1 -2
  75. package/dist/cjs/src/transaction/http/FetchHttpClient.js.map +1 -1
  76. package/dist/cjs/src/wallet/CachedKeyDeriver.js +1 -1
  77. package/dist/cjs/src/wallet/CachedKeyDeriver.js.map +1 -1
  78. package/dist/cjs/src/wallet/KeyDeriver.js +4 -3
  79. package/dist/cjs/src/wallet/KeyDeriver.js.map +1 -1
  80. package/dist/cjs/src/wallet/ProtoWallet.js +21 -25
  81. package/dist/cjs/src/wallet/ProtoWallet.js.map +1 -1
  82. package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js +2 -3
  83. package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
  84. package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js +1 -1
  85. package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
  86. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js +12 -19
  87. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  88. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  89. package/dist/esm/src/overlay-tools/LookupResolver.js +4 -0
  90. package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
  91. package/dist/esm/src/primitives/ECDSA.js +174 -395
  92. package/dist/esm/src/primitives/ECDSA.js.map +1 -1
  93. package/dist/esm/src/primitives/Point.js +192 -146
  94. package/dist/esm/src/primitives/Point.js.map +1 -1
  95. package/dist/esm/src/wallet/KeyDeriver.js +3 -1
  96. package/dist/esm/src/wallet/KeyDeriver.js.map +1 -1
  97. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  98. package/dist/types/src/overlay-tools/LookupResolver.d.ts.map +1 -1
  99. package/dist/types/src/primitives/ECDSA.d.ts.map +1 -1
  100. package/dist/types/src/primitives/Point.d.ts.map +1 -1
  101. package/dist/types/src/wallet/KeyDeriver.d.ts.map +1 -1
  102. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  103. package/dist/umd/bundle.js +1 -1
  104. package/docs/reference/primitives.md +165 -377
  105. package/package.json +1 -1
  106. package/src/overlay-tools/LookupResolver.ts +5 -0
  107. package/src/primitives/ECDSA.ts +218 -488
  108. package/src/primitives/Point.ts +212 -162
  109. package/src/transaction/__tests/Transaction.test.ts +1 -1
  110. package/src/wallet/KeyDeriver.ts +2 -1
  111. package/src/wallet/__tests/ProtoWallet.test.ts +46 -1
@@ -55,265 +55,73 @@ function truncateToN(msg, truncOnly, curve = new Curve_js_1.default()) {
55
55
  * const signature = sign(msg, key)
56
56
  */
57
57
  const sign = (msg, key, forceLowS = false, customK) => {
58
- if (typeof BigInt === 'function') {
59
- // Curve parameters for secp256k1
60
- const zero = BigInt(0);
61
- const one = BigInt(1);
62
- const two = BigInt(2);
63
- const n = BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'); // Order of the curve
64
- const p = BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F'); // Field prime
65
- const Gx = BigInt('0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798');
66
- const Gy = BigInt('0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8');
67
- const G = { x: Gx, y: Gy };
68
- // Convert msg and key to BigInt
69
- const z = BigInt('0x' + msg.toString(16));
70
- const d = BigInt('0x' + key.toString(16));
71
- // Validate private key
72
- if (d <= zero || d >= n) {
73
- throw new Error('Invalid private key');
58
+ const curve = new Curve_js_1.default();
59
+ msg = truncateToN(msg);
60
+ // Zero-extend key to provide enough entropy
61
+ const bytes = curve.n.byteLength();
62
+ const bkey = key.toArray('be', bytes);
63
+ // Zero-extend nonce to have the same byte size as N
64
+ const nonce = msg.toArray('be', bytes);
65
+ // Instantiate Hmac_DRBG
66
+ const drbg = new DRBG_js_1.default(bkey, nonce);
67
+ // Number of bytes to generate
68
+ const ns1 = curve.n.subn(1);
69
+ for (let iter = 0;; iter++) {
70
+ // Compute the k-value
71
+ let k = typeof customK === 'function'
72
+ ? customK(iter)
73
+ : BigNumber_js_1.default.isBN(customK)
74
+ ? customK
75
+ : new BigNumber_js_1.default(drbg.generate(bytes), 16);
76
+ if (k != null) {
77
+ k = truncateToN(k, true);
74
78
  }
75
- // Helper function to convert BigInt to byte array
76
- function bigIntToBytes(value, length) {
77
- const hex = value.toString(16).padStart(length * 2, '0');
78
- const bytes = new Uint8Array(length);
79
- for (let i = 0; i < length; i++) {
80
- bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
81
- }
82
- return bytes;
79
+ else {
80
+ throw new Error('k is undefined');
83
81
  }
84
- // Zero-extend key to provide enough entropy
85
- const bytes = 32; // Assuming 256-bit curve
86
- const bkey = bigIntToBytes(d, bytes); // 'd' is the private key BigInt
87
- // Zero-extend nonce to have the same byte size as N
88
- const nonce = bigIntToBytes(z, bytes); // 'z' is the message hash BigInt
89
- // Instantiate Hmac_DRBG
90
- const drbg = new DRBG_js_1.default(Array.from(bkey), Array.from(nonce));
91
- // Number of bytes to generate
92
- const ns1 = n - one;
93
- let iter = 0;
94
- // Truncate to N function for BigInt
95
- function truncateToN(k, n, truncOnly = true) {
96
- const kBitLength = k.toString(2).length;
97
- const nBitLength = n.toString(2).length;
98
- const delta = kBitLength - nBitLength;
99
- if (delta > 0) {
100
- k = k >> BigInt(delta);
101
- }
102
- if (!truncOnly && k >= n) {
103
- return k - n;
82
+ if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0) {
83
+ if (BigNumber_js_1.default.isBN(customK)) {
84
+ throw new Error('Invalid fixed custom K value (must be more than 1 and less than N-1)');
104
85
  }
105
86
  else {
106
- return k;
87
+ continue;
107
88
  }
108
89
  }
109
- function generateK(customK) {
110
- if (typeof customK === 'function') {
111
- // Call customK function to get k as BigNumber
112
- const kbn = customK(iter);
113
- // Convert k_bn (BigNumber) to BigInt
114
- const kstr = kbn.toString(16);
115
- return BigInt('0x' + kstr);
116
- }
117
- else if ((customK != null) && BigNumber_js_1.default.isBN(customK)) {
118
- // Use customK provided, convert to BigInt
119
- const kstr = customK.toString(16);
120
- return BigInt('0x' + kstr);
90
+ const kp = curve.g.mul(k);
91
+ if (kp.isInfinity()) {
92
+ if (BigNumber_js_1.default.isBN(customK)) {
93
+ throw new Error('Invalid fixed custom K value (must not create a point at infinity when multiplied by the generator point)');
121
94
  }
122
95
  else {
123
- // Use DRBG to generate k
124
- const khex = drbg.generate(bytes); // Generate hex string
125
- return BigInt('0x' + khex);
126
- }
127
- }
128
- // Modular arithmetic functions
129
- function mod(a, m) {
130
- return ((a % m) + m) % m;
131
- }
132
- function modInv(a, m) {
133
- let lm = one;
134
- let hm = zero;
135
- let low = mod(a, m);
136
- let high = m;
137
- while (low > one) {
138
- const r = high / low;
139
- const nm = hm - lm * r;
140
- const neww = high - low * r;
141
- hm = lm;
142
- lm = nm;
143
- high = low;
144
- low = neww;
96
+ continue;
145
97
  }
146
- return mod(lm, m);
147
98
  }
148
- function pointAdd(P, Q) {
149
- if (P === null)
150
- return Q;
151
- if (Q === null)
152
- return P;
153
- if (P.x === Q.x && P.y === mod(-Q.y, p)) {
154
- return null; // Point at infinity
155
- }
156
- let m;
157
- if (P.x === Q.x && P.y === Q.y) {
158
- // Point doubling
159
- if (P.y === zero) {
160
- return null; // Point at infinity
161
- }
162
- const numerator = mod(BigInt(3) * P.x * P.x, p); // 3 * x^2
163
- const denominator = modInv(two * P.y, p);
164
- m = mod(numerator * denominator, p);
99
+ const kpX = kp.getX();
100
+ const r = kpX.umod(curve.n);
101
+ if (r.cmpn(0) === 0) {
102
+ if (BigNumber_js_1.default.isBN(customK)) {
103
+ throw new Error('Invalid fixed custom K value (when multiplied by G, the resulting x coordinate mod N must not be zero)');
165
104
  }
166
105
  else {
167
- const numerator = mod(Q.y - P.y, p);
168
- const denominator = modInv(Q.x - P.x, p);
169
- m = mod(numerator * denominator, p);
170
- }
171
- const xR = mod(m * m - P.x - Q.x, p);
172
- const yR = mod(m * (P.x - xR) - P.y, p);
173
- return { x: xR, y: yR };
174
- }
175
- function scalarMul(k, P) {
176
- var _a, _b;
177
- let N = P;
178
- let Q = null;
179
- while (k > BigInt(0)) {
180
- if (k % BigInt(2) === BigInt(1)) {
181
- Q = Q === null ? N : ((_a = pointAdd(Q, N)) !== null && _a !== void 0 ? _a : Q);
182
- }
183
- N = (_b = pointAdd(N, N)) !== null && _b !== void 0 ? _b : N;
184
- k >>= BigInt(1);
185
- }
186
- if (Q === null) {
187
- throw new Error('Scalar multiplication resulted in an invalid point.');
106
+ continue;
188
107
  }
189
- return Q;
190
- }
191
- let validSignature = false;
192
- while (!validSignature) {
193
- iter += 1;
194
- validSignature = true;
195
- iter += 1;
196
- // Generate k value
197
- let k = generateK(customK);
198
- // Truncate k to n bits
199
- k = truncateToN(k, n, true);
200
- if (k <= one || k >= ns1) {
201
- if (customK instanceof BigNumber_js_1.default) {
202
- throw new Error('Invalid fixed custom K value (must be more than 1 and less than N-1)');
203
- }
204
- else {
205
- continue;
206
- }
207
- }
208
- const R = scalarMul(k, G);
209
- if (R === null) {
210
- if (customK instanceof BigNumber_js_1.default) {
211
- throw new Error('Invalid fixed custom K value (must not create a point at infinity when multiplied by the generator point)');
212
- }
213
- else {
214
- continue;
215
- }
216
- }
217
- const r = mod(R.x, n);
218
- if (r === zero) {
219
- if (customK instanceof BigNumber_js_1.default) {
220
- throw new Error('Invalid fixed custom K value (when multiplied by G, the resulting x coordinate mod N must not be zero)');
221
- }
222
- else {
223
- continue;
224
- }
225
- }
226
- const kInv = modInv(k, n);
227
- const rd = mod(r * d, n);
228
- let s = mod(kInv * (z + rd), n);
229
- if (s === zero) {
230
- if (customK instanceof BigNumber_js_1.default) {
231
- throw new Error('Invalid fixed custom K value (when used with the key, it cannot create a zero value for S)');
232
- }
233
- else {
234
- continue;
235
- }
236
- }
237
- // Use complement of `s` if it is > n / 2
238
- if (forceLowS && s > n / two) {
239
- s = n - s;
240
- }
241
- // Return signature as BigNumbers
242
- const rbn = new BigNumber_js_1.default(r.toString(16), 16);
243
- const sbn = new BigNumber_js_1.default(s.toString(16), 16);
244
- return new Signature_js_1.default(rbn, sbn);
245
108
  }
246
- }
247
- else {
248
- const curve = new Curve_js_1.default();
249
- msg = truncateToN(msg);
250
- // Zero-extend key to provide enough entropy
251
- const bytes = curve.n.byteLength();
252
- const bkey = key.toArray('be', bytes);
253
- // Zero-extend nonce to have the same byte size as N
254
- const nonce = msg.toArray('be', bytes);
255
- // Instantiate Hmac_DRBG
256
- const drbg = new DRBG_js_1.default(bkey, nonce);
257
- // Number of bytes to generate
258
- const ns1 = curve.n.subn(1);
259
- for (let iter = 0;; iter++) {
260
- // Compute the k-value
261
- let k = typeof customK === 'function'
262
- ? customK(iter)
263
- : BigNumber_js_1.default.isBN(customK)
264
- ? customK
265
- : new BigNumber_js_1.default(drbg.generate(bytes), 16);
266
- if (k != null) {
267
- k = truncateToN(k, true);
109
+ let s = k.invm(curve.n).mul(r.mul(key).iadd(msg));
110
+ s = s.umod(curve.n);
111
+ if (s.cmpn(0) === 0) {
112
+ if (BigNumber_js_1.default.isBN(customK)) {
113
+ throw new Error('Invalid fixed custom K value (when used with the key, it cannot create a zero value for S)');
268
114
  }
269
115
  else {
270
- throw new Error('k is undefined');
116
+ continue;
271
117
  }
272
- if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0) {
273
- if (BigNumber_js_1.default.isBN(customK)) {
274
- throw new Error('Invalid fixed custom K value (must be more than 1 and less than N-1)');
275
- }
276
- else {
277
- continue;
278
- }
279
- }
280
- const kp = curve.g.mul(k);
281
- if (kp.isInfinity()) {
282
- if (BigNumber_js_1.default.isBN(customK)) {
283
- throw new Error('Invalid fixed custom K value (must not create a point at infinity when multiplied by the generator point)');
284
- }
285
- else {
286
- continue;
287
- }
288
- }
289
- const kpX = kp.getX();
290
- const r = kpX.umod(curve.n);
291
- if (r.cmpn(0) === 0) {
292
- if (BigNumber_js_1.default.isBN(customK)) {
293
- throw new Error('Invalid fixed custom K value (when multiplied by G, the resulting x coordinate mod N must not be zero)');
294
- }
295
- else {
296
- continue;
297
- }
298
- }
299
- let s = k.invm(curve.n).mul(r.mul(key).iadd(msg));
300
- s = s.umod(curve.n);
301
- if (s.cmpn(0) === 0) {
302
- if (BigNumber_js_1.default.isBN(customK)) {
303
- throw new Error('Invalid fixed custom K value (when used with the key, it cannot create a zero value for S)');
304
- }
305
- else {
306
- continue;
307
- }
308
- }
309
- // Use complement of `s`, if it is > `n / 2`
310
- if (forceLowS && s.cmp(curve.n.ushrn(1)) > 0) {
311
- s = curve.n.sub(s);
312
- }
313
- return new Signature_js_1.default(r, s);
314
118
  }
119
+ // Use complement of `s`, if it is > `n / 2`
120
+ if (forceLowS && s.cmp(curve.n.ushrn(1)) > 0) {
121
+ s = curve.n.sub(s);
122
+ }
123
+ return new Signature_js_1.default(r, s);
315
124
  }
316
- throw new Error('Failed to generate a valid signature');
317
125
  };
318
126
  exports.sign = sign;
319
127
  /**
@@ -335,174 +143,144 @@ exports.sign = sign;
335
143
  * const isVerified = verify(msg, sig, key)
336
144
  */
337
145
  const verify = (msg, sig, key) => {
338
- // Use BigInt for verification opportunistically
339
- if (typeof BigInt === 'function') {
340
- // Curve parameters for secp256k1
341
- const zero = BigInt(0);
342
- const one = BigInt(1);
343
- const two = BigInt(2);
344
- const three = BigInt(3);
345
- const p = BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F'); // Field prime
346
- const n = BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'); // Order of the curve
347
- const G = {
348
- x: BigInt('0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798'),
349
- y: BigInt('0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8')
350
- };
351
- // Modular arithmetic functions
352
- const mod = (a, m) => ((a % m) + m) % m;
353
- const modInv = (a, m) => {
354
- // Extended Euclidean Algorithm for modular inverse
355
- let [oldr, r] = [a, m];
356
- let [olds, s] = [BigInt(1), BigInt(0)];
357
- while (r !== zero) {
358
- const q = oldr / r;
359
- [oldr, r] = [r, oldr - q * r];
360
- [olds, s] = [s, olds - q * s];
361
- }
362
- if (oldr > one)
363
- return zero; // No inverse
364
- return mod(olds, m);
365
- };
366
- const modMul = (a, b, m) => mod(a * b, m);
367
- const modSub = (a, b, m) => mod(a - b, m);
368
- // Define constants
369
- const four = BigInt(4);
370
- const eight = BigInt(8);
371
- // Point Doubling
372
- const pointDouble = (P) => {
373
- const { X: X1, Y: Y1, Z: Z1 } = P;
374
- if (Y1 === zero) {
375
- return { X: zero, Y: one, Z: zero }; // Point at infinity
376
- }
377
- const Y1sq = modMul(Y1, Y1, p); // Y1^2
378
- const S = modMul(four, modMul(X1, Y1sq, p), p); // S = 4 * X1 * Y1^2
379
- const M = modMul(three, modMul(X1, X1, p), p); // M = 3 * X1^2
380
- const X3 = modSub(modMul(M, M, p), modMul(two, S, p), p); // X3 = M^2 - 2 * S
381
- const Y3 = modSub(modMul(M, modSub(S, X3, p), p), modMul(eight, modMul(Y1sq, Y1sq, p), p), p); // Y3 = M * (S - X3) - 8 * Y1^4
382
- const Z3 = modMul(two, modMul(Y1, Z1, p), p); // Z3 = 2 * Y1 * Z1
383
- return { X: X3, Y: Y3, Z: Z3 };
384
- };
385
- // Point Addition
386
- const pointAdd = (P, Q) => {
387
- if (P.Z === zero)
388
- return Q;
389
- if (Q.Z === zero)
390
- return P;
391
- const Z1Z1 = modMul(P.Z, P.Z, p);
392
- const Z2Z2 = modMul(Q.Z, Q.Z, p);
393
- const U1 = modMul(P.X, Z2Z2, p);
394
- const U2 = modMul(Q.X, Z1Z1, p);
395
- const S1 = modMul(P.Y, modMul(Z2Z2, Q.Z, p), p);
396
- const S2 = modMul(Q.Y, modMul(Z1Z1, P.Z, p), p);
397
- const H = modSub(U2, U1, p);
398
- const r = modSub(S2, S1, p);
399
- if (H === zero) {
400
- if (r === zero) {
401
- // P == Q
402
- return pointDouble(P);
403
- }
404
- else {
405
- // Point at infinity
406
- return { X: zero, Y: one, Z: zero };
407
- }
408
- }
409
- const HH = modMul(H, H, p);
410
- const HHH = modMul(H, HH, p);
411
- const V = modMul(U1, HH, p);
412
- const X3 = modSub(modSub(modMul(r, r, p), HHH, p), modMul(two, V, p), p);
413
- const Y3 = modSub(modMul(r, modSub(V, X3, p), p), modMul(S1, HHH, p), p);
414
- const Z3 = modMul(H, modMul(P.Z, Q.Z, p), p);
415
- return { X: X3, Y: Y3, Z: Z3 };
416
- };
417
- // Scalar Multiplication
418
- const scalarMultiply = (k, P) => {
419
- const N = { X: P.x, Y: P.y, Z: one };
420
- let Q = { X: zero, Y: one, Z: zero }; // Point at infinity
421
- const kBin = k.toString(2);
422
- for (let i = 0; i < kBin.length; i++) {
423
- Q = pointDouble(Q);
424
- if (kBin[i] === '1') {
425
- Q = pointAdd(Q, N);
426
- }
427
- }
146
+ // Curve parameters for secp256k1
147
+ const zero = BigInt(0);
148
+ const one = BigInt(1);
149
+ const two = BigInt(2);
150
+ const three = BigInt(3);
151
+ const p = BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F'); // Field prime
152
+ const n = BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'); // Order of the curve
153
+ const G = {
154
+ x: BigInt('0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798'),
155
+ y: BigInt('0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8')
156
+ };
157
+ // Modular arithmetic functions
158
+ const mod = (a, m) => ((a % m) + m) % m;
159
+ const modInv = (a, m) => {
160
+ // Extended Euclidean Algorithm for modular inverse
161
+ let [oldr, r] = [a, m];
162
+ let [olds, s] = [BigInt(1), BigInt(0)];
163
+ while (r !== zero) {
164
+ const q = oldr / r;
165
+ [oldr, r] = [r, oldr - q * r];
166
+ [olds, s] = [s, olds - q * s];
167
+ }
168
+ if (oldr > one)
169
+ return zero; // No inverse
170
+ return mod(olds, m);
171
+ };
172
+ const modMul = (a, b, m) => mod(a * b, m);
173
+ const modSub = (a, b, m) => mod(a - b, m);
174
+ // Define constants
175
+ const four = BigInt(4);
176
+ const eight = BigInt(8);
177
+ // Point Doubling
178
+ const pointDouble = (P) => {
179
+ const { X: X1, Y: Y1, Z: Z1 } = P;
180
+ if (Y1 === zero) {
181
+ return { X: zero, Y: one, Z: zero }; // Point at infinity
182
+ }
183
+ const Y1sq = modMul(Y1, Y1, p); // Y1^2
184
+ const S = modMul(four, modMul(X1, Y1sq, p), p); // S = 4 * X1 * Y1^2
185
+ const M = modMul(three, modMul(X1, X1, p), p); // M = 3 * X1^2
186
+ const X3 = modSub(modMul(M, M, p), modMul(two, S, p), p); // X3 = M^2 - 2 * S
187
+ const Y3 = modSub(modMul(M, modSub(S, X3, p), p), modMul(eight, modMul(Y1sq, Y1sq, p), p), p); // Y3 = M * (S - X3) - 8 * Y1^4
188
+ const Z3 = modMul(two, modMul(Y1, Z1, p), p); // Z3 = 2 * Y1 * Z1
189
+ return { X: X3, Y: Y3, Z: Z3 };
190
+ };
191
+ // Point Addition
192
+ const pointAdd = (P, Q) => {
193
+ if (P.Z === zero)
428
194
  return Q;
429
- };
430
- // Verify Function Using Jacobian Coordinates
431
- const verifyECDSA = (hash, publicKey, signature) => {
432
- const { r, s } = signature;
433
- const z = hash;
434
- // Check r and s are in [1, n - 1]
435
- if (r <= zero || r >= n || s <= zero || s >= n) {
436
- return false;
437
- }
438
- const w = modInv(s, n); // w = s^-1 mod n
439
- if (w === zero) {
440
- return false; // No inverse exists
195
+ if (Q.Z === zero)
196
+ return P;
197
+ const Z1Z1 = modMul(P.Z, P.Z, p);
198
+ const Z2Z2 = modMul(Q.Z, Q.Z, p);
199
+ const U1 = modMul(P.X, Z2Z2, p);
200
+ const U2 = modMul(Q.X, Z1Z1, p);
201
+ const S1 = modMul(P.Y, modMul(Z2Z2, Q.Z, p), p);
202
+ const S2 = modMul(Q.Y, modMul(Z1Z1, P.Z, p), p);
203
+ const H = modSub(U2, U1, p);
204
+ const r = modSub(S2, S1, p);
205
+ if (H === zero) {
206
+ if (r === zero) {
207
+ // P == Q
208
+ return pointDouble(P);
441
209
  }
442
- const u1 = modMul(z, w, n);
443
- const u2 = modMul(r, w, n);
444
- // Compute point R = u1 * G + u2 * Q
445
- const RG = scalarMultiply(u1, G);
446
- const RQ = scalarMultiply(u2, publicKey);
447
- const R = pointAdd(RG, RQ);
448
- if (R.Z === zero) {
210
+ else {
449
211
  // Point at infinity
450
- return false;
212
+ return { X: zero, Y: one, Z: zero };
451
213
  }
452
- // Compute affine x-coordinate x1 = X / Z^2 mod p
453
- const ZInv = modInv(R.Z, p);
454
- if (ZInv === zero) {
455
- return false; // No inverse exists
214
+ }
215
+ const HH = modMul(H, H, p);
216
+ const HHH = modMul(H, HH, p);
217
+ const V = modMul(U1, HH, p);
218
+ const X3 = modSub(modSub(modMul(r, r, p), HHH, p), modMul(two, V, p), p);
219
+ const Y3 = modSub(modMul(r, modSub(V, X3, p), p), modMul(S1, HHH, p), p);
220
+ const Z3 = modMul(H, modMul(P.Z, Q.Z, p), p);
221
+ return { X: X3, Y: Y3, Z: Z3 };
222
+ };
223
+ // Scalar Multiplication
224
+ const scalarMultiply = (k, P) => {
225
+ const N = { X: P.x, Y: P.y, Z: one };
226
+ let Q = { X: zero, Y: one, Z: zero }; // Point at infinity
227
+ const kBin = k.toString(2);
228
+ for (let i = 0; i < kBin.length; i++) {
229
+ Q = pointDouble(Q);
230
+ if (kBin[i] === '1') {
231
+ Q = pointAdd(Q, N);
456
232
  }
457
- const ZInv2 = modMul(ZInv, ZInv, p);
458
- const x1affine = modMul(R.X, ZInv2, p);
459
- // Compute v = x1_affine mod n
460
- const v = mod(x1affine, n);
461
- // Signature is valid if v == r mod n
462
- return v === r;
463
- };
464
- // Convert inputs to BigInt
465
- const hash = BigInt('0x' + msg.toString(16));
466
- if ((key.x == null) || (key.y == null)) {
467
- throw new Error('Invalid public key: missing coordinates.');
468
233
  }
469
- const publicKey = {
470
- x: BigInt('0x' + key.x.toString(16)),
471
- y: BigInt('0x' + key.y.toString(16))
472
- };
473
- const signature = {
474
- r: BigInt('0x' + sig.r.toString(16)),
475
- s: BigInt('0x' + sig.s.toString(16))
476
- };
477
- return verifyECDSA(hash, publicKey, signature);
478
- }
479
- else {
480
- const curve = new Curve_js_1.default();
481
- msg = truncateToN(msg);
482
- // Perform primitive values validation
483
- const r = sig.r;
484
- const s = sig.s;
485
- if (r.cmpn(1) < 0 || r.cmp(curve.n) >= 0) {
234
+ return Q;
235
+ };
236
+ // Verify Function Using Jacobian Coordinates
237
+ const verifyECDSA = (hash, publicKey, signature) => {
238
+ const { r, s } = signature;
239
+ const z = hash;
240
+ // Check r and s are in [1, n - 1]
241
+ if (r <= zero || r >= n || s <= zero || s >= n) {
486
242
  return false;
487
243
  }
488
- if (s.cmpn(1) < 0 || s.cmp(curve.n) >= 0) {
489
- return false;
244
+ const w = modInv(s, n); // w = s^-1 mod n
245
+ if (w === zero) {
246
+ return false; // No inverse exists
490
247
  }
491
- // Validate signature
492
- const sinv = s.invm(curve.n);
493
- const u1 = sinv.mul(msg).umod(curve.n);
494
- const u2 = sinv.mul(r).umod(curve.n);
495
- // NOTE: Greg Maxwell's trick, inspired by:
496
- // https://git.io/vad3K
497
- const p = curve.g.jmulAdd(u1, key, u2);
498
- if (p.isInfinity()) {
248
+ const u1 = modMul(z, w, n);
249
+ const u2 = modMul(r, w, n);
250
+ // Compute point R = u1 * G + u2 * Q
251
+ const RG = scalarMultiply(u1, G);
252
+ const RQ = scalarMultiply(u2, publicKey);
253
+ const R = pointAdd(RG, RQ);
254
+ if (R.Z === zero) {
255
+ // Point at infinity
499
256
  return false;
500
257
  }
501
- // Compare `p.x` of Jacobian point with `r`,
502
- // this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the
503
- // inverse of `p.z^2`
504
- return p.eqXToP(r);
258
+ // Compute affine x-coordinate x1 = X / Z^2 mod p
259
+ const ZInv = modInv(R.Z, p);
260
+ if (ZInv === zero) {
261
+ return false; // No inverse exists
262
+ }
263
+ const ZInv2 = modMul(ZInv, ZInv, p);
264
+ const x1affine = modMul(R.X, ZInv2, p);
265
+ // Compute v = x1_affine mod n
266
+ const v = mod(x1affine, n);
267
+ // Signature is valid if v == r mod n
268
+ return v === r;
269
+ };
270
+ // Convert inputs to BigInt
271
+ const hash = BigInt('0x' + msg.toString(16));
272
+ if ((key.x == null) || (key.y == null)) {
273
+ throw new Error('Invalid public key: missing coordinates.');
505
274
  }
275
+ const publicKey = {
276
+ x: BigInt('0x' + key.x.toString(16)),
277
+ y: BigInt('0x' + key.y.toString(16))
278
+ };
279
+ const signature = {
280
+ r: BigInt('0x' + sig.r.toString(16)),
281
+ s: BigInt('0x' + sig.s.toString(16))
282
+ };
283
+ return verifyECDSA(hash, publicKey, signature);
506
284
  };
507
285
  exports.verify = verify;
508
286
  //# sourceMappingURL=ECDSA.js.map