@bsv/sdk 1.0.1 → 1.0.2

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 (112) hide show
  1. package/dist/cjs/package.json +8 -4
  2. package/dist/cjs/src/transaction/broadcasters/ARC.js +13 -2
  3. package/dist/cjs/src/transaction/broadcasters/ARC.js.map +1 -1
  4. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  5. package/dist/esm/src/transaction/broadcasters/ARC.js +13 -2
  6. package/dist/esm/src/transaction/broadcasters/ARC.js.map +1 -1
  7. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  8. package/dist/types/src/transaction/broadcasters/ARC.d.ts.map +1 -1
  9. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  10. package/package.json +2 -1
  11. package/src/compat/BSM.ts +51 -0
  12. package/src/compat/ECIES.ts +557 -0
  13. package/src/compat/HD.ts +348 -0
  14. package/src/compat/Mnemonic.ts +295 -0
  15. package/src/compat/__tests/BSM.test.ts +38 -0
  16. package/src/compat/__tests/ECIES.test.ts +90 -0
  17. package/src/compat/__tests/HD.test.ts +405 -0
  18. package/src/compat/__tests/Mnemonic.test.ts +177 -0
  19. package/src/compat/__tests/Mnemonic.vectors.ts +172 -0
  20. package/src/compat/bip-39-wordlist-en.ts +2053 -0
  21. package/src/compat/index.ts +4 -0
  22. package/src/messages/EncryptedMessage.ts +70 -0
  23. package/src/messages/SignedMessage.ts +87 -0
  24. package/src/messages/__tests/EncryptedMessage.test.ts +36 -0
  25. package/src/messages/__tests/SignedMessage.test.ts +53 -0
  26. package/src/messages/index.ts +2 -0
  27. package/src/primitives/AESGCM.ts +479 -0
  28. package/src/primitives/BasePoint.ts +21 -0
  29. package/src/primitives/BigNumber.ts +4619 -0
  30. package/src/primitives/Curve.ts +1163 -0
  31. package/src/primitives/DRBG.ts +102 -0
  32. package/src/primitives/ECDSA.ts +164 -0
  33. package/src/primitives/Hash.ts +1420 -0
  34. package/src/primitives/JacobianPoint.ts +410 -0
  35. package/src/primitives/K256.ts +116 -0
  36. package/src/primitives/Mersenne.ts +123 -0
  37. package/src/primitives/MontgomoryMethod.ts +160 -0
  38. package/src/primitives/Point.ts +852 -0
  39. package/src/primitives/PrivateKey.ts +195 -0
  40. package/src/primitives/PublicKey.ts +154 -0
  41. package/src/primitives/Random.ts +55 -0
  42. package/src/primitives/ReductionContext.ts +528 -0
  43. package/src/primitives/Signature.ts +235 -0
  44. package/src/primitives/SymmetricKey.ts +75 -0
  45. package/src/primitives/TransactionSignature.ts +189 -0
  46. package/src/primitives/__tests/AESGCM.test.ts +338 -0
  47. package/src/primitives/__tests/BRC42.private.vectors.ts +33 -0
  48. package/src/primitives/__tests/BRC42.public.vectors.ts +33 -0
  49. package/src/primitives/__tests/BigNumber.arithmatic.test.ts +572 -0
  50. package/src/primitives/__tests/BigNumber.binary.test.ts +203 -0
  51. package/src/primitives/__tests/BigNumber.constructor.test.ts +176 -0
  52. package/src/primitives/__tests/BigNumber.dhGroup.test.ts +18 -0
  53. package/src/primitives/__tests/BigNumber.fixtures.ts +264 -0
  54. package/src/primitives/__tests/BigNumber.serializers.test.ts +157 -0
  55. package/src/primitives/__tests/BigNumber.utils.test.ts +347 -0
  56. package/src/primitives/__tests/Curve.unit.test.ts +192 -0
  57. package/src/primitives/__tests/DRBG.test.ts +18 -0
  58. package/src/primitives/__tests/DRBG.vectors.ts +167 -0
  59. package/src/primitives/__tests/ECDH.test.ts +31 -0
  60. package/src/primitives/__tests/ECDSA.test.ts +58 -0
  61. package/src/primitives/__tests/HMAC.test.ts +59 -0
  62. package/src/primitives/__tests/Hash.test.ts +121 -0
  63. package/src/primitives/__tests/PBKDF2.vectors.ts +119 -0
  64. package/src/primitives/__tests/PrivateKey.test.ts +17 -0
  65. package/src/primitives/__tests/PublicKey.test.ts +66 -0
  66. package/src/primitives/__tests/Random.test.ts +14 -0
  67. package/src/primitives/__tests/Reader.test.ts +296 -0
  68. package/src/primitives/__tests/ReductionContext.test.ts +279 -0
  69. package/src/primitives/__tests/SymmetricKey.test.ts +58 -0
  70. package/src/primitives/__tests/SymmetricKey.vectors.ts +40 -0
  71. package/src/primitives/__tests/Writer.test.ts +198 -0
  72. package/src/primitives/__tests/sighash.vectors.ts +3503 -0
  73. package/src/primitives/__tests/utils.test.ts +108 -0
  74. package/src/primitives/index.ts +8 -0
  75. package/src/primitives/utils.ts +665 -0
  76. package/src/script/LockingScript.ts +30 -0
  77. package/src/script/OP.ts +219 -0
  78. package/src/script/Script.ts +426 -0
  79. package/src/script/ScriptChunk.ts +7 -0
  80. package/src/script/ScriptTemplate.ts +36 -0
  81. package/src/script/Spend.ts +1379 -0
  82. package/src/script/UnlockingScript.ts +30 -0
  83. package/src/script/__tests/Script.test.ts +369 -0
  84. package/src/script/__tests/Spend.test.ts +248 -0
  85. package/src/script/__tests/script.invalid.vectors.ts +925 -0
  86. package/src/script/__tests/script.valid.vectors.ts +1120 -0
  87. package/src/script/__tests/scriptFromVector.ts +42 -0
  88. package/src/script/__tests/spend.valid.vectors.ts +2288 -0
  89. package/src/script/index.ts +7 -0
  90. package/src/script/templates/P2PKH.ts +109 -0
  91. package/src/script/templates/RPuzzle.ts +140 -0
  92. package/src/script/templates/index.ts +2 -0
  93. package/src/transaction/Broadcaster.ts +42 -0
  94. package/src/transaction/ChainTracker.ts +22 -0
  95. package/src/transaction/FeeModel.ts +13 -0
  96. package/src/transaction/MerklePath.ts +259 -0
  97. package/src/transaction/Transaction.ts +602 -0
  98. package/src/transaction/TransactionInput.ts +63 -0
  99. package/src/transaction/TransactionOutput.ts +37 -0
  100. package/src/transaction/__tests/MerklePath.test.ts +181 -0
  101. package/src/transaction/__tests/Transaction.test.ts +413 -0
  102. package/src/transaction/__tests/bigtx.vectors.ts +4 -0
  103. package/src/transaction/__tests/bump.invalid.vectors.ts +8 -0
  104. package/src/transaction/__tests/bump.valid.vectors.ts +4 -0
  105. package/src/transaction/__tests/tx.invalid.vectors.ts +281 -0
  106. package/src/transaction/__tests/tx.valid.vectors.ts +364 -0
  107. package/src/transaction/broadcasters/ARC.ts +115 -0
  108. package/src/transaction/broadcasters/__tests/ARC.test.ts +115 -0
  109. package/src/transaction/broadcasters/index.ts +1 -0
  110. package/src/transaction/fee-models/SatoshisPerKilobyte.ts +71 -0
  111. package/src/transaction/fee-models/index.ts +1 -0
  112. package/src/transaction/index.ts +6 -0
@@ -0,0 +1,479 @@
1
+ const SBox = [[0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76],
2
+ [0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0],
3
+ [0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15],
4
+ [0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75],
5
+ [0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84],
6
+ [0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf],
7
+ [0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8],
8
+ [0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2],
9
+ [0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73],
10
+ [0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb],
11
+ [0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79],
12
+ [0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08],
13
+ [0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a],
14
+ [0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e],
15
+ [0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf],
16
+ [0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16]]
17
+ const Rcon = [[0x00, 0x00, 0x00, 0x00], [0x01, 0x00, 0x00, 0x00], [0x02, 0x00, 0x00, 0x00], [0x04, 0x00, 0x00, 0x00],
18
+ [0x08, 0x00, 0x00, 0x00], [0x10, 0x00, 0x00, 0x00], [0x20, 0x00, 0x00, 0x00], [0x40, 0x00, 0x00, 0x00],
19
+ [0x80, 0x00, 0x00, 0x00], [0x1b, 0x00, 0x00, 0x00], [0x36, 0x00, 0x00, 0x00]]
20
+
21
+ function addRoundKey(
22
+ state: number[][],
23
+ roundKeyArray: number[][],
24
+ offset: number
25
+ ): void {
26
+ let i
27
+ let j: number
28
+ for (i = 0; i < 4; i++) {
29
+ for (j = 0; j < 4; j++) {
30
+ state[i][j] = state[i][j] ^ roundKeyArray[offset + j][i]
31
+ }
32
+ }
33
+ }
34
+
35
+ function subBytes(state: number[][]): void {
36
+ let i
37
+ let j
38
+ for (i = 0; i < 4; i++) {
39
+ for (j = 0; j < 4; j++) {
40
+ state[i][j] = SBox[(state[i][j] & 0xF0) >> 4][(state[i][j] & 0x0F)]
41
+ }
42
+ }
43
+ }
44
+
45
+ function subWord(value: number[]): void {
46
+ let i
47
+ for (i = 0; i < 4; i++) {
48
+ value[i] = SBox[(value[i] & 0xF0) >> 4][(value[i] & 0x0F)]
49
+ }
50
+ }
51
+
52
+ function rotWord(value: number[]): void {
53
+ const temp = value[0]
54
+
55
+ value[0] = value[1]
56
+ value[1] = value[2]
57
+ value[2] = value[3]
58
+ value[3] = temp
59
+ }
60
+
61
+ function shiftRows(state: number[][]): void {
62
+ let i: number
63
+ let j: number
64
+ let k: number
65
+ let l: number
66
+ let temp
67
+
68
+ for (i = 1; i < 4; i++) {
69
+ for (j = 0; j < ((i - 1) % 2) + 1; j++) {
70
+ temp = state[i][j]
71
+ k = j
72
+ while (true) {
73
+ l = k + i
74
+ if (l >= 4) {
75
+ l = l - 4
76
+ }
77
+
78
+ if (l === j) {
79
+ break
80
+ }
81
+
82
+ state[i][k] = state[i][l]
83
+ k = l
84
+ }
85
+
86
+ state[i][k] = temp
87
+ }
88
+ }
89
+ }
90
+
91
+ function finiteFieldMultiplication(value0: number, value1: number): number {
92
+ let i
93
+ let result = 0
94
+
95
+ for (i = 0; i < 8; i++) {
96
+ if ((value1 & 1) !== 0) {
97
+ result = result ^ value0
98
+ }
99
+
100
+ if ((value0 & 0x80) !== 0) {
101
+ value0 = value0 << 1
102
+ value0 = value0 ^ 0x11b
103
+ } else {
104
+ value0 = value0 << 1
105
+ }
106
+
107
+ value1 = value1 >> 1
108
+ }
109
+
110
+ return result
111
+ }
112
+
113
+ function mixColumns(state: number[][]): void {
114
+ let i
115
+ let j
116
+ const temp: number[][] = [[], [], [], []]
117
+
118
+ for (i = 0; i < 4; i++) {
119
+ temp[0][i] = finiteFieldMultiplication(0x02, state[0][i]) ^ finiteFieldMultiplication(0x03, state[1][i]) ^
120
+ state[2][i] ^ state[3][i]
121
+ temp[1][i] = state[0][i] ^ finiteFieldMultiplication(0x02, state[1][i]) ^
122
+ finiteFieldMultiplication(0x03, state[2][i]) ^ state[3][i]
123
+ temp[2][i] = state[0][i] ^ state[1][i] ^ finiteFieldMultiplication(0x02, state[2][i]) ^
124
+ finiteFieldMultiplication(0x03, state[3][i])
125
+ temp[3][i] = finiteFieldMultiplication(0x03, state[0][i]) ^ state[1][i] ^ state[2][i] ^
126
+ finiteFieldMultiplication(0x02, state[3][i])
127
+ }
128
+
129
+ for (i = 0; i < 4; i++) {
130
+ for (j = 0; j < 4; j++) {
131
+ state[i][j] = temp[i][j]
132
+ }
133
+ }
134
+ }
135
+
136
+ function keyExpansion(roundLimit: number, key: number[]): number[][] {
137
+ let i
138
+ let j
139
+ const nK = parseInt(String(key.length / 4))
140
+ const result = []
141
+
142
+ for (i = 0; i < key.length; i++) {
143
+ if (i % 4 === 0) {
144
+ result.push([])
145
+ }
146
+
147
+ result[parseInt(String(i / 4))].push(key[i])
148
+ }
149
+
150
+ for (i = nK; i < 4 * roundLimit; i++) {
151
+ result[i] = []
152
+ const temp = result[i - 1].slice()
153
+
154
+ if (i % nK === 0) {
155
+ rotWord(temp)
156
+ subWord(temp)
157
+
158
+ for (j = 0; j < 4; j++) {
159
+ temp[j] = temp[j] ^ Rcon[parseInt(String(i / nK))][j]
160
+ }
161
+ } else if (nK > 6 && (i % nK) === 4) {
162
+ subWord(temp)
163
+ }
164
+
165
+ for (j = 0; j < 4; j++) {
166
+ result[i][j] = result[i - nK][j] ^ temp[j]
167
+ }
168
+ }
169
+
170
+ return result
171
+ }
172
+
173
+ export function AES(input: number[], key: number[]): number[] {
174
+ let i
175
+ let j
176
+ let round: number
177
+ let roundLimit
178
+ const state = [[], [], [], []]
179
+ const output = []
180
+
181
+ if (key.length === 16) {
182
+ roundLimit = 11
183
+ } else if (key.length === 24) {
184
+ roundLimit = 13
185
+ } else if (key.length === 32) {
186
+ roundLimit = 15
187
+ } else {
188
+ throw new Error('Illegal key length: ' + String(key.length))
189
+ }
190
+
191
+ const w = keyExpansion(roundLimit, key)
192
+
193
+ for (i = 0; i < 15; i++) {
194
+ state[parseInt(String(i / 4))].push(input[(i * 4) % 15])
195
+ }
196
+ state[3].push(input[15])
197
+
198
+ addRoundKey(state, w, 0)
199
+ for (round = 1; round < roundLimit; round++) {
200
+ subBytes(state)
201
+ shiftRows(state)
202
+
203
+ if (round + 1 < roundLimit) {
204
+ mixColumns(state)
205
+ }
206
+
207
+ addRoundKey(state, w, round * 4)
208
+ }
209
+
210
+ for (i = 0; i < 4; i++) {
211
+ for (j = 0; j < 4; j++) {
212
+ output.push(state[j][i])
213
+ }
214
+ }
215
+
216
+ return output
217
+ }
218
+
219
+ export const checkBit = function (
220
+ byteArray: number[],
221
+ byteIndex: number,
222
+ bitIndex: number
223
+ ): 1 | 0 {
224
+ return (byteArray[byteIndex] & (0x01 << bitIndex)) !== 0 ? 1 : 0
225
+ }
226
+
227
+ export const getBytes = function (numericValue: number): number[] {
228
+ return [
229
+ (numericValue & 0xFF000000) >>> 24,
230
+ (numericValue & 0x00FF0000) >> 16,
231
+ (numericValue & 0x0000FF00) >> 8,
232
+ numericValue & 0x000000FF
233
+ ]
234
+ }
235
+
236
+ const createZeroBlock = function (length: number): number[] {
237
+ let i
238
+ const result = []
239
+
240
+ for (i = 0; i < length; i++) {
241
+ result.push(0x00)
242
+ }
243
+
244
+ return result
245
+ }
246
+
247
+ const R = [0xe1].concat(createZeroBlock(15))
248
+
249
+ export const exclusiveOR = function (block0: number[], block1: number[]): number[] {
250
+ let i
251
+ const result = []
252
+
253
+ for (i = 0; i < block0.length; i++) {
254
+ result[i] = block0[i] ^ block1[i]
255
+ }
256
+
257
+ return result
258
+ }
259
+
260
+ export const rightShift = function (block: number[]): number[] {
261
+ let i: number
262
+ let carry = 0
263
+ let oldCarry = 0
264
+
265
+ for (i = 0; i < block.length; i++) {
266
+ oldCarry = carry
267
+ carry = block[i] & 0x01
268
+ block[i] = block[i] >> 1
269
+
270
+ if (oldCarry !== 0) {
271
+ block[i] = block[i] | 0x80
272
+ }
273
+ }
274
+
275
+ return block
276
+ }
277
+
278
+ export const multiply = function (block0: number[], block1: number[]): number[] {
279
+ let i
280
+ let j
281
+ let v = block1.slice()
282
+ let z = createZeroBlock(16)
283
+
284
+ for (i = 0; i < 16; i++) {
285
+ for (j = 7; j !== -1; j--) {
286
+ if (checkBit(block0, i, j) !== 0) {
287
+ z = exclusiveOR(z, v)
288
+ }
289
+
290
+ if (checkBit(v, 15, 0) !== 0) {
291
+ v = exclusiveOR(rightShift(v), R)
292
+ } else {
293
+ v = rightShift(v)
294
+ }
295
+ }
296
+ }
297
+
298
+ return z
299
+ }
300
+
301
+ export const incrementLeastSignificantThirtyTwoBits = function (
302
+ block: number[]
303
+ ): number[] {
304
+ let i
305
+ const result = block.slice()
306
+ for (i = 15; i !== 11; i--) {
307
+ result[i] = result[i] + 1
308
+
309
+ if (result[i] === 256) {
310
+ result[i] = 0
311
+ } else {
312
+ break
313
+ }
314
+ }
315
+
316
+ return result
317
+ }
318
+
319
+ export function ghash(input: number[], hashSubKey: number[]): number[] {
320
+ let i: number
321
+ let result = createZeroBlock(16)
322
+
323
+ for (i = 0; i < input.length; i += 16) {
324
+ result = multiply(
325
+ exclusiveOR(
326
+ result,
327
+ input.slice(i, Math.min(i + 16, input.length))
328
+ ),
329
+ hashSubKey
330
+ )
331
+ }
332
+
333
+ return result
334
+ }
335
+
336
+ function gctr(
337
+ input: number[],
338
+ initialCounterBlock: number[],
339
+ key: number[]
340
+ ): number[] {
341
+ let i: number
342
+ let j
343
+ let y
344
+ let counterBlock = initialCounterBlock
345
+ const output = []
346
+
347
+ if (input.length === 0) {
348
+ return input
349
+ }
350
+
351
+ const n = Math.ceil(input.length / 16)
352
+ for (i = 0; i < n; i++) {
353
+ y = exclusiveOR(input.slice(i * 16, Math.min((i + 1) * 16, input.length)),
354
+ AES(counterBlock, key))
355
+
356
+ for (j = 0; j < y.length; j++) {
357
+ output.push(y[j])
358
+ }
359
+
360
+ if (i + 1 < n) {
361
+ counterBlock = incrementLeastSignificantThirtyTwoBits(counterBlock)
362
+ }
363
+ }
364
+
365
+ return output
366
+ }
367
+
368
+ export function AESGCM(
369
+ plainText: number[],
370
+ additionalAuthenticatedData: number[],
371
+ initializationVector: number[],
372
+ key: number[]
373
+ ): { result: number[], authenticationTag: number[] } {
374
+ let preCounterBlock
375
+ let plainTag
376
+ const hashSubKey = AES(createZeroBlock(16), key)
377
+ preCounterBlock = [...initializationVector]
378
+ if (initializationVector.length === 12) {
379
+ preCounterBlock = preCounterBlock.concat(createZeroBlock(3)).concat([0x01])
380
+ } else {
381
+ if (initializationVector.length % 16 !== 0) {
382
+ preCounterBlock = preCounterBlock.concat(
383
+ createZeroBlock(16 - (initializationVector.length % 16))
384
+ )
385
+ }
386
+
387
+ preCounterBlock = preCounterBlock.concat(createZeroBlock(8))
388
+
389
+ preCounterBlock = ghash(preCounterBlock.concat(createZeroBlock(4))
390
+ .concat(getBytes(initializationVector.length * 8)), hashSubKey)
391
+ }
392
+
393
+ const cipherText = gctr(plainText, incrementLeastSignificantThirtyTwoBits(preCounterBlock), key)
394
+
395
+ plainTag = additionalAuthenticatedData.slice()
396
+
397
+ if (additionalAuthenticatedData.length === 0) {
398
+ plainTag = plainTag.concat(createZeroBlock(16))
399
+ } else if (additionalAuthenticatedData.length % 16 !== 0) {
400
+ plainTag = plainTag.concat(createZeroBlock(16 - (additionalAuthenticatedData.length % 16)))
401
+ }
402
+
403
+ plainTag = plainTag.concat(cipherText)
404
+
405
+ if (cipherText.length === 0) {
406
+ plainTag = plainTag.concat(createZeroBlock(16))
407
+ } else if (cipherText.length % 16 !== 0) {
408
+ plainTag = plainTag.concat(createZeroBlock(16 - (cipherText.length % 16)))
409
+ }
410
+
411
+ plainTag = plainTag.concat(createZeroBlock(4))
412
+ .concat(getBytes(additionalAuthenticatedData.length * 8))
413
+ .concat(createZeroBlock(4)).concat(getBytes(cipherText.length * 8))
414
+
415
+ return {
416
+ result: cipherText,
417
+ authenticationTag: gctr(ghash(plainTag, hashSubKey), preCounterBlock, key)
418
+ }
419
+ }
420
+
421
+ export function AESGCMDecrypt(
422
+ cipherText: number[],
423
+ additionalAuthenticatedData: number[],
424
+ initializationVector: number[],
425
+ authenticationTag: number[],
426
+ key: number[]
427
+ ): number[] | null {
428
+ let preCounterBlock
429
+ let compareTag
430
+
431
+ // Generate the hash subkey
432
+ const hashSubKey = AES(createZeroBlock(16), key)
433
+
434
+ preCounterBlock = [...initializationVector]
435
+ if (initializationVector.length === 12) {
436
+ preCounterBlock = preCounterBlock.concat(createZeroBlock(3)).concat([0x01])
437
+ } else {
438
+ if (initializationVector.length % 16 !== 0) {
439
+ preCounterBlock = preCounterBlock.concat(createZeroBlock(16 - (initializationVector.length % 16)))
440
+ }
441
+
442
+ preCounterBlock = preCounterBlock.concat(createZeroBlock(8))
443
+
444
+ preCounterBlock = ghash(preCounterBlock.concat(createZeroBlock(4)).concat(getBytes(initializationVector.length * 8)), hashSubKey)
445
+ }
446
+
447
+ // Decrypt to obtain the plain text
448
+ const plainText = gctr(cipherText, incrementLeastSignificantThirtyTwoBits(preCounterBlock), key)
449
+
450
+ compareTag = additionalAuthenticatedData.slice()
451
+
452
+ if (additionalAuthenticatedData.length === 0) {
453
+ compareTag = compareTag.concat(createZeroBlock(16))
454
+ } else if (additionalAuthenticatedData.length % 16 !== 0) {
455
+ compareTag = compareTag.concat(createZeroBlock(16 - (additionalAuthenticatedData.length % 16)))
456
+ }
457
+
458
+ compareTag = compareTag.concat(cipherText)
459
+
460
+ if (cipherText.length === 0) {
461
+ compareTag = compareTag.concat(createZeroBlock(16))
462
+ } else if (cipherText.length % 16 !== 0) {
463
+ compareTag = compareTag.concat(createZeroBlock(16 - (cipherText.length % 16)))
464
+ }
465
+
466
+ compareTag = compareTag.concat(createZeroBlock(4))
467
+ .concat(getBytes(additionalAuthenticatedData.length * 8))
468
+ .concat(createZeroBlock(4)).concat(getBytes(cipherText.length * 8))
469
+
470
+ // Generate the authentication tag
471
+ const calculatedTag = gctr(ghash(compareTag, hashSubKey), preCounterBlock, key)
472
+
473
+ // If the calculated tag does not match the provided tag, return null - the decryption failed.
474
+ if (calculatedTag.join() !== authenticationTag.join()) {
475
+ return null
476
+ }
477
+
478
+ return plainText
479
+ }
@@ -0,0 +1,21 @@
1
+ import Curve from './Curve.js'
2
+
3
+ /**
4
+ * Base class for Point (affine coordinates) and JacobianPoint classes,
5
+ * defining their curve and type.
6
+ */
7
+ export default abstract class BasePoint {
8
+ curve: Curve
9
+ type: 'affine' | 'jacobian'
10
+ precomputed: {
11
+ doubles: { step: number, points: any[] } | undefined
12
+ naf: { wnd: any, points: any[] } | undefined
13
+ beta: BasePoint | null | undefined
14
+ } | null
15
+
16
+ constructor (type: 'affine' | 'jacobian') {
17
+ this.curve = new Curve()
18
+ this.type = type
19
+ this.precomputed = null
20
+ }
21
+ }