@bsv/sdk 1.6.17 → 1.6.19

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 (50) hide show
  1. package/README.md +11 -11
  2. package/dist/cjs/package.json +4 -8
  3. package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js +39 -39
  4. package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
  5. package/dist/cjs/src/overlay-tools/LookupResolver.js +4 -0
  6. package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
  7. package/dist/cjs/src/primitives/ECDSA.js +26 -125
  8. package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
  9. package/dist/cjs/src/primitives/Hash.js +660 -436
  10. package/dist/cjs/src/primitives/Hash.js.map +1 -1
  11. package/dist/cjs/src/primitives/Point.js +226 -213
  12. package/dist/cjs/src/primitives/Point.js.map +1 -1
  13. package/dist/cjs/src/transaction/Beef.js +4 -4
  14. package/dist/cjs/src/transaction/Transaction.js +3 -3
  15. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  16. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  17. package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js +39 -39
  18. package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
  19. package/dist/esm/src/overlay-tools/LookupResolver.js +4 -0
  20. package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
  21. package/dist/esm/src/primitives/ECDSA.js +26 -125
  22. package/dist/esm/src/primitives/ECDSA.js.map +1 -1
  23. package/dist/esm/src/primitives/Hash.js +672 -444
  24. package/dist/esm/src/primitives/Hash.js.map +1 -1
  25. package/dist/esm/src/primitives/Point.js +211 -213
  26. package/dist/esm/src/primitives/Point.js.map +1 -1
  27. package/dist/esm/src/transaction/Beef.js +4 -4
  28. package/dist/esm/src/transaction/Transaction.js +3 -3
  29. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  30. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  31. package/dist/types/src/auth/transports/SimplifiedFetchTransport.d.ts +1 -1
  32. package/dist/types/src/auth/transports/SimplifiedFetchTransport.d.ts.map +1 -1
  33. package/dist/types/src/overlay-tools/LookupResolver.d.ts.map +1 -1
  34. package/dist/types/src/primitives/ECDSA.d.ts.map +1 -1
  35. package/dist/types/src/primitives/Hash.d.ts +12 -19
  36. package/dist/types/src/primitives/Hash.d.ts.map +1 -1
  37. package/dist/types/src/primitives/Point.d.ts +34 -0
  38. package/dist/types/src/primitives/Point.d.ts.map +1 -1
  39. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  40. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  41. package/dist/umd/bundle.js +20 -1
  42. package/dist/umd/bundle.js.map +1 -0
  43. package/package.json +4 -8
  44. package/src/auth/transports/SimplifiedFetchTransport.ts +64 -67
  45. package/src/overlay-tools/LookupResolver.ts +5 -0
  46. package/src/primitives/ECDSA.ts +30 -173
  47. package/src/primitives/Hash.ts +752 -589
  48. package/src/primitives/Point.ts +222 -247
  49. package/src/transaction/Beef.ts +4 -4
  50. package/src/transaction/Transaction.ts +11 -3
@@ -1,3 +1,4 @@
1
+
1
2
  // @ts-nocheck
2
3
  /* eslint-disable @typescript-eslint/naming-convention */
3
4
  const assert = (
@@ -239,7 +240,7 @@ export function toArray (
239
240
  if (!(msg as unknown as boolean)) {
240
241
  return []
241
242
  }
242
- const res = []
243
+ const res: number[] = []
243
244
  if (typeof msg === 'string') {
244
245
  if (enc !== 'hex') {
245
246
  // Inspired by stringToUtf8ByteArray() in closure-library by Google
@@ -325,6 +326,12 @@ function zero8 (word: string): string {
325
326
  }
326
327
  }
327
328
 
329
+ function bytesToHex (data: Uint8Array): string {
330
+ let res = ''
331
+ for (const b of data) res += (b.toString(16).padStart(2, '0') as string)
332
+ return res
333
+ }
334
+
328
335
  function join32 (msg, start, end, endian): number[] {
329
336
  const len = end - start
330
337
  assert(len % 4 === 0)
@@ -400,6 +407,7 @@ function FT_1 (s, x, y, z): number {
400
407
  if (s === 2) {
401
408
  return maj32(x, y, z)
402
409
  }
410
+ return 0
403
411
  }
404
412
 
405
413
  function ch32 (x, y, z): number {
@@ -500,126 +508,6 @@ function Kh (j): number {
500
508
  }
501
509
  }
502
510
 
503
- function sum64 (buf: number[], pos: number, ah: number, al: number): void {
504
- const bh = buf[pos]
505
- const bl = buf[pos + 1]
506
-
507
- const lo = (al + bl) >>> 0
508
- const hi = (lo < al ? 1 : 0) + ah + bh
509
- buf[pos] = hi >>> 0
510
- buf[pos + 1] = lo
511
- }
512
-
513
- function sum64HI (ah: number, al: number, bh: number, bl: number): number {
514
- const lo = (al + bl) >>> 0
515
- const hi = (lo < al ? 1 : 0) + ah + bh
516
- return hi >>> 0
517
- }
518
-
519
- function sum64LO (ah: number, al: number, bh: number, bl: number): number {
520
- const lo = al + bl
521
- return lo >>> 0
522
- }
523
-
524
- function sum64and4HI (
525
- ah: number,
526
- al: number,
527
- bh: number,
528
- bl: number,
529
- ch: number,
530
- cl: number,
531
- dh: number,
532
- dl: number
533
- ): number {
534
- let carry = 0
535
- let lo = al
536
- lo = (lo + bl) >>> 0
537
- carry += lo < al ? 1 : 0
538
- lo = (lo + cl) >>> 0
539
- carry += lo < cl ? 1 : 0
540
- lo = (lo + dl) >>> 0
541
- carry += lo < dl ? 1 : 0
542
-
543
- const hi = ah + bh + ch + dh + carry
544
- return hi >>> 0
545
- }
546
-
547
- function sum64and4LO (
548
- ah: number,
549
- al: number,
550
- bh: number,
551
- bl: number,
552
- ch: number,
553
- cl: number,
554
- dh: number,
555
- dl: number
556
- ): number {
557
- const lo = al + bl + cl + dl
558
- return lo >>> 0
559
- }
560
-
561
- function sum64and5HI (
562
- ah: number,
563
- al: number,
564
- bh: number,
565
- bl: number,
566
- ch: number,
567
- cl: number,
568
- dh: number,
569
- dl: number,
570
- eh: number,
571
- el: number
572
- ): number {
573
- let carry = 0
574
- let lo = al
575
- lo = (lo + bl) >>> 0
576
- carry += lo < al ? 1 : 0
577
- lo = (lo + cl) >>> 0
578
- carry += lo < cl ? 1 : 0
579
- lo = (lo + dl) >>> 0
580
- carry += lo < dl ? 1 : 0
581
- lo = (lo + el) >>> 0
582
- carry += lo < el ? 1 : 0
583
-
584
- const hi = ah + bh + ch + dh + eh + carry
585
- return hi >>> 0
586
- }
587
-
588
- function sum64and5LO (
589
- ah: number,
590
- al: number,
591
- bh: number,
592
- bl: number,
593
- ch: number,
594
- cl: number,
595
- dh: number,
596
- dl: number,
597
- eh: number,
598
- el: number
599
- ): number {
600
- const lo = al + bl + cl + dl + el
601
- return lo >>> 0
602
- }
603
-
604
- function rotr64HI (ah: number, al: number, num: number): number {
605
- const r = (al << (32 - num)) | (ah >>> num)
606
- return r >>> 0
607
- }
608
-
609
- function rotr64LO (ah: number, al: number, num: number): number {
610
- const r = (ah << (32 - num)) | (al >>> num)
611
- return r >>> 0
612
- }
613
-
614
- function shr64HI (ah: number, al: number, num: number): number {
615
- return ah >>> num
616
- }
617
-
618
- function shr64LO (ah: number, al: number, num: number): number {
619
- const r = (ah << (32 - num)) | (al >>> num)
620
- return r >>> 0
621
- }
622
-
623
511
  /**
624
512
  * An implementation of RIPEMD160 cryptographic hash function. Extends the BaseHash class.
625
513
  * It provides a way to compute a 'digest' for any kind of input data; transforming the data
@@ -719,88 +607,24 @@ export class RIPEMD160 extends BaseHash {
719
607
  * @property W - Provides a way to recycle usage of the array memory.
720
608
  * @property k - The round constants used for each round of SHA-256
721
609
  */
722
- export class SHA256 extends BaseHash {
723
- h: number[]
724
- W: number[]
725
- k: number[]
726
-
610
+ export class SHA256 {
611
+ private readonly h: FastSHA256
727
612
  constructor () {
728
- super(512, 256, 192, 64)
729
- this.h = [
730
- 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
731
- 0x1f83d9ab, 0x5be0cd19
732
- ]
733
- this.k = [
734
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
735
- 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
736
- 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
737
- 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
738
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
739
- 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
740
- 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
741
- 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
742
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
743
- 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
744
- 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
745
- ]
746
- this.W = new Array(64)
613
+ this.h = new FastSHA256()
747
614
  }
748
615
 
749
- _update (msg: number[], start?: number): void {
750
- const W = this.W
751
-
752
- // Default start to 0
753
- if (start === undefined) {
754
- start = 0
755
- }
756
-
757
- let i: number
758
- for (i = 0; i < 16; i++) {
759
- W[i] = msg[start + i]
760
- }
761
- for (; i < W.length; i++) {
762
- W[i] = SUM32_4(G1_256(W[i - 2]), W[i - 7], G0_256(W[i - 15]), W[i - 16])
763
- }
764
-
765
- let a = this.h[0]
766
- let b = this.h[1]
767
- let c = this.h[2]
768
- let d = this.h[3]
769
- let e = this.h[4]
770
- let f = this.h[5]
771
- let g = this.h[6]
772
- let h = this.h[7]
773
-
774
- assert(this.k.length === W.length)
775
- for (i = 0; i < W.length; i++) {
776
- const T1 = SUM32_5(h, S1_256(e), ch32(e, f, g), this.k[i], W[i])
777
- const T2 = sum32(S0_256(a), maj32(a, b, c))
778
- h = g
779
- g = f
780
- f = e
781
- e = sum32(d, T1)
782
- d = c
783
- c = b
784
- b = a
785
- a = sum32(T1, T2)
786
- }
787
-
788
- this.h[0] = sum32(this.h[0], a)
789
- this.h[1] = sum32(this.h[1], b)
790
- this.h[2] = sum32(this.h[2], c)
791
- this.h[3] = sum32(this.h[3], d)
792
- this.h[4] = sum32(this.h[4], e)
793
- this.h[5] = sum32(this.h[5], f)
794
- this.h[6] = sum32(this.h[6], g)
795
- this.h[7] = sum32(this.h[7], h)
616
+ update (msg: number[] | string, enc?: 'hex' | 'utf8'): this {
617
+ const data = Uint8Array.from(toArray(msg, enc))
618
+ this.h.update(data)
619
+ return this
796
620
  }
797
621
 
798
- _digest (): number[] {
799
- return split32(this.h, 'big')
622
+ digest (): number[] {
623
+ return Array.from(this.h.digest())
800
624
  }
801
625
 
802
- _digestHex (): string {
803
- return toHex32(this.h, 'big')
626
+ digestHex (): string {
627
+ return bytesToHex(this.h.digest())
804
628
  }
805
629
  }
806
630
 
@@ -903,321 +727,25 @@ export class SHA1 extends BaseHash {
903
727
  * @property W - Provides a way to recycle usage of the array memory.
904
728
  * @property k - The round constants used for each round of SHA-512.
905
729
  */
906
- export class SHA512 extends BaseHash {
907
- h: number[]
908
- W: number[]
909
- k: number[]
910
-
730
+ export class SHA512 {
731
+ private readonly h: FastSHA512
911
732
  constructor () {
912
- super(1024, 512, 192, 128)
913
- this.h = [
914
- 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b,
915
- 0xa54ff53a, 0x5f1d36f1, 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f,
916
- 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179
917
- ]
918
- this.k = [
919
- 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, 0xb5c0fbcf, 0xec4d3b2f,
920
- 0xe9b5dba5, 0x8189dbbc, 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
921
- 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, 0xd807aa98, 0xa3030242,
922
- 0x12835b01, 0x45706fbe, 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
923
- 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, 0x9bdc06a7, 0x25c71235,
924
- 0xc19bf174, 0xcf692694, 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
925
- 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, 0x2de92c6f, 0x592b0275,
926
- 0x4a7484aa, 0x6ea6e483, 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
927
- 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, 0xb00327c8, 0x98fb213f,
928
- 0xbf597fc7, 0xbeef0ee4, 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
929
- 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, 0x27b70a85, 0x46d22ffc,
930
- 0x2e1b2138, 0x5c26c926, 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
931
- 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, 0x81c2c92e, 0x47edaee6,
932
- 0x92722c85, 0x1482353b, 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
933
- 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, 0xd192e819, 0xd6ef5218,
934
- 0xd6990624, 0x5565a910, 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
935
- 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, 0x2748774c, 0xdf8eeb99,
936
- 0x34b0bcb5, 0xe19b48a8, 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
937
- 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, 0x748f82ee, 0x5defb2fc,
938
- 0x78a5636f, 0x43172f60, 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
939
- 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, 0xbef9a3f7, 0xb2c67915,
940
- 0xc67178f2, 0xe372532b, 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
941
- 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, 0x06f067aa, 0x72176fba,
942
- 0x0a637dc5, 0xa2c898a6, 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
943
- 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, 0x3c9ebe0a, 0x15c9bebc,
944
- 0x431d67c4, 0x9c100d4c, 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
945
- 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
946
- ]
947
- this.W = new Array(160)
948
- }
949
-
950
- _prepareBlock (msg: number[], start: number): void {
951
- const W = this.W
952
-
953
- // 32 x 32bit words
954
- let i: number
955
- for (i = 0; i < 32; i++) {
956
- W[i] = msg[start + i]
957
- }
958
- for (; i < W.length; i += 2) {
959
- const c0Hi = g1_512_hi(W[i - 4], W[i - 3]) // i - 2
960
- const c0Lo = g1_512_lo(W[i - 4], W[i - 3])
961
- const c1Hi = W[i - 14] // i - 7
962
- const c1Lo = W[i - 13]
963
- const c2Hi = g0_512_hi(W[i - 30], W[i - 29]) // i - 15
964
- const c2Lo = g0_512_lo(W[i - 30], W[i - 29])
965
- const c3Hi = W[i - 32] // i - 16
966
- const c3Lo = W[i - 31]
967
-
968
- W[i] = sum64and4HI(c0Hi, c0Lo, c1Hi, c1Lo, c2Hi, c2Lo, c3Hi, c3Lo)
969
- W[i + 1] = sum64and4LO(
970
- c0Hi,
971
- c0Lo,
972
- c1Hi,
973
- c1Lo,
974
- c2Hi,
975
- c2Lo,
976
- c3Hi,
977
- c3Lo
978
- )
979
- }
980
- }
981
-
982
- _update (msg: any, start: number): void {
983
- this._prepareBlock(msg, start)
984
-
985
- const W = this.W
986
-
987
- let aHigh = this.h[0]
988
- let aLow = this.h[1]
989
- let bHigh = this.h[2]
990
- let bLow = this.h[3]
991
- let cHigh = this.h[4]
992
- let cLow = this.h[5]
993
- let dHigh = this.h[6]
994
- let dLow = this.h[7]
995
- let eHigh = this.h[8]
996
- let eLow = this.h[9]
997
- let fHigh = this.h[10]
998
- let fLow = this.h[11]
999
- let gHigh = this.h[12]
1000
- let gLow = this.h[13]
1001
- let hHigh = this.h[14]
1002
- let hLow = this.h[15]
1003
-
1004
- assert(this.k.length === W.length)
1005
-
1006
- for (let i = 0; i < W.length; i += 2) {
1007
- let temp0High = hHigh
1008
- let temp0Low = hLow
1009
- let temp1High = s1_512_hi(eHigh, eLow)
1010
- let temp1Low = s1_512_lo(eHigh, eLow)
1011
- const temp2High = ch64_hi(eHigh, eLow, fHigh, fLow, gHigh, gLow)
1012
- const temp2Low = ch64_lo(eHigh, eLow, fHigh, fLow, gHigh, gLow)
1013
- const temp3High = this.k[i]
1014
- const temp3Low = this.k[i + 1]
1015
- const temp4High = W[i]
1016
- const temp4Low = W[i + 1]
1017
-
1018
- const t1High = sum64and5HI(
1019
- temp0High,
1020
- temp0Low,
1021
- temp1High,
1022
- temp1Low,
1023
- temp2High,
1024
- temp2Low,
1025
- temp3High,
1026
- temp3Low,
1027
- temp4High,
1028
- temp4Low
1029
- )
1030
- const t1Low = sum64and5LO(
1031
- temp0High,
1032
- temp0Low,
1033
- temp1High,
1034
- temp1Low,
1035
- temp2High,
1036
- temp2Low,
1037
- temp3High,
1038
- temp3Low,
1039
- temp4High,
1040
- temp4Low
1041
- )
1042
-
1043
- temp0High = s0_512_hi(aHigh, aLow)
1044
- temp0Low = s0_512_lo(aHigh, aLow)
1045
- temp1High = maj64_hi(aHigh, aLow, bHigh, bLow, cHigh, cLow)
1046
- temp1Low = maj64_lo(aHigh, aLow, bHigh, bLow, cHigh, cLow)
1047
-
1048
- const t2High = sum64HI(temp0High, temp0Low, temp1High, temp1Low)
1049
- const t2Low = sum64LO(temp0High, temp0Low, temp1High, temp1Low)
1050
-
1051
- hHigh = gHigh
1052
- hLow = gLow
1053
-
1054
- gHigh = fHigh
1055
- gLow = fLow
1056
-
1057
- fHigh = eHigh
1058
- fLow = eLow
1059
-
1060
- eHigh = sum64HI(dHigh, dLow, t1High, t1Low)
1061
- eLow = sum64LO(dLow, dLow, t1High, t1Low)
1062
-
1063
- dHigh = cHigh
1064
- dLow = cLow
1065
-
1066
- cHigh = bHigh
1067
- cLow = bLow
1068
-
1069
- bHigh = aHigh
1070
- bLow = aLow
1071
-
1072
- aHigh = sum64HI(t1High, t1Low, t2High, t2Low)
1073
- aLow = sum64LO(t1High, t1Low, t2High, t2Low)
1074
- }
1075
-
1076
- sum64(this.h, 0, aHigh, aLow)
1077
- sum64(this.h, 2, bHigh, bLow)
1078
- sum64(this.h, 4, cHigh, cLow)
1079
- sum64(this.h, 6, dHigh, dLow)
1080
- sum64(this.h, 8, eHigh, eLow)
1081
- sum64(this.h, 10, fHigh, fLow)
1082
- sum64(this.h, 12, gHigh, gLow)
1083
- sum64(this.h, 14, hHigh, hLow)
1084
- }
1085
-
1086
- _digest (): number[] {
1087
- return split32(this.h, 'big')
1088
- }
1089
-
1090
- _digestHex (): string {
1091
- return toHex32(this.h, 'big')
1092
- }
1093
- }
1094
-
1095
- function ch64_hi (xh: number, xl: number, yh: number, yl: number, zh: number, zl: number): number {
1096
- let r: number = (xh & yh) ^ (~xh & zh)
1097
- if (r < 0) {
1098
- r += 0x100000000
1099
- }
1100
- return r
1101
- }
1102
-
1103
- function ch64_lo (xh: number, xl: number, yh: number, yl: number, zh: number, zl: number): number {
1104
- let r: number = (xl & yl) ^ (~xl & zl)
1105
- if (r < 0) {
1106
- r += 0x100000000
1107
- }
1108
- return r
1109
- }
1110
-
1111
- function maj64_hi (xh: number, xl: number, yh: number, yl: number, zh: number, zl: number): number {
1112
- let r: number = (xh & yh) ^ (xh & zh) ^ (yh & zh)
1113
- if (r < 0) {
1114
- r += 0x100000000
1115
- }
1116
- return r
1117
- }
1118
-
1119
- function maj64_lo (xh: number, xl: number, yh: number, yl: number, zh: number, zl: number): number {
1120
- let r: number = (xl & yl) ^ (xl & zl) ^ (yl & zl)
1121
- if (r < 0) {
1122
- r += 0x100000000
733
+ this.h = new FastSHA512()
1123
734
  }
1124
- return r
1125
- }
1126
-
1127
- function s0_512_hi (xh: number, xl: number): number {
1128
- const c0_hi: number = rotr64HI(xh, xl, 28)
1129
- const c1_hi: number = rotr64HI(xl, xh, 2) // 34
1130
- const c2_hi: number = rotr64HI(xl, xh, 7) // 39
1131
735
 
1132
- let r: number = c0_hi ^ c1_hi ^ c2_hi
1133
- if (r < 0) {
1134
- r += 0x100000000
1135
- }
1136
- return r
1137
- }
1138
-
1139
- function s0_512_lo (xh: number, xl: number): number {
1140
- const c0_lo: number = rotr64LO(xh, xl, 28)
1141
- const c1_lo: number = rotr64LO(xl, xh, 2) // 34
1142
- const c2_lo: number = rotr64LO(xl, xh, 7) // 39
1143
-
1144
- let r: number = c0_lo ^ c1_lo ^ c2_lo
1145
- if (r < 0) {
1146
- r += 0x100000000
1147
- }
1148
- return r
1149
- }
1150
-
1151
- function s1_512_hi (xh: number, xl: number): number {
1152
- const c0_hi: number = rotr64HI(xh, xl, 14)
1153
- const c1_hi: number = rotr64HI(xh, xl, 18)
1154
- const c2_hi: number = rotr64HI(xl, xh, 9) // 41
1155
-
1156
- let r: number = c0_hi ^ c1_hi ^ c2_hi
1157
- if (r < 0) {
1158
- r += 0x100000000
1159
- }
1160
- return r
1161
- }
1162
-
1163
- function s1_512_lo (xh: number, xl: number): number {
1164
- const c0_lo: number = rotr64LO(xh, xl, 14)
1165
- const c1_lo: number = rotr64LO(xh, xl, 18)
1166
- const c2_lo: number = rotr64LO(xl, xh, 9) // 41
1167
-
1168
- let r: number = c0_lo ^ c1_lo ^ c2_lo
1169
- if (r < 0) {
1170
- r += 0x100000000
1171
- }
1172
- return r
1173
- }
1174
-
1175
- function g0_512_hi (xh: number, xl: number): number {
1176
- const c0_hi: number = rotr64HI(xh, xl, 1)
1177
- const c1_hi: number = rotr64HI(xh, xl, 8)
1178
- const c2_hi: number = shr64HI(xh, xl, 7)
1179
-
1180
- let r: number = c0_hi ^ c1_hi ^ c2_hi
1181
- if (r < 0) {
1182
- r += 0x100000000
1183
- }
1184
- return r
1185
- }
1186
-
1187
- function g0_512_lo (xh: number, xl: number): number {
1188
- const c0_lo: number = rotr64LO(xh, xl, 1)
1189
- const c1_lo: number = rotr64LO(xh, xl, 8)
1190
- const c2_lo: number = shr64LO(xh, xl, 7)
1191
-
1192
- let r: number = c0_lo ^ c1_lo ^ c2_lo
1193
- if (r < 0) {
1194
- r += 0x100000000
736
+ update (msg: number[] | string, enc?: 'hex' | 'utf8'): this {
737
+ const data = Uint8Array.from(toArray(msg, enc))
738
+ this.h.update(data)
739
+ return this
1195
740
  }
1196
- return r
1197
- }
1198
741
 
1199
- function g1_512_hi (xh: number, xl: number): number {
1200
- const c0_hi: number = rotr64HI(xh, xl, 19)
1201
- const c1_hi: number = rotr64HI(xl, xh, 29) // 61
1202
- const c2_hi: number = shr64HI(xh, xl, 6)
1203
-
1204
- let r: number = c0_hi ^ c1_hi ^ c2_hi
1205
- if (r < 0) {
1206
- r += 0x100000000
742
+ digest (): number[] {
743
+ return Array.from(this.h.digest())
1207
744
  }
1208
- return r
1209
- }
1210
-
1211
- function g1_512_lo (xh: number, xl: number): number {
1212
- const c0_lo: number = rotr64LO(xh, xl, 19)
1213
- const c1_lo: number = rotr64LO(xl, xh, 29) // 61
1214
- const c2_lo: number = shr64LO(xh, xl, 6)
1215
745
 
1216
- let r: number = c0_lo ^ c1_lo ^ c2_lo
1217
- if (r < 0) {
1218
- r += 0x100000000
746
+ digestHex (): string {
747
+ return bytesToHex(this.h.digest())
1219
748
  }
1220
- return r
1221
749
  }
1222
750
 
1223
751
  /**
@@ -1233,8 +761,7 @@ function g1_512_lo (xh: number, xl: number): number {
1233
761
  * @property outSize - The output size of the SHA-256 hash function, in bytes. It's set to 32 bytes.
1234
762
  */
1235
763
  export class SHA256HMAC {
1236
- inner: SHA256
1237
- outer: SHA256
764
+ private readonly h: HMAC<FastSHA256>
1238
765
  blockSize = 64
1239
766
  outSize = 32
1240
767
 
@@ -1252,29 +779,8 @@ export class SHA256HMAC {
1252
779
  * const myHMAC = new SHA256HMAC('deadbeef');
1253
780
  */
1254
781
  constructor (key: number[] | string) {
1255
- key = toArray(key, 'hex')
1256
- // Shorten key, if needed
1257
- if (key.length > this.blockSize) {
1258
- key = new SHA256().update(key).digest()
1259
- }
1260
- assert(key.length <= this.blockSize)
1261
-
1262
- // Add padding to key
1263
- let i
1264
- for (i = key.length; i < this.blockSize; i++) {
1265
- key.push(0)
1266
- }
1267
-
1268
- for (i = 0; i < key.length; i++) {
1269
- key[i] ^= 0x36
1270
- }
1271
- this.inner = new SHA256().update(key)
1272
-
1273
- // 0x36 ^ 0x5c = 0x6a
1274
- for (i = 0; i < key.length; i++) {
1275
- key[i] ^= 0x6a
1276
- }
1277
- this.outer = new SHA256().update(key)
782
+ const k = Uint8Array.from(toArray(key, 'hex'))
783
+ this.h = new HMAC(sha256Fast, k)
1278
784
  }
1279
785
 
1280
786
  /**
@@ -1289,7 +795,7 @@ export class SHA256HMAC {
1289
795
  * myHMAC.update('deadbeef', 'hex');
1290
796
  */
1291
797
  update (msg: number[] | string, enc?: 'hex'): SHA256HMAC {
1292
- this.inner.update(msg, enc)
798
+ this.h.update(Uint8Array.from(toArray(msg, enc)))
1293
799
  return this
1294
800
  }
1295
801
 
@@ -1303,8 +809,7 @@ export class SHA256HMAC {
1303
809
  * let hashedMessage = myHMAC.digest();
1304
810
  */
1305
811
  digest (): number[] {
1306
- this.outer.update(this.inner.digest())
1307
- return this.outer.digest()
812
+ return Array.from(this.h.digest())
1308
813
  }
1309
814
 
1310
815
  /**
@@ -1317,8 +822,7 @@ export class SHA256HMAC {
1317
822
  * let hashedMessage = myHMAC.digestHex();
1318
823
  */
1319
824
  digestHex (): string {
1320
- this.outer.update(this.inner.digest())
1321
- return this.outer.digestHex()
825
+ return bytesToHex(this.h.digest())
1322
826
  }
1323
827
  }
1324
828
 
@@ -1381,8 +885,7 @@ export class SHA1HMAC {
1381
885
  * @property outSize - The output size of the SHA-512 hash function, in bytes. It's set to 64 bytes.
1382
886
  */
1383
887
  export class SHA512HMAC {
1384
- inner: SHA512
1385
- outer: SHA512
888
+ private readonly h: HMAC<FastSHA512>
1386
889
  blockSize = 128
1387
890
  outSize = 32
1388
891
 
@@ -1400,29 +903,8 @@ export class SHA512HMAC {
1400
903
  * const myHMAC = new SHA512HMAC('deadbeef');
1401
904
  */
1402
905
  constructor (key: number[] | string) {
1403
- key = toArray(key, 'hex')
1404
- // Shorten key, if needed
1405
- if (key.length > this.blockSize) {
1406
- key = new SHA512().update(key).digest()
1407
- }
1408
- assert(key.length <= this.blockSize)
1409
-
1410
- // Add padding to key
1411
- let i
1412
- for (i = key.length; i < this.blockSize; i++) {
1413
- key.push(0)
1414
- }
1415
-
1416
- for (i = 0; i < key.length; i++) {
1417
- key[i] ^= 0x36
1418
- }
1419
- this.inner = new SHA512().update(key)
1420
-
1421
- // 0x36 ^ 0x5c = 0x6a
1422
- for (i = 0; i < key.length; i++) {
1423
- key[i] ^= 0x6a
1424
- }
1425
- this.outer = new SHA512().update(key)
906
+ const k = Uint8Array.from(toArray(key, 'hex'))
907
+ this.h = new HMAC(sha512Fast, k)
1426
908
  }
1427
909
 
1428
910
  /**
@@ -1437,7 +919,7 @@ export class SHA512HMAC {
1437
919
  * myHMAC.update('deadbeef', 'hex');
1438
920
  */
1439
921
  update (msg: number[] | string, enc?: 'hex' | 'utf8'): SHA512HMAC {
1440
- this.inner.update(msg, enc)
922
+ this.h.update(Uint8Array.from(toArray(msg, enc)))
1441
923
  return this
1442
924
  }
1443
925
 
@@ -1451,8 +933,7 @@ export class SHA512HMAC {
1451
933
  * let hashedMessage = myHMAC.digest();
1452
934
  */
1453
935
  digest (): number[] {
1454
- this.outer.update(this.inner.digest())
1455
- return this.outer.digest()
936
+ return Array.from(this.h.digest())
1456
937
  }
1457
938
 
1458
939
  /**
@@ -1465,8 +946,7 @@ export class SHA512HMAC {
1465
946
  * let hashedMessage = myHMAC.digestHex();
1466
947
  */
1467
948
  digestHex (): string {
1468
- this.outer.update(this.inner.digest())
1469
- return this.outer.digestHex()
949
+ return bytesToHex(this.h.digest())
1470
950
  }
1471
951
  }
1472
952
 
@@ -1623,6 +1103,698 @@ export const sha512hmac = (
1623
1103
  return new SHA512HMAC(key).update(msg, enc).digest()
1624
1104
  }
1625
1105
 
1106
+ // BEGIN fast-pbkdf2 helpers
1107
+ // Utils
1108
+ function isBytes (a: unknown): a is Uint8Array {
1109
+ return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array')
1110
+ }
1111
+ function anumber (n: number): void {
1112
+ if (!Number.isSafeInteger(n) || n < 0) {
1113
+ throw new Error(`positive integer expected, got ${n}`)
1114
+ }
1115
+ }
1116
+ function abytes (b: Uint8Array | undefined, ...lengths: number[]): void {
1117
+ if (!isBytes(b)) throw new Error('Uint8Array expected')
1118
+ if (lengths.length > 0 && !lengths.includes(b.length)) {
1119
+ const lens = lengths.join(',')
1120
+ throw new Error(`Uint8Array expected of length ${lens}, got length=${b.length}`)
1121
+ }
1122
+ }
1123
+ function ahash (h: IHash): void {
1124
+ if (typeof h !== 'function' || typeof h.create !== 'function') { throw new Error('Hash should be wrapped by utils.createHasher') }
1125
+ anumber(h.outputLen)
1126
+ anumber(h.blockLen)
1127
+ }
1128
+ function aexists (instance: any, checkFinished = true): void {
1129
+ if (instance.destroyed === true) throw new Error('Hash instance has been destroyed')
1130
+ if (checkFinished && instance.finished === true) {
1131
+ throw new Error('Hash#digest() has already been called')
1132
+ }
1133
+ }
1134
+ function aoutput (out: any, instance: any): void {
1135
+ abytes(out)
1136
+ const min: number = instance.outputLen as number
1137
+ if (out.length < min) {
1138
+ throw new Error(`digestInto() expects output buffer of length at least ${min}`)
1139
+ }
1140
+ }
1141
+ type TypedArray =
1142
+ | Int8Array
1143
+ | Uint8ClampedArray
1144
+ | Uint8Array
1145
+ | Uint16Array
1146
+ | Int16Array
1147
+ | Uint32Array
1148
+ | Int32Array
1149
+
1150
+ function clean (...arrays: TypedArray[]): void {
1151
+ for (let i = 0; i < arrays.length; i++) arrays[i].fill(0)
1152
+ }
1153
+ function createView (arr: TypedArray): DataView {
1154
+ return new DataView(arr.buffer, arr.byteOffset, arr.byteLength)
1155
+ }
1156
+ function toBytes (data: Input): Uint8Array {
1157
+ if (typeof data === 'string') data = utf8ToBytes(data)
1158
+ abytes(data)
1159
+ return data
1160
+ }
1161
+ function utf8ToBytes (str: string): Uint8Array {
1162
+ if (typeof str !== 'string') throw new Error('string expected')
1163
+ return new Uint8Array(new TextEncoder().encode(str))
1164
+ }
1165
+ type Input = string | Uint8Array
1166
+ type KDFInput = string | Uint8Array
1167
+ function kdfInputToBytes (data: KDFInput): Uint8Array {
1168
+ if (typeof data === 'string') data = utf8ToBytes(data)
1169
+ abytes(data)
1170
+ return data
1171
+ }
1172
+ interface IHash {
1173
+ (data: Uint8Array): Uint8Array
1174
+ blockLen: number
1175
+ outputLen: number
1176
+ create: any
1177
+ }
1178
+
1179
+ interface Hasher<T extends Hash<T>> {
1180
+ (msg: Input): Uint8Array
1181
+ blockLen: number
1182
+ outputLen: number
1183
+ create: () => Hash<T>
1184
+ }
1185
+ abstract class Hash<T extends Hash<T>> {
1186
+ abstract blockLen: number
1187
+ abstract outputLen: number
1188
+ abstract update (buf: Input): this
1189
+ abstract digestInto (buf: Uint8Array): void
1190
+ abstract digest (): Uint8Array
1191
+ abstract destroy (): void
1192
+ abstract _cloneInto (to?: T): T
1193
+ abstract clone (): T
1194
+ }
1195
+ function createHasher<T extends Hash<T>> (hashCons: () => Hash<T>): Hasher<T> {
1196
+ const hashC = (msg: Input): Uint8Array => hashCons().update(toBytes(msg)).digest()
1197
+ const tmp = hashCons()
1198
+ hashC.outputLen = tmp.outputLen
1199
+ hashC.blockLen = tmp.blockLen
1200
+ hashC.create = () => hashCons()
1201
+ return hashC
1202
+ }
1203
+
1204
+ // u64 helpers
1205
+ const U32_MASK64 = BigInt(2 ** 32 - 1)
1206
+ const _32n = BigInt(32)
1207
+ function fromBig (n: bigint, le = false): { h: number, l: number } {
1208
+ if (le) return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) }
1209
+ return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 }
1210
+ }
1211
+ function split (lst: bigint[], le = false): Uint32Array[] {
1212
+ const len = lst.length
1213
+ const Ah = new Uint32Array(len)
1214
+ const Al = new Uint32Array(len)
1215
+ for (let i = 0; i < len; i++) {
1216
+ const { h, l } = fromBig(lst[i], le)
1217
+ Ah[i] = h
1218
+ Al[i] = l
1219
+ }
1220
+ return [Ah, Al]
1221
+ }
1222
+ const shrSH = (h: number, _l: number, s: number): number => h >>> s
1223
+ const shrSL = (h: number, l: number, s: number): number => (h << (32 - s)) | (l >>> s)
1224
+ const rotrSH = (h: number, l: number, s: number): number => (h >>> s) | (l << (32 - s))
1225
+ const rotrSL = (h: number, l: number, s: number): number => (h << (32 - s)) | (l >>> s)
1226
+ const rotrBH = (h: number, l: number, s: number): number => (h << (64 - s)) | (l >>> (s - 32))
1227
+ const rotrBL = (h: number, l: number, s: number): number => (h >>> (s - 32)) | (l << (64 - s))
1228
+ function add (Ah: number, Al: number, Bh: number, Bl: number): { h: number, l: number } {
1229
+ const l = (Al >>> 0) + (Bl >>> 0)
1230
+ return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 }
1231
+ }
1232
+ const add3L = (Al: number, Bl: number, Cl: number): number => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0)
1233
+ const add3H = (low: number, Ah: number, Bh: number, Ch: number): number => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0
1234
+ const add4L = (Al: number, Bl: number, Cl: number, Dl: number): number => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0)
1235
+ const add4H = (low: number, Ah: number, Bh: number, Ch: number, Dh: number): number => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0
1236
+ const add5L = (Al: number, Bl: number, Cl: number, Dl: number, El: number): number =>
1237
+ (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0)
1238
+ const add5H = (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number): number =>
1239
+ (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0
1240
+
1241
+ // _md helpers
1242
+ abstract class HashMD<T extends HashMD<T>> extends Hash<T> {
1243
+ readonly blockLen: number
1244
+ readonly outputLen: number
1245
+ readonly padOffset: number
1246
+ readonly isLE: boolean
1247
+ protected buffer: Uint8Array
1248
+ protected view: DataView
1249
+ protected finished = false
1250
+ protected length = 0
1251
+ protected pos = 0
1252
+ protected destroyed = false
1253
+ constructor (blockLen: number, outputLen: number, padOffset: number, isLE: boolean) {
1254
+ super()
1255
+ this.blockLen = blockLen
1256
+ this.outputLen = outputLen
1257
+ this.padOffset = padOffset
1258
+ this.isLE = isLE
1259
+ this.buffer = new Uint8Array(blockLen)
1260
+ this.view = createView(this.buffer)
1261
+ }
1262
+
1263
+ protected abstract process (buf: DataView, offset: number): void
1264
+ protected abstract get (): number[]
1265
+ protected abstract set (...args: number[]): void
1266
+ abstract destroy (): void
1267
+ protected abstract roundClean (): void
1268
+ update (data: Input): this {
1269
+ aexists(this)
1270
+ data = toBytes(data)
1271
+ abytes(data)
1272
+ const { view, buffer, blockLen } = this
1273
+ const len = data.length
1274
+ for (let pos = 0; pos < len;) {
1275
+ const take = Math.min(blockLen - this.pos, len - pos)
1276
+ if (take === blockLen) {
1277
+ const dataView = createView(data)
1278
+ for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos)
1279
+ continue
1280
+ }
1281
+ buffer.set(data.subarray(pos, pos + take), this.pos)
1282
+ this.pos += take
1283
+ pos += take
1284
+ if (this.pos === blockLen) {
1285
+ this.process(view, 0)
1286
+ this.pos = 0
1287
+ }
1288
+ }
1289
+ this.length += data.length
1290
+ this.roundClean()
1291
+ return this
1292
+ }
1293
+
1294
+ digestInto (out: Uint8Array): void {
1295
+ aexists(this)
1296
+ aoutput(out, this)
1297
+ this.finished = true
1298
+ const { buffer, view, blockLen, isLE } = this
1299
+ let { pos } = this
1300
+ buffer[pos++] = 0b10000000
1301
+ clean(this.buffer.subarray(pos))
1302
+ if (this.padOffset > blockLen - pos) {
1303
+ this.process(view, 0)
1304
+ pos = 0
1305
+ }
1306
+ for (let i = pos; i < blockLen; i++) buffer[i] = 0
1307
+ setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE)
1308
+ this.process(view, 0)
1309
+ const oview = createView(out)
1310
+ const len = this.outputLen
1311
+ if (len % 4 !== 0) throw new Error('_sha2: outputLen should be aligned to 32bit')
1312
+ const outLen = len / 4
1313
+ const state = this.get()
1314
+ if (outLen > state.length) throw new Error('_sha2: outputLen bigger than state')
1315
+ for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE)
1316
+ }
1317
+
1318
+ digest (): Uint8Array {
1319
+ const { buffer, outputLen } = this
1320
+ this.digestInto(buffer)
1321
+ const res = buffer.slice(0, outputLen)
1322
+ this.destroy()
1323
+ return res
1324
+ }
1325
+
1326
+ _cloneInto (to?: T): T {
1327
+ to ||= new (this.constructor as any)() as T
1328
+ to.set(...this.get())
1329
+ const { blockLen, buffer, length, finished, destroyed, pos } = this
1330
+ to.destroyed = destroyed
1331
+ to.finished = finished
1332
+ to.length = length
1333
+ to.pos = pos
1334
+ if (length % blockLen !== 0) to.buffer.set(buffer)
1335
+ return to
1336
+ }
1337
+
1338
+ clone (): T {
1339
+ return this._cloneInto()
1340
+ }
1341
+ }
1342
+ function setBigUint64 (view: DataView, byteOffset: number, value: bigint, isLE: boolean): void {
1343
+ if (typeof view.setBigUint64 === 'function') return view.setBigUint64(byteOffset, value, isLE)
1344
+ const _32n = BigInt(32)
1345
+ const _u32_max = BigInt(0xffffffff)
1346
+ const wh = Number((value >> _32n) & _u32_max)
1347
+ const wl = Number(value & _u32_max)
1348
+ const h = isLE ? 4 : 0
1349
+ const l = isLE ? 0 : 4
1350
+ view.setUint32(byteOffset + h, wh, isLE)
1351
+ view.setUint32(byteOffset + l, wl, isLE)
1352
+ }
1353
+
1354
+ // sha256 fast constants
1355
+ const SHA256_IV = Uint32Array.from([
1356
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
1357
+ 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
1358
+ ])
1359
+ const K256 = Uint32Array.from([
1360
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
1361
+ 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
1362
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
1363
+ 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
1364
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
1365
+ 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
1366
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
1367
+ 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
1368
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
1369
+ 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
1370
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
1371
+ ])
1372
+ const SHA256_W = new Uint32Array(64)
1373
+
1374
+ class FastSHA256 extends HashMD<FastSHA256> {
1375
+ protected A = SHA256_IV[0] | 0
1376
+ protected B = SHA256_IV[1] | 0
1377
+ protected C = SHA256_IV[2] | 0
1378
+ protected D = SHA256_IV[3] | 0
1379
+ protected E = SHA256_IV[4] | 0
1380
+ protected F = SHA256_IV[5] | 0
1381
+ protected G = SHA256_IV[6] | 0
1382
+ protected H = SHA256_IV[7] | 0
1383
+ constructor (outputLen = 32) {
1384
+ super(64, outputLen, 8, false)
1385
+ }
1386
+
1387
+ protected get (): number[] {
1388
+ const { A, B, C, D, E, F, G, H } = this
1389
+ return [A, B, C, D, E, F, G, H]
1390
+ }
1391
+
1392
+ protected set (
1393
+ A: number,
1394
+ B: number,
1395
+ C: number,
1396
+ D: number,
1397
+ E: number,
1398
+ F: number,
1399
+ G: number,
1400
+ H: number
1401
+ ): void {
1402
+ this.A = A | 0
1403
+ this.B = B | 0
1404
+ this.C = C | 0
1405
+ this.D = D | 0
1406
+ this.E = E | 0
1407
+ this.F = F | 0
1408
+ this.G = G | 0
1409
+ this.H = H | 0
1410
+ }
1411
+
1412
+ protected process (view: DataView, offset: number): void {
1413
+ for (let i = 0; i < 16; i++, offset += 4) {
1414
+ SHA256_W[i] = view.getUint32(offset)
1415
+ }
1416
+ for (let i = 16; i < 64; i++) {
1417
+ const w15 = SHA256_W[i - 15]
1418
+ const w2 = SHA256_W[i - 2]
1419
+ const s0 = G0_256(w15)
1420
+ const s1 = G1_256(w2)
1421
+ SHA256_W[i] = sum32(sum32(s0, SHA256_W[i - 7]), sum32(s1, SHA256_W[i - 16]))
1422
+ }
1423
+
1424
+ let { A, B, C, D, E, F, G, H } = this
1425
+ for (let i = 0; i < 64; i++) {
1426
+ const T1 = SUM32_5(H, S1_256(E), ch32(E, F, G), K256[i], SHA256_W[i])
1427
+ const T2 = sum32(S0_256(A), maj32(A, B, C))
1428
+ H = G
1429
+ G = F
1430
+ F = E
1431
+ E = sum32(D, T1)
1432
+ D = C
1433
+ C = B
1434
+ B = A
1435
+ A = sum32(T1, T2)
1436
+ }
1437
+ this.A = sum32(this.A, A)
1438
+ this.B = sum32(this.B, B)
1439
+ this.C = sum32(this.C, C)
1440
+ this.D = sum32(this.D, D)
1441
+ this.E = sum32(this.E, E)
1442
+ this.F = sum32(this.F, F)
1443
+ this.G = sum32(this.G, G)
1444
+ this.H = sum32(this.H, H)
1445
+ }
1446
+
1447
+ protected roundClean (): void {
1448
+ clean(SHA256_W)
1449
+ }
1450
+
1451
+ destroy (): void {
1452
+ clean(this.buffer)
1453
+ this.set(0, 0, 0, 0, 0, 0, 0, 0)
1454
+ }
1455
+ }
1456
+ const sha256Fast = createHasher(() => new FastSHA256())
1457
+
1458
+ // sha512
1459
+ const SHA512_IV = Uint32Array.from([
1460
+ 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,
1461
+ 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179
1462
+ ])
1463
+ const K512 = (() =>
1464
+ split([
1465
+ '0x428a2f98d728ae22',
1466
+ '0x7137449123ef65cd',
1467
+ '0xb5c0fbcfec4d3b2f',
1468
+ '0xe9b5dba58189dbbc',
1469
+ '0x3956c25bf348b538',
1470
+ '0x59f111f1b605d019',
1471
+ '0x923f82a4af194f9b',
1472
+ '0xab1c5ed5da6d8118',
1473
+ '0xd807aa98a3030242',
1474
+ '0x12835b0145706fbe',
1475
+ '0x243185be4ee4b28c',
1476
+ '0x550c7dc3d5ffb4e2',
1477
+ '0x72be5d74f27b896f',
1478
+ '0x80deb1fe3b1696b1',
1479
+ '0x9bdc06a725c71235',
1480
+ '0xc19bf174cf692694',
1481
+ '0xe49b69c19ef14ad2',
1482
+ '0xefbe4786384f25e3',
1483
+ '0x0fc19dc68b8cd5b5',
1484
+ '0x240ca1cc77ac9c65',
1485
+ '0x2de92c6f592b0275',
1486
+ '0x4a7484aa6ea6e483',
1487
+ '0x5cb0a9dcbd41fbd4',
1488
+ '0x76f988da831153b5',
1489
+ '0x983e5152ee66dfab',
1490
+ '0xa831c66d2db43210',
1491
+ '0xb00327c898fb213f',
1492
+ '0xbf597fc7beef0ee4',
1493
+ '0xc6e00bf33da88fc2',
1494
+ '0xd5a79147930aa725',
1495
+ '0x06ca6351e003826f',
1496
+ '0x142929670a0e6e70',
1497
+ '0x27b70a8546d22ffc',
1498
+ '0x2e1b21385c26c926',
1499
+ '0x4d2c6dfc5ac42aed',
1500
+ '0x53380d139d95b3df',
1501
+ '0x650a73548baf63de',
1502
+ '0x766a0abb3c77b2a8',
1503
+ '0x81c2c92e47edaee6',
1504
+ '0x92722c851482353b',
1505
+ '0xa2bfe8a14cf10364',
1506
+ '0xa81a664bbc423001',
1507
+ '0xc24b8b70d0f89791',
1508
+ '0xc76c51a30654be30',
1509
+ '0xd192e819d6ef5218',
1510
+ '0xd69906245565a910',
1511
+ '0xf40e35855771202a',
1512
+ '0x106aa07032bbd1b8',
1513
+ '0x19a4c116b8d2d0c8',
1514
+ '0x1e376c085141ab53',
1515
+ '0x2748774cdf8eeb99',
1516
+ '0x34b0bcb5e19b48a8',
1517
+ '0x391c0cb3c5c95a63',
1518
+ '0x4ed8aa4ae3418acb',
1519
+ '0x5b9cca4f7763e373',
1520
+ '0x682e6ff3d6b2b8a3',
1521
+ '0x748f82ee5defb2fc',
1522
+ '0x78a5636f43172f60',
1523
+ '0x84c87814a1f0ab72',
1524
+ '0x8cc702081a6439ec',
1525
+ '0x90befffa23631e28',
1526
+ '0xa4506cebde82bde9',
1527
+ '0xbef9a3f7b2c67915',
1528
+ '0xc67178f2e372532b',
1529
+ '0xca273eceea26619c',
1530
+ '0xd186b8c721c0c207',
1531
+ '0xeada7dd6cde0eb1e',
1532
+ '0xf57d4f7fee6ed178',
1533
+ '0x06f067aa72176fba',
1534
+ '0x0a637dc5a2c898a6',
1535
+ '0x113f9804bef90dae',
1536
+ '0x1b710b35131c471b',
1537
+ '0x28db77f523047d84',
1538
+ '0x32caab7b40c72493',
1539
+ '0x3c9ebe0a15c9bebc',
1540
+ '0x431d67c49c100d4c',
1541
+ '0x4cc5d4becb3e42b6',
1542
+ '0x597f299cfc657e2a',
1543
+ '0x5fcb6fab3ad6faec',
1544
+ '0x6c44198c4a475817'
1545
+ ].map((n) => BigInt(n)))
1546
+ )()
1547
+ const SHA512_Kh = (() => K512[0])()
1548
+ const SHA512_Kl = (() => K512[1])()
1549
+ const SHA512_W_H = new Uint32Array(80)
1550
+ const SHA512_W_L = new Uint32Array(80)
1551
+
1552
+ class FastSHA512 extends HashMD<FastSHA512> {
1553
+ protected Ah = SHA512_IV[0] | 0
1554
+ protected Al = SHA512_IV[1] | 0
1555
+ protected Bh = SHA512_IV[2] | 0
1556
+ protected Bl = SHA512_IV[3] | 0
1557
+ protected Ch = SHA512_IV[4] | 0
1558
+ protected Cl = SHA512_IV[5] | 0
1559
+ protected Dh = SHA512_IV[6] | 0
1560
+ protected Dl = SHA512_IV[7] | 0
1561
+ protected Eh = SHA512_IV[8] | 0
1562
+ protected El = SHA512_IV[9] | 0
1563
+ protected Fh = SHA512_IV[10] | 0
1564
+ protected Fl = SHA512_IV[11] | 0
1565
+ protected Gh = SHA512_IV[12] | 0
1566
+ protected Gl = SHA512_IV[13] | 0
1567
+ protected Hh = SHA512_IV[14] | 0
1568
+ protected Hl = SHA512_IV[15] | 0
1569
+ constructor (outputLen = 64) {
1570
+ super(128, outputLen, 16, false)
1571
+ }
1572
+
1573
+ protected get (): number[] {
1574
+ const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this
1575
+ return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl]
1576
+ }
1577
+
1578
+ protected set (
1579
+ Ah: number,
1580
+ Al: number,
1581
+ Bh: number,
1582
+ Bl: number,
1583
+ Ch: number,
1584
+ Cl: number,
1585
+ Dh: number,
1586
+ Dl: number,
1587
+ Eh: number,
1588
+ El: number,
1589
+ Fh: number,
1590
+ Fl: number,
1591
+ Gh: number,
1592
+ Gl: number,
1593
+ Hh: number,
1594
+ Hl: number
1595
+ ): void {
1596
+ this.Ah = Ah | 0
1597
+ this.Al = Al | 0
1598
+ this.Bh = Bh | 0
1599
+ this.Bl = Bl | 0
1600
+ this.Ch = Ch | 0
1601
+ this.Cl = Cl | 0
1602
+ this.Dh = Dh | 0
1603
+ this.Dl = Dl | 0
1604
+ this.Eh = Eh | 0
1605
+ this.El = El | 0
1606
+ this.Fh = Fh | 0
1607
+ this.Fl = Fl | 0
1608
+ this.Gh = Gh | 0
1609
+ this.Gl = Gl | 0
1610
+ this.Hh = Hh | 0
1611
+ this.Hl = Hl | 0
1612
+ }
1613
+
1614
+ protected process (view: DataView, offset: number): void {
1615
+ for (let i = 0; i < 16; i++, offset += 4) {
1616
+ SHA512_W_H[i] = view.getUint32(offset)
1617
+ SHA512_W_L[i] = view.getUint32((offset += 4))
1618
+ }
1619
+ for (let i = 16; i < 80; i++) {
1620
+ const W15h = SHA512_W_H[i - 15] | 0
1621
+ const W15l = SHA512_W_L[i - 15] | 0
1622
+ const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7)
1623
+ const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7)
1624
+ const W2h = SHA512_W_H[i - 2] | 0
1625
+ const W2l = SHA512_W_L[i - 2] | 0
1626
+ const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6)
1627
+ const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6)
1628
+ const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16])
1629
+ const SUMh = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16])
1630
+ SHA512_W_H[i] = SUMh | 0
1631
+ SHA512_W_L[i] = SUMl | 0
1632
+ }
1633
+ let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this
1634
+ for (let i = 0; i < 80; i++) {
1635
+ const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41)
1636
+ const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41)
1637
+ const CHIh = (Eh & Fh) ^ (~Eh & Gh)
1638
+ const CHIl = (El & Fl) ^ (~El & Gl)
1639
+ const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i])
1640
+ const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i])
1641
+ const T1l = T1ll | 0
1642
+ const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39)
1643
+ const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39)
1644
+ const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch)
1645
+ const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl)
1646
+ Hh = Gh | 0
1647
+ Hl = Gl | 0
1648
+ Gh = Fh | 0
1649
+ Gl = Fl | 0
1650
+ Fh = Eh | 0
1651
+ Fl = El | 0
1652
+ ;({ h: Eh, l: El } = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0))
1653
+ Dh = Ch | 0
1654
+ Dl = Cl | 0
1655
+ Ch = Bh | 0
1656
+ Cl = Bl | 0
1657
+ Bh = Ah | 0
1658
+ Bl = Al | 0
1659
+ const T2l = add3L(sigma0l, MAJl, T1l)
1660
+ Ah = add3H(T2l, sigma0h, MAJh, T1h)
1661
+ Al = T2l | 0
1662
+ }
1663
+ ;({ h: Ah, l: Al } = add(Ah, Al, this.Ah, this.Al))
1664
+ ;({ h: Bh, l: Bl } = add(Bh, Bl, this.Bh, this.Bl))
1665
+ ;({ h: Ch, l: Cl } = add(Ch, Cl, this.Ch, this.Cl))
1666
+ ;({ h: Dh, l: Dl } = add(Dh, Dl, this.Dh, this.Dl))
1667
+ ;({ h: Eh, l: El } = add(Eh, El, this.Eh, this.El))
1668
+ ;({ h: Fh, l: Fl } = add(Fh, Fl, this.Fh, this.Fl))
1669
+ ;({ h: Gh, l: Gl } = add(Gh, Gl, this.Gh, this.Gl))
1670
+ ;({ h: Hh, l: Hl } = add(Hh, Hl, this.Hh, this.Hl))
1671
+ this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl)
1672
+ }
1673
+
1674
+ protected roundClean (): void {
1675
+ clean(SHA512_W_H, SHA512_W_L)
1676
+ }
1677
+
1678
+ destroy (): void {
1679
+ clean(this.buffer)
1680
+ this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
1681
+ }
1682
+ }
1683
+ const sha512Fast = createHasher(() => new FastSHA512())
1684
+
1685
+ class HMAC<T extends Hash<T>> extends Hash<HMAC<T>> {
1686
+ oHash: T
1687
+ iHash: T
1688
+ blockLen: number
1689
+ outputLen: number
1690
+ private finished = false
1691
+ private destroyed = false
1692
+ constructor (hash: (msg: Input) => Uint8Array & { create: () => T, blockLen: number, outputLen: number }, _key: Input) {
1693
+ super()
1694
+ ahash(hash)
1695
+ const key = toBytes(_key)
1696
+ this.iHash = hash.create() as T
1697
+ if (typeof (this.iHash as any).update !== 'function') { throw new Error('Expected instance of class which extends utils.Hash') }
1698
+ this.blockLen = this.iHash.blockLen
1699
+ this.outputLen = this.iHash.outputLen
1700
+ const blockLen = this.blockLen
1701
+ const pad = new Uint8Array(blockLen)
1702
+ pad.set(key.length > blockLen ? hash.create().update(key).digest() : key)
1703
+ for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36
1704
+ this.iHash.update(pad)
1705
+ this.oHash = hash.create() as T
1706
+ for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36 ^ 0x5c
1707
+ this.oHash.update(pad)
1708
+ clean(pad)
1709
+ }
1710
+
1711
+ update (buf: Input): this {
1712
+ aexists(this)
1713
+ this.iHash.update(buf)
1714
+ return this
1715
+ }
1716
+
1717
+ digestInto (out: Uint8Array): void {
1718
+ aexists(this)
1719
+ abytes(out, this.outputLen)
1720
+ this.finished = true
1721
+ this.iHash.digestInto(out)
1722
+ this.oHash.update(out)
1723
+ this.oHash.digestInto(out)
1724
+ this.destroy()
1725
+ }
1726
+
1727
+ digest (): Uint8Array {
1728
+ const out = new Uint8Array(this.oHash.outputLen)
1729
+ this.digestInto(out)
1730
+ return out
1731
+ }
1732
+
1733
+ _cloneInto (to?: HMAC<T>): HMAC<T> {
1734
+ to ||= Object.create(Object.getPrototypeOf(this), {})
1735
+ const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this
1736
+ to = to as this
1737
+ to.finished = finished
1738
+ to.destroyed = destroyed
1739
+ to.blockLen = blockLen
1740
+ to.outputLen = outputLen
1741
+ to.oHash = oHash._cloneInto(to.oHash ?? undefined)
1742
+ to.iHash = iHash._cloneInto(to.iHash ?? undefined)
1743
+ return to
1744
+ }
1745
+
1746
+ clone (): HMAC<T> {
1747
+ return this._cloneInto()
1748
+ }
1749
+
1750
+ destroy (): void {
1751
+ this.destroyed = true
1752
+ this.oHash.destroy()
1753
+ this.iHash.destroy()
1754
+ }
1755
+ }
1756
+
1757
+ function pbkdf2Core (hash: (msg: Input) => Uint8Array & { create: () => FastSHA512, blockLen: number, outputLen: number }, password: KDFInput, salt: KDFInput, opts: { c: number, dkLen?: number }): Uint8Array {
1758
+ ahash(hash)
1759
+ const { c, dkLen } = Object.assign({ dkLen: 32 }, opts)
1760
+ anumber(c)
1761
+ anumber(dkLen)
1762
+ if (c < 1) throw new Error('iterations (c) should be >= 1')
1763
+ const pwd = kdfInputToBytes(password)
1764
+ const slt = kdfInputToBytes(salt)
1765
+ const DK = new Uint8Array(dkLen)
1766
+ const PRF = hmac.create(hash, pwd)
1767
+ const PRFSalt = PRF._cloneInto().update(slt)
1768
+ let prfW: any
1769
+ const arr = new Uint8Array(4)
1770
+ const view = createView(arr)
1771
+ const u = new Uint8Array(PRF.outputLen)
1772
+ for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
1773
+ const Ti = DK.subarray(pos, pos + PRF.outputLen)
1774
+ view.setInt32(0, ti, false)
1775
+ ;(prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u)
1776
+ Ti.set(u.subarray(0, Ti.length))
1777
+ for (let ui = 1; ui < c; ui++) {
1778
+ PRF._cloneInto(prfW).update(u).digestInto(u)
1779
+ for (let i = 0; i < Ti.length; i++) Ti[i] ^= u[i]
1780
+ }
1781
+ }
1782
+ PRF.destroy()
1783
+ PRFSalt.destroy()
1784
+ if (prfW != null) prfW.destroy()
1785
+ clean(u)
1786
+ return DK
1787
+ }
1788
+
1789
+ const hmac = (hash: any, key: Input, message: Input): Uint8Array =>
1790
+ new HMAC<any>(hash, key).update(message).digest()
1791
+ hmac.create = (hash: any, key: Input) => new HMAC<any>(hash, key)
1792
+
1793
+ function pbkdf2Fast (password: Uint8Array, salt: Uint8Array, iterations: number, keylen: number): Uint8Array {
1794
+ return pbkdf2Core(sha512Fast, password, salt, { c: iterations, dkLen: keylen })
1795
+ }
1796
+ // END fast-pbkdf2 helpers
1797
+
1626
1798
  /**
1627
1799
  * Limited SHA-512-only PBKDF2 function for use in deprecated BIP39 code.
1628
1800
  * @function pbkdf2
@@ -1644,32 +1816,23 @@ export function pbkdf2 (
1644
1816
  if (digest !== 'sha512') {
1645
1817
  throw new Error('Only sha512 is supported in this PBKDF2 implementation')
1646
1818
  }
1647
- const DK = new Array(keylen)
1648
- const block1 = [...salt, 0, 0, 0, 0]
1649
-
1650
- let destPos = 0
1651
- const hLen = 64
1652
- const l = Math.ceil(keylen / hLen)
1653
-
1654
- for (let i = 1; i <= l; i++) {
1655
- block1[salt.length] = (i >> 24) & 0xff // MSB
1656
- block1[salt.length + 1] = (i >> 16) & 0xff
1657
- block1[salt.length + 2] = (i >> 8) & 0xff
1658
- block1[salt.length + 3] = i & 0xff // LSB
1659
-
1660
- const T = sha512hmac(password, block1)
1661
- let U = T
1662
-
1663
- for (let j = 1; j < iterations; j++) {
1664
- U = sha512hmac(password, U)
1665
- for (let k = 0; k < hLen; k++) T[k] ^= U[k]
1819
+ // Attempt to use the native Node.js implementation if available as it is
1820
+ // considerably faster than the pure TypeScript fallback below. If the crypto
1821
+ // module isn't present (for example in a browser build) we'll silently fall
1822
+ // back to the original implementation.
1823
+ try {
1824
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
1825
+ const nodeCrypto = require('crypto')
1826
+ if (typeof nodeCrypto.pbkdf2Sync === 'function') {
1827
+ const p = Buffer.from(password)
1828
+ const s = Buffer.from(salt)
1829
+ return [...nodeCrypto.pbkdf2Sync(p, s, iterations, keylen, digest)]
1666
1830
  }
1667
-
1668
- for (let i = 0; i < T.length; i++) {
1669
- DK[destPos + i] = T[i]
1670
- }
1671
- destPos += hLen
1831
+ } catch {
1832
+ // ignore
1672
1833
  }
1673
-
1674
- return DK.slice(0, keylen)
1834
+ const p = Uint8Array.from(password)
1835
+ const s = Uint8Array.from(salt)
1836
+ const out = pbkdf2Fast(p, s, iterations, keylen)
1837
+ return Array.from(out)
1675
1838
  }