@zip.js/zip.js 2.13.1 → 2.14.1

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 (51) hide show
  1. package/BENCHMARKS.md +349 -416
  2. package/deno.json +1 -1
  3. package/dist/zip-core-external.js +761 -945
  4. package/dist/zip-core-external.min.js +1 -1
  5. package/dist/zip-core.js +626 -911
  6. package/dist/zip-core.min.js +1 -1
  7. package/dist/zip-fs-core-external.js +768 -948
  8. package/dist/zip-fs-core-external.min.js +1 -1
  9. package/dist/zip-fs-core.js +633 -914
  10. package/dist/zip-fs-core.min.js +1 -1
  11. package/dist/zip-fs-external.js +768 -948
  12. package/dist/zip-fs-external.min.js +1 -1
  13. package/dist/zip-fs-native.js +635 -916
  14. package/dist/zip-fs-native.min.js +1 -1
  15. package/dist/zip-fs.js +771 -951
  16. package/dist/zip-fs.min.js +1 -1
  17. package/dist/zip-legacy.js +628 -913
  18. package/dist/zip-legacy.min.js +1 -1
  19. package/dist/zip-module.wasm +0 -0
  20. package/dist/zip-native.js +628 -913
  21. package/dist/zip-native.min.js +1 -1
  22. package/dist/zip-web-worker-native.js +1 -1
  23. package/dist/zip-web-worker.js +1 -1
  24. package/dist/zip.js +764 -948
  25. package/dist/zip.min.js +1 -1
  26. package/index-native.cjs +635 -916
  27. package/index-native.min.js +1 -1
  28. package/index.cjs +771 -951
  29. package/index.d.cts +52 -12
  30. package/index.d.ts +52 -12
  31. package/index.min.js +1 -1
  32. package/lib/core/codec-worker.js +37 -26
  33. package/lib/core/io.js +29 -21
  34. package/lib/core/streams/aes-crypto-stream.js +58 -99
  35. package/lib/core/streams/codecs/aes-hmac-sha1.js +486 -0
  36. package/lib/core/streams/zlib-wasm/aes-hmac-sha1-wasm.js +106 -0
  37. package/lib/core/streams/zlib-wasm/zlib-streams-loader.js +4 -0
  38. package/lib/core/streams/zlib-wasm/zlib-streams.js +2 -7
  39. package/lib/core/streams/zlib-wasm/zlib-streams.wasm +0 -0
  40. package/lib/core/version.js +1 -1
  41. package/lib/core/web-worker-base.js +15 -9
  42. package/lib/core/web-worker-inline-native.js +1 -1
  43. package/lib/core/web-worker-inline-wasm.js +1 -1
  44. package/lib/core/web-worker-wasm.js +2 -0
  45. package/lib/core/zip-fs.js +7 -3
  46. package/lib/core/zip-reader.js +53 -6
  47. package/lib/core/zip-writer.js +1 -2
  48. package/lib/core/zlib-streams-inline.js +1 -1
  49. package/lib/zip-module-wasm-base.js +3 -1
  50. package/package.json +1 -1
  51. package/lib/core/streams/codecs/sjcl.js +0 -795
@@ -0,0 +1,486 @@
1
+ /*
2
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in
12
+ the documentation and/or other materials provided with the distribution.
13
+
14
+ 3. The names of the authors may not be used to endorse or promote products
15
+ derived from this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
18
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
20
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
21
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ */
28
+
29
+ const BLOCK_LENGTH = 16;
30
+ const ROUND_KEYS_LENGTH = 60;
31
+ const SHA1_BLOCK_LENGTH = 64;
32
+ const SHA1_DIGEST_LENGTH = 20;
33
+ const SHA1_SCHEDULE_LENGTH = 16;
34
+ const SHA1_LENGTH_OFFSET = 56;
35
+ const SHA1_PADDING = new Uint8Array([0x80]);
36
+ const SHA1_ZERO = new Uint8Array(1);
37
+ const SHA1_INITIAL_STATE = new Int32Array([0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]);
38
+ const HMAC_INNER_PADDING = 0x36;
39
+ const HMAC_OUTER_PADDING = 0x5c;
40
+ const S_BOX = new Uint8Array(256);
41
+ const T0 = new Int32Array(256);
42
+ const T1 = new Int32Array(256);
43
+ const T2 = new Int32Array(256);
44
+ const T3 = new Int32Array(256);
45
+
46
+ let tablesInitialized = false;
47
+
48
+ export {
49
+ createEngine,
50
+ pbkdf2
51
+ };
52
+
53
+ function createEngine(key, authenticationKey) {
54
+ initTables();
55
+ const roundKeys = new Int32Array(ROUND_KEYS_LENGTH);
56
+ const rounds = expandKey(key, roundKeys);
57
+ const keystream = new Int32Array(BLOCK_LENGTH / 4);
58
+ const hmac = createHmac(authenticationKey);
59
+ let counter0 = 0;
60
+ let counter1 = 0;
61
+ let counter2 = 0;
62
+ let counter3 = 0;
63
+ return {
64
+ process(data, decrypt) {
65
+ if (decrypt) {
66
+ hmac.update(data, 0, data.length);
67
+ }
68
+ encrypt(data);
69
+ if (!decrypt) {
70
+ hmac.update(data, 0, data.length);
71
+ }
72
+ },
73
+ digest() {
74
+ return hmac.digest();
75
+ }
76
+ };
77
+
78
+ function encrypt(data) {
79
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
80
+ const length = data.length;
81
+ let offset = 0;
82
+ for (; offset + BLOCK_LENGTH <= length; offset += BLOCK_LENGTH) {
83
+ nextKeystream();
84
+ view.setInt32(offset, view.getInt32(offset) ^ keystream[0]);
85
+ view.setInt32(offset + 4, view.getInt32(offset + 4) ^ keystream[1]);
86
+ view.setInt32(offset + 8, view.getInt32(offset + 8) ^ keystream[2]);
87
+ view.setInt32(offset + 12, view.getInt32(offset + 12) ^ keystream[3]);
88
+ }
89
+ if (offset < length) {
90
+ nextKeystream();
91
+ for (let indexByte = 0; offset < length; offset++, indexByte++) {
92
+ data[offset] ^= keystream[indexByte >> 2] >>> (24 - 8 * (indexByte & 3));
93
+ }
94
+ }
95
+ }
96
+
97
+ function nextKeystream() {
98
+ counter0 = (counter0 + 1) | 0;
99
+ if (!counter0) {
100
+ counter1 = (counter1 + 1) | 0;
101
+ if (!counter1) {
102
+ counter2 = (counter2 + 1) | 0;
103
+ if (!counter2) {
104
+ counter3 = (counter3 + 1) | 0;
105
+ }
106
+ }
107
+ }
108
+ let s0 = swapBytes(counter0) ^ roundKeys[0];
109
+ let s1 = swapBytes(counter1) ^ roundKeys[1];
110
+ let s2 = swapBytes(counter2) ^ roundKeys[2];
111
+ let s3 = swapBytes(counter3) ^ roundKeys[3];
112
+ let t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[4];
113
+ let t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[5];
114
+ let t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[6];
115
+ let t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[7];
116
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[8];
117
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[9];
118
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[10];
119
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[11];
120
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[12];
121
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[13];
122
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[14];
123
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[15];
124
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[16];
125
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[17];
126
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[18];
127
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[19];
128
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[20];
129
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[21];
130
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[22];
131
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[23];
132
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[24];
133
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[25];
134
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[26];
135
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[27];
136
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[28];
137
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[29];
138
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[30];
139
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[31];
140
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[32];
141
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[33];
142
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[34];
143
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[35];
144
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[36];
145
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[37];
146
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[38];
147
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[39];
148
+ let indexKey = 40;
149
+ if (rounds > 10) {
150
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[40];
151
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[41];
152
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[42];
153
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[43];
154
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[44];
155
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[45];
156
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[46];
157
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[47];
158
+ indexKey = 48;
159
+ }
160
+ if (rounds > 12) {
161
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[48];
162
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[49];
163
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[50];
164
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[51];
165
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[52];
166
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[53];
167
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[54];
168
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[55];
169
+ indexKey = 56;
170
+ }
171
+ keystream[0] = ((S_BOX[t0 >>> 24] << 24) | (S_BOX[(t1 >>> 16) & 255] << 16) | (S_BOX[(t2 >>> 8) & 255] << 8) | S_BOX[t3 & 255]) ^ roundKeys[indexKey];
172
+ keystream[1] = ((S_BOX[t1 >>> 24] << 24) | (S_BOX[(t2 >>> 16) & 255] << 16) | (S_BOX[(t3 >>> 8) & 255] << 8) | S_BOX[t0 & 255]) ^ roundKeys[indexKey + 1];
173
+ keystream[2] = ((S_BOX[t2 >>> 24] << 24) | (S_BOX[(t3 >>> 16) & 255] << 16) | (S_BOX[(t0 >>> 8) & 255] << 8) | S_BOX[t1 & 255]) ^ roundKeys[indexKey + 2];
174
+ keystream[3] = ((S_BOX[t3 >>> 24] << 24) | (S_BOX[(t0 >>> 16) & 255] << 16) | (S_BOX[(t1 >>> 8) & 255] << 8) | S_BOX[t2 & 255]) ^ roundKeys[indexKey + 3];
175
+ }
176
+ }
177
+
178
+ function pbkdf2(password, salt, iterations, length) {
179
+ const hmac = createHmac(password);
180
+ const result = new Uint8Array(length);
181
+ const block = new Uint8Array(salt.length + 4);
182
+ const blockView = new DataView(block.buffer);
183
+ block.set(salt);
184
+ for (let indexBlock = 1, offset = 0; offset < length; indexBlock++, offset += SHA1_DIGEST_LENGTH) {
185
+ blockView.setUint32(salt.length, indexBlock);
186
+ hmac.update(block, 0, block.length);
187
+ let previous = hmac.digest();
188
+ const output = previous.slice();
189
+ for (let iteration = 1; iteration < iterations; iteration++) {
190
+ hmac.update(previous, 0, SHA1_DIGEST_LENGTH);
191
+ previous = hmac.digest();
192
+ for (let indexByte = 0; indexByte < SHA1_DIGEST_LENGTH; indexByte++) {
193
+ output[indexByte] ^= previous[indexByte];
194
+ }
195
+ }
196
+ result.set(output.subarray(0, Math.min(SHA1_DIGEST_LENGTH, length - offset)), offset);
197
+ }
198
+ return result;
199
+ }
200
+
201
+ function createHmac(key) {
202
+ const sha1 = createSha1();
203
+ const innerKey = new Uint8Array(SHA1_BLOCK_LENGTH);
204
+ const outerKey = new Uint8Array(SHA1_BLOCK_LENGTH);
205
+ if (key.length > SHA1_BLOCK_LENGTH) {
206
+ sha1.update(key, 0, key.length);
207
+ key = sha1.digest();
208
+ }
209
+ for (let indexByte = 0; indexByte < SHA1_BLOCK_LENGTH; indexByte++) {
210
+ const keyByte = indexByte < key.length ? key[indexByte] : 0;
211
+ innerKey[indexByte] = keyByte ^ HMAC_INNER_PADDING;
212
+ outerKey[indexByte] = keyByte ^ HMAC_OUTER_PADDING;
213
+ }
214
+ sha1.update(innerKey, 0, SHA1_BLOCK_LENGTH);
215
+ return {
216
+ update(data, offset, length) {
217
+ sha1.update(data, offset, length);
218
+ },
219
+ digest() {
220
+ const innerDigest = sha1.digest();
221
+ sha1.update(outerKey, 0, SHA1_BLOCK_LENGTH);
222
+ sha1.update(innerDigest, 0, SHA1_DIGEST_LENGTH);
223
+ const result = sha1.digest();
224
+ sha1.update(innerKey, 0, SHA1_BLOCK_LENGTH);
225
+ return result;
226
+ }
227
+ };
228
+ }
229
+
230
+ function createSha1() {
231
+ const state = new Int32Array(SHA1_INITIAL_STATE);
232
+ const schedule = new Int32Array(SHA1_SCHEDULE_LENGTH);
233
+ const block = new Uint8Array(SHA1_BLOCK_LENGTH);
234
+ const blockView = new DataView(block.buffer);
235
+ const lengthBytes = new Uint8Array(8);
236
+ let blockLength = 0;
237
+ let totalLength = 0;
238
+ return {
239
+ update,
240
+ digest
241
+ };
242
+
243
+ function update(data, offset, length) {
244
+ const end = offset + length;
245
+ totalLength += length;
246
+ if (blockLength) {
247
+ while (offset < end && blockLength < SHA1_BLOCK_LENGTH) {
248
+ block[blockLength++] = data[offset++];
249
+ }
250
+ if (blockLength == SHA1_BLOCK_LENGTH) {
251
+ compress(blockView, 0);
252
+ blockLength = 0;
253
+ }
254
+ }
255
+ if (offset + SHA1_BLOCK_LENGTH <= end) {
256
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
257
+ for (; offset + SHA1_BLOCK_LENGTH <= end; offset += SHA1_BLOCK_LENGTH) {
258
+ compress(view, offset);
259
+ }
260
+ }
261
+ while (offset < end) {
262
+ block[blockLength++] = data[offset++];
263
+ }
264
+ }
265
+
266
+ function digest() {
267
+ const bits = totalLength * 8;
268
+ const high = Math.floor(bits / 0x100000000);
269
+ const low = bits >>> 0;
270
+ update(SHA1_PADDING, 0, 1);
271
+ while (blockLength != SHA1_LENGTH_OFFSET) {
272
+ update(SHA1_ZERO, 0, 1);
273
+ }
274
+ lengthBytes[0] = high >>> 24;
275
+ lengthBytes[1] = high >>> 16;
276
+ lengthBytes[2] = high >>> 8;
277
+ lengthBytes[3] = high;
278
+ lengthBytes[4] = low >>> 24;
279
+ lengthBytes[5] = low >>> 16;
280
+ lengthBytes[6] = low >>> 8;
281
+ lengthBytes[7] = low;
282
+ update(lengthBytes, 0, 8);
283
+ const result = new Uint8Array(SHA1_DIGEST_LENGTH);
284
+ const resultView = new DataView(result.buffer);
285
+ for (let indexWord = 0; indexWord < state.length; indexWord++) {
286
+ resultView.setInt32(4 * indexWord, state[indexWord]);
287
+ }
288
+ state.set(SHA1_INITIAL_STATE);
289
+ blockLength = 0;
290
+ totalLength = 0;
291
+ return result;
292
+ }
293
+
294
+ function compress(view, offset) {
295
+ for (let index = 0; index < 16; index++) {
296
+ schedule[index] = view.getInt32(offset + 4 * index);
297
+ }
298
+ let a = state[0];
299
+ let b = state[1];
300
+ let c = state[2];
301
+ let d = state[3];
302
+ let e = state[4];
303
+ let t;
304
+ for (let index = 0; index < 15; index += 5) {
305
+ e = (((a << 5) | (a >>> 27)) + (((c ^ d) & b) ^ d) + e + 0x5A827999 + schedule[index]) | 0;
306
+ b = (b << 30) | (b >>> 2);
307
+ d = (((e << 5) | (e >>> 27)) + (((b ^ c) & a) ^ c) + d + 0x5A827999 + schedule[index + 1]) | 0;
308
+ a = (a << 30) | (a >>> 2);
309
+ c = (((d << 5) | (d >>> 27)) + (((a ^ b) & e) ^ b) + c + 0x5A827999 + schedule[index + 2]) | 0;
310
+ e = (e << 30) | (e >>> 2);
311
+ b = (((c << 5) | (c >>> 27)) + (((e ^ a) & d) ^ a) + b + 0x5A827999 + schedule[index + 3]) | 0;
312
+ d = (d << 30) | (d >>> 2);
313
+ a = (((b << 5) | (b >>> 27)) + (((d ^ e) & c) ^ e) + a + 0x5A827999 + schedule[index + 4]) | 0;
314
+ c = (c << 30) | (c >>> 2);
315
+ }
316
+ e = (((a << 5) | (a >>> 27)) + (((c ^ d) & b) ^ d) + e + 0x5A827999 + schedule[15]) | 0;
317
+ b = (b << 30) | (b >>> 2);
318
+ t = schedule[13] ^ schedule[8] ^ schedule[2] ^ schedule[0];
319
+ t = (t << 1) | (t >>> 31);
320
+ schedule[0] = t;
321
+ d = (((e << 5) | (e >>> 27)) + (((b ^ c) & a) ^ c) + d + 0x5A827999 + t) | 0;
322
+ a = (a << 30) | (a >>> 2);
323
+ t = schedule[14] ^ schedule[9] ^ schedule[3] ^ schedule[1];
324
+ t = (t << 1) | (t >>> 31);
325
+ schedule[1] = t;
326
+ c = (((d << 5) | (d >>> 27)) + (((a ^ b) & e) ^ b) + c + 0x5A827999 + t) | 0;
327
+ e = (e << 30) | (e >>> 2);
328
+ t = schedule[15] ^ schedule[10] ^ schedule[4] ^ schedule[2];
329
+ t = (t << 1) | (t >>> 31);
330
+ schedule[2] = t;
331
+ b = (((c << 5) | (c >>> 27)) + (((e ^ a) & d) ^ a) + b + 0x5A827999 + t) | 0;
332
+ d = (d << 30) | (d >>> 2);
333
+ t = schedule[0] ^ schedule[11] ^ schedule[5] ^ schedule[3];
334
+ t = (t << 1) | (t >>> 31);
335
+ schedule[3] = t;
336
+ a = (((b << 5) | (b >>> 27)) + (((d ^ e) & c) ^ e) + a + 0x5A827999 + t) | 0;
337
+ c = (c << 30) | (c >>> 2);
338
+ for (let index = 20; index < 40; index += 5) {
339
+ t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
340
+ t = (t << 1) | (t >>> 31);
341
+ schedule[(index) & 15] = t;
342
+ e = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0x6ED9EBA1 + t) | 0;
343
+ b = (b << 30) | (b >>> 2);
344
+ t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
345
+ t = (t << 1) | (t >>> 31);
346
+ schedule[(index + 1) & 15] = t;
347
+ d = (((e << 5) | (e >>> 27)) + (a ^ b ^ c) + d + 0x6ED9EBA1 + t) | 0;
348
+ a = (a << 30) | (a >>> 2);
349
+ t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
350
+ t = (t << 1) | (t >>> 31);
351
+ schedule[(index + 2) & 15] = t;
352
+ c = (((d << 5) | (d >>> 27)) + (e ^ a ^ b) + c + 0x6ED9EBA1 + t) | 0;
353
+ e = (e << 30) | (e >>> 2);
354
+ t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
355
+ t = (t << 1) | (t >>> 31);
356
+ schedule[(index + 3) & 15] = t;
357
+ b = (((c << 5) | (c >>> 27)) + (d ^ e ^ a) + b + 0x6ED9EBA1 + t) | 0;
358
+ d = (d << 30) | (d >>> 2);
359
+ t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
360
+ t = (t << 1) | (t >>> 31);
361
+ schedule[(index + 4) & 15] = t;
362
+ a = (((b << 5) | (b >>> 27)) + (c ^ d ^ e) + a + 0x6ED9EBA1 + t) | 0;
363
+ c = (c << 30) | (c >>> 2);
364
+ }
365
+ for (let index = 40; index < 60; index += 5) {
366
+ t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
367
+ t = (t << 1) | (t >>> 31);
368
+ schedule[(index) & 15] = t;
369
+ e = (((a << 5) | (a >>> 27)) + ((b & c) | ((b | c) & d)) + e + 0x8F1BBCDC + t) | 0;
370
+ b = (b << 30) | (b >>> 2);
371
+ t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
372
+ t = (t << 1) | (t >>> 31);
373
+ schedule[(index + 1) & 15] = t;
374
+ d = (((e << 5) | (e >>> 27)) + ((a & b) | ((a | b) & c)) + d + 0x8F1BBCDC + t) | 0;
375
+ a = (a << 30) | (a >>> 2);
376
+ t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
377
+ t = (t << 1) | (t >>> 31);
378
+ schedule[(index + 2) & 15] = t;
379
+ c = (((d << 5) | (d >>> 27)) + ((e & a) | ((e | a) & b)) + c + 0x8F1BBCDC + t) | 0;
380
+ e = (e << 30) | (e >>> 2);
381
+ t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
382
+ t = (t << 1) | (t >>> 31);
383
+ schedule[(index + 3) & 15] = t;
384
+ b = (((c << 5) | (c >>> 27)) + ((d & e) | ((d | e) & a)) + b + 0x8F1BBCDC + t) | 0;
385
+ d = (d << 30) | (d >>> 2);
386
+ t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
387
+ t = (t << 1) | (t >>> 31);
388
+ schedule[(index + 4) & 15] = t;
389
+ a = (((b << 5) | (b >>> 27)) + ((c & d) | ((c | d) & e)) + a + 0x8F1BBCDC + t) | 0;
390
+ c = (c << 30) | (c >>> 2);
391
+ }
392
+ for (let index = 60; index < 80; index += 5) {
393
+ t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
394
+ t = (t << 1) | (t >>> 31);
395
+ schedule[(index) & 15] = t;
396
+ e = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0xCA62C1D6 + t) | 0;
397
+ b = (b << 30) | (b >>> 2);
398
+ t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
399
+ t = (t << 1) | (t >>> 31);
400
+ schedule[(index + 1) & 15] = t;
401
+ d = (((e << 5) | (e >>> 27)) + (a ^ b ^ c) + d + 0xCA62C1D6 + t) | 0;
402
+ a = (a << 30) | (a >>> 2);
403
+ t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
404
+ t = (t << 1) | (t >>> 31);
405
+ schedule[(index + 2) & 15] = t;
406
+ c = (((d << 5) | (d >>> 27)) + (e ^ a ^ b) + c + 0xCA62C1D6 + t) | 0;
407
+ e = (e << 30) | (e >>> 2);
408
+ t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
409
+ t = (t << 1) | (t >>> 31);
410
+ schedule[(index + 3) & 15] = t;
411
+ b = (((c << 5) | (c >>> 27)) + (d ^ e ^ a) + b + 0xCA62C1D6 + t) | 0;
412
+ d = (d << 30) | (d >>> 2);
413
+ t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
414
+ t = (t << 1) | (t >>> 31);
415
+ schedule[(index + 4) & 15] = t;
416
+ a = (((b << 5) | (b >>> 27)) + (c ^ d ^ e) + a + 0xCA62C1D6 + t) | 0;
417
+ c = (c << 30) | (c >>> 2);
418
+ }
419
+ state[0] = (state[0] + a) | 0;
420
+ state[1] = (state[1] + b) | 0;
421
+ state[2] = (state[2] + c) | 0;
422
+ state[3] = (state[3] + d) | 0;
423
+ state[4] = (state[4] + e) | 0;
424
+ }
425
+ }
426
+
427
+ function initTables() {
428
+ if (!tablesInitialized) {
429
+ let p = 1;
430
+ let q = 1;
431
+ do {
432
+ p = (p ^ (p << 1) ^ ((p & 0x80) ? 0x1b : 0)) & 255;
433
+ q = (q ^ (q << 1)) & 255;
434
+ q = (q ^ (q << 2)) & 255;
435
+ q = (q ^ (q << 4)) & 255;
436
+ if (q & 0x80) {
437
+ q ^= 0x09;
438
+ }
439
+ S_BOX[p] = (q ^ ((q << 1) | (q >> 7)) ^ ((q << 2) | (q >> 6)) ^ ((q << 3) | (q >> 5)) ^ ((q << 4) | (q >> 4)) ^ 0x63) & 255;
440
+ } while (p != 1);
441
+ S_BOX[0] = 0x63;
442
+ for (let index = 0; index < 256; index++) {
443
+ const s = S_BOX[index];
444
+ const s2 = multiplyByTwo(s);
445
+ const t = (s2 << 24) | (s << 16) | (s << 8) | (s2 ^ s);
446
+ T0[index] = t;
447
+ T1[index] = (t >>> 8) | (t << 24);
448
+ T2[index] = (t >>> 16) | (t << 16);
449
+ T3[index] = (t >>> 24) | (t << 8);
450
+ }
451
+ tablesInitialized = true;
452
+ }
453
+ }
454
+
455
+ function expandKey(key, roundKeys) {
456
+ const keyWords = key.length >> 2;
457
+ const rounds = keyWords + 6;
458
+ const total = 4 * (rounds + 1);
459
+ let roundConstant = 1;
460
+ for (let index = 0; index < keyWords; index++) {
461
+ roundKeys[index] = (key[4 * index] << 24) | (key[4 * index + 1] << 16) | (key[4 * index + 2] << 8) | key[4 * index + 3];
462
+ }
463
+ for (let index = keyWords; index < total; index++) {
464
+ let word = roundKeys[index - 1];
465
+ if (index % keyWords == 0) {
466
+ word = substituteWord((word << 8) | (word >>> 24)) ^ (roundConstant << 24);
467
+ roundConstant = multiplyByTwo(roundConstant);
468
+ } else if (keyWords > 6 && index % keyWords == 4) {
469
+ word = substituteWord(word);
470
+ }
471
+ roundKeys[index] = roundKeys[index - keyWords] ^ word;
472
+ }
473
+ return rounds;
474
+ }
475
+
476
+ function substituteWord(word) {
477
+ return (S_BOX[word >>> 24] << 24) | (S_BOX[(word >>> 16) & 255] << 16) | (S_BOX[(word >>> 8) & 255] << 8) | S_BOX[word & 255];
478
+ }
479
+
480
+ function swapBytes(value) {
481
+ return (value << 24) | ((value & 0xff00) << 8) | ((value >>> 8) & 0xff00) | (value >>> 24);
482
+ }
483
+
484
+ function multiplyByTwo(value) {
485
+ return ((value << 1) ^ ((value >> 7) * 0x1b)) & 255;
486
+ }
@@ -0,0 +1,106 @@
1
+ /*
2
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in
12
+ the documentation and/or other materials provided with the distribution.
13
+
14
+ 3. The names of the authors may not be used to endorse or promote products
15
+ derived from this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
18
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
20
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
21
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ */
28
+
29
+ import { FUNCTION_TYPE } from "../../constants.js";
30
+ import { createEngine as createDefaultEngine } from "../codecs/aes-hmac-sha1.js";
31
+
32
+ const BUFFER_LENGTH = 64 * 1024;
33
+ const DIGEST_LENGTH = 20;
34
+
35
+ let wasm, buffer;
36
+
37
+ export {
38
+ setWasmExports,
39
+ resetWasmExports,
40
+ createEngine
41
+ };
42
+
43
+ function setWasmExports(wasmAPI) {
44
+ // deno-lint-ignore valid-typeof
45
+ if (typeof wasmAPI.aes_hmac_new == FUNCTION_TYPE) {
46
+ wasm = wasmAPI;
47
+ buffer = 0;
48
+ }
49
+ }
50
+
51
+ function resetWasmExports() {
52
+ wasm = null;
53
+ buffer = 0;
54
+ }
55
+
56
+ function createEngine(key, authenticationKey) {
57
+ const exports = wasm;
58
+ let context = exports ? createContext(exports, key, authenticationKey) : 0;
59
+ if (!context) {
60
+ return createDefaultEngine(key, authenticationKey);
61
+ }
62
+ const scratch = buffer;
63
+ return {
64
+ process(data, decrypt) {
65
+ for (let offset = 0; offset < data.length; offset += BUFFER_LENGTH) {
66
+ const chunk = data.subarray(offset, offset + BUFFER_LENGTH);
67
+ const heap = getHeap(exports);
68
+ heap.set(chunk, scratch);
69
+ exports.aes_hmac_process(context, scratch, chunk.length, decrypt ? 1 : 0);
70
+ chunk.set(heap.subarray(scratch, scratch + chunk.length));
71
+ }
72
+ },
73
+ digest() {
74
+ exports.aes_hmac_end(context, scratch);
75
+ context = 0;
76
+ return getHeap(exports).slice(scratch, scratch + DIGEST_LENGTH);
77
+ },
78
+ dispose() {
79
+ if (context) {
80
+ exports.aes_hmac_end(context, 0);
81
+ context = 0;
82
+ }
83
+ }
84
+ };
85
+ }
86
+
87
+ function createContext(exports, key, authenticationKey) {
88
+ if (!buffer) {
89
+ buffer = exports.malloc(BUFFER_LENGTH);
90
+ }
91
+ const context = buffer ? exports.aes_hmac_new() : 0;
92
+ if (context) {
93
+ const heap = getHeap(exports);
94
+ heap.set(key, buffer);
95
+ heap.set(authenticationKey, buffer + key.length);
96
+ if (exports.aes_hmac_init(context, buffer, key.length, buffer + key.length, authenticationKey.length)) {
97
+ exports.aes_hmac_end(context, 0);
98
+ return 0;
99
+ }
100
+ }
101
+ return context;
102
+ }
103
+
104
+ function getHeap(exports) {
105
+ return new Uint8Array(exports.memory.buffer);
106
+ }
@@ -29,6 +29,7 @@
29
29
  /* global WebAssembly, URL, fetch, atob */
30
30
 
31
31
  import { setWasmExports, setInitError, resetWasmExports } from "./zlib-streams.js";
32
+ import { setWasmExports as setEngineWasmExports, resetWasmExports as resetEngineWasmExports } from "./aes-hmac-sha1-wasm.js";
32
33
 
33
34
  let initializedModule = false;
34
35
 
@@ -63,11 +64,13 @@ async function instantiateModule(wasmURI, baseURI) {
63
64
  }
64
65
  const wasmInstance = await WebAssembly.instantiate(arrayBuffer);
65
66
  setWasmExports(wasmInstance.instance.exports);
67
+ setEngineWasmExports(wasmInstance.instance.exports);
66
68
  }
67
69
 
68
70
  function resetWasmModule() {
69
71
  initializedModule = false;
70
72
  resetWasmExports();
73
+ resetEngineWasmExports();
71
74
  }
72
75
 
73
76
  function arrayBufferFromDataURI(dataURI) {
@@ -85,6 +88,7 @@ export {
85
88
  CompressionStreamZlib,
86
89
  DecompressionStreamZlib
87
90
  } from "./zlib-streams.js";
91
+ export { createEngine as createAESEngine } from "./aes-hmac-sha1-wasm.js";
88
92
  export {
89
93
  initModule,
90
94
  resetWasmModule
@@ -72,7 +72,6 @@ function _make(isCompress, type, options = {}) {
72
72
  if (!this.out || !this.in) {
73
73
  throw new Error("allocation failed");
74
74
  }
75
- this._scratch = new Uint8Array(outBufferSize);
76
75
  if (isCompress) {
77
76
  this._process = wasm.deflate_process;
78
77
  this._last_consumed = wasm.deflate_last_consumed;
@@ -121,7 +120,6 @@ function _make(isCompress, type, options = {}) {
121
120
  const process = this._process;
122
121
  const last_consumed = this._last_consumed;
123
122
  const out = this.out;
124
- const scratch = this._scratch;
125
123
  let offset = 0;
126
124
  while (offset < buffer.length) {
127
125
  const toRead = Math.min(buffer.length - offset, 32 * 1024);
@@ -146,8 +144,7 @@ function _make(isCompress, type, options = {}) {
146
144
  }
147
145
  const prod = result & 0x00ffffff;
148
146
  if (prod) {
149
- scratch.set(heap.subarray(out, out + prod), 0);
150
- controller.enqueue(scratch.slice(0, prod));
147
+ controller.enqueue(heap.slice(out, out + prod));
151
148
  }
152
149
  const consumed = last_consumed(this.streamHandle);
153
150
  if (consumed === 0 && prod === 0) {
@@ -165,7 +162,6 @@ function _make(isCompress, type, options = {}) {
165
162
  const heap = new Uint8Array(memory.buffer);
166
163
  const process = this._process;
167
164
  const out = this.out;
168
- const scratch = this._scratch;
169
165
  while (true) {
170
166
  const result = process(this.streamHandle, 0, 0, out, outBufferSize, 4);
171
167
  const code = (result >> 24) & 0xff;
@@ -175,8 +171,7 @@ function _make(isCompress, type, options = {}) {
175
171
  }
176
172
  const produced = result & 0x00ffffff;
177
173
  if (produced) {
178
- scratch.set(heap.subarray(out, out + produced), 0);
179
- controller.enqueue(scratch.slice(0, produced));
174
+ controller.enqueue(heap.slice(out, out + produced));
180
175
  }
181
176
  if (code === 1 || produced === 0) {
182
177
  break;
@@ -26,6 +26,6 @@
26
26
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
27
  */
28
28
 
29
- const VERSION = "2.13.1";
29
+ const VERSION = "2.14.1";
30
30
 
31
31
  export { VERSION };