@queue-it/fastly 1.0.3 → 1.1.0

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.
@@ -1,340 +1,340 @@
1
- // Hash implements SHA256 hash algorithm.
2
- export class Hash {
3
- blockSize: i32;
4
- digestLength: i32;
5
- private readonly state: Int32Array;
6
- private readonly temp: Int32Array;
7
- private readonly buffer: Uint8Array;
8
- private bufferLength: i32;
9
- private bytesHashed: i32;
10
- finished: bool = false
11
-
12
- // SHA-256 constants
13
- static K: u64[] = [
14
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
15
- 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
16
- 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
17
- 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
18
- 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
19
- 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
20
- 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
21
- 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
22
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
23
- 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
24
- 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
25
- 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
26
- 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
27
-
28
- constructor() {
29
- this.digestLength = 32;
30
- this.blockSize = 64;
31
- // Note: Int32Array is used instead of Uint32Array for performance reasons.
32
- this.state = new Int32Array(8); // hash state
33
- this.temp = new Int32Array(64); // temporary state
34
- this.buffer = new Uint8Array(128); // buffer for data to hash
35
- this.bufferLength = 0; // number of bytes in buffer
36
- this.bytesHashed = 0; // number of total bytes hashed
37
- this.finished = false; // indicates whether the hash was finalized
38
- this.reset();
39
- }
40
-
41
- // Resets hash state making it possible
42
- // to re-use this instance to hash other data.
43
- reset(): Hash {
44
- this.state[0] = 0x6a09e667;
45
- this.state[1] = 0xbb67ae85;
46
- this.state[2] = 0x3c6ef372;
47
- this.state[3] = 0xa54ff53a;
48
- this.state[4] = 0x510e527f;
49
- this.state[5] = 0x9b05688c;
50
- this.state[6] = 0x1f83d9ab;
51
- this.state[7] = 0x5be0cd19;
52
- this.bufferLength = 0;
53
- this.bytesHashed = 0;
54
- this.finished = false;
55
- return this;
56
- };
57
-
58
- // Cleans internal buffers and re-initializes hash state.
59
- clean(): void {
60
- for (let i = 0; i < this.buffer.length; i++) {
61
- this.buffer[i] = 0;
62
- }
63
- for (let i = 0; i < this.temp.length; i++) {
64
- this.temp[i] = 0;
65
- }
66
- this.reset();
67
- };
68
-
69
- // Updates hash state with the given data.
70
- //
71
- // Optionally, length of the data can be specified to hash
72
- // fewer bytes than data.length.
73
-
74
- // Throws error when trying to update already finalized hash:
75
- // instance must be reset to use it again.
76
- update(data: Uint8Array, dataLength: i32 = 0): Hash {
77
- if (dataLength == 0) {
78
- dataLength = data.length;
79
- }
80
- if (this.finished) {
81
- throw new Error("SHA256: can't update because hash was finished.");
82
- }
83
-
84
- let dataPos: i32 = 0;
85
- this.bytesHashed += dataLength;
86
- if (this.bufferLength > 0) {
87
- while (this.bufferLength < 64 && dataLength > 0) {
88
- this.buffer[this.bufferLength++] = data[dataPos++];
89
- dataLength--;
90
- }
91
- if (this.bufferLength == 64) {
92
- Hash.hashBlocks(this.temp, this.state, this.buffer, 0, 64);
93
- this.bufferLength = 0;
94
- }
95
- }
96
- if (dataLength >= 64) {
97
- dataPos = Hash.hashBlocks(this.temp, this.state, data, dataPos, dataLength);
98
- dataLength %= 64;
99
- }
100
- while (dataLength > 0) {
101
- this.buffer[this.bufferLength++] = data[dataPos++];
102
- dataLength--;
103
- }
104
- return this;
105
- };
106
-
107
- // Finalizes hash state and puts hash into out.
108
- //
109
- // If hash was already finalized, puts the same value.
110
- finish(out: Uint8Array): Hash {
111
- if (!this.finished) {
112
- let bytesHashed: i32 = this.bytesHashed;
113
- let left: i32 = this.bufferLength;
114
- let bitLenHi: u32 = (bytesHashed / 0x20000000) | 0;
115
- let bitLenLo: u32 = bytesHashed << 3;
116
- let padLength: i32 = (bytesHashed % 64 < 56) ? 64 : 128;
117
- this.buffer[left] = 0x80;
118
- for (let i = left + 1; i < padLength - 8; i++) {
119
- this.buffer[i] = 0;
120
- }
121
- this.buffer[padLength - 8] = (bitLenHi >>> 24) & 0xff;
122
- this.buffer[padLength - 7] = (bitLenHi >>> 16) & 0xff;
123
- this.buffer[padLength - 6] = (bitLenHi >>> 8) & 0xff;
124
- this.buffer[padLength - 5] = (bitLenHi >>> 0) & 0xff;
125
- this.buffer[padLength - 4] = (bitLenLo >>> 24) & 0xff;
126
- this.buffer[padLength - 3] = (bitLenLo >>> 16) & 0xff;
127
- this.buffer[padLength - 2] = (bitLenLo >>> 8) & 0xff;
128
- this.buffer[padLength - 1] = (bitLenLo >>> 0) & 0xff;
129
-
130
- Hash.hashBlocks(this.temp, this.state, this.buffer, 0, padLength);
131
- this.finished = true;
132
- }
133
- for (let i = 0; i < 8; i++) {
134
- out[i * 4] = (this.state[i] >>> 24) & 0xff;
135
- out[i * 4 + 1] = (this.state[i] >>> 16) & 0xff;
136
- out[i * 4 + 2] = (this.state[i] >>> 8) & 0xff;
137
- out[i * 4 + 3] = (this.state[i] >>> 0) & 0xff;
138
- }
139
- return this;
140
- };
141
-
142
- // Returns the final hash digest.
143
- digest(): Uint8Array {
144
- let out = new Uint8Array(this.digestLength);
145
- this.finish(out);
146
- return out;
147
- };
148
-
149
- // Internal function for use in HMAC for optimization.
150
- _saveState(out: Uint32Array): void {
151
- for (let i = 0; i < this.state.length; i++) {
152
- out[i] = this.state[i];
153
- }
154
- };
155
-
156
- // Internal function for use in HMAC for optimization.
157
- _restoreState(from: Uint32Array, bytesHashed: i32): void {
158
- for (let i = 0; i < this.state.length; i++) {
159
- this.state[i] = from[i];
160
- }
161
- this.bytesHashed = bytesHashed;
162
- this.finished = false;
163
- this.bufferLength = 0;
164
- };
165
-
166
- static hashBlocks(w: Int32Array, v: Int32Array, p: Uint8Array, pos: i32, len: u64): i32 {
167
- let a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32, u: i32, i: i8, j: i32, t1: i32, t2: i32;
168
- while (len >= 64) {
169
- a = v[0];
170
- b = v[1];
171
- c = v[2];
172
- d = v[3];
173
- e = v[4];
174
- f = v[5];
175
- g = v[6];
176
- h = v[7];
177
- for (i = 0; i < 16; i++) {
178
- j = pos + i * 4;
179
- let p1 = (((p[j] as i32) & 0xff) << 24);
180
- let p2 = (((p[j + 1] as i32) & 0xff) << 16);
181
- let p3 = (((p[j + 2] as i32) & 0xff) << 8);
182
- let p4 = ((p[j + 3] as i32) & 0xff);
183
- w[i] = p1 | p2 | p3 | p4;
184
- }
185
-
186
- for (i = 16; i < 64; i++) {
187
- u = w[i - 2];
188
- t1 = (u >>> 17 | u << (32 - 17)) ^ (u >>> 19 | u << (32 - 19)) ^ (u >>> 10);
189
- u = w[i - 15];
190
- t2 = (u >>> 7 | u << (32 - 7)) ^ (u >>> 18 | u << (32 - 18)) ^ (u >>> 3);
191
- w[i] = (t1 + w[i - 7] | 0) + (t2 + w[i - 16] | 0);
192
- }
193
- for (i = 0; i < 64; i++) {
194
- t1 = (((((e >>> 6 | e << (32 - 6)) ^ (e >>> 11 | e << (32 - 11)) ^
195
- (e >>> 25 | e << (32 - 25))) + ((e & f) ^ (~e & g))) | 0) +
196
- ((h + (((Hash.K[i] as i32) + w[i]) | 0)) | 0)) | 0;
197
- t2 = (((a >>> 2 | a << (32 - 2)) ^ (a >>> 13 | a << (32 - 13)) ^
198
- (a >>> 22 | a << (32 - 22))) + ((a & b) ^ (a & c) ^ (b & c))) | 0;
199
- h = g;
200
- g = f;
201
- f = e;
202
- e = (d + t1) | 0;
203
- d = c;
204
- c = b;
205
- b = a;
206
- a = (t1 + t2) | 0;
207
- }
208
- v[0] += a;
209
- v[1] += b;
210
- v[2] += c;
211
- v[3] += d;
212
- v[4] += e;
213
- v[5] += f;
214
- v[6] += g;
215
- v[7] += h;
216
- pos += 64;
217
- len -= 64;
218
- }
219
- return pos;
220
- }
221
- }
222
-
223
- // HMAC implements HMAC-SHA256 message authentication algorithm.
224
- export class HMAC {
225
- private inner: Hash
226
- private outer: Hash
227
- blockSize: i32
228
- digestLength: i32
229
- private readonly istate: Uint32Array
230
- private readonly ostate: Uint32Array
231
-
232
- constructor(key: Uint8Array) {
233
- this.inner = new Hash();
234
- this.outer = new Hash();
235
- this.blockSize = this.inner.blockSize;
236
- this.digestLength = this.inner.digestLength;
237
- const pad = new Uint8Array(this.blockSize);
238
- if (key.length > this.blockSize) {
239
- (new Hash()).update(key).finish(pad).clean();
240
- } else {
241
- for (let i = 0; i < key.length; i++) {
242
- pad[i] = key[i];
243
- }
244
- }
245
- for (let i = 0; i < pad.length; i++) {
246
- pad[i] ^= 0x36;
247
- }
248
- this.inner.update(pad);
249
- for (let i = 0; i < pad.length; i++) {
250
- pad[i] ^= 0x36 ^ 0x5c;
251
- }
252
- this.outer.update(pad);
253
- this.istate = new Uint32Array(8);
254
- this.ostate = new Uint32Array(8);
255
- this.inner._saveState(this.istate);
256
- this.outer._saveState(this.ostate);
257
- for (let i = 0; i < pad.length; i++) {
258
- pad[i] = 0;
259
- }
260
- }
261
-
262
- // Returns HMAC state to the state initialized with key
263
- // to make it possible to run HMAC over the other data with the same
264
- // key without creating a new instance.
265
- reset(): HMAC {
266
- this.inner._restoreState(this.istate, this.inner.blockSize);
267
- this.outer._restoreState(this.ostate, this.outer.blockSize);
268
- return this;
269
- };
270
-
271
- // Cleans HMAC state.
272
- clean(): void {
273
- for (let i = 0; i < this.istate.length; i++) {
274
- this.ostate[i] = this.istate[i] = 0;
275
- }
276
- this.inner.clean();
277
- this.outer.clean();
278
- };
279
-
280
- // Updates state with provided data.
281
- update(data: Uint8Array): HMAC {
282
- this.inner.update(data);
283
- return this;
284
- };
285
-
286
- // Finalizes HMAC and puts the result in out.
287
- finish(out: Uint8Array): HMAC {
288
- if (this.outer.finished) {
289
- this.outer.finish(out);
290
- } else {
291
- this.inner.finish(out);
292
- this.outer.update(out, this.digestLength).finish(out);
293
- }
294
- return this;
295
- };
296
-
297
- // Returns message authentication code.
298
- digest(): Uint8Array {
299
- let out = new Uint8Array(this.digestLength);
300
- this.finish(out);
301
- return out;
302
- };
303
- }
304
-
305
- // Returns SHA256 hash of data.
306
- export function hash(data: Uint8Array): Uint8Array {
307
- const h = (new Hash()).update(data);
308
- const digest = h.digest();
309
- h.clean();
310
- return digest;
311
- }
312
-
313
- export function hashString(data: string): string {
314
- return toHex(hash(Uint8Array.wrap(String.UTF8.encode(data))))
315
- }
316
-
317
- // Returns HMAC-SHA256 of data under the key.
318
- export function hmac(key: Uint8Array, data: Uint8Array): Uint8Array {
319
- const h = (new HMAC(key)).update(data);
320
- const digest = h.digest();
321
- h.clean();
322
- return digest;
323
- }
324
-
325
- export function toHex(byteArray: Uint8Array): string {
326
- let acc = '';
327
- for(let i=0; i<byteArray.length; i++){
328
- let val = byteArray[i];
329
- acc += ('0' + val.toString(16)).slice(-2);
330
- }
331
- return acc;
332
- //return byteArray.reduce((acc, val) => (acc + ('0' + val.toString(16)).slice(-2)), '');
333
- }
334
-
335
- export function hmacString(key: string, data: string): string {
336
- const hash = hmac(
337
- Uint8Array.wrap(String.UTF8.encode(key)),
338
- Uint8Array.wrap(String.UTF8.encode(data)));
339
- return toHex(hash)
340
- }
1
+ // Hash implements SHA256 hash algorithm.
2
+ export class Hash {
3
+ blockSize: i32;
4
+ digestLength: i32;
5
+ private readonly state: Int32Array;
6
+ private readonly temp: Int32Array;
7
+ private readonly buffer: Uint8Array;
8
+ private bufferLength: i32;
9
+ private bytesHashed: i32;
10
+ finished: bool = false
11
+
12
+ // SHA-256 constants
13
+ static K: u64[] = [
14
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
15
+ 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
16
+ 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
17
+ 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
18
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
19
+ 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
20
+ 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
21
+ 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
22
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
23
+ 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
24
+ 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
25
+ 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
26
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
27
+
28
+ constructor() {
29
+ this.digestLength = 32;
30
+ this.blockSize = 64;
31
+ // Note: Int32Array is used instead of Uint32Array for performance reasons.
32
+ this.state = new Int32Array(8); // hash state
33
+ this.temp = new Int32Array(64); // temporary state
34
+ this.buffer = new Uint8Array(128); // buffer for data to hash
35
+ this.bufferLength = 0; // number of bytes in buffer
36
+ this.bytesHashed = 0; // number of total bytes hashed
37
+ this.finished = false; // indicates whether the hash was finalized
38
+ this.reset();
39
+ }
40
+
41
+ // Resets hash state making it possible
42
+ // to re-use this instance to hash other data.
43
+ reset(): Hash {
44
+ this.state[0] = 0x6a09e667;
45
+ this.state[1] = 0xbb67ae85;
46
+ this.state[2] = 0x3c6ef372;
47
+ this.state[3] = 0xa54ff53a;
48
+ this.state[4] = 0x510e527f;
49
+ this.state[5] = 0x9b05688c;
50
+ this.state[6] = 0x1f83d9ab;
51
+ this.state[7] = 0x5be0cd19;
52
+ this.bufferLength = 0;
53
+ this.bytesHashed = 0;
54
+ this.finished = false;
55
+ return this;
56
+ };
57
+
58
+ // Cleans internal buffers and re-initializes hash state.
59
+ clean(): void {
60
+ for (let i = 0; i < this.buffer.length; i++) {
61
+ this.buffer[i] = 0;
62
+ }
63
+ for (let i = 0; i < this.temp.length; i++) {
64
+ this.temp[i] = 0;
65
+ }
66
+ this.reset();
67
+ };
68
+
69
+ // Updates hash state with the given data.
70
+ //
71
+ // Optionally, length of the data can be specified to hash
72
+ // fewer bytes than data.length.
73
+
74
+ // Throws error when trying to update already finalized hash:
75
+ // instance must be reset to use it again.
76
+ update(data: Uint8Array, dataLength: i32 = 0): Hash {
77
+ if (dataLength == 0) {
78
+ dataLength = data.length;
79
+ }
80
+ if (this.finished) {
81
+ throw new Error("SHA256: can't update because hash was finished.");
82
+ }
83
+
84
+ let dataPos: i32 = 0;
85
+ this.bytesHashed += dataLength;
86
+ if (this.bufferLength > 0) {
87
+ while (this.bufferLength < 64 && dataLength > 0) {
88
+ this.buffer[this.bufferLength++] = data[dataPos++];
89
+ dataLength--;
90
+ }
91
+ if (this.bufferLength == 64) {
92
+ Hash.hashBlocks(this.temp, this.state, this.buffer, 0, 64);
93
+ this.bufferLength = 0;
94
+ }
95
+ }
96
+ if (dataLength >= 64) {
97
+ dataPos = Hash.hashBlocks(this.temp, this.state, data, dataPos, dataLength);
98
+ dataLength %= 64;
99
+ }
100
+ while (dataLength > 0) {
101
+ this.buffer[this.bufferLength++] = data[dataPos++];
102
+ dataLength--;
103
+ }
104
+ return this;
105
+ };
106
+
107
+ // Finalizes hash state and puts hash into out.
108
+ //
109
+ // If hash was already finalized, puts the same value.
110
+ finish(out: Uint8Array): Hash {
111
+ if (!this.finished) {
112
+ let bytesHashed: i32 = this.bytesHashed;
113
+ let left: i32 = this.bufferLength;
114
+ let bitLenHi: u32 = (bytesHashed / 0x20000000) | 0;
115
+ let bitLenLo: u32 = bytesHashed << 3;
116
+ let padLength: i32 = (bytesHashed % 64 < 56) ? 64 : 128;
117
+ this.buffer[left] = 0x80;
118
+ for (let i = left + 1; i < padLength - 8; i++) {
119
+ this.buffer[i] = 0;
120
+ }
121
+ this.buffer[padLength - 8] = (bitLenHi >>> 24) & 0xff;
122
+ this.buffer[padLength - 7] = (bitLenHi >>> 16) & 0xff;
123
+ this.buffer[padLength - 6] = (bitLenHi >>> 8) & 0xff;
124
+ this.buffer[padLength - 5] = (bitLenHi >>> 0) & 0xff;
125
+ this.buffer[padLength - 4] = (bitLenLo >>> 24) & 0xff;
126
+ this.buffer[padLength - 3] = (bitLenLo >>> 16) & 0xff;
127
+ this.buffer[padLength - 2] = (bitLenLo >>> 8) & 0xff;
128
+ this.buffer[padLength - 1] = (bitLenLo >>> 0) & 0xff;
129
+
130
+ Hash.hashBlocks(this.temp, this.state, this.buffer, 0, padLength);
131
+ this.finished = true;
132
+ }
133
+ for (let i = 0; i < 8; i++) {
134
+ out[i * 4] = (this.state[i] >>> 24) & 0xff;
135
+ out[i * 4 + 1] = (this.state[i] >>> 16) & 0xff;
136
+ out[i * 4 + 2] = (this.state[i] >>> 8) & 0xff;
137
+ out[i * 4 + 3] = (this.state[i] >>> 0) & 0xff;
138
+ }
139
+ return this;
140
+ };
141
+
142
+ // Returns the final hash digest.
143
+ digest(): Uint8Array {
144
+ let out = new Uint8Array(this.digestLength);
145
+ this.finish(out);
146
+ return out;
147
+ };
148
+
149
+ // Internal function for use in HMAC for optimization.
150
+ _saveState(out: Uint32Array): void {
151
+ for (let i = 0; i < this.state.length; i++) {
152
+ out[i] = this.state[i];
153
+ }
154
+ };
155
+
156
+ // Internal function for use in HMAC for optimization.
157
+ _restoreState(from: Uint32Array, bytesHashed: i32): void {
158
+ for (let i = 0; i < this.state.length; i++) {
159
+ this.state[i] = from[i];
160
+ }
161
+ this.bytesHashed = bytesHashed;
162
+ this.finished = false;
163
+ this.bufferLength = 0;
164
+ };
165
+
166
+ static hashBlocks(w: Int32Array, v: Int32Array, p: Uint8Array, pos: i32, len: u64): i32 {
167
+ let a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32, u: i32, i: i8, j: i32, t1: i32, t2: i32;
168
+ while (len >= 64) {
169
+ a = v[0];
170
+ b = v[1];
171
+ c = v[2];
172
+ d = v[3];
173
+ e = v[4];
174
+ f = v[5];
175
+ g = v[6];
176
+ h = v[7];
177
+ for (i = 0; i < 16; i++) {
178
+ j = pos + i * 4;
179
+ let p1 = (((p[j] as i32) & 0xff) << 24);
180
+ let p2 = (((p[j + 1] as i32) & 0xff) << 16);
181
+ let p3 = (((p[j + 2] as i32) & 0xff) << 8);
182
+ let p4 = ((p[j + 3] as i32) & 0xff);
183
+ w[i] = p1 | p2 | p3 | p4;
184
+ }
185
+
186
+ for (i = 16; i < 64; i++) {
187
+ u = w[i - 2];
188
+ t1 = (u >>> 17 | u << (32 - 17)) ^ (u >>> 19 | u << (32 - 19)) ^ (u >>> 10);
189
+ u = w[i - 15];
190
+ t2 = (u >>> 7 | u << (32 - 7)) ^ (u >>> 18 | u << (32 - 18)) ^ (u >>> 3);
191
+ w[i] = (t1 + w[i - 7] | 0) + (t2 + w[i - 16] | 0);
192
+ }
193
+ for (i = 0; i < 64; i++) {
194
+ t1 = (((((e >>> 6 | e << (32 - 6)) ^ (e >>> 11 | e << (32 - 11)) ^
195
+ (e >>> 25 | e << (32 - 25))) + ((e & f) ^ (~e & g))) | 0) +
196
+ ((h + (((Hash.K[i] as i32) + w[i]) | 0)) | 0)) | 0;
197
+ t2 = (((a >>> 2 | a << (32 - 2)) ^ (a >>> 13 | a << (32 - 13)) ^
198
+ (a >>> 22 | a << (32 - 22))) + ((a & b) ^ (a & c) ^ (b & c))) | 0;
199
+ h = g;
200
+ g = f;
201
+ f = e;
202
+ e = (d + t1) | 0;
203
+ d = c;
204
+ c = b;
205
+ b = a;
206
+ a = (t1 + t2) | 0;
207
+ }
208
+ v[0] += a;
209
+ v[1] += b;
210
+ v[2] += c;
211
+ v[3] += d;
212
+ v[4] += e;
213
+ v[5] += f;
214
+ v[6] += g;
215
+ v[7] += h;
216
+ pos += 64;
217
+ len -= 64;
218
+ }
219
+ return pos;
220
+ }
221
+ }
222
+
223
+ // HMAC implements HMAC-SHA256 message authentication algorithm.
224
+ export class HMAC {
225
+ private inner: Hash
226
+ private outer: Hash
227
+ blockSize: i32
228
+ digestLength: i32
229
+ private readonly istate: Uint32Array
230
+ private readonly ostate: Uint32Array
231
+
232
+ constructor(key: Uint8Array) {
233
+ this.inner = new Hash();
234
+ this.outer = new Hash();
235
+ this.blockSize = this.inner.blockSize;
236
+ this.digestLength = this.inner.digestLength;
237
+ const pad = new Uint8Array(this.blockSize);
238
+ if (key.length > this.blockSize) {
239
+ (new Hash()).update(key).finish(pad).clean();
240
+ } else {
241
+ for (let i = 0; i < key.length; i++) {
242
+ pad[i] = key[i];
243
+ }
244
+ }
245
+ for (let i = 0; i < pad.length; i++) {
246
+ pad[i] ^= 0x36;
247
+ }
248
+ this.inner.update(pad);
249
+ for (let i = 0; i < pad.length; i++) {
250
+ pad[i] ^= 0x36 ^ 0x5c;
251
+ }
252
+ this.outer.update(pad);
253
+ this.istate = new Uint32Array(8);
254
+ this.ostate = new Uint32Array(8);
255
+ this.inner._saveState(this.istate);
256
+ this.outer._saveState(this.ostate);
257
+ for (let i = 0; i < pad.length; i++) {
258
+ pad[i] = 0;
259
+ }
260
+ }
261
+
262
+ // Returns HMAC state to the state initialized with key
263
+ // to make it possible to run HMAC over the other data with the same
264
+ // key without creating a new instance.
265
+ reset(): HMAC {
266
+ this.inner._restoreState(this.istate, this.inner.blockSize);
267
+ this.outer._restoreState(this.ostate, this.outer.blockSize);
268
+ return this;
269
+ };
270
+
271
+ // Cleans HMAC state.
272
+ clean(): void {
273
+ for (let i = 0; i < this.istate.length; i++) {
274
+ this.ostate[i] = this.istate[i] = 0;
275
+ }
276
+ this.inner.clean();
277
+ this.outer.clean();
278
+ };
279
+
280
+ // Updates state with provided data.
281
+ update(data: Uint8Array): HMAC {
282
+ this.inner.update(data);
283
+ return this;
284
+ };
285
+
286
+ // Finalizes HMAC and puts the result in out.
287
+ finish(out: Uint8Array): HMAC {
288
+ if (this.outer.finished) {
289
+ this.outer.finish(out);
290
+ } else {
291
+ this.inner.finish(out);
292
+ this.outer.update(out, this.digestLength).finish(out);
293
+ }
294
+ return this;
295
+ };
296
+
297
+ // Returns message authentication code.
298
+ digest(): Uint8Array {
299
+ let out = new Uint8Array(this.digestLength);
300
+ this.finish(out);
301
+ return out;
302
+ };
303
+ }
304
+
305
+ // Returns SHA256 hash of data.
306
+ export function hash(data: Uint8Array): Uint8Array {
307
+ const h = (new Hash()).update(data);
308
+ const digest = h.digest();
309
+ h.clean();
310
+ return digest;
311
+ }
312
+
313
+ export function hashString(data: string): string {
314
+ return toHex(hash(Uint8Array.wrap(String.UTF8.encode(data))))
315
+ }
316
+
317
+ // Returns HMAC-SHA256 of data under the key.
318
+ export function hmac(key: Uint8Array, data: Uint8Array): Uint8Array {
319
+ const h = (new HMAC(key)).update(data);
320
+ const digest = h.digest();
321
+ h.clean();
322
+ return digest;
323
+ }
324
+
325
+ export function toHex(byteArray: Uint8Array): string {
326
+ let acc = '';
327
+ for(let i=0; i<byteArray.length; i++){
328
+ let val = byteArray[i];
329
+ acc += ('0' + val.toString(16)).slice(-2);
330
+ }
331
+ return acc;
332
+ //return byteArray.reduce((acc, val) => (acc + ('0' + val.toString(16)).slice(-2)), '');
333
+ }
334
+
335
+ export function hmacString(key: string, data: string): string {
336
+ const hash = hmac(
337
+ Uint8Array.wrap(String.UTF8.encode(key)),
338
+ Uint8Array.wrap(String.UTF8.encode(data)));
339
+ return toHex(hash)
340
+ }