@bsv/sdk 1.0.13 → 1.0.15

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 (119) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/package.json +2 -2
  3. package/dist/cjs/src/compat/BSM.js.map +1 -1
  4. package/dist/cjs/src/compat/ECIES.js +105 -76
  5. package/dist/cjs/src/compat/ECIES.js.map +1 -1
  6. package/dist/cjs/src/compat/HD.js +65 -65
  7. package/dist/cjs/src/compat/HD.js.map +1 -1
  8. package/dist/cjs/src/compat/Mnemonic.js +79 -79
  9. package/dist/cjs/src/compat/Mnemonic.js.map +1 -1
  10. package/dist/cjs/src/compat/bip-39-wordlist-en.js +2 -2
  11. package/dist/cjs/src/compat/bip-39-wordlist-en.js.map +1 -1
  12. package/dist/cjs/src/primitives/AESGCM.js.map +1 -1
  13. package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
  14. package/dist/cjs/src/primitives/DRBG.js.map +1 -1
  15. package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
  16. package/dist/cjs/src/primitives/Hash.js +26 -13
  17. package/dist/cjs/src/primitives/Hash.js.map +1 -1
  18. package/dist/cjs/src/primitives/PrivateKey.js +3 -2
  19. package/dist/cjs/src/primitives/PrivateKey.js.map +1 -1
  20. package/dist/cjs/src/primitives/PublicKey.js +1 -2
  21. package/dist/cjs/src/primitives/PublicKey.js.map +1 -1
  22. package/dist/cjs/src/primitives/Random.js +2 -2
  23. package/dist/cjs/src/primitives/Random.js.map +1 -1
  24. package/dist/cjs/src/primitives/Signature.js +141 -4
  25. package/dist/cjs/src/primitives/Signature.js.map +1 -1
  26. package/dist/cjs/src/primitives/SymmetricKey.js.map +1 -1
  27. package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
  28. package/dist/cjs/src/primitives/utils.js +14 -9
  29. package/dist/cjs/src/primitives/utils.js.map +1 -1
  30. package/dist/cjs/src/script/Spend.js.map +1 -1
  31. package/dist/cjs/src/script/templates/P2PKH.js +1 -1
  32. package/dist/cjs/src/script/templates/P2PKH.js.map +1 -1
  33. package/dist/cjs/src/transaction/MerklePath.js +3 -3
  34. package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
  35. package/dist/cjs/src/transaction/Transaction.js +2 -2
  36. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  37. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  38. package/dist/esm/src/compat/BSM.js.map +1 -1
  39. package/dist/esm/src/compat/ECIES.js +105 -76
  40. package/dist/esm/src/compat/ECIES.js.map +1 -1
  41. package/dist/esm/src/compat/HD.js +65 -65
  42. package/dist/esm/src/compat/HD.js.map +1 -1
  43. package/dist/esm/src/compat/Mnemonic.js +79 -79
  44. package/dist/esm/src/compat/Mnemonic.js.map +1 -1
  45. package/dist/esm/src/compat/bip-39-wordlist-en.js +2 -2
  46. package/dist/esm/src/compat/bip-39-wordlist-en.js.map +1 -1
  47. package/dist/esm/src/primitives/AESGCM.js.map +1 -1
  48. package/dist/esm/src/primitives/BigNumber.js.map +1 -1
  49. package/dist/esm/src/primitives/DRBG.js.map +1 -1
  50. package/dist/esm/src/primitives/ECDSA.js.map +1 -1
  51. package/dist/esm/src/primitives/Hash.js +26 -13
  52. package/dist/esm/src/primitives/Hash.js.map +1 -1
  53. package/dist/esm/src/primitives/PrivateKey.js +3 -2
  54. package/dist/esm/src/primitives/PrivateKey.js.map +1 -1
  55. package/dist/esm/src/primitives/PublicKey.js +1 -2
  56. package/dist/esm/src/primitives/PublicKey.js.map +1 -1
  57. package/dist/esm/src/primitives/Random.js +2 -2
  58. package/dist/esm/src/primitives/Random.js.map +1 -1
  59. package/dist/esm/src/primitives/Signature.js +141 -4
  60. package/dist/esm/src/primitives/Signature.js.map +1 -1
  61. package/dist/esm/src/primitives/SymmetricKey.js.map +1 -1
  62. package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
  63. package/dist/esm/src/primitives/utils.js +14 -9
  64. package/dist/esm/src/primitives/utils.js.map +1 -1
  65. package/dist/esm/src/script/Spend.js.map +1 -1
  66. package/dist/esm/src/script/templates/P2PKH.js +1 -1
  67. package/dist/esm/src/script/templates/P2PKH.js.map +1 -1
  68. package/dist/esm/src/transaction/MerklePath.js +3 -3
  69. package/dist/esm/src/transaction/MerklePath.js.map +1 -1
  70. package/dist/esm/src/transaction/Transaction.js +2 -2
  71. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  72. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  73. package/dist/types/src/compat/ECIES.d.ts +36 -36
  74. package/dist/types/src/compat/ECIES.d.ts.map +1 -1
  75. package/dist/types/src/compat/HD.d.ts +65 -65
  76. package/dist/types/src/compat/HD.d.ts.map +1 -1
  77. package/dist/types/src/compat/Mnemonic.d.ts +79 -79
  78. package/dist/types/src/compat/Mnemonic.d.ts.map +1 -1
  79. package/dist/types/src/primitives/AESGCM.d.ts.map +1 -1
  80. package/dist/types/src/primitives/BigNumber.d.ts.map +1 -1
  81. package/dist/types/src/primitives/Hash.d.ts.map +1 -1
  82. package/dist/types/src/primitives/PrivateKey.d.ts.map +1 -1
  83. package/dist/types/src/primitives/PublicKey.d.ts.map +1 -1
  84. package/dist/types/src/primitives/Signature.d.ts +62 -0
  85. package/dist/types/src/primitives/Signature.d.ts.map +1 -1
  86. package/dist/types/src/primitives/SymmetricKey.d.ts.map +1 -1
  87. package/dist/types/src/primitives/TransactionSignature.d.ts.map +1 -1
  88. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  89. package/dist/types/src/script/Spend.d.ts.map +1 -1
  90. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  91. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  92. package/docs/compat.md +4 -4
  93. package/docs/primitives.md +288 -79
  94. package/mod.ts +8 -0
  95. package/package.json +5 -3
  96. package/src/compat/BSM.ts +12 -12
  97. package/src/compat/ECIES.ts +417 -418
  98. package/src/compat/HD.ts +228 -228
  99. package/src/compat/Mnemonic.ts +173 -173
  100. package/src/compat/__tests/BSM.test.ts +13 -2
  101. package/src/compat/bip-39-wordlist-en.ts +2052 -2052
  102. package/src/primitives/AESGCM.ts +30 -30
  103. package/src/primitives/BigNumber.ts +0 -1
  104. package/src/primitives/DRBG.ts +5 -5
  105. package/src/primitives/ECDSA.ts +1 -1
  106. package/src/primitives/Hash.ts +278 -293
  107. package/src/primitives/PrivateKey.ts +18 -19
  108. package/src/primitives/PublicKey.ts +9 -10
  109. package/src/primitives/Random.ts +4 -4
  110. package/src/primitives/Signature.ts +158 -14
  111. package/src/primitives/SymmetricKey.ts +3 -3
  112. package/src/primitives/TransactionSignature.ts +9 -9
  113. package/src/primitives/index.ts +1 -1
  114. package/src/primitives/utils.ts +60 -64
  115. package/src/script/Spend.ts +12 -12
  116. package/src/script/index.ts +1 -1
  117. package/src/script/templates/P2PKH.ts +1 -1
  118. package/src/transaction/MerklePath.ts +3 -3
  119. package/src/transaction/Transaction.ts +23 -23
@@ -6,70 +6,70 @@ import Point from '../primitives/Point.js'
6
6
  import * as Hash from '../primitives/Hash.js'
7
7
  import { toArray, toHex, encode } from '../primitives/utils.js'
8
8
 
9
- function AES(key) {
10
- if (!this._tables[0][0][0]) this._precompute();
11
-
12
- var tmp, encKey, decKey;
13
- var sbox = this._tables[0][4];
14
- var decTable = this._tables[1];
15
- var keyLen = key.length;
16
- var rcon = 1;
17
-
18
- if (keyLen !== 4 && keyLen !== 6 && keyLen !== 8) {
19
- throw new Error("invalid aes key size");
9
+ function AES (key) {
10
+ if (!this._tables[0][0][0]) this._precompute()
11
+
12
+ let tmp, encKey, decKey
13
+ const sbox = this._tables[0][4]
14
+ const decTable = this._tables[1]
15
+ const keyLen = key.length
16
+ let rcon = 1
17
+
18
+ if (keyLen !== 4 && keyLen !== 6 && keyLen !== 8) {
19
+ throw new Error('invalid aes key size')
20
+ }
21
+
22
+ this._key = [encKey = key.slice(0), decKey = []]
23
+
24
+ // schedule encryption keys
25
+ for (var i = keyLen; i < 4 * keyLen + 28; i++) {
26
+ tmp = encKey[i - 1]
27
+
28
+ // apply sbox
29
+ if (i % keyLen === 0 || (keyLen === 8 && i % keyLen === 4)) {
30
+ tmp = sbox[tmp >>> 24] << 24 ^ sbox[tmp >> 16 & 255] << 16 ^ sbox[tmp >> 8 & 255] << 8 ^ sbox[tmp & 255]
31
+
32
+ // shift rows and add rcon
33
+ if (i % keyLen === 0) {
34
+ tmp = tmp << 8 ^ tmp >>> 24 ^ rcon << 24
35
+ rcon = rcon << 1 ^ (rcon >> 7) * 283
36
+ }
20
37
  }
21
38
 
22
- this._key = [encKey = key.slice(0), decKey = []];
23
-
24
- // schedule encryption keys
25
- for (var i = keyLen; i < 4 * keyLen + 28; i++) {
26
- tmp = encKey[i - 1];
27
-
28
- // apply sbox
29
- if (i % keyLen === 0 || (keyLen === 8 && i % keyLen === 4)) {
30
- tmp = sbox[tmp >>> 24] << 24 ^ sbox[tmp >> 16 & 255] << 16 ^ sbox[tmp >> 8 & 255] << 8 ^ sbox[tmp & 255];
31
-
32
- // shift rows and add rcon
33
- if (i % keyLen === 0) {
34
- tmp = tmp << 8 ^ tmp >>> 24 ^ rcon << 24;
35
- rcon = rcon << 1 ^ (rcon >> 7) * 283;
36
- }
37
- }
38
-
39
- encKey[i] = encKey[i - keyLen] ^ tmp;
40
- }
39
+ encKey[i] = encKey[i - keyLen] ^ tmp
40
+ }
41
41
 
42
- // schedule decryption keys
43
- for (var j = 0; i; j++, i--) {
44
- tmp = encKey[j & 3 ? i : i - 4];
45
- if (i <= 4 || j < 4) {
46
- decKey[j] = tmp;
47
- } else {
48
- decKey[j] = decTable[0][sbox[tmp >>> 24]] ^
42
+ // schedule decryption keys
43
+ for (let j = 0; i; j++, i--) {
44
+ tmp = encKey[j & 3 ? i : i - 4]
45
+ if (i <= 4 || j < 4) {
46
+ decKey[j] = tmp
47
+ } else {
48
+ decKey[j] = decTable[0][sbox[tmp >>> 24]] ^
49
49
  decTable[1][sbox[tmp >> 16 & 255]] ^
50
50
  decTable[2][sbox[tmp >> 8 & 255]] ^
51
- decTable[3][sbox[tmp & 255]];
52
- }
51
+ decTable[3][sbox[tmp & 255]]
53
52
  }
53
+ }
54
54
  }
55
55
 
56
56
  AES.prototype = {
57
57
 
58
- /**
58
+ /**
59
59
  * Encrypt an array of 4 big-endian words.
60
60
  * @param {Array} data The plaintext.
61
61
  * @return {Array} The ciphertext.
62
62
  */
63
- encrypt: function (data) { return this._crypt(data, 0); },
63
+ encrypt: function (data) { return this._crypt(data, 0) },
64
64
 
65
- /**
65
+ /**
66
66
  * Decrypt an array of 4 big-endian words.
67
67
  * @param {Array} data The ciphertext.
68
68
  * @return {Array} The plaintext.
69
69
  */
70
- decrypt: function (data) { return this._crypt(data, 1); },
70
+ decrypt: function (data) { return this._crypt(data, 1) },
71
71
 
72
- /**
72
+ /**
73
73
  * The expanded S-box and inverse S-box tables. These will be computed
74
74
  * on the client so that we don't have to send them down the wire.
75
75
  *
@@ -81,388 +81,387 @@ AES.prototype = {
81
81
  *
82
82
  * @private
83
83
  */
84
- _tables: [
85
- [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)],
86
- [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)]
87
- ],
88
-
89
- //Expand the S-box tables.
90
- _precompute: function () {
91
- var encTable = this._tables[0], decTable = this._tables[1],
92
- sbox = encTable[4], sboxInv = decTable[4],
93
- i, x, xInv, d = new Uint8Array(256), th = new Uint8Array(256), x2, x4, x8, s, tEnc, tDec;
94
-
95
- // Compute double and third tables
96
- for (i = 0; i < 256; i++) {
97
- th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i;
98
- }
99
-
100
- for (x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) {
101
- // Compute sbox
102
- s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4;
103
- s = s >> 8 ^ s & 255 ^ 99;
104
- sbox[x] = s;
105
- sboxInv[s] = x;
106
-
107
- // Compute MixColumns
108
- x8 = d[x4 = d[x2 = d[x]]];
109
- tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
110
- tEnc = d[s] * 0x101 ^ s * 0x1010100;
111
-
112
- for (i = 0; i < 4; i++) {
113
- encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8;
114
- decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8;
115
- }
116
- }
117
- },
118
-
119
- /**
84
+ _tables: [
85
+ [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)],
86
+ [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)]
87
+ ],
88
+
89
+ // Expand the S-box tables.
90
+ _precompute: function () {
91
+ const encTable = this._tables[0]; const decTable = this._tables[1]
92
+ const sbox = encTable[4]; const sboxInv = decTable[4]
93
+ let i; let x; let xInv; const d = new Uint8Array(256); const th = new Uint8Array(256); let x2; let x4; let x8; let s; let tEnc; let tDec
94
+
95
+ // Compute double and third tables
96
+ for (i = 0; i < 256; i++) {
97
+ th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i
98
+ }
99
+
100
+ for (x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) {
101
+ // Compute sbox
102
+ s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4
103
+ s = s >> 8 ^ s & 255 ^ 99
104
+ sbox[x] = s
105
+ sboxInv[s] = x
106
+
107
+ // Compute MixColumns
108
+ x8 = d[x4 = d[x2 = d[x]]]
109
+ tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100
110
+ tEnc = d[s] * 0x101 ^ s * 0x1010100
111
+
112
+ for (i = 0; i < 4; i++) {
113
+ encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8
114
+ decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8
115
+ }
116
+ }
117
+ },
118
+
119
+ /**
120
120
  * Encryption and decryption core.
121
121
  * @param {Array} input Four words to be encrypted or decrypted.
122
122
  * @param dir The direction, 0 for encrypt and 1 for decrypt.
123
123
  * @return {Array} The four encrypted or decrypted words.
124
124
  * @private
125
125
  */
126
- _crypt: function (input, dir) {
127
- if (input.length !== 4) {
128
- throw new Error("invalid aes block size");
129
- }
130
-
131
- var key = this._key[dir],
132
- // state variables a,b,c,d are loaded with pre-whitened data
133
- a = input[0] ^ key[0],
134
- b = input[dir ? 3 : 1] ^ key[1],
135
- c = input[2] ^ key[2],
136
- d = input[dir ? 1 : 3] ^ key[3],
137
- a2, b2, c2,
138
-
139
- nInnerRounds = key.length / 4 - 2,
140
- i,
141
- kIndex = 4,
142
- out = new Uint32Array(4),// <--- this is slower in Node.js, about the same in Chrome */
143
- table = this._tables[dir],
144
-
145
- // load up the tables
146
- t0 = table[0],
147
- t1 = table[1],
148
- t2 = table[2],
149
- t3 = table[3],
150
- sbox = table[4];
151
-
152
- // Inner rounds. Cribbed from OpenSSL.
153
- for (i = 0; i < nInnerRounds; i++) {
154
- a2 = t0[a >>> 24] ^ t1[b >> 16 & 255] ^ t2[c >> 8 & 255] ^ t3[d & 255] ^ key[kIndex];
155
- b2 = t0[b >>> 24] ^ t1[c >> 16 & 255] ^ t2[d >> 8 & 255] ^ t3[a & 255] ^ key[kIndex + 1];
156
- c2 = t0[c >>> 24] ^ t1[d >> 16 & 255] ^ t2[a >> 8 & 255] ^ t3[b & 255] ^ key[kIndex + 2];
157
- d = t0[d >>> 24] ^ t1[a >> 16 & 255] ^ t2[b >> 8 & 255] ^ t3[c & 255] ^ key[kIndex + 3];
158
- kIndex += 4;
159
- a = a2; b = b2; c = c2;
160
- }
161
-
162
- // Last round.
163
- for (i = 0; i < 4; i++) {
164
- out[dir ? 3 & -i : i] =
126
+ _crypt: function (input, dir) {
127
+ if (input.length !== 4) {
128
+ throw new Error('invalid aes block size')
129
+ }
130
+
131
+ const key = this._key[dir]
132
+ // state variables a,b,c,d are loaded with pre-whitened data
133
+ let a = input[0] ^ key[0]
134
+ let b = input[dir ? 3 : 1] ^ key[1]
135
+ let c = input[2] ^ key[2]
136
+ let d = input[dir ? 1 : 3] ^ key[3]
137
+ let a2; let b2; let c2
138
+
139
+ const nInnerRounds = key.length / 4 - 2
140
+ let i
141
+ let kIndex = 4
142
+ const out = new Uint32Array(4); const // <--- this is slower in Node.js, about the same in Chrome */
143
+ table = this._tables[dir]
144
+
145
+ // load up the tables
146
+ const t0 = table[0]
147
+ const t1 = table[1]
148
+ const t2 = table[2]
149
+ const t3 = table[3]
150
+ const sbox = table[4]
151
+
152
+ // Inner rounds. Cribbed from OpenSSL.
153
+ for (i = 0; i < nInnerRounds; i++) {
154
+ a2 = t0[a >>> 24] ^ t1[b >> 16 & 255] ^ t2[c >> 8 & 255] ^ t3[d & 255] ^ key[kIndex]
155
+ b2 = t0[b >>> 24] ^ t1[c >> 16 & 255] ^ t2[d >> 8 & 255] ^ t3[a & 255] ^ key[kIndex + 1]
156
+ c2 = t0[c >>> 24] ^ t1[d >> 16 & 255] ^ t2[a >> 8 & 255] ^ t3[b & 255] ^ key[kIndex + 2]
157
+ d = t0[d >>> 24] ^ t1[a >> 16 & 255] ^ t2[b >> 8 & 255] ^ t3[c & 255] ^ key[kIndex + 3]
158
+ kIndex += 4
159
+ a = a2; b = b2; c = c2
160
+ }
161
+
162
+ // Last round.
163
+ for (i = 0; i < 4; i++) {
164
+ out[dir ? 3 & -i : i] =
165
165
  sbox[a >>> 24] << 24 ^
166
166
  sbox[b >> 16 & 255] << 16 ^
167
167
  sbox[c >> 8 & 255] << 8 ^
168
168
  sbox[d & 255] ^
169
- key[kIndex++];
170
- a2 = a; a = b; b = c; c = d; d = a2;
171
- }
172
-
173
- return out;
169
+ key[kIndex++]
170
+ a2 = a; a = b; b = c; c = d; d = a2
174
171
  }
172
+
173
+ return out
174
+ }
175
175
  }
176
176
 
177
177
  class AESWrapper {
178
- public static encrypt(messageBuf: number[], keyBuf: number[]): number[] {
179
- const key = AESWrapper.buf2Words((keyBuf))
180
- const message = AESWrapper.buf2Words((messageBuf))
181
- const a = new AES(key)
182
- const enc = a.encrypt(message)
183
- const encBuf = AESWrapper.words2Buf(enc)
184
- return encBuf
178
+ public static encrypt (messageBuf: number[], keyBuf: number[]): number[] {
179
+ const key = AESWrapper.buf2Words((keyBuf))
180
+ const message = AESWrapper.buf2Words((messageBuf))
181
+ const a = new AES(key)
182
+ const enc = a.encrypt(message)
183
+ const encBuf = AESWrapper.words2Buf(enc)
184
+ return encBuf
185
+ }
186
+
187
+ public static decrypt (encBuf: number[], keyBuf: number[]): number[] {
188
+ const enc = AESWrapper.buf2Words((encBuf))
189
+ const key = AESWrapper.buf2Words((keyBuf))
190
+ const a = new AES(key)
191
+ const message = a.decrypt(enc)
192
+ const messageBuf = AESWrapper.words2Buf(message)
193
+ return messageBuf
194
+ }
195
+
196
+ public static buf2Words (buf: number[]): number[] {
197
+ if (buf.length % 4) {
198
+ throw new Error('buf length must be a multiple of 4')
185
199
  }
186
-
187
- public static decrypt(encBuf: number[], keyBuf: number[]): number[] {
188
- const enc = AESWrapper.buf2Words((encBuf))
189
- const key = AESWrapper.buf2Words((keyBuf))
190
- const a = new AES(key)
191
- const message = a.decrypt(enc)
192
- const messageBuf = AESWrapper.words2Buf(message)
193
- return messageBuf
194
- }
195
-
196
- public static buf2Words(buf: number[]): number[] {
197
- if (buf.length % 4) {
198
- throw new Error('buf length must be a multiple of 4')
199
- }
200
- const words = []
201
- for (let i = 0; i < buf.length / 4; i++) {
202
- const val =
200
+ const words = []
201
+ for (let i = 0; i < buf.length / 4; i++) {
202
+ const val =
203
203
  (buf[i * 4] * 0x1000000) + // Shift the first byte by 24 bits
204
204
  ((buf[i * 4 + 1] << 16) | // Shift the second byte by 16 bits
205
205
  (buf[i * 4 + 2] << 8) | // Shift the third byte by 8 bits
206
206
  buf[i * 4 + 3]) // The fourth byte
207
- words.push(val)
208
- }
209
- return words
207
+ words.push(val)
210
208
  }
211
-
212
- public static words2Buf(words: number[]): number[] {
213
- const buf = new Array(words.length * 4)
214
-
215
- for (let i = 0; i < words.length; i++) {
216
- const word = words[i];
217
- buf[i * 4] = (word >>> 24) & 0xFF;
218
- buf[i * 4 + 1] = (word >>> 16) & 0xFF;
219
- buf[i * 4 + 2] = (word >>> 8) & 0xFF;
220
- buf[i * 4 + 3] = word & 0xFF;
221
- }
222
-
223
- return buf
209
+ return words
210
+ }
211
+
212
+ public static words2Buf (words: number[]): number[] {
213
+ const buf = new Array(words.length * 4)
214
+
215
+ for (let i = 0; i < words.length; i++) {
216
+ const word = words[i]
217
+ buf[i * 4] = (word >>> 24) & 0xFF
218
+ buf[i * 4 + 1] = (word >>> 16) & 0xFF
219
+ buf[i * 4 + 2] = (word >>> 8) & 0xFF
220
+ buf[i * 4 + 3] = word & 0xFF
224
221
  }
222
+
223
+ return buf
224
+ }
225
225
  }
226
226
 
227
227
  class CBC {
228
- public static buf2BlocksBuf(buf: number[], blockSize: number): number[][] {
229
- const bytesize = blockSize / 8
230
- const blockBufs = []
231
-
232
- for (let i = 0; i <= buf.length / bytesize; i++) {
233
- let blockBuf = buf.slice(i * bytesize, i * bytesize + bytesize)
234
-
235
- if (blockBuf.length < blockSize) {
236
- blockBuf = CBC.pkcs7Pad(blockBuf, blockSize)
237
- }
238
-
239
- blockBufs.push(blockBuf)
240
- }
241
-
242
- return blockBufs
243
- }
244
-
245
- public static blockBufs2Buf(blockBufs: number[][]): number[] {
246
- let last = blockBufs[blockBufs.length - 1]
247
- last = CBC.pkcs7Unpad(last)
248
- blockBufs[blockBufs.length - 1] = last
228
+ public static buf2BlocksBuf (buf: number[], blockSize: number): number[][] {
229
+ const bytesize = blockSize / 8
230
+ const blockBufs = []
249
231
 
250
- const buf = blockBufs.flat()
251
-
252
- return buf
253
- }
232
+ for (let i = 0; i <= buf.length / bytesize; i++) {
233
+ let blockBuf = buf.slice(i * bytesize, i * bytesize + bytesize)
254
234
 
255
- public static encrypt(
256
- messageBuf: number[],
257
- ivBuf: number[],
258
- blockCipher: any /* TODO: type */,
259
- cipherKeyBuf: number[]
260
- ): number[] {
261
- const blockSize = ivBuf.length * 8
262
- const blockBufs = CBC.buf2BlocksBuf(messageBuf, blockSize)
263
- const encBufs = CBC.encryptBlocks(blockBufs, ivBuf, blockCipher, cipherKeyBuf)
264
- const encBuf = encBufs.flat()
265
- return encBuf
266
- }
267
-
268
- public static decrypt(
269
- encBuf: number[],
270
- ivBuf: number[],
271
- blockCipher: any /* TODO: type */,
272
- cipherKeyBuf: number[]
273
- ): number[] {
274
- const bytesize = ivBuf.length
275
- const encBufs = []
276
- for (let i = 0; i < encBuf.length / bytesize; i++) {
277
- encBufs.push(encBuf.slice(i * bytesize, i * bytesize + bytesize))
278
- }
279
- const blockBufs = CBC.decryptBlocks(encBufs, ivBuf, blockCipher, cipherKeyBuf)
280
- const buf = CBC.blockBufs2Buf(blockBufs)
281
- return buf
282
- }
235
+ if (blockBuf.length < blockSize) {
236
+ blockBuf = CBC.pkcs7Pad(blockBuf, blockSize)
237
+ }
283
238
 
284
- public static encryptBlock(
285
- blockBuf: number[],
286
- ivBuf: number[],
287
- blockCipher: any /* TODO: type */,
288
- cipherKeyBuf: number[]
289
- ): number[] {
290
- const xorbuf = CBC.xorBufs(blockBuf, ivBuf)
291
- const encBuf = blockCipher.encrypt(xorbuf, cipherKeyBuf)
292
- return encBuf
239
+ blockBufs.push(blockBuf)
293
240
  }
294
241
 
295
- public static decryptBlock(
296
- encBuf: number[],
297
- ivBuf: number[],
298
- blockCipher: any /* TODO: type */,
299
- cipherKeyBuf: number[]
300
- ): number[] {
301
- const xorbuf = blockCipher.decrypt(encBuf, cipherKeyBuf)
302
- const blockBuf = CBC.xorBufs(xorbuf, ivBuf)
303
- return blockBuf
242
+ return blockBufs
243
+ }
244
+
245
+ public static blockBufs2Buf (blockBufs: number[][]): number[] {
246
+ let last = blockBufs[blockBufs.length - 1]
247
+ last = CBC.pkcs7Unpad(last)
248
+ blockBufs[blockBufs.length - 1] = last
249
+
250
+ const buf = blockBufs.flat()
251
+
252
+ return buf
253
+ }
254
+
255
+ public static encrypt (
256
+ messageBuf: number[],
257
+ ivBuf: number[],
258
+ blockCipher: any /* TODO: type */,
259
+ cipherKeyBuf: number[]
260
+ ): number[] {
261
+ const blockSize = ivBuf.length * 8
262
+ const blockBufs = CBC.buf2BlocksBuf(messageBuf, blockSize)
263
+ const encBufs = CBC.encryptBlocks(blockBufs, ivBuf, blockCipher, cipherKeyBuf)
264
+ const encBuf = encBufs.flat()
265
+ return encBuf
266
+ }
267
+
268
+ public static decrypt (
269
+ encBuf: number[],
270
+ ivBuf: number[],
271
+ blockCipher: any /* TODO: type */,
272
+ cipherKeyBuf: number[]
273
+ ): number[] {
274
+ const bytesize = ivBuf.length
275
+ const encBufs = []
276
+ for (let i = 0; i < encBuf.length / bytesize; i++) {
277
+ encBufs.push(encBuf.slice(i * bytesize, i * bytesize + bytesize))
304
278
  }
305
-
306
- public static encryptBlocks(
307
- blockBufs: number[][],
308
- ivBuf: number[],
309
- blockCipher: any /* TODO: type */,
310
- cipherKeyBuf: number[]
311
- ): number[][] {
312
- const encBufs = []
313
-
314
- for (let i = 0; i < blockBufs.length; i++) {
315
- const blockBuf = blockBufs[i]
316
- const encBuf = CBC.encryptBlock(blockBuf, ivBuf, blockCipher, cipherKeyBuf)
317
-
318
- encBufs.push(encBuf)
319
-
320
- ivBuf = encBuf
321
- }
322
-
323
- return encBufs
279
+ const blockBufs = CBC.decryptBlocks(encBufs, ivBuf, blockCipher, cipherKeyBuf)
280
+ const buf = CBC.blockBufs2Buf(blockBufs)
281
+ return buf
282
+ }
283
+
284
+ public static encryptBlock (
285
+ blockBuf: number[],
286
+ ivBuf: number[],
287
+ blockCipher: any /* TODO: type */,
288
+ cipherKeyBuf: number[]
289
+ ): number[] {
290
+ const xorbuf = CBC.xorBufs(blockBuf, ivBuf)
291
+ const encBuf = blockCipher.encrypt(xorbuf, cipherKeyBuf)
292
+ return encBuf
293
+ }
294
+
295
+ public static decryptBlock (
296
+ encBuf: number[],
297
+ ivBuf: number[],
298
+ blockCipher: any /* TODO: type */,
299
+ cipherKeyBuf: number[]
300
+ ): number[] {
301
+ const xorbuf = blockCipher.decrypt(encBuf, cipherKeyBuf)
302
+ const blockBuf = CBC.xorBufs(xorbuf, ivBuf)
303
+ return blockBuf
304
+ }
305
+
306
+ public static encryptBlocks (
307
+ blockBufs: number[][],
308
+ ivBuf: number[],
309
+ blockCipher: any /* TODO: type */,
310
+ cipherKeyBuf: number[]
311
+ ): number[][] {
312
+ const encBufs = []
313
+
314
+ for (let i = 0; i < blockBufs.length; i++) {
315
+ const blockBuf = blockBufs[i]
316
+ const encBuf = CBC.encryptBlock(blockBuf, ivBuf, blockCipher, cipherKeyBuf)
317
+
318
+ encBufs.push(encBuf)
319
+
320
+ ivBuf = encBuf
324
321
  }
325
322
 
326
- public static decryptBlocks(
327
- encBufs: number[][],
328
- ivBuf: number[],
329
- blockCipher: any /* TODO: type */,
330
- cipherKeyBuf: number[]
331
- ): number[][] {
332
- const blockBufs = []
323
+ return encBufs
324
+ }
333
325
 
334
- for (let i = 0; i < encBufs.length; i++) {
335
- const encBuf = encBufs[i]
336
- const blockBuf = CBC.decryptBlock(encBuf, ivBuf, blockCipher, cipherKeyBuf)
326
+ public static decryptBlocks (
327
+ encBufs: number[][],
328
+ ivBuf: number[],
329
+ blockCipher: any /* TODO: type */,
330
+ cipherKeyBuf: number[]
331
+ ): number[][] {
332
+ const blockBufs = []
337
333
 
338
- blockBufs.push(blockBuf)
334
+ for (let i = 0; i < encBufs.length; i++) {
335
+ const encBuf = encBufs[i]
336
+ const blockBuf = CBC.decryptBlock(encBuf, ivBuf, blockCipher, cipherKeyBuf)
339
337
 
340
- ivBuf = encBuf
341
- }
338
+ blockBufs.push(blockBuf)
342
339
 
343
- return blockBufs
340
+ ivBuf = encBuf
344
341
  }
345
342
 
346
- public static pkcs7Pad(buf: number[], blockSize: number): number[] {
347
- const bytesize = blockSize / 8
348
- const padbytesize = bytesize - buf.length
349
- const pad = new Array(padbytesize)
350
- pad.fill(padbytesize)
351
- const paddedbuf = [...buf, ...pad]
352
- return paddedbuf
343
+ return blockBufs
344
+ }
345
+
346
+ public static pkcs7Pad (buf: number[], blockSize: number): number[] {
347
+ const bytesize = blockSize / 8
348
+ const padbytesize = bytesize - buf.length
349
+ const pad = new Array(padbytesize)
350
+ pad.fill(padbytesize)
351
+ const paddedbuf = [...buf, ...pad]
352
+ return paddedbuf
353
+ }
354
+
355
+ public static pkcs7Unpad (paddedbuf: number[]): number[] {
356
+ const padlength = paddedbuf[paddedbuf.length - 1]
357
+ const padbuf = paddedbuf.slice(paddedbuf.length - padlength, paddedbuf.length)
358
+ const padbuf2 = new Array(padlength)
359
+ padbuf2.fill(padlength)
360
+ if (toHex(padbuf) !== toHex(padbuf2)) {
361
+ throw new Error('invalid padding')
353
362
  }
363
+ return paddedbuf.slice(0, paddedbuf.length - padlength)
364
+ }
354
365
 
355
- public static pkcs7Unpad(paddedbuf: number[]): number[] {
356
- const padlength = paddedbuf[paddedbuf.length - 1]
357
- const padbuf = paddedbuf.slice(paddedbuf.length - padlength, paddedbuf.length)
358
- const padbuf2 = new Array(padlength)
359
- padbuf2.fill(padlength)
360
- if (toHex(padbuf) !== toHex(padbuf2)) {
361
- throw new Error('invalid padding')
362
- }
363
- return paddedbuf.slice(0, paddedbuf.length - padlength)
366
+ public static xorBufs (buf1: number[], buf2: number[]): number[] {
367
+ if (buf1.length !== buf2.length) {
368
+ throw new Error('bufs must have the same length')
364
369
  }
365
370
 
366
- public static xorBufs(buf1: number[], buf2: number[]): number[] {
367
- if (buf1.length !== buf2.length) {
368
- throw new Error('bufs must have the same length')
369
- }
370
-
371
- const buf = new Array(buf1.length)
372
-
373
- for (let i = 0; i < buf1.length; i++) {
374
- buf[i] = buf1[i] ^ buf2[i]
375
- }
371
+ const buf = new Array(buf1.length)
376
372
 
377
- return buf
373
+ for (let i = 0; i < buf1.length; i++) {
374
+ buf[i] = buf1[i] ^ buf2[i]
378
375
  }
376
+
377
+ return buf
378
+ }
379
379
  }
380
380
 
381
381
  class AESCBC {
382
- public static encrypt(messageBuf: number[], cipherKeyBuf: number[], ivBuf: number[], concatIvBuf = true): number[] {
383
- ivBuf = ivBuf || new Array(128 / 8).fill(0) || Random(128 / 8)
384
- const ctBuf = CBC.encrypt(messageBuf, ivBuf, AESWrapper, cipherKeyBuf)
385
- if (concatIvBuf) {
386
- return [...ivBuf, ...ctBuf]
387
- } else {
388
- return [...ctBuf]
389
- }
382
+ public static encrypt (messageBuf: number[], cipherKeyBuf: number[], ivBuf: number[], concatIvBuf = true): number[] {
383
+ ivBuf = ivBuf || new Array(128 / 8).fill(0) || Random(128 / 8)
384
+ const ctBuf = CBC.encrypt(messageBuf, ivBuf, AESWrapper, cipherKeyBuf)
385
+ if (concatIvBuf) {
386
+ return [...ivBuf, ...ctBuf]
387
+ } else {
388
+ return [...ctBuf]
390
389
  }
391
-
392
- public static decrypt(encBuf: number[], cipherKeyBuf: number[], ivBuf?: number[]): number[] {
393
- if (!ivBuf) {
394
- ivBuf = encBuf.slice(0, 128 / 8)
395
- const ctBuf = encBuf.slice(128 / 8)
396
- return CBC.decrypt(ctBuf, ivBuf, AESWrapper, cipherKeyBuf)
397
- } else {
398
- const ctBuf = encBuf
399
- return CBC.decrypt(ctBuf, ivBuf, AESWrapper, cipherKeyBuf)
400
- }
390
+ }
391
+
392
+ public static decrypt (encBuf: number[], cipherKeyBuf: number[], ivBuf?: number[]): number[] {
393
+ if (!ivBuf) {
394
+ ivBuf = encBuf.slice(0, 128 / 8)
395
+ const ctBuf = encBuf.slice(128 / 8)
396
+ return CBC.decrypt(ctBuf, ivBuf, AESWrapper, cipherKeyBuf)
397
+ } else {
398
+ const ctBuf = encBuf
399
+ return CBC.decrypt(ctBuf, ivBuf, AESWrapper, cipherKeyBuf)
401
400
  }
401
+ }
402
402
  }
403
403
 
404
404
  /**
405
405
  * @class ECIES
406
406
  * Implements the Electrum ECIES protocol for encrypted communication.
407
- *
407
+ *
408
408
  * @prprecated This class is deprecated in favor of the BRC-78 standard for portable encrypted messages,
409
409
  * which provides a more comprehensive and secure solution by integrating with BRC-42 and BRC-43 standards.
410
410
  */
411
411
  export default class ECIES {
412
-
413
- /**
414
- * Generates the initialization vector (iv), encryption key (kE), and MAC key (kM)
412
+ /**
413
+ * Generates the initialization vector (iv), encryption key (kE), and MAC key (kM)
415
414
  * using the sender's private key and receiver's public key.
416
415
  *
417
416
  * @param {PrivateKey} privKey - The sender's private key.
418
417
  * @param {PublicKey} pubKey - The receiver's public key.
419
418
  * @returns {Object} An object containing the iv, kE, and kM as number arrays.
420
419
  */
421
- public static ivkEkM(privKey: PrivateKey, pubKey: PublicKey): { iv: number[]; kE: number[]; kM: number[] } {
422
- const r = privKey
423
- const KB = pubKey
424
- const P = KB.mul(r)
425
- const S = new PublicKey(P.x, P.y)
426
- const Sbuf = S.encode(true) as number[]
427
- const hash = Hash.sha512(Sbuf) as number[]
428
- return {
429
- iv: hash.slice(0, 16),
430
- kE: hash.slice(16, 32),
431
- kM: hash.slice(32, 64),
432
- }
420
+ public static ivkEkM (privKey: PrivateKey, pubKey: PublicKey): { iv: number[], kE: number[], kM: number[] } {
421
+ const r = privKey
422
+ const KB = pubKey
423
+ const P = KB.mul(r)
424
+ const S = new PublicKey(P.x, P.y)
425
+ const Sbuf = S.encode(true) as number[]
426
+ const hash = Hash.sha512(Sbuf)
427
+ return {
428
+ iv: hash.slice(0, 16),
429
+ kE: hash.slice(16, 32),
430
+ kM: hash.slice(32, 64)
433
431
  }
432
+ }
434
433
 
435
- /**
434
+ /**
436
435
  * Encrypts a given message using the Electrum ECIES method.
437
- *
436
+ *
438
437
  * @param {number[]} messageBuf - The message to be encrypted, in number array format.
439
438
  * @param {PublicKey} toPublicKey - The public key of the recipient.
440
439
  * @param {PrivateKey} [fromPrivateKey] - The private key of the sender. If not provided, a random private key is used.
441
440
  * @param {boolean} [noKey=false] - If true, does not include the sender's public key in the encrypted message.
442
441
  * @returns {number[]} The encrypted message as a number array.
443
442
  */
444
- public static electrumEncrypt(messageBuf: number[], toPublicKey: PublicKey, fromPrivateKey?: PrivateKey, noKey = false): number[] {
445
- let Rbuf
446
- if (fromPrivateKey === null) {
447
- fromPrivateKey = PrivateKey.fromRandom()
448
- }
449
- if (!noKey) {
450
- Rbuf = fromPrivateKey.toPublicKey().encode(true)
451
- }
452
- const { iv, kE, kM } = ECIES.ivkEkM(fromPrivateKey, toPublicKey)
453
- const ciphertext = AESCBC.encrypt(messageBuf, kE, iv, false)
454
- const BIE1 = toArray('BIE1', 'utf8')
455
- let encBuf: number[]
456
- if (Rbuf) {
457
- encBuf = [...BIE1, ...Rbuf, ...ciphertext]
458
- } else {
459
- encBuf = [...BIE1, ...ciphertext]
460
- }
461
- const hmac = Hash.sha256hmac(kM, encBuf) as number[]
462
- return [...encBuf, ...hmac]
443
+ public static electrumEncrypt (messageBuf: number[], toPublicKey: PublicKey, fromPrivateKey?: PrivateKey, noKey = false): number[] {
444
+ let Rbuf
445
+ if (fromPrivateKey === null) {
446
+ fromPrivateKey = PrivateKey.fromRandom()
463
447
  }
448
+ if (!noKey) {
449
+ Rbuf = fromPrivateKey.toPublicKey().encode(true)
450
+ }
451
+ const { iv, kE, kM } = ECIES.ivkEkM(fromPrivateKey, toPublicKey)
452
+ const ciphertext = AESCBC.encrypt(messageBuf, kE, iv, false)
453
+ const BIE1 = toArray('BIE1', 'utf8')
454
+ let encBuf: number[]
455
+ if (Rbuf) {
456
+ encBuf = [...BIE1, ...Rbuf, ...ciphertext]
457
+ } else {
458
+ encBuf = [...BIE1, ...ciphertext]
459
+ }
460
+ const hmac = Hash.sha256hmac(kM, encBuf)
461
+ return [...encBuf, ...hmac]
462
+ }
464
463
 
465
- /**
464
+ /**
466
465
  * Decrypts a message encrypted using the Electrum ECIES method.
467
466
  *
468
467
  * @param {number[]} encBuf - The encrypted message buffer.
@@ -470,88 +469,88 @@ export default class ECIES {
470
469
  * @param {PublicKey} [fromPublicKey=null] - The public key of the sender. If not provided, it is extracted from the message.
471
470
  * @returns {number[]} The decrypted message as a number array.
472
471
  */
473
- public static electrumDecrypt(encBuf: number[], toPrivateKey: PrivateKey, fromPublicKey: PublicKey = null): number[] {
474
- const tagLength = 32
475
-
476
- const magic = encBuf.slice(0, 4)
477
- if (encode(magic, 'utf8') !== 'BIE1') {
478
- throw new Error('Invalid Magic')
479
- }
480
- let offset = 4
481
- if (fromPublicKey === null) {
482
- // BIE1 use compressed public key, length is always 33.
483
- const pub = encBuf.slice(4, 37)
484
- fromPublicKey = PublicKey.fromString(toHex(pub))
485
- offset = 37
486
- }
487
- const { iv, kE, kM } = ECIES.ivkEkM(toPrivateKey, fromPublicKey)
488
- const ciphertext = encBuf.slice(offset, encBuf.length - tagLength)
489
- const hmac = encBuf.slice(encBuf.length - tagLength, encBuf.length)
490
-
491
- const hmac2 = Hash.sha256hmac(kM, encBuf.slice(0, encBuf.length - tagLength)) as number[]
492
-
493
- if (toHex(hmac) !== toHex(hmac2)) {
494
- throw new Error('Invalid checksum')
495
- }
496
- return AESCBC.decrypt(ciphertext, kE, iv)
472
+ public static electrumDecrypt (encBuf: number[], toPrivateKey: PrivateKey, fromPublicKey: PublicKey = null): number[] {
473
+ const tagLength = 32
474
+
475
+ const magic = encBuf.slice(0, 4)
476
+ if (encode(magic, 'utf8') !== 'BIE1') {
477
+ throw new Error('Invalid Magic')
497
478
  }
479
+ let offset = 4
480
+ if (fromPublicKey === null) {
481
+ // BIE1 use compressed public key, length is always 33.
482
+ const pub = encBuf.slice(4, 37)
483
+ fromPublicKey = PublicKey.fromString(toHex(pub))
484
+ offset = 37
485
+ }
486
+ const { iv, kE, kM } = ECIES.ivkEkM(toPrivateKey, fromPublicKey)
487
+ const ciphertext = encBuf.slice(offset, encBuf.length - tagLength)
488
+ const hmac = encBuf.slice(encBuf.length - tagLength, encBuf.length)
489
+
490
+ const hmac2 = Hash.sha256hmac(kM, encBuf.slice(0, encBuf.length - tagLength))
491
+
492
+ if (toHex(hmac) !== toHex(hmac2)) {
493
+ throw new Error('Invalid checksum')
494
+ }
495
+ return AESCBC.decrypt(ciphertext, kE, iv)
496
+ }
498
497
 
499
- /**
498
+ /**
500
499
  * Encrypts a given message using the Bitcore variant of ECIES.
501
- *
500
+ *
502
501
  * @param {number[]} messageBuf - The message to be encrypted, in number array format.
503
502
  * @param {PublicKey} toPublicKey - The public key of the recipient.
504
503
  * @param {PrivateKey} [fromPrivateKey] - The private key of the sender. If not provided, a random private key is used.
505
504
  * @param {number[]} [ivBuf] - The initialization vector for encryption. If not provided, a random IV is used.
506
505
  * @returns {number[]} The encrypted message as a number array.
507
506
  */
508
- public static bitcoreEncrypt(messageBuf: number[], toPublicKey: PublicKey, fromPrivateKey?: PrivateKey, ivBuf?: number[]): number[] {
509
- if (!fromPrivateKey) {
510
- fromPrivateKey = PrivateKey.fromRandom()
511
- }
512
- const r = fromPrivateKey
513
- const RPublicKey = fromPrivateKey.toPublicKey()
514
- const RBuf = RPublicKey.encode(true) as number[]
515
- const KB = toPublicKey
516
- const P = KB.mul(r)
517
- const S = P.getX()
518
- const Sbuf = S.toArray('be', 32)
519
- const kEkM = Hash.sha512(Sbuf) as number[]
520
- const kE = kEkM.slice(0, 32)
521
- const kM = kEkM.slice(32, 64)
522
- const c = AESCBC.encrypt(messageBuf, kE, ivBuf)
523
- const d = Hash.sha256hmac(kM, [...c]) as number[]
524
- const encBuf = [...RBuf, ...c, ...d]
525
- return encBuf
507
+ public static bitcoreEncrypt (messageBuf: number[], toPublicKey: PublicKey, fromPrivateKey?: PrivateKey, ivBuf?: number[]): number[] {
508
+ if (!fromPrivateKey) {
509
+ fromPrivateKey = PrivateKey.fromRandom()
526
510
  }
527
-
528
- /**
511
+ const r = fromPrivateKey
512
+ const RPublicKey = fromPrivateKey.toPublicKey()
513
+ const RBuf = RPublicKey.encode(true) as number[]
514
+ const KB = toPublicKey
515
+ const P = KB.mul(r)
516
+ const S = P.getX()
517
+ const Sbuf = S.toArray('be', 32)
518
+ const kEkM = Hash.sha512(Sbuf)
519
+ const kE = kEkM.slice(0, 32)
520
+ const kM = kEkM.slice(32, 64)
521
+ const c = AESCBC.encrypt(messageBuf, kE, ivBuf)
522
+ const d = Hash.sha256hmac(kM, [...c])
523
+ const encBuf = [...RBuf, ...c, ...d]
524
+ return encBuf
525
+ }
526
+
527
+ /**
529
528
  * Decrypts a message encrypted using the Bitcore variant of ECIES.
530
529
  *
531
530
  * @param {number[]} encBuf - The encrypted message buffer.
532
531
  * @param {PrivateKey} toPrivateKey - The private key of the recipient.
533
532
  * @returns {number[]} The decrypted message as a number array.
534
533
  */
535
- public static bitcoreDecrypt(encBuf: number[], toPrivateKey: PrivateKey): number[] {
536
- const kB = toPrivateKey
537
- const fromPublicKey = PublicKey.fromString(toHex(encBuf.slice(0, 33)))
538
- const R = fromPublicKey
539
- const P = R.mul(kB)
540
- if (P.eq(new Point(0, 0))) {
541
- throw new Error('P equals 0')
542
- }
543
- const S = P.getX()
544
- const Sbuf = S.toArray('be', 32)
545
- const kEkM = Hash.sha512(Sbuf) as number[]
546
- const kE = kEkM.slice(0, 32)
547
- const kM = kEkM.slice(32, 64)
548
- const c = encBuf.slice(33, encBuf.length - 32)
549
- const d = encBuf.slice(encBuf.length - 32, encBuf.length)
550
- const d2 = Hash.sha256hmac(kM, c) as number[]
551
- if (toHex(d) !== toHex(d2)) {
552
- throw new Error('Invalid checksum')
553
- }
554
- const messageBuf = AESCBC.decrypt(c, kE)
555
- return [...messageBuf]
534
+ public static bitcoreDecrypt (encBuf: number[], toPrivateKey: PrivateKey): number[] {
535
+ const kB = toPrivateKey
536
+ const fromPublicKey = PublicKey.fromString(toHex(encBuf.slice(0, 33)))
537
+ const R = fromPublicKey
538
+ const P = R.mul(kB)
539
+ if (P.eq(new Point(0, 0))) {
540
+ throw new Error('P equals 0')
541
+ }
542
+ const S = P.getX()
543
+ const Sbuf = S.toArray('be', 32)
544
+ const kEkM = Hash.sha512(Sbuf)
545
+ const kE = kEkM.slice(0, 32)
546
+ const kM = kEkM.slice(32, 64)
547
+ const c = encBuf.slice(33, encBuf.length - 32)
548
+ const d = encBuf.slice(encBuf.length - 32, encBuf.length)
549
+ const d2 = Hash.sha256hmac(kM, c)
550
+ if (toHex(d) !== toHex(d2)) {
551
+ throw new Error('Invalid checksum')
556
552
  }
553
+ const messageBuf = AESCBC.decrypt(c, kE)
554
+ return [...messageBuf]
555
+ }
557
556
  }