@bsv/sdk 1.6.16 → 1.6.17

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