@bsv/sdk 1.9.24 → 1.9.30
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/dist/cjs/package.json +1 -1
- package/dist/cjs/src/primitives/AESGCM.js +160 -76
- package/dist/cjs/src/primitives/AESGCM.js.map +1 -1
- package/dist/cjs/src/primitives/ECDSA.js +22 -23
- package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
- package/dist/cjs/src/primitives/Point.js +102 -22
- package/dist/cjs/src/primitives/Point.js.map +1 -1
- package/dist/cjs/src/primitives/PrivateKey.js +2 -2
- package/dist/cjs/src/primitives/PrivateKey.js.map +1 -1
- package/dist/cjs/src/primitives/PublicKey.js +1 -1
- package/dist/cjs/src/primitives/PublicKey.js.map +1 -1
- package/dist/cjs/src/primitives/SymmetricKey.js +20 -19
- package/dist/cjs/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/cjs/src/primitives/hex.js +1 -3
- package/dist/cjs/src/primitives/hex.js.map +1 -1
- package/dist/cjs/src/primitives/utils.js +10 -0
- package/dist/cjs/src/primitives/utils.js.map +1 -1
- package/dist/cjs/src/totp/totp.js +3 -1
- package/dist/cjs/src/totp/totp.js.map +1 -1
- package/dist/cjs/src/wallet/ProtoWallet.js +4 -2
- package/dist/cjs/src/wallet/ProtoWallet.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/primitives/AESGCM.js +158 -75
- package/dist/esm/src/primitives/AESGCM.js.map +1 -1
- package/dist/esm/src/primitives/ECDSA.js +22 -23
- package/dist/esm/src/primitives/ECDSA.js.map +1 -1
- package/dist/esm/src/primitives/Point.js +102 -22
- package/dist/esm/src/primitives/Point.js.map +1 -1
- package/dist/esm/src/primitives/PrivateKey.js +2 -2
- package/dist/esm/src/primitives/PrivateKey.js.map +1 -1
- package/dist/esm/src/primitives/PublicKey.js +1 -1
- package/dist/esm/src/primitives/PublicKey.js.map +1 -1
- package/dist/esm/src/primitives/SymmetricKey.js +20 -19
- package/dist/esm/src/primitives/SymmetricKey.js.map +1 -1
- package/dist/esm/src/primitives/hex.js +1 -3
- package/dist/esm/src/primitives/hex.js.map +1 -1
- package/dist/esm/src/primitives/utils.js +9 -0
- package/dist/esm/src/primitives/utils.js.map +1 -1
- package/dist/esm/src/totp/totp.js +3 -1
- package/dist/esm/src/totp/totp.js.map +1 -1
- package/dist/esm/src/wallet/ProtoWallet.js +4 -2
- package/dist/esm/src/wallet/ProtoWallet.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/primitives/AESGCM.d.ts +59 -9
- package/dist/types/src/primitives/AESGCM.d.ts.map +1 -1
- package/dist/types/src/primitives/ECDSA.d.ts.map +1 -1
- package/dist/types/src/primitives/Point.d.ts +2 -0
- package/dist/types/src/primitives/Point.d.ts.map +1 -1
- package/dist/types/src/primitives/SymmetricKey.d.ts.map +1 -1
- package/dist/types/src/primitives/hex.d.ts.map +1 -1
- package/dist/types/src/primitives/utils.d.ts +1 -0
- package/dist/types/src/primitives/utils.d.ts.map +1 -1
- package/dist/types/src/totp/totp.d.ts.map +1 -1
- package/dist/types/src/wallet/ProtoWallet.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +3 -3
- package/dist/umd/bundle.js.map +1 -1
- package/docs/reference/primitives.md +206 -60
- package/package.json +1 -1
- package/src/primitives/AESGCM.ts +225 -103
- package/src/primitives/ECDSA.ts +25 -23
- package/src/primitives/Point.ts +142 -23
- package/src/primitives/PrivateKey.ts +2 -2
- package/src/primitives/PublicKey.ts +1 -1
- package/src/primitives/SymmetricKey.ts +28 -20
- package/src/primitives/__tests/AESGCM.test.ts +254 -354
- package/src/primitives/__tests/ECDSA.test.ts +39 -0
- package/src/primitives/__tests/Point.test.ts +112 -0
- package/src/primitives/__tests/utils.test.ts +24 -1
- package/src/primitives/hex.ts +1 -3
- package/src/primitives/utils.ts +10 -0
- package/src/totp/__tests/totp.test.ts +21 -0
- package/src/totp/totp.ts +9 -1
- package/src/wallet/ProtoWallet.ts +8 -3
- package/src/wallet/__tests/ProtoWallet.test.ts +55 -34
package/src/primitives/Point.ts
CHANGED
|
@@ -3,6 +3,21 @@ import JPoint from './JacobianPoint.js'
|
|
|
3
3
|
import BigNumber from './BigNumber.js'
|
|
4
4
|
import { toArray, toHex } from './utils.js'
|
|
5
5
|
|
|
6
|
+
function ctSwap (
|
|
7
|
+
swap: bigint,
|
|
8
|
+
a: JacobianPointBI,
|
|
9
|
+
b: JacobianPointBI
|
|
10
|
+
): void {
|
|
11
|
+
const mask = -swap
|
|
12
|
+
const swapX = (a.X ^ b.X) & mask
|
|
13
|
+
const swapY = (a.Y ^ b.Y) & mask
|
|
14
|
+
const swapZ = (a.Z ^ b.Z) & mask
|
|
15
|
+
|
|
16
|
+
a.X ^= swapX; b.X ^= swapX
|
|
17
|
+
a.Y ^= swapY; b.Y ^= swapY
|
|
18
|
+
a.Z ^= swapZ; b.Z ^= swapZ
|
|
19
|
+
}
|
|
20
|
+
|
|
6
21
|
// -----------------------------------------------------------------------------
|
|
7
22
|
// BigInt helpers & constants (secp256k1) – hoisted so we don't recreate them on
|
|
8
23
|
// every Point.mul() call.
|
|
@@ -44,14 +59,17 @@ export const biModInv = (a: bigint): bigint => { // binary‑ext GCD
|
|
|
44
59
|
export const biModSqr = (a: bigint): bigint => biModMul(a, a)
|
|
45
60
|
|
|
46
61
|
export const biModPow = (base: bigint, exp: bigint): bigint => {
|
|
47
|
-
let result =
|
|
62
|
+
let result = 1n
|
|
48
63
|
base = biMod(base)
|
|
49
|
-
|
|
50
|
-
while (
|
|
51
|
-
if ((
|
|
64
|
+
|
|
65
|
+
while (exp > 0n) {
|
|
66
|
+
if ((exp & 1n) !== 0n) {
|
|
67
|
+
result = biModMul(result, base)
|
|
68
|
+
}
|
|
52
69
|
base = biModMul(base, base)
|
|
53
|
-
|
|
70
|
+
exp >>= 1n
|
|
54
71
|
}
|
|
72
|
+
|
|
55
73
|
return result
|
|
56
74
|
}
|
|
57
75
|
|
|
@@ -59,7 +77,12 @@ export const P_PLUS1_DIV4 = (P_BIGINT + 1n) >> 2n
|
|
|
59
77
|
|
|
60
78
|
export const biModSqrt = (a: bigint): bigint | null => {
|
|
61
79
|
const r = biModPow(a, P_PLUS1_DIV4)
|
|
62
|
-
|
|
80
|
+
|
|
81
|
+
if (biModMul(r, r) !== biMod(a)) {
|
|
82
|
+
return null
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return r
|
|
63
86
|
}
|
|
64
87
|
|
|
65
88
|
const toBigInt = (x: BigNumber | number | number[] | string): bigint => {
|
|
@@ -94,6 +117,10 @@ export const jpDouble = (P: JacobianPointBI): JacobianPointBI => {
|
|
|
94
117
|
return { X: X3, Y: Y3, Z: Z3 }
|
|
95
118
|
}
|
|
96
119
|
|
|
120
|
+
// NOTE:
|
|
121
|
+
// jpAdd contains conditional branches.
|
|
122
|
+
// In mulCT, jpAdd and jpDouble are executed in a fixed pattern
|
|
123
|
+
// independent of scalar bits, satisfying TOB-4 constant-time requirements.
|
|
97
124
|
export const jpAdd = (P: JacobianPointBI, Q: JacobianPointBI): JacobianPointBI => {
|
|
98
125
|
if (P.Z === BI_ZERO) return Q
|
|
99
126
|
if (Q.Z === BI_ZERO) return P
|
|
@@ -220,6 +247,13 @@ export default class Point extends BasePoint {
|
|
|
220
247
|
y: BigNumber | null
|
|
221
248
|
inf: boolean
|
|
222
249
|
|
|
250
|
+
static _assertOnCurve (p: Point): Point {
|
|
251
|
+
if (!p.validate()) {
|
|
252
|
+
throw new Error('Invalid point')
|
|
253
|
+
}
|
|
254
|
+
return p
|
|
255
|
+
}
|
|
256
|
+
|
|
223
257
|
/**
|
|
224
258
|
* Creates a point object from a given Array. These numbers can represent coordinates in hex format, or points
|
|
225
259
|
* in multiple established formats.
|
|
@@ -238,7 +272,6 @@ export default class Point extends BasePoint {
|
|
|
238
272
|
*/
|
|
239
273
|
static fromDER (bytes: number[]): Point {
|
|
240
274
|
const len = 32
|
|
241
|
-
// uncompressed, hybrid-odd, hybrid-even
|
|
242
275
|
if (
|
|
243
276
|
(bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) &&
|
|
244
277
|
bytes.length - 1 === 2 * len
|
|
@@ -258,12 +291,14 @@ export default class Point extends BasePoint {
|
|
|
258
291
|
bytes.slice(1 + len, 1 + 2 * len)
|
|
259
292
|
)
|
|
260
293
|
|
|
261
|
-
return res
|
|
294
|
+
return Point._assertOnCurve(res)
|
|
262
295
|
} else if (
|
|
263
296
|
(bytes[0] === 0x02 || bytes[0] === 0x03) &&
|
|
264
297
|
bytes.length - 1 === len
|
|
265
298
|
) {
|
|
266
|
-
return Point.
|
|
299
|
+
return Point._assertOnCurve(
|
|
300
|
+
Point.fromX(bytes.slice(1, 1 + len), bytes[0] === 0x03)
|
|
301
|
+
)
|
|
267
302
|
}
|
|
268
303
|
throw new Error('Unknown point format')
|
|
269
304
|
}
|
|
@@ -287,7 +322,7 @@ export default class Point extends BasePoint {
|
|
|
287
322
|
*/
|
|
288
323
|
static fromString (str: string): Point {
|
|
289
324
|
const bytes = toArray(str, 'hex')
|
|
290
|
-
return Point.fromDER(bytes)
|
|
325
|
+
return Point._assertOnCurve(Point.fromDER(bytes))
|
|
291
326
|
}
|
|
292
327
|
|
|
293
328
|
/**
|
|
@@ -308,16 +343,22 @@ export default class Point extends BasePoint {
|
|
|
308
343
|
static fromX (x: BigNumber | number | number[] | string, odd: boolean): Point {
|
|
309
344
|
let xBigInt = toBigInt(x)
|
|
310
345
|
xBigInt = biMod(xBigInt)
|
|
346
|
+
|
|
311
347
|
const y2 = biModAdd(biModMul(biModSqr(xBigInt), xBigInt), 7n)
|
|
312
348
|
const y = biModSqrt(y2)
|
|
313
|
-
if (y === null)
|
|
349
|
+
if (y === null) {
|
|
350
|
+
throw new Error('Invalid point')
|
|
351
|
+
}
|
|
352
|
+
|
|
314
353
|
let yBig = y
|
|
315
354
|
if ((yBig & BI_ONE) !== (odd ? BI_ONE : BI_ZERO)) {
|
|
316
355
|
yBig = biModSub(P_BIGINT, yBig)
|
|
317
356
|
}
|
|
357
|
+
|
|
318
358
|
const xBN = new BigNumber(xBigInt.toString(16), 16)
|
|
319
359
|
const yBN = new BigNumber(yBig.toString(16), 16)
|
|
320
|
-
|
|
360
|
+
|
|
361
|
+
return Point._assertOnCurve(new Point(xBN, yBN))
|
|
321
362
|
}
|
|
322
363
|
|
|
323
364
|
/**
|
|
@@ -339,33 +380,45 @@ export default class Point extends BasePoint {
|
|
|
339
380
|
if (typeof obj === 'string') {
|
|
340
381
|
obj = JSON.parse(obj)
|
|
341
382
|
}
|
|
342
|
-
|
|
343
|
-
|
|
383
|
+
|
|
384
|
+
let res = new Point(obj[0], obj[1], isRed)
|
|
385
|
+
res = Point._assertOnCurve(res)
|
|
386
|
+
|
|
387
|
+
if (typeof obj[2] !== 'object' || obj[2] === null) {
|
|
344
388
|
return res
|
|
345
389
|
}
|
|
346
390
|
|
|
347
|
-
const
|
|
348
|
-
|
|
391
|
+
const pre = obj[2]
|
|
392
|
+
|
|
393
|
+
const obj2point = (p): Point => {
|
|
394
|
+
const pt = new Point(p[0], p[1], isRed)
|
|
395
|
+
return Point._assertOnCurve(pt)
|
|
349
396
|
}
|
|
350
397
|
|
|
351
|
-
const pre = obj[2]
|
|
352
398
|
res.precomputed = {
|
|
353
399
|
beta: null,
|
|
400
|
+
|
|
354
401
|
doubles:
|
|
355
402
|
typeof pre.doubles === 'object' && pre.doubles !== null
|
|
356
403
|
? {
|
|
357
404
|
step: pre.doubles.step,
|
|
358
|
-
points: [res].concat(
|
|
405
|
+
points: [res].concat(
|
|
406
|
+
pre.doubles.points.map(obj2point)
|
|
407
|
+
)
|
|
359
408
|
}
|
|
360
409
|
: undefined,
|
|
410
|
+
|
|
361
411
|
naf:
|
|
362
412
|
typeof pre.naf === 'object' && pre.naf !== null
|
|
363
413
|
? {
|
|
364
414
|
wnd: pre.naf.wnd,
|
|
365
|
-
points: [res].concat(
|
|
415
|
+
points: [res].concat(
|
|
416
|
+
pre.naf.points.map(obj2point)
|
|
417
|
+
)
|
|
366
418
|
}
|
|
367
419
|
: undefined
|
|
368
420
|
}
|
|
421
|
+
|
|
369
422
|
return res
|
|
370
423
|
}
|
|
371
424
|
|
|
@@ -426,7 +479,20 @@ export default class Point extends BasePoint {
|
|
|
426
479
|
* const isValid = aPoint.validate();
|
|
427
480
|
*/
|
|
428
481
|
validate (): boolean {
|
|
429
|
-
|
|
482
|
+
if (this.inf || this.x == null || this.y == null) return false
|
|
483
|
+
|
|
484
|
+
try {
|
|
485
|
+
const xBig = BigInt('0x' + this.x.fromRed().toString(16))
|
|
486
|
+
const yBig = BigInt('0x' + this.y.fromRed().toString(16))
|
|
487
|
+
|
|
488
|
+
// compute y² and x³ + 7 using bigint-secure field ops
|
|
489
|
+
const lhs = biModMul(yBig, yBig)
|
|
490
|
+
const rhs = biModAdd(biModMul(biModMul(xBig, xBig), xBig), 7n)
|
|
491
|
+
|
|
492
|
+
return lhs === rhs
|
|
493
|
+
} catch {
|
|
494
|
+
return false
|
|
495
|
+
}
|
|
430
496
|
}
|
|
431
497
|
|
|
432
498
|
/**
|
|
@@ -687,13 +753,17 @@ export default class Point extends BasePoint {
|
|
|
687
753
|
return this
|
|
688
754
|
}
|
|
689
755
|
|
|
690
|
-
|
|
691
|
-
const
|
|
692
|
-
|
|
756
|
+
const isNeg = k.isNeg()
|
|
757
|
+
const kAbs = isNeg ? k.neg() : k
|
|
758
|
+
let kBig = BigInt('0x' + kAbs.toString(16))
|
|
759
|
+
|
|
693
760
|
kBig = biMod(kBig)
|
|
694
761
|
if (kBig === BI_ZERO) {
|
|
695
762
|
return new Point(null, null)
|
|
696
763
|
}
|
|
764
|
+
if (kBig === BI_ZERO) {
|
|
765
|
+
return new Point(null, null)
|
|
766
|
+
}
|
|
697
767
|
|
|
698
768
|
if (this.x === null || this.y === null) {
|
|
699
769
|
throw new Error('Point coordinates cannot be null')
|
|
@@ -727,6 +797,55 @@ export default class Point extends BasePoint {
|
|
|
727
797
|
return result
|
|
728
798
|
}
|
|
729
799
|
|
|
800
|
+
mulCT (k: BigNumber | number | number[] | string): Point {
|
|
801
|
+
if (!BigNumber.isBN(k)) {
|
|
802
|
+
k = new BigNumber(k as any, 16)
|
|
803
|
+
}
|
|
804
|
+
k = k as BigNumber
|
|
805
|
+
|
|
806
|
+
if (this.inf) return new Point(null, null)
|
|
807
|
+
|
|
808
|
+
// ✅ SAFE sign handling (this is the fix)
|
|
809
|
+
const isNeg = k.isNeg()
|
|
810
|
+
const kAbs = isNeg ? k.neg() : k
|
|
811
|
+
let kBig = BigInt('0x' + kAbs.toString(16))
|
|
812
|
+
|
|
813
|
+
kBig = biMod(kBig)
|
|
814
|
+
if (kBig === 0n) return new Point(null, null)
|
|
815
|
+
|
|
816
|
+
const Px =
|
|
817
|
+
this === this.curve.g
|
|
818
|
+
? GX_BIGINT
|
|
819
|
+
: BigInt('0x' + this.getX().toString(16))
|
|
820
|
+
|
|
821
|
+
const Py =
|
|
822
|
+
this === this.curve.g
|
|
823
|
+
? GY_BIGINT
|
|
824
|
+
: BigInt('0x' + this.getY().toString(16))
|
|
825
|
+
|
|
826
|
+
let R0: JacobianPointBI = { X: 0n, Y: 1n, Z: 0n }
|
|
827
|
+
let R1: JacobianPointBI = { X: Px, Y: Py, Z: 1n }
|
|
828
|
+
|
|
829
|
+
const bits = kBig.toString(2)
|
|
830
|
+
for (let i = 0; i < bits.length; i++) {
|
|
831
|
+
const bit = bits[i] === '1' ? 1n : 0n
|
|
832
|
+
ctSwap(bit, R0, R1)
|
|
833
|
+
R1 = jpAdd(R0, R1)
|
|
834
|
+
R0 = jpDouble(R0)
|
|
835
|
+
ctSwap(bit, R0, R1)
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
if (R0.Z === 0n) return new Point(null, null)
|
|
839
|
+
|
|
840
|
+
const zInv = biModInv(R0.Z)
|
|
841
|
+
const zInv2 = biModMul(zInv, zInv)
|
|
842
|
+
const x = biModMul(R0.X, zInv2)
|
|
843
|
+
const y = biModMul(R0.Y, biModMul(zInv2, zInv))
|
|
844
|
+
|
|
845
|
+
const result = new Point(x.toString(16), y.toString(16))
|
|
846
|
+
return isNeg ? result.neg() : result
|
|
847
|
+
}
|
|
848
|
+
|
|
730
849
|
/**
|
|
731
850
|
* Performs a multiplication and addition operation in a single step.
|
|
732
851
|
* Multiplies this Point by k1, adds the resulting Point to the result of p2 multiplied by k2.
|
|
@@ -260,7 +260,7 @@ export default class PrivateKey extends BigNumber {
|
|
|
260
260
|
*/
|
|
261
261
|
toPublicKey (): PublicKey {
|
|
262
262
|
const c = new Curve()
|
|
263
|
-
const p = c.g.
|
|
263
|
+
const p = c.g.mulCT(this)
|
|
264
264
|
return new PublicKey(p.x, p.y)
|
|
265
265
|
}
|
|
266
266
|
|
|
@@ -352,7 +352,7 @@ export default class PrivateKey extends BigNumber {
|
|
|
352
352
|
if (!key.validate()) {
|
|
353
353
|
throw new Error('Public key not valid for ECDH secret derivation')
|
|
354
354
|
}
|
|
355
|
-
return key.
|
|
355
|
+
return key.mulCT(this)
|
|
356
356
|
}
|
|
357
357
|
|
|
358
358
|
/**
|
|
@@ -41,19 +41,27 @@ export default class SymmetricKey extends BigNumber {
|
|
|
41
41
|
* const encryptedMessage = key.encrypt('plainText', 'utf8');
|
|
42
42
|
*/
|
|
43
43
|
encrypt (msg: number[] | string, enc?: 'hex'): string | number[] {
|
|
44
|
-
const iv = Random(32)
|
|
45
|
-
|
|
46
|
-
const keyBytes = this.toArray('be', 32)
|
|
47
|
-
|
|
44
|
+
const iv = new Uint8Array(Random(32))
|
|
45
|
+
const msgBytes = new Uint8Array(toArray(msg, enc))
|
|
46
|
+
const keyBytes = new Uint8Array(this.toArray('be', 32))
|
|
47
|
+
|
|
48
|
+
const { result, authenticationTag } = AESGCM(
|
|
49
|
+
msgBytes,
|
|
50
|
+
iv,
|
|
51
|
+
keyBytes
|
|
52
|
+
)
|
|
53
|
+
|
|
48
54
|
const totalLength = iv.length + result.length + authenticationTag.length
|
|
49
|
-
const combined = new
|
|
55
|
+
const combined = new Uint8Array(totalLength)
|
|
50
56
|
let offset = 0
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
|
|
58
|
+
combined.set(iv, offset)
|
|
59
|
+
offset += iv.length
|
|
60
|
+
combined.set(result, offset)
|
|
61
|
+
offset += result.length
|
|
62
|
+
combined.set(authenticationTag, offset)
|
|
63
|
+
|
|
64
|
+
return encode(Array.from(combined), enc)
|
|
57
65
|
}
|
|
58
66
|
|
|
59
67
|
/**
|
|
@@ -73,30 +81,30 @@ export default class SymmetricKey extends BigNumber {
|
|
|
73
81
|
* @throws {Error} Will throw an error if the decryption fails, likely due to message tampering or incorrect decryption key.
|
|
74
82
|
*/
|
|
75
83
|
decrypt (msg: number[] | string, enc?: 'hex' | 'utf8'): string | number[] {
|
|
76
|
-
|
|
84
|
+
const msgBytes = new Uint8Array(toArray(msg, enc))
|
|
77
85
|
|
|
78
86
|
const ivLength = 32
|
|
79
87
|
const tagLength = 16
|
|
80
88
|
|
|
81
|
-
if (
|
|
89
|
+
if (msgBytes.length < ivLength + tagLength) {
|
|
82
90
|
throw new Error('Ciphertext too short')
|
|
83
91
|
}
|
|
84
92
|
|
|
85
|
-
const iv =
|
|
86
|
-
const tagStart =
|
|
87
|
-
const ciphertext =
|
|
88
|
-
const messageTag =
|
|
93
|
+
const iv = msgBytes.slice(0, ivLength)
|
|
94
|
+
const tagStart = msgBytes.length - tagLength
|
|
95
|
+
const ciphertext = msgBytes.slice(ivLength, tagStart)
|
|
96
|
+
const messageTag = msgBytes.slice(tagStart)
|
|
89
97
|
|
|
98
|
+
const keyBytes = new Uint8Array(this.toArray('be', 32))
|
|
90
99
|
const result = AESGCMDecrypt(
|
|
91
100
|
ciphertext,
|
|
92
|
-
[],
|
|
93
101
|
iv,
|
|
94
102
|
messageTag,
|
|
95
|
-
|
|
103
|
+
keyBytes
|
|
96
104
|
)
|
|
97
105
|
if (result === null) {
|
|
98
106
|
throw new Error('Decryption failed!')
|
|
99
107
|
}
|
|
100
|
-
return encode(result, enc)
|
|
108
|
+
return encode(Array.from(result), enc)
|
|
101
109
|
}
|
|
102
110
|
}
|