@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.
- package/BENCHMARKS.md +349 -416
- package/deno.json +1 -1
- package/dist/zip-core-external.js +761 -945
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +626 -911
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +768 -948
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +633 -914
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +768 -948
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +635 -916
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +771 -951
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +628 -913
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-module.wasm +0 -0
- package/dist/zip-native.js +628 -913
- package/dist/zip-native.min.js +1 -1
- package/dist/zip-web-worker-native.js +1 -1
- package/dist/zip-web-worker.js +1 -1
- package/dist/zip.js +764 -948
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +635 -916
- package/index-native.min.js +1 -1
- package/index.cjs +771 -951
- package/index.d.cts +52 -12
- package/index.d.ts +52 -12
- package/index.min.js +1 -1
- package/lib/core/codec-worker.js +37 -26
- package/lib/core/io.js +29 -21
- package/lib/core/streams/aes-crypto-stream.js +58 -99
- package/lib/core/streams/codecs/aes-hmac-sha1.js +486 -0
- package/lib/core/streams/zlib-wasm/aes-hmac-sha1-wasm.js +106 -0
- package/lib/core/streams/zlib-wasm/zlib-streams-loader.js +4 -0
- package/lib/core/streams/zlib-wasm/zlib-streams.js +2 -7
- package/lib/core/streams/zlib-wasm/zlib-streams.wasm +0 -0
- package/lib/core/version.js +1 -1
- package/lib/core/web-worker-base.js +15 -9
- package/lib/core/web-worker-inline-native.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/web-worker-wasm.js +2 -0
- package/lib/core/zip-fs.js +7 -3
- package/lib/core/zip-reader.js +53 -6
- package/lib/core/zip-writer.js +1 -2
- package/lib/core/zlib-streams-inline.js +1 -1
- package/lib/zip-module-wasm-base.js +3 -1
- package/package.json +1 -1
- package/lib/core/streams/codecs/sjcl.js +0 -795
|
@@ -600,7 +600,7 @@ for (let n = 0; n < 256; n++) {
|
|
|
600
600
|
T[k][n] = (previous >>> 8) ^ T[0][previous & 0xFF];
|
|
601
601
|
}
|
|
602
602
|
}
|
|
603
|
-
const [T0, T1, T2, T3, T4, T5, T6, T7] = T;
|
|
603
|
+
const [T0$1, T1$1, T2$1, T3$1, T4, T5, T6, T7] = T;
|
|
604
604
|
|
|
605
605
|
class Crc32 {
|
|
606
606
|
|
|
@@ -622,12 +622,12 @@ class Crc32 {
|
|
|
622
622
|
const a = crc ^ view.getInt32(offset, true);
|
|
623
623
|
const b = view.getInt32(offset + 4, true);
|
|
624
624
|
crc = T7[a & 0xFF] ^ T6[(a >>> 8) & 0xFF] ^ T5[(a >>> 16) & 0xFF] ^ T4[(a >>> 24) & 0xFF] ^
|
|
625
|
-
T3[b & 0xFF] ^ T2[(b >>> 8) & 0xFF] ^ T1[(b >>> 16) & 0xFF] ^ T0[(b >>> 24) & 0xFF];
|
|
625
|
+
T3$1[b & 0xFF] ^ T2$1[(b >>> 8) & 0xFF] ^ T1$1[(b >>> 16) & 0xFF] ^ T0$1[(b >>> 24) & 0xFF];
|
|
626
626
|
}
|
|
627
627
|
}
|
|
628
628
|
// Remaining tail (and non-typed inputs) byte-at-a-time with the base table.
|
|
629
629
|
for (; offset < length; offset++) {
|
|
630
|
-
crc = (crc >>> 8) ^ T0[(crc ^ data[offset]) & 0xFF];
|
|
630
|
+
crc = (crc >>> 8) ^ T0$1[(crc ^ data[offset]) & 0xFF];
|
|
631
631
|
}
|
|
632
632
|
this.crc = crc;
|
|
633
633
|
}
|
|
@@ -731,794 +731,487 @@ function encodeText(value) {
|
|
|
731
731
|
}
|
|
732
732
|
}
|
|
733
733
|
|
|
734
|
-
// Derived from https://github.com/xqdoo00o/jszip/blob/master/lib/sjcl.js and https://github.com/bitwiseshiftleft/sjcl
|
|
735
|
-
|
|
736
|
-
// deno-lint-ignore-file no-this-alias
|
|
737
|
-
|
|
738
734
|
/*
|
|
739
|
-
|
|
740
|
-
* license or under the GNU GPL, version 2.0.
|
|
741
|
-
*/
|
|
742
|
-
|
|
743
|
-
/** @fileOverview Javascript cryptography implementation.
|
|
744
|
-
*
|
|
745
|
-
* Crush to remove comments, shorten variable names and
|
|
746
|
-
* generally reduce transmission size.
|
|
747
|
-
*
|
|
748
|
-
* @author Emily Stark
|
|
749
|
-
* @author Mike Hamburg
|
|
750
|
-
* @author Dan Boneh
|
|
751
|
-
*/
|
|
752
|
-
|
|
753
|
-
/*jslint indent: 2, bitwise: false, nomen: false, plusplus: false, white: false, regexp: false */
|
|
754
|
-
|
|
755
|
-
/** @fileOverview Arrays of bits, encoded as arrays of Numbers.
|
|
756
|
-
*
|
|
757
|
-
* @author Emily Stark
|
|
758
|
-
* @author Mike Hamburg
|
|
759
|
-
* @author Dan Boneh
|
|
760
|
-
*/
|
|
761
|
-
|
|
762
|
-
/**
|
|
763
|
-
* Arrays of bits, encoded as arrays of Numbers.
|
|
764
|
-
* @namespace
|
|
765
|
-
* @description
|
|
766
|
-
* <p>
|
|
767
|
-
* These objects are the currency accepted by SJCL's crypto functions.
|
|
768
|
-
* </p>
|
|
769
|
-
*
|
|
770
|
-
* <p>
|
|
771
|
-
* Most of our crypto primitives operate on arrays of 4-byte words internally,
|
|
772
|
-
* but many of them can take arguments that are not a multiple of 4 bytes.
|
|
773
|
-
* This library encodes arrays of bits (whose size need not be a multiple of 8
|
|
774
|
-
* bits) as arrays of 32-bit words. The bits are packed, big-endian, into an
|
|
775
|
-
* array of words, 32 bits at a time. Since the words are double-precision
|
|
776
|
-
* floating point numbers, they fit some extra data. We use this (in a private,
|
|
777
|
-
* possibly-changing manner) to encode the number of bits actually present
|
|
778
|
-
* in the last word of the array.
|
|
779
|
-
* </p>
|
|
780
|
-
*
|
|
781
|
-
* <p>
|
|
782
|
-
* Because bitwise ops clear this out-of-band data, these arrays can be passed
|
|
783
|
-
* to ciphers like AES which want arrays of words.
|
|
784
|
-
* </p>
|
|
785
|
-
*/
|
|
786
|
-
const bitArray = {
|
|
787
|
-
/**
|
|
788
|
-
* Concatenate two bit arrays.
|
|
789
|
-
* @param {bitArray} a1 The first array.
|
|
790
|
-
* @param {bitArray} a2 The second array.
|
|
791
|
-
* @return {bitArray} The concatenation of a1 and a2.
|
|
792
|
-
*/
|
|
793
|
-
concat(a1, a2) {
|
|
794
|
-
if (a1.length === 0 || a2.length === 0) {
|
|
795
|
-
return a1.concat(a2);
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
const last = a1[a1.length - 1], shift = bitArray.getPartial(last);
|
|
799
|
-
if (shift === 32) {
|
|
800
|
-
return a1.concat(a2);
|
|
801
|
-
} else {
|
|
802
|
-
return bitArray._shiftRight(a2, shift, last | 0, a1.slice(0, a1.length - 1));
|
|
803
|
-
}
|
|
804
|
-
},
|
|
805
|
-
|
|
806
|
-
/**
|
|
807
|
-
* Find the length of an array of bits.
|
|
808
|
-
* @param {bitArray} a The array.
|
|
809
|
-
* @return {Number} The length of a, in bits.
|
|
810
|
-
*/
|
|
811
|
-
bitLength(a) {
|
|
812
|
-
const l = a.length;
|
|
813
|
-
if (l === 0) {
|
|
814
|
-
return 0;
|
|
815
|
-
}
|
|
816
|
-
const x = a[l - 1];
|
|
817
|
-
return (l - 1) * 32 + bitArray.getPartial(x);
|
|
818
|
-
},
|
|
819
|
-
|
|
820
|
-
/**
|
|
821
|
-
* Truncate an array.
|
|
822
|
-
* @param {bitArray} a The array.
|
|
823
|
-
* @param {Number} len The length to truncate to, in bits.
|
|
824
|
-
* @return {bitArray} A new array, truncated to len bits.
|
|
825
|
-
*/
|
|
826
|
-
clamp(a, len) {
|
|
827
|
-
if (a.length * 32 < len) {
|
|
828
|
-
return a;
|
|
829
|
-
}
|
|
830
|
-
a = a.slice(0, Math.ceil(len / 32));
|
|
831
|
-
const l = a.length;
|
|
832
|
-
len = len & 31;
|
|
833
|
-
if (l > 0 && len) {
|
|
834
|
-
a[l - 1] = bitArray.partial(len, a[l - 1] & 0x80000000 >> (len - 1), 1);
|
|
835
|
-
}
|
|
836
|
-
return a;
|
|
837
|
-
},
|
|
838
|
-
|
|
839
|
-
/**
|
|
840
|
-
* Make a partial word for a bit array.
|
|
841
|
-
* @param {Number} len The number of bits in the word.
|
|
842
|
-
* @param {Number} x The bits.
|
|
843
|
-
* @param {Number} [_end=0] Pass 1 if x has already been shifted to the high side.
|
|
844
|
-
* @return {Number} The partial word.
|
|
845
|
-
*/
|
|
846
|
-
partial(len, x, _end) {
|
|
847
|
-
if (len === 32) {
|
|
848
|
-
return x;
|
|
849
|
-
}
|
|
850
|
-
return (_end ? x | 0 : x << (32 - len)) + len * 0x10000000000;
|
|
851
|
-
},
|
|
735
|
+
Copyright (c) 2026 Gildas Lormeau. All rights reserved.
|
|
852
736
|
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
* @param {Number} x The partial word.
|
|
856
|
-
* @return {Number} The number of bits used by the partial word.
|
|
857
|
-
*/
|
|
858
|
-
getPartial(x) {
|
|
859
|
-
return Math.round(x / 0x10000000000) || 32;
|
|
860
|
-
},
|
|
737
|
+
Redistribution and use in source and binary forms, with or without
|
|
738
|
+
modification, are permitted provided that the following conditions are met:
|
|
861
739
|
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
* @param {Number} shift The number of bits to shift.
|
|
865
|
-
* @param {Number} [carry=0] A byte to carry in
|
|
866
|
-
* @param {bitArray} [out=[]] An array to prepend to the output.
|
|
867
|
-
* @private
|
|
868
|
-
*/
|
|
869
|
-
_shiftRight(a, shift, carry, out) {
|
|
870
|
-
if (out === undefined) {
|
|
871
|
-
out = [];
|
|
872
|
-
}
|
|
740
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
741
|
+
this list of conditions and the following disclaimer.
|
|
873
742
|
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
}
|
|
878
|
-
if (shift === 0) {
|
|
879
|
-
return out.concat(a);
|
|
880
|
-
}
|
|
743
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
744
|
+
notice, this list of conditions and the following disclaimer in
|
|
745
|
+
the documentation and/or other materials provided with the distribution.
|
|
881
746
|
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
carry = a[i] << (32 - shift);
|
|
885
|
-
}
|
|
886
|
-
const last2 = a.length ? a[a.length - 1] : 0;
|
|
887
|
-
const shift2 = bitArray.getPartial(last2);
|
|
888
|
-
out.push(bitArray.partial(shift + shift2 & 31, (shift + shift2 > 32) ? carry : out.pop(), 1));
|
|
889
|
-
return out;
|
|
890
|
-
}
|
|
891
|
-
};
|
|
747
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
748
|
+
derived from this software without specific prior written permission.
|
|
892
749
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
750
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
751
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
752
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
753
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
754
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
755
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
756
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
757
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
758
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
759
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
898
760
|
*/
|
|
899
761
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
const
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
762
|
+
const BLOCK_LENGTH$1 = 16;
|
|
763
|
+
const ROUND_KEYS_LENGTH = 60;
|
|
764
|
+
const SHA1_BLOCK_LENGTH = 64;
|
|
765
|
+
const SHA1_DIGEST_LENGTH = 20;
|
|
766
|
+
const SHA1_SCHEDULE_LENGTH = 16;
|
|
767
|
+
const SHA1_LENGTH_OFFSET = 56;
|
|
768
|
+
const SHA1_PADDING = new Uint8Array([0x80]);
|
|
769
|
+
const SHA1_ZERO = new Uint8Array(1);
|
|
770
|
+
const SHA1_INITIAL_STATE = new Int32Array([0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]);
|
|
771
|
+
const HMAC_INNER_PADDING = 0x36;
|
|
772
|
+
const HMAC_OUTER_PADDING = 0x5c;
|
|
773
|
+
const S_BOX = new Uint8Array(256);
|
|
774
|
+
const T0 = new Int32Array(256);
|
|
775
|
+
const T1 = new Int32Array(256);
|
|
776
|
+
const T2 = new Int32Array(256);
|
|
777
|
+
const T3 = new Int32Array(256);
|
|
778
|
+
|
|
779
|
+
let tablesInitialized = false;
|
|
780
|
+
|
|
781
|
+
function createEngine$2(key, authenticationKey) {
|
|
782
|
+
initTables();
|
|
783
|
+
const roundKeys = new Int32Array(ROUND_KEYS_LENGTH);
|
|
784
|
+
const rounds = expandKey(key, roundKeys);
|
|
785
|
+
const keystream = new Int32Array(BLOCK_LENGTH$1 / 4);
|
|
786
|
+
const hmac = createHmac(authenticationKey);
|
|
787
|
+
let counter0 = 0;
|
|
788
|
+
let counter1 = 0;
|
|
789
|
+
let counter2 = 0;
|
|
790
|
+
let counter3 = 0;
|
|
791
|
+
return {
|
|
792
|
+
process(data, decrypt) {
|
|
793
|
+
if (decrypt) {
|
|
794
|
+
hmac.update(data, 0, data.length);
|
|
932
795
|
}
|
|
933
|
-
|
|
934
|
-
|
|
796
|
+
encrypt(data);
|
|
797
|
+
if (!decrypt) {
|
|
798
|
+
hmac.update(data, 0, data.length);
|
|
935
799
|
}
|
|
936
|
-
|
|
800
|
+
},
|
|
801
|
+
digest() {
|
|
802
|
+
return hmac.digest();
|
|
937
803
|
}
|
|
938
|
-
}
|
|
939
|
-
};
|
|
940
|
-
|
|
941
|
-
const hash = {};
|
|
942
|
-
|
|
943
|
-
/**
|
|
944
|
-
* Context for a SHA-1 operation in progress.
|
|
945
|
-
* @constructor
|
|
946
|
-
*/
|
|
947
|
-
hash.sha1 = class {
|
|
948
|
-
constructor(hash) {
|
|
949
|
-
const sha1 = this;
|
|
950
|
-
/**
|
|
951
|
-
* The hash's block size, in bits.
|
|
952
|
-
* @constant
|
|
953
|
-
*/
|
|
954
|
-
sha1.blockSize = 512;
|
|
955
|
-
/**
|
|
956
|
-
* The SHA-1 initialization vector.
|
|
957
|
-
* @private
|
|
958
|
-
*/
|
|
959
|
-
sha1._init = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0];
|
|
960
|
-
/**
|
|
961
|
-
* The SHA-1 hash key.
|
|
962
|
-
* @private
|
|
963
|
-
*/
|
|
964
|
-
sha1._key = [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6];
|
|
965
|
-
if (hash) {
|
|
966
|
-
sha1._h = hash._h.slice(0);
|
|
967
|
-
sha1._buffer = hash._buffer.slice(0);
|
|
968
|
-
sha1._length = hash._length;
|
|
969
|
-
} else {
|
|
970
|
-
sha1.reset();
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
/**
|
|
975
|
-
* Reset the hash state.
|
|
976
|
-
* @return this
|
|
977
|
-
*/
|
|
978
|
-
reset() {
|
|
979
|
-
const sha1 = this;
|
|
980
|
-
sha1._h = sha1._init.slice(0);
|
|
981
|
-
sha1._buffer = [];
|
|
982
|
-
sha1._length = 0;
|
|
983
|
-
return sha1;
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
/**
|
|
987
|
-
* Input several words to the hash.
|
|
988
|
-
* @param {bitArray|String} data the data to hash.
|
|
989
|
-
* @return this
|
|
990
|
-
*/
|
|
991
|
-
update(data) {
|
|
992
|
-
const sha1 = this;
|
|
993
|
-
if (typeof data === "string") {
|
|
994
|
-
data = codec.utf8String.toBits(data);
|
|
995
|
-
}
|
|
996
|
-
const b = sha1._buffer = bitArray.concat(sha1._buffer, data);
|
|
997
|
-
const ol = sha1._length;
|
|
998
|
-
const nl = sha1._length = ol + bitArray.bitLength(data);
|
|
999
|
-
if (nl > 9007199254740991) {
|
|
1000
|
-
throw new Error("Cannot hash more than 2^53 - 1 bits");
|
|
1001
|
-
}
|
|
1002
|
-
const c = new Uint32Array(b);
|
|
1003
|
-
let j = 0;
|
|
1004
|
-
for (let i = sha1.blockSize + ol - ((sha1.blockSize + ol) & (sha1.blockSize - 1)); i <= nl;
|
|
1005
|
-
i += sha1.blockSize) {
|
|
1006
|
-
sha1._block(c.subarray(16 * j, 16 * (j + 1)));
|
|
1007
|
-
j += 1;
|
|
1008
|
-
}
|
|
1009
|
-
b.splice(0, 16 * j);
|
|
1010
|
-
return sha1;
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
/**
|
|
1014
|
-
* Complete hashing and output the hash value.
|
|
1015
|
-
* @return {bitArray} The hash value, an array of 5 big-endian words. TODO
|
|
1016
|
-
*/
|
|
1017
|
-
finalize() {
|
|
1018
|
-
const sha1 = this;
|
|
1019
|
-
let b = sha1._buffer;
|
|
1020
|
-
const h = sha1._h;
|
|
1021
|
-
|
|
1022
|
-
// Round out and push the buffer
|
|
1023
|
-
b = bitArray.concat(b, [bitArray.partial(1, 1)]);
|
|
1024
|
-
// Round out the buffer to a multiple of 16 words, less the 2 length words.
|
|
1025
|
-
for (let i = b.length + 2; i & 15; i++) {
|
|
1026
|
-
b.push(0);
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
// append the length
|
|
1030
|
-
b.push(Math.floor(sha1._length / 0x100000000));
|
|
1031
|
-
b.push(sha1._length | 0);
|
|
1032
|
-
|
|
1033
|
-
while (b.length) {
|
|
1034
|
-
sha1._block(b.splice(0, 16));
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
sha1.reset();
|
|
1038
|
-
return h;
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
/**
|
|
1042
|
-
* The SHA-1 logical functions f(0), f(1), ..., f(79).
|
|
1043
|
-
* @private
|
|
1044
|
-
*/
|
|
1045
|
-
_f(t, b, c, d) {
|
|
1046
|
-
if (t <= 19) {
|
|
1047
|
-
return (b & c) | (~b & d);
|
|
1048
|
-
} else if (t <= 39) {
|
|
1049
|
-
return b ^ c ^ d;
|
|
1050
|
-
} else if (t <= 59) {
|
|
1051
|
-
return (b & c) | (b & d) | (c & d);
|
|
1052
|
-
} else if (t <= 79) {
|
|
1053
|
-
return b ^ c ^ d;
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
|
|
1057
|
-
/**
|
|
1058
|
-
* Circular left-shift operator.
|
|
1059
|
-
* @private
|
|
1060
|
-
*/
|
|
1061
|
-
_S(n, x) {
|
|
1062
|
-
return (x << n) | (x >>> 32 - n);
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1065
|
-
/**
|
|
1066
|
-
* Perform one cycle of SHA-1.
|
|
1067
|
-
* @param {Uint32Array|bitArray} words one block of words.
|
|
1068
|
-
* @private
|
|
1069
|
-
*/
|
|
1070
|
-
_block(words) {
|
|
1071
|
-
const sha1 = this;
|
|
1072
|
-
const h = sha1._h;
|
|
1073
|
-
// When words is passed to _block, it has 16 elements. SHA1 _block
|
|
1074
|
-
// function extends words with new elements (at the end there are 80 elements).
|
|
1075
|
-
// The problem is that if we use Uint32Array instead of Array,
|
|
1076
|
-
// the length of Uint32Array cannot be changed. Thus, we replace words with a
|
|
1077
|
-
// normal Array here.
|
|
1078
|
-
const w = Array(80); // do not use Uint32Array here as the instantiation is slower
|
|
1079
|
-
for (let j = 0; j < 16; j++) {
|
|
1080
|
-
w[j] = words[j];
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
let a = h[0];
|
|
1084
|
-
let b = h[1];
|
|
1085
|
-
let c = h[2];
|
|
1086
|
-
let d = h[3];
|
|
1087
|
-
let e = h[4];
|
|
1088
|
-
|
|
1089
|
-
for (let t = 0; t <= 79; t++) {
|
|
1090
|
-
if (t >= 16) {
|
|
1091
|
-
w[t] = sha1._S(1, w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]);
|
|
1092
|
-
}
|
|
1093
|
-
const tmp = (sha1._S(5, a) + sha1._f(t, b, c, d) + e + w[t] +
|
|
1094
|
-
sha1._key[Math.floor(t / 20)]) | 0;
|
|
1095
|
-
e = d;
|
|
1096
|
-
d = c;
|
|
1097
|
-
c = sha1._S(30, b);
|
|
1098
|
-
b = a;
|
|
1099
|
-
a = tmp;
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
h[0] = (h[0] + a) | 0;
|
|
1103
|
-
h[1] = (h[1] + b) | 0;
|
|
1104
|
-
h[2] = (h[2] + c) | 0;
|
|
1105
|
-
h[3] = (h[3] + d) | 0;
|
|
1106
|
-
h[4] = (h[4] + e) | 0;
|
|
1107
|
-
}
|
|
1108
|
-
};
|
|
1109
|
-
|
|
1110
|
-
/** @fileOverview Low-level AES implementation.
|
|
1111
|
-
*
|
|
1112
|
-
* This file contains a low-level implementation of AES, optimized for
|
|
1113
|
-
* size and for efficiency on several browsers. It is based on
|
|
1114
|
-
* OpenSSL's aes_core.c, a public-domain implementation by Vincent
|
|
1115
|
-
* Rijmen, Antoon Bosselaers and Paulo Barreto.
|
|
1116
|
-
*
|
|
1117
|
-
* An older version of this implementation is available in the public
|
|
1118
|
-
* domain, but this one is (c) Emily Stark, Mike Hamburg, Dan Boneh,
|
|
1119
|
-
* Stanford University 2008-2010 and BSD-licensed for liability
|
|
1120
|
-
* reasons.
|
|
1121
|
-
*
|
|
1122
|
-
* @author Emily Stark
|
|
1123
|
-
* @author Mike Hamburg
|
|
1124
|
-
* @author Dan Boneh
|
|
1125
|
-
*/
|
|
1126
|
-
|
|
1127
|
-
const cipher = {};
|
|
1128
|
-
|
|
1129
|
-
/**
|
|
1130
|
-
* Schedule out an AES key for both encryption and decryption. This
|
|
1131
|
-
* is a low-level class. Use a cipher mode to do bulk encryption.
|
|
1132
|
-
*
|
|
1133
|
-
* @constructor
|
|
1134
|
-
* @param {Array} key The key as an array of 4, 6 or 8 words.
|
|
1135
|
-
*/
|
|
1136
|
-
cipher.aes = class {
|
|
1137
|
-
constructor(key) {
|
|
1138
|
-
/**
|
|
1139
|
-
* The expanded S-box and inverse S-box tables. These will be computed
|
|
1140
|
-
* on the client so that we don't have to send them down the wire.
|
|
1141
|
-
*
|
|
1142
|
-
* There are two tables, _tables[0] is for encryption and
|
|
1143
|
-
* _tables[1] is for decryption.
|
|
1144
|
-
*
|
|
1145
|
-
* The first 4 sub-tables are the expanded S-box with MixColumns. The
|
|
1146
|
-
* last (_tables[01][4]) is the S-box itself.
|
|
1147
|
-
*
|
|
1148
|
-
* @private
|
|
1149
|
-
*/
|
|
1150
|
-
const aes = this;
|
|
1151
|
-
aes._tables = [[[], [], [], [], []], [[], [], [], [], []]];
|
|
1152
|
-
|
|
1153
|
-
if (!aes._tables[0][0][0]) {
|
|
1154
|
-
aes._precompute();
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
const sbox = aes._tables[0][4];
|
|
1158
|
-
const decTable = aes._tables[1];
|
|
1159
|
-
const keyLen = key.length;
|
|
1160
|
-
|
|
1161
|
-
let i, encKey, decKey, rcon = 1;
|
|
1162
|
-
|
|
1163
|
-
if (keyLen !== 4 && keyLen !== 6 && keyLen !== 8) {
|
|
1164
|
-
throw new Error("invalid aes key size");
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
aes._key = [encKey = key.slice(0), decKey = []];
|
|
1168
|
-
|
|
1169
|
-
// schedule encryption keys
|
|
1170
|
-
for (i = keyLen; i < 4 * keyLen + 28; i++) {
|
|
1171
|
-
let tmp = encKey[i - 1];
|
|
1172
|
-
|
|
1173
|
-
// apply sbox
|
|
1174
|
-
if (i % keyLen === 0 || (keyLen === 8 && i % keyLen === 4)) {
|
|
1175
|
-
tmp = sbox[tmp >>> 24] << 24 ^ sbox[tmp >> 16 & 255] << 16 ^ sbox[tmp >> 8 & 255] << 8 ^ sbox[tmp & 255];
|
|
1176
|
-
|
|
1177
|
-
// shift rows and add rcon
|
|
1178
|
-
if (i % keyLen === 0) {
|
|
1179
|
-
tmp = tmp << 8 ^ tmp >>> 24 ^ rcon << 24;
|
|
1180
|
-
rcon = rcon << 1 ^ (rcon >> 7) * 283;
|
|
1181
|
-
}
|
|
1182
|
-
}
|
|
804
|
+
};
|
|
1183
805
|
|
|
1184
|
-
|
|
806
|
+
function encrypt(data) {
|
|
807
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
808
|
+
const length = data.length;
|
|
809
|
+
let offset = 0;
|
|
810
|
+
for (; offset + BLOCK_LENGTH$1 <= length; offset += BLOCK_LENGTH$1) {
|
|
811
|
+
nextKeystream();
|
|
812
|
+
view.setInt32(offset, view.getInt32(offset) ^ keystream[0]);
|
|
813
|
+
view.setInt32(offset + 4, view.getInt32(offset + 4) ^ keystream[1]);
|
|
814
|
+
view.setInt32(offset + 8, view.getInt32(offset + 8) ^ keystream[2]);
|
|
815
|
+
view.setInt32(offset + 12, view.getInt32(offset + 12) ^ keystream[3]);
|
|
1185
816
|
}
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
if (i <= 4 || j < 4) {
|
|
1191
|
-
decKey[j] = tmp;
|
|
1192
|
-
} else {
|
|
1193
|
-
decKey[j] = decTable[0][sbox[tmp >>> 24]] ^
|
|
1194
|
-
decTable[1][sbox[tmp >> 16 & 255]] ^
|
|
1195
|
-
decTable[2][sbox[tmp >> 8 & 255]] ^
|
|
1196
|
-
decTable[3][sbox[tmp & 255]];
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
// public
|
|
1201
|
-
/* Something like this might appear here eventually
|
|
1202
|
-
name: "AES",
|
|
1203
|
-
blockSize: 4,
|
|
1204
|
-
keySizes: [4,6,8],
|
|
1205
|
-
*/
|
|
1206
|
-
|
|
1207
|
-
/**
|
|
1208
|
-
* Encrypt an array of 4 big-endian words.
|
|
1209
|
-
* @param {Array} data The plaintext.
|
|
1210
|
-
* @return {Array} The ciphertext.
|
|
1211
|
-
*/
|
|
1212
|
-
encrypt(data) {
|
|
1213
|
-
return this._crypt(data, 0);
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
/**
|
|
1217
|
-
* Decrypt an array of 4 big-endian words.
|
|
1218
|
-
* @param {Array} data The ciphertext.
|
|
1219
|
-
* @return {Array} The plaintext.
|
|
1220
|
-
*/
|
|
1221
|
-
decrypt(data) {
|
|
1222
|
-
return this._crypt(data, 1);
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
|
-
/**
|
|
1226
|
-
* Expand the S-box tables.
|
|
1227
|
-
*
|
|
1228
|
-
* @private
|
|
1229
|
-
*/
|
|
1230
|
-
_precompute() {
|
|
1231
|
-
const encTable = this._tables[0];
|
|
1232
|
-
const decTable = this._tables[1];
|
|
1233
|
-
const sbox = encTable[4];
|
|
1234
|
-
const sboxInv = decTable[4];
|
|
1235
|
-
const d = [];
|
|
1236
|
-
const th = [];
|
|
1237
|
-
let xInv, x2, x4, x8;
|
|
1238
|
-
|
|
1239
|
-
// Compute double and third tables
|
|
1240
|
-
for (let i = 0; i < 256; i++) {
|
|
1241
|
-
th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i;
|
|
1242
|
-
}
|
|
1243
|
-
|
|
1244
|
-
for (let x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) {
|
|
1245
|
-
// Compute sbox
|
|
1246
|
-
let s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4;
|
|
1247
|
-
s = s >> 8 ^ s & 255 ^ 99;
|
|
1248
|
-
sbox[x] = s;
|
|
1249
|
-
sboxInv[s] = x;
|
|
1250
|
-
|
|
1251
|
-
// Compute MixColumns
|
|
1252
|
-
x8 = d[x4 = d[x2 = d[x]]];
|
|
1253
|
-
let tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
|
|
1254
|
-
let tEnc = d[s] * 0x101 ^ s * 0x1010100;
|
|
1255
|
-
|
|
1256
|
-
for (let i = 0; i < 4; i++) {
|
|
1257
|
-
encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8;
|
|
1258
|
-
decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8;
|
|
1259
|
-
}
|
|
1260
|
-
}
|
|
1261
|
-
|
|
1262
|
-
// Compactify. Considerable speedup on Firefox.
|
|
1263
|
-
for (let i = 0; i < 5; i++) {
|
|
1264
|
-
encTable[i] = encTable[i].slice(0);
|
|
1265
|
-
decTable[i] = decTable[i].slice(0);
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
/**
|
|
1270
|
-
* Encryption and decryption core.
|
|
1271
|
-
* @param {Array} input Four words to be encrypted or decrypted.
|
|
1272
|
-
* @param dir The direction, 0 for encrypt and 1 for decrypt.
|
|
1273
|
-
* @return {Array} The four encrypted or decrypted words.
|
|
1274
|
-
* @private
|
|
1275
|
-
*/
|
|
1276
|
-
_crypt(input, dir) {
|
|
1277
|
-
if (input.length !== 4) {
|
|
1278
|
-
throw new Error("invalid aes block size");
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
|
-
const key = this._key[dir];
|
|
1282
|
-
|
|
1283
|
-
const nInnerRounds = key.length / 4 - 2;
|
|
1284
|
-
const out = [0, 0, 0, 0];
|
|
1285
|
-
const table = this._tables[dir];
|
|
1286
|
-
|
|
1287
|
-
// load up the tables
|
|
1288
|
-
const t0 = table[0];
|
|
1289
|
-
const t1 = table[1];
|
|
1290
|
-
const t2 = table[2];
|
|
1291
|
-
const t3 = table[3];
|
|
1292
|
-
const sbox = table[4];
|
|
1293
|
-
|
|
1294
|
-
// state variables a,b,c,d are loaded with pre-whitened data
|
|
1295
|
-
let a = input[0] ^ key[0];
|
|
1296
|
-
let b = input[dir ? 3 : 1] ^ key[1];
|
|
1297
|
-
let c = input[2] ^ key[2];
|
|
1298
|
-
let d = input[dir ? 1 : 3] ^ key[3];
|
|
1299
|
-
let kIndex = 4;
|
|
1300
|
-
let a2, b2, c2;
|
|
1301
|
-
|
|
1302
|
-
// Inner rounds. Cribbed from OpenSSL.
|
|
1303
|
-
for (let i = 0; i < nInnerRounds; i++) {
|
|
1304
|
-
a2 = t0[a >>> 24] ^ t1[b >> 16 & 255] ^ t2[c >> 8 & 255] ^ t3[d & 255] ^ key[kIndex];
|
|
1305
|
-
b2 = t0[b >>> 24] ^ t1[c >> 16 & 255] ^ t2[d >> 8 & 255] ^ t3[a & 255] ^ key[kIndex + 1];
|
|
1306
|
-
c2 = t0[c >>> 24] ^ t1[d >> 16 & 255] ^ t2[a >> 8 & 255] ^ t3[b & 255] ^ key[kIndex + 2];
|
|
1307
|
-
d = t0[d >>> 24] ^ t1[a >> 16 & 255] ^ t2[b >> 8 & 255] ^ t3[c & 255] ^ key[kIndex + 3];
|
|
1308
|
-
kIndex += 4;
|
|
1309
|
-
a = a2; b = b2; c = c2;
|
|
1310
|
-
}
|
|
1311
|
-
|
|
1312
|
-
// Last round.
|
|
1313
|
-
for (let i = 0; i < 4; i++) {
|
|
1314
|
-
out[dir ? 3 & -i : i] =
|
|
1315
|
-
sbox[a >>> 24] << 24 ^
|
|
1316
|
-
sbox[b >> 16 & 255] << 16 ^
|
|
1317
|
-
sbox[c >> 8 & 255] << 8 ^
|
|
1318
|
-
sbox[d & 255] ^
|
|
1319
|
-
key[kIndex++];
|
|
1320
|
-
a2 = a; a = b; b = c; c = d; d = a2;
|
|
1321
|
-
}
|
|
1322
|
-
|
|
1323
|
-
return out;
|
|
1324
|
-
}
|
|
1325
|
-
};
|
|
1326
|
-
|
|
1327
|
-
/** @fileOverview CTR mode implementation.
|
|
1328
|
-
*
|
|
1329
|
-
* Special thanks to Roy Nicholson for pointing out a bug in our
|
|
1330
|
-
* implementation.
|
|
1331
|
-
*
|
|
1332
|
-
* @author Emily Stark
|
|
1333
|
-
* @author Mike Hamburg
|
|
1334
|
-
* @author Dan Boneh
|
|
1335
|
-
*/
|
|
1336
|
-
|
|
1337
|
-
/** Brian Gladman's CTR Mode.
|
|
1338
|
-
* @constructor
|
|
1339
|
-
* @param {Object} _prf The aes instance to generate key.
|
|
1340
|
-
* @param {bitArray} _iv The iv for ctr mode, it must be 128 bits.
|
|
1341
|
-
*/
|
|
1342
|
-
|
|
1343
|
-
const mode = {};
|
|
1344
|
-
|
|
1345
|
-
/**
|
|
1346
|
-
* Brian Gladman's CTR Mode.
|
|
1347
|
-
* @namespace
|
|
1348
|
-
*/
|
|
1349
|
-
mode.ctrGladman = class {
|
|
1350
|
-
constructor(prf, iv) {
|
|
1351
|
-
this._prf = prf;
|
|
1352
|
-
this._initIv = iv;
|
|
1353
|
-
this._iv = iv;
|
|
1354
|
-
}
|
|
1355
|
-
|
|
1356
|
-
reset() {
|
|
1357
|
-
this._iv = this._initIv;
|
|
1358
|
-
}
|
|
1359
|
-
|
|
1360
|
-
/** Input some data to calculate.
|
|
1361
|
-
* @param {bitArray} data the data to process, it must be intergral multiple of 128 bits unless it's the last.
|
|
1362
|
-
*/
|
|
1363
|
-
update(data) {
|
|
1364
|
-
return this.calculate(this._prf, data, this._iv);
|
|
1365
|
-
}
|
|
1366
|
-
|
|
1367
|
-
incWord(word) {
|
|
1368
|
-
if (((word >> 24) & 0xff) === 0xff) { //overflow
|
|
1369
|
-
let b1 = (word >> 16) & 0xff;
|
|
1370
|
-
let b2 = (word >> 8) & 0xff;
|
|
1371
|
-
let b3 = word & 0xff;
|
|
1372
|
-
|
|
1373
|
-
if (b1 === 0xff) { // overflow b1
|
|
1374
|
-
b1 = 0;
|
|
1375
|
-
if (b2 === 0xff) {
|
|
1376
|
-
b2 = 0;
|
|
1377
|
-
if (b3 === 0xff) {
|
|
1378
|
-
b3 = 0;
|
|
1379
|
-
} else {
|
|
1380
|
-
++b3;
|
|
1381
|
-
}
|
|
1382
|
-
} else {
|
|
1383
|
-
++b2;
|
|
1384
|
-
}
|
|
1385
|
-
} else {
|
|
1386
|
-
++b1;
|
|
817
|
+
if (offset < length) {
|
|
818
|
+
nextKeystream();
|
|
819
|
+
for (let indexByte = 0; offset < length; offset++, indexByte++) {
|
|
820
|
+
data[offset] ^= keystream[indexByte >> 2] >>> (24 - 8 * (indexByte & 3));
|
|
1387
821
|
}
|
|
1388
|
-
|
|
1389
|
-
word = 0;
|
|
1390
|
-
word += (b1 << 16);
|
|
1391
|
-
word += (b2 << 8);
|
|
1392
|
-
word += b3;
|
|
1393
|
-
} else {
|
|
1394
|
-
word += (0x01 << 24);
|
|
1395
822
|
}
|
|
1396
|
-
return word;
|
|
1397
823
|
}
|
|
1398
824
|
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
let l;
|
|
1408
|
-
if (!(l = data.length)) {
|
|
1409
|
-
return [];
|
|
1410
|
-
}
|
|
1411
|
-
const bl = bitArray.bitLength(data);
|
|
1412
|
-
for (let i = 0; i < l; i += 4) {
|
|
1413
|
-
this.incCounter(iv);
|
|
1414
|
-
const e = prf.encrypt(iv);
|
|
1415
|
-
data[i] ^= e[0];
|
|
1416
|
-
data[i + 1] ^= e[1];
|
|
1417
|
-
data[i + 2] ^= e[2];
|
|
1418
|
-
data[i + 3] ^= e[3];
|
|
1419
|
-
}
|
|
1420
|
-
return bitArray.clamp(data, bl);
|
|
1421
|
-
}
|
|
1422
|
-
};
|
|
1423
|
-
|
|
1424
|
-
const misc = {
|
|
1425
|
-
importKey(password) {
|
|
1426
|
-
return new misc.hmacSha1(codec.bytes.toBits(password));
|
|
1427
|
-
},
|
|
1428
|
-
pbkdf2(prf, salt, count, length) {
|
|
1429
|
-
count = count || 10000;
|
|
1430
|
-
if (length < 0 || count < 0) {
|
|
1431
|
-
throw new Error("invalid params to pbkdf2");
|
|
1432
|
-
}
|
|
1433
|
-
const byteLength = ((length >> 5) + 1) << 2;
|
|
1434
|
-
let u, ui, i, j, k;
|
|
1435
|
-
const arrayBuffer = new ArrayBuffer(byteLength);
|
|
1436
|
-
const out = new DataView(arrayBuffer);
|
|
1437
|
-
let outLength = 0;
|
|
1438
|
-
const b = bitArray;
|
|
1439
|
-
salt = codec.bytes.toBits(salt);
|
|
1440
|
-
for (k = 1; outLength < (byteLength || 1); k++) {
|
|
1441
|
-
u = ui = prf.encrypt(b.concat(salt, [k]));
|
|
1442
|
-
for (i = 1; i < count; i++) {
|
|
1443
|
-
ui = prf.encrypt(ui);
|
|
1444
|
-
for (j = 0; j < ui.length; j++) {
|
|
1445
|
-
u[j] ^= ui[j];
|
|
825
|
+
function nextKeystream() {
|
|
826
|
+
counter0 = (counter0 + 1) | 0;
|
|
827
|
+
if (!counter0) {
|
|
828
|
+
counter1 = (counter1 + 1) | 0;
|
|
829
|
+
if (!counter1) {
|
|
830
|
+
counter2 = (counter2 + 1) | 0;
|
|
831
|
+
if (!counter2) {
|
|
832
|
+
counter3 = (counter3 + 1) | 0;
|
|
1446
833
|
}
|
|
1447
834
|
}
|
|
1448
|
-
for (i = 0; outLength < (byteLength || 1) && i < u.length; i++) {
|
|
1449
|
-
out.setInt32(outLength, u[i]);
|
|
1450
|
-
outLength += 4;
|
|
1451
|
-
}
|
|
1452
835
|
}
|
|
1453
|
-
|
|
836
|
+
let s0 = swapBytes(counter0) ^ roundKeys[0];
|
|
837
|
+
let s1 = swapBytes(counter1) ^ roundKeys[1];
|
|
838
|
+
let s2 = swapBytes(counter2) ^ roundKeys[2];
|
|
839
|
+
let s3 = swapBytes(counter3) ^ roundKeys[3];
|
|
840
|
+
let t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[4];
|
|
841
|
+
let t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[5];
|
|
842
|
+
let t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[6];
|
|
843
|
+
let t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[7];
|
|
844
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[8];
|
|
845
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[9];
|
|
846
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[10];
|
|
847
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[11];
|
|
848
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[12];
|
|
849
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[13];
|
|
850
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[14];
|
|
851
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[15];
|
|
852
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[16];
|
|
853
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[17];
|
|
854
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[18];
|
|
855
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[19];
|
|
856
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[20];
|
|
857
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[21];
|
|
858
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[22];
|
|
859
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[23];
|
|
860
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[24];
|
|
861
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[25];
|
|
862
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[26];
|
|
863
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[27];
|
|
864
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[28];
|
|
865
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[29];
|
|
866
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[30];
|
|
867
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[31];
|
|
868
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[32];
|
|
869
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[33];
|
|
870
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[34];
|
|
871
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[35];
|
|
872
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[36];
|
|
873
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[37];
|
|
874
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[38];
|
|
875
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[39];
|
|
876
|
+
let indexKey = 40;
|
|
877
|
+
if (rounds > 10) {
|
|
878
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[40];
|
|
879
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[41];
|
|
880
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[42];
|
|
881
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[43];
|
|
882
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[44];
|
|
883
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[45];
|
|
884
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[46];
|
|
885
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[47];
|
|
886
|
+
indexKey = 48;
|
|
887
|
+
}
|
|
888
|
+
if (rounds > 12) {
|
|
889
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[48];
|
|
890
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[49];
|
|
891
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[50];
|
|
892
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[51];
|
|
893
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[52];
|
|
894
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[53];
|
|
895
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[54];
|
|
896
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[55];
|
|
897
|
+
indexKey = 56;
|
|
898
|
+
}
|
|
899
|
+
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];
|
|
900
|
+
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];
|
|
901
|
+
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];
|
|
902
|
+
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];
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
function pbkdf2(password, salt, iterations, length) {
|
|
907
|
+
const hmac = createHmac(password);
|
|
908
|
+
const result = new Uint8Array(length);
|
|
909
|
+
const block = new Uint8Array(salt.length + 4);
|
|
910
|
+
const blockView = new DataView(block.buffer);
|
|
911
|
+
block.set(salt);
|
|
912
|
+
for (let indexBlock = 1, offset = 0; offset < length; indexBlock++, offset += SHA1_DIGEST_LENGTH) {
|
|
913
|
+
blockView.setUint32(salt.length, indexBlock);
|
|
914
|
+
hmac.update(block, 0, block.length);
|
|
915
|
+
let previous = hmac.digest();
|
|
916
|
+
const output = previous.slice();
|
|
917
|
+
for (let iteration = 1; iteration < iterations; iteration++) {
|
|
918
|
+
hmac.update(previous, 0, SHA1_DIGEST_LENGTH);
|
|
919
|
+
previous = hmac.digest();
|
|
920
|
+
for (let indexByte = 0; indexByte < SHA1_DIGEST_LENGTH; indexByte++) {
|
|
921
|
+
output[indexByte] ^= previous[indexByte];
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
result.set(output.subarray(0, Math.min(SHA1_DIGEST_LENGTH, length - offset)), offset);
|
|
1454
925
|
}
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
/** @fileOverview HMAC implementation.
|
|
1458
|
-
*
|
|
1459
|
-
* @author Emily Stark
|
|
1460
|
-
* @author Mike Hamburg
|
|
1461
|
-
* @author Dan Boneh
|
|
1462
|
-
*/
|
|
1463
|
-
|
|
1464
|
-
/** HMAC with the specified hash function.
|
|
1465
|
-
* @constructor
|
|
1466
|
-
* @param {bitArray} key the key for HMAC.
|
|
1467
|
-
* @param {Object} [Hash=hash.sha1] The hash function to use.
|
|
1468
|
-
*/
|
|
1469
|
-
misc.hmacSha1 = class {
|
|
1470
|
-
|
|
1471
|
-
constructor(key) {
|
|
1472
|
-
const hmac = this;
|
|
1473
|
-
const Hash = hmac._hash = hash.sha1;
|
|
1474
|
-
const exKey = [[], []];
|
|
1475
|
-
hmac._baseHash = [new Hash(), new Hash()];
|
|
1476
|
-
const bs = hmac._baseHash[0].blockSize / 32;
|
|
1477
|
-
|
|
1478
|
-
if (key.length > bs) {
|
|
1479
|
-
key = new Hash().update(key).finalize();
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1482
|
-
for (let i = 0; i < bs; i++) {
|
|
1483
|
-
exKey[0][i] = key[i] ^ 0x36363636;
|
|
1484
|
-
exKey[1][i] = key[i] ^ 0x5C5C5C5C;
|
|
1485
|
-
}
|
|
926
|
+
return result;
|
|
927
|
+
}
|
|
1486
928
|
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
hmac._updated = false;
|
|
929
|
+
function createHmac(key) {
|
|
930
|
+
const sha1 = createSha1();
|
|
931
|
+
const innerKey = new Uint8Array(SHA1_BLOCK_LENGTH);
|
|
932
|
+
const outerKey = new Uint8Array(SHA1_BLOCK_LENGTH);
|
|
933
|
+
if (key.length > SHA1_BLOCK_LENGTH) {
|
|
934
|
+
sha1.update(key, 0, key.length);
|
|
935
|
+
key = sha1.digest();
|
|
1495
936
|
}
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
hmac._resultHash.update(data);
|
|
937
|
+
for (let indexByte = 0; indexByte < SHA1_BLOCK_LENGTH; indexByte++) {
|
|
938
|
+
const keyByte = indexByte < key.length ? key[indexByte] : 0;
|
|
939
|
+
innerKey[indexByte] = keyByte ^ HMAC_INNER_PADDING;
|
|
940
|
+
outerKey[indexByte] = keyByte ^ HMAC_OUTER_PADDING;
|
|
1501
941
|
}
|
|
942
|
+
sha1.update(innerKey, 0, SHA1_BLOCK_LENGTH);
|
|
943
|
+
return {
|
|
944
|
+
update(data, offset, length) {
|
|
945
|
+
sha1.update(data, offset, length);
|
|
946
|
+
},
|
|
947
|
+
digest() {
|
|
948
|
+
const innerDigest = sha1.digest();
|
|
949
|
+
sha1.update(outerKey, 0, SHA1_BLOCK_LENGTH);
|
|
950
|
+
sha1.update(innerDigest, 0, SHA1_DIGEST_LENGTH);
|
|
951
|
+
const result = sha1.digest();
|
|
952
|
+
sha1.update(innerKey, 0, SHA1_BLOCK_LENGTH);
|
|
953
|
+
return result;
|
|
954
|
+
}
|
|
955
|
+
};
|
|
956
|
+
}
|
|
1502
957
|
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
958
|
+
function createSha1() {
|
|
959
|
+
const state = new Int32Array(SHA1_INITIAL_STATE);
|
|
960
|
+
const schedule = new Int32Array(SHA1_SCHEDULE_LENGTH);
|
|
961
|
+
const block = new Uint8Array(SHA1_BLOCK_LENGTH);
|
|
962
|
+
const blockView = new DataView(block.buffer);
|
|
963
|
+
const lengthBytes = new Uint8Array(8);
|
|
964
|
+
let blockLength = 0;
|
|
965
|
+
let totalLength = 0;
|
|
966
|
+
return {
|
|
967
|
+
update,
|
|
968
|
+
digest
|
|
969
|
+
};
|
|
1509
970
|
|
|
971
|
+
function update(data, offset, length) {
|
|
972
|
+
const end = offset + length;
|
|
973
|
+
totalLength += length;
|
|
974
|
+
if (blockLength) {
|
|
975
|
+
while (offset < end && blockLength < SHA1_BLOCK_LENGTH) {
|
|
976
|
+
block[blockLength++] = data[offset++];
|
|
977
|
+
}
|
|
978
|
+
if (blockLength == SHA1_BLOCK_LENGTH) {
|
|
979
|
+
compress(blockView, 0);
|
|
980
|
+
blockLength = 0;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
if (offset + SHA1_BLOCK_LENGTH <= end) {
|
|
984
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
985
|
+
for (; offset + SHA1_BLOCK_LENGTH <= end; offset += SHA1_BLOCK_LENGTH) {
|
|
986
|
+
compress(view, offset);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
while (offset < end) {
|
|
990
|
+
block[blockLength++] = data[offset++];
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
function digest() {
|
|
995
|
+
const bits = totalLength * 8;
|
|
996
|
+
const high = Math.floor(bits / 0x100000000);
|
|
997
|
+
const low = bits >>> 0;
|
|
998
|
+
update(SHA1_PADDING, 0, 1);
|
|
999
|
+
while (blockLength != SHA1_LENGTH_OFFSET) {
|
|
1000
|
+
update(SHA1_ZERO, 0, 1);
|
|
1001
|
+
}
|
|
1002
|
+
lengthBytes[0] = high >>> 24;
|
|
1003
|
+
lengthBytes[1] = high >>> 16;
|
|
1004
|
+
lengthBytes[2] = high >>> 8;
|
|
1005
|
+
lengthBytes[3] = high;
|
|
1006
|
+
lengthBytes[4] = low >>> 24;
|
|
1007
|
+
lengthBytes[5] = low >>> 16;
|
|
1008
|
+
lengthBytes[6] = low >>> 8;
|
|
1009
|
+
lengthBytes[7] = low;
|
|
1010
|
+
update(lengthBytes, 0, 8);
|
|
1011
|
+
const result = new Uint8Array(SHA1_DIGEST_LENGTH);
|
|
1012
|
+
const resultView = new DataView(result.buffer);
|
|
1013
|
+
for (let indexWord = 0; indexWord < state.length; indexWord++) {
|
|
1014
|
+
resultView.setInt32(4 * indexWord, state[indexWord]);
|
|
1015
|
+
}
|
|
1016
|
+
state.set(SHA1_INITIAL_STATE);
|
|
1017
|
+
blockLength = 0;
|
|
1018
|
+
totalLength = 0;
|
|
1510
1019
|
return result;
|
|
1511
1020
|
}
|
|
1512
1021
|
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1022
|
+
function compress(view, offset) {
|
|
1023
|
+
for (let index = 0; index < 16; index++) {
|
|
1024
|
+
schedule[index] = view.getInt32(offset + 4 * index);
|
|
1025
|
+
}
|
|
1026
|
+
let a = state[0];
|
|
1027
|
+
let b = state[1];
|
|
1028
|
+
let c = state[2];
|
|
1029
|
+
let d = state[3];
|
|
1030
|
+
let e = state[4];
|
|
1031
|
+
let t;
|
|
1032
|
+
for (let index = 0; index < 15; index += 5) {
|
|
1033
|
+
e = (((a << 5) | (a >>> 27)) + (((c ^ d) & b) ^ d) + e + 0x5A827999 + schedule[index]) | 0;
|
|
1034
|
+
b = (b << 30) | (b >>> 2);
|
|
1035
|
+
d = (((e << 5) | (e >>> 27)) + (((b ^ c) & a) ^ c) + d + 0x5A827999 + schedule[index + 1]) | 0;
|
|
1036
|
+
a = (a << 30) | (a >>> 2);
|
|
1037
|
+
c = (((d << 5) | (d >>> 27)) + (((a ^ b) & e) ^ b) + c + 0x5A827999 + schedule[index + 2]) | 0;
|
|
1038
|
+
e = (e << 30) | (e >>> 2);
|
|
1039
|
+
b = (((c << 5) | (c >>> 27)) + (((e ^ a) & d) ^ a) + b + 0x5A827999 + schedule[index + 3]) | 0;
|
|
1040
|
+
d = (d << 30) | (d >>> 2);
|
|
1041
|
+
a = (((b << 5) | (b >>> 27)) + (((d ^ e) & c) ^ e) + a + 0x5A827999 + schedule[index + 4]) | 0;
|
|
1042
|
+
c = (c << 30) | (c >>> 2);
|
|
1043
|
+
}
|
|
1044
|
+
e = (((a << 5) | (a >>> 27)) + (((c ^ d) & b) ^ d) + e + 0x5A827999 + schedule[15]) | 0;
|
|
1045
|
+
b = (b << 30) | (b >>> 2);
|
|
1046
|
+
t = schedule[13] ^ schedule[8] ^ schedule[2] ^ schedule[0];
|
|
1047
|
+
t = (t << 1) | (t >>> 31);
|
|
1048
|
+
schedule[0] = t;
|
|
1049
|
+
d = (((e << 5) | (e >>> 27)) + (((b ^ c) & a) ^ c) + d + 0x5A827999 + t) | 0;
|
|
1050
|
+
a = (a << 30) | (a >>> 2);
|
|
1051
|
+
t = schedule[14] ^ schedule[9] ^ schedule[3] ^ schedule[1];
|
|
1052
|
+
t = (t << 1) | (t >>> 31);
|
|
1053
|
+
schedule[1] = t;
|
|
1054
|
+
c = (((d << 5) | (d >>> 27)) + (((a ^ b) & e) ^ b) + c + 0x5A827999 + t) | 0;
|
|
1055
|
+
e = (e << 30) | (e >>> 2);
|
|
1056
|
+
t = schedule[15] ^ schedule[10] ^ schedule[4] ^ schedule[2];
|
|
1057
|
+
t = (t << 1) | (t >>> 31);
|
|
1058
|
+
schedule[2] = t;
|
|
1059
|
+
b = (((c << 5) | (c >>> 27)) + (((e ^ a) & d) ^ a) + b + 0x5A827999 + t) | 0;
|
|
1060
|
+
d = (d << 30) | (d >>> 2);
|
|
1061
|
+
t = schedule[0] ^ schedule[11] ^ schedule[5] ^ schedule[3];
|
|
1062
|
+
t = (t << 1) | (t >>> 31);
|
|
1063
|
+
schedule[3] = t;
|
|
1064
|
+
a = (((b << 5) | (b >>> 27)) + (((d ^ e) & c) ^ e) + a + 0x5A827999 + t) | 0;
|
|
1065
|
+
c = (c << 30) | (c >>> 2);
|
|
1066
|
+
for (let index = 20; index < 40; index += 5) {
|
|
1067
|
+
t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
|
|
1068
|
+
t = (t << 1) | (t >>> 31);
|
|
1069
|
+
schedule[(index) & 15] = t;
|
|
1070
|
+
e = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0x6ED9EBA1 + t) | 0;
|
|
1071
|
+
b = (b << 30) | (b >>> 2);
|
|
1072
|
+
t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
|
|
1073
|
+
t = (t << 1) | (t >>> 31);
|
|
1074
|
+
schedule[(index + 1) & 15] = t;
|
|
1075
|
+
d = (((e << 5) | (e >>> 27)) + (a ^ b ^ c) + d + 0x6ED9EBA1 + t) | 0;
|
|
1076
|
+
a = (a << 30) | (a >>> 2);
|
|
1077
|
+
t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
|
|
1078
|
+
t = (t << 1) | (t >>> 31);
|
|
1079
|
+
schedule[(index + 2) & 15] = t;
|
|
1080
|
+
c = (((d << 5) | (d >>> 27)) + (e ^ a ^ b) + c + 0x6ED9EBA1 + t) | 0;
|
|
1081
|
+
e = (e << 30) | (e >>> 2);
|
|
1082
|
+
t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
|
|
1083
|
+
t = (t << 1) | (t >>> 31);
|
|
1084
|
+
schedule[(index + 3) & 15] = t;
|
|
1085
|
+
b = (((c << 5) | (c >>> 27)) + (d ^ e ^ a) + b + 0x6ED9EBA1 + t) | 0;
|
|
1086
|
+
d = (d << 30) | (d >>> 2);
|
|
1087
|
+
t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
|
|
1088
|
+
t = (t << 1) | (t >>> 31);
|
|
1089
|
+
schedule[(index + 4) & 15] = t;
|
|
1090
|
+
a = (((b << 5) | (b >>> 27)) + (c ^ d ^ e) + a + 0x6ED9EBA1 + t) | 0;
|
|
1091
|
+
c = (c << 30) | (c >>> 2);
|
|
1092
|
+
}
|
|
1093
|
+
for (let index = 40; index < 60; index += 5) {
|
|
1094
|
+
t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
|
|
1095
|
+
t = (t << 1) | (t >>> 31);
|
|
1096
|
+
schedule[(index) & 15] = t;
|
|
1097
|
+
e = (((a << 5) | (a >>> 27)) + ((b & c) | ((b | c) & d)) + e + 0x8F1BBCDC + t) | 0;
|
|
1098
|
+
b = (b << 30) | (b >>> 2);
|
|
1099
|
+
t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
|
|
1100
|
+
t = (t << 1) | (t >>> 31);
|
|
1101
|
+
schedule[(index + 1) & 15] = t;
|
|
1102
|
+
d = (((e << 5) | (e >>> 27)) + ((a & b) | ((a | b) & c)) + d + 0x8F1BBCDC + t) | 0;
|
|
1103
|
+
a = (a << 30) | (a >>> 2);
|
|
1104
|
+
t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
|
|
1105
|
+
t = (t << 1) | (t >>> 31);
|
|
1106
|
+
schedule[(index + 2) & 15] = t;
|
|
1107
|
+
c = (((d << 5) | (d >>> 27)) + ((e & a) | ((e | a) & b)) + c + 0x8F1BBCDC + t) | 0;
|
|
1108
|
+
e = (e << 30) | (e >>> 2);
|
|
1109
|
+
t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
|
|
1110
|
+
t = (t << 1) | (t >>> 31);
|
|
1111
|
+
schedule[(index + 3) & 15] = t;
|
|
1112
|
+
b = (((c << 5) | (c >>> 27)) + ((d & e) | ((d | e) & a)) + b + 0x8F1BBCDC + t) | 0;
|
|
1113
|
+
d = (d << 30) | (d >>> 2);
|
|
1114
|
+
t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
|
|
1115
|
+
t = (t << 1) | (t >>> 31);
|
|
1116
|
+
schedule[(index + 4) & 15] = t;
|
|
1117
|
+
a = (((b << 5) | (b >>> 27)) + ((c & d) | ((c | d) & e)) + a + 0x8F1BBCDC + t) | 0;
|
|
1118
|
+
c = (c << 30) | (c >>> 2);
|
|
1119
|
+
}
|
|
1120
|
+
for (let index = 60; index < 80; index += 5) {
|
|
1121
|
+
t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
|
|
1122
|
+
t = (t << 1) | (t >>> 31);
|
|
1123
|
+
schedule[(index) & 15] = t;
|
|
1124
|
+
e = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0xCA62C1D6 + t) | 0;
|
|
1125
|
+
b = (b << 30) | (b >>> 2);
|
|
1126
|
+
t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
|
|
1127
|
+
t = (t << 1) | (t >>> 31);
|
|
1128
|
+
schedule[(index + 1) & 15] = t;
|
|
1129
|
+
d = (((e << 5) | (e >>> 27)) + (a ^ b ^ c) + d + 0xCA62C1D6 + t) | 0;
|
|
1130
|
+
a = (a << 30) | (a >>> 2);
|
|
1131
|
+
t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
|
|
1132
|
+
t = (t << 1) | (t >>> 31);
|
|
1133
|
+
schedule[(index + 2) & 15] = t;
|
|
1134
|
+
c = (((d << 5) | (d >>> 27)) + (e ^ a ^ b) + c + 0xCA62C1D6 + t) | 0;
|
|
1135
|
+
e = (e << 30) | (e >>> 2);
|
|
1136
|
+
t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
|
|
1137
|
+
t = (t << 1) | (t >>> 31);
|
|
1138
|
+
schedule[(index + 3) & 15] = t;
|
|
1139
|
+
b = (((c << 5) | (c >>> 27)) + (d ^ e ^ a) + b + 0xCA62C1D6 + t) | 0;
|
|
1140
|
+
d = (d << 30) | (d >>> 2);
|
|
1141
|
+
t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
|
|
1142
|
+
t = (t << 1) | (t >>> 31);
|
|
1143
|
+
schedule[(index + 4) & 15] = t;
|
|
1144
|
+
a = (((b << 5) | (b >>> 27)) + (c ^ d ^ e) + a + 0xCA62C1D6 + t) | 0;
|
|
1145
|
+
c = (c << 30) | (c >>> 2);
|
|
1146
|
+
}
|
|
1147
|
+
state[0] = (state[0] + a) | 0;
|
|
1148
|
+
state[1] = (state[1] + b) | 0;
|
|
1149
|
+
state[2] = (state[2] + c) | 0;
|
|
1150
|
+
state[3] = (state[3] + d) | 0;
|
|
1151
|
+
state[4] = (state[4] + e) | 0;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
function initTables() {
|
|
1156
|
+
if (!tablesInitialized) {
|
|
1157
|
+
let p = 1;
|
|
1158
|
+
let q = 1;
|
|
1159
|
+
do {
|
|
1160
|
+
p = (p ^ (p << 1) ^ ((p & 0x80) ? 0x1b : 0)) & 255;
|
|
1161
|
+
q = (q ^ (q << 1)) & 255;
|
|
1162
|
+
q = (q ^ (q << 2)) & 255;
|
|
1163
|
+
q = (q ^ (q << 4)) & 255;
|
|
1164
|
+
if (q & 0x80) {
|
|
1165
|
+
q ^= 0x09;
|
|
1166
|
+
}
|
|
1167
|
+
S_BOX[p] = (q ^ ((q << 1) | (q >> 7)) ^ ((q << 2) | (q >> 6)) ^ ((q << 3) | (q >> 5)) ^ ((q << 4) | (q >> 4)) ^ 0x63) & 255;
|
|
1168
|
+
} while (p != 1);
|
|
1169
|
+
S_BOX[0] = 0x63;
|
|
1170
|
+
for (let index = 0; index < 256; index++) {
|
|
1171
|
+
const s = S_BOX[index];
|
|
1172
|
+
const s2 = multiplyByTwo(s);
|
|
1173
|
+
const t = (s2 << 24) | (s << 16) | (s << 8) | (s2 ^ s);
|
|
1174
|
+
T0[index] = t;
|
|
1175
|
+
T1[index] = (t >>> 8) | (t << 24);
|
|
1176
|
+
T2[index] = (t >>> 16) | (t << 16);
|
|
1177
|
+
T3[index] = (t >>> 24) | (t << 8);
|
|
1178
|
+
}
|
|
1179
|
+
tablesInitialized = true;
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
function expandKey(key, roundKeys) {
|
|
1184
|
+
const keyWords = key.length >> 2;
|
|
1185
|
+
const rounds = keyWords + 6;
|
|
1186
|
+
const total = 4 * (rounds + 1);
|
|
1187
|
+
let roundConstant = 1;
|
|
1188
|
+
for (let index = 0; index < keyWords; index++) {
|
|
1189
|
+
roundKeys[index] = (key[4 * index] << 24) | (key[4 * index + 1] << 16) | (key[4 * index + 2] << 8) | key[4 * index + 3];
|
|
1190
|
+
}
|
|
1191
|
+
for (let index = keyWords; index < total; index++) {
|
|
1192
|
+
let word = roundKeys[index - 1];
|
|
1193
|
+
if (index % keyWords == 0) {
|
|
1194
|
+
word = substituteWord((word << 8) | (word >>> 24)) ^ (roundConstant << 24);
|
|
1195
|
+
roundConstant = multiplyByTwo(roundConstant);
|
|
1196
|
+
} else if (keyWords > 6 && index % keyWords == 4) {
|
|
1197
|
+
word = substituteWord(word);
|
|
1198
|
+
}
|
|
1199
|
+
roundKeys[index] = roundKeys[index - keyWords] ^ word;
|
|
1200
|
+
}
|
|
1201
|
+
return rounds;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
function substituteWord(word) {
|
|
1205
|
+
return (S_BOX[word >>> 24] << 24) | (S_BOX[(word >>> 16) & 255] << 16) | (S_BOX[(word >>> 8) & 255] << 8) | S_BOX[word & 255];
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
function swapBytes(value) {
|
|
1209
|
+
return (value << 24) | ((value & 0xff00) << 8) | ((value >>> 8) & 0xff00) | (value >>> 24);
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
function multiplyByTwo(value) {
|
|
1213
|
+
return ((value << 1) ^ ((value >> 7) * 0x1b)) & 255;
|
|
1214
|
+
}
|
|
1522
1215
|
|
|
1523
1216
|
/*
|
|
1524
1217
|
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
@@ -1573,8 +1266,8 @@ function getRandomValues(array) {
|
|
|
1573
1266
|
1. Redistributions of source code must retain the above copyright notice,
|
|
1574
1267
|
this list of conditions and the following disclaimer.
|
|
1575
1268
|
|
|
1576
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
1577
|
-
notice, this list of conditions and the following disclaimer in
|
|
1269
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
1270
|
+
notice, this list of conditions and the following disclaimer in
|
|
1578
1271
|
the documentation and/or other materials provided with the distribution.
|
|
1579
1272
|
|
|
1580
1273
|
3. The names of the authors may not be used to endorse or promote products
|
|
@@ -1598,24 +1291,21 @@ const RAW_FORMAT = "raw";
|
|
|
1598
1291
|
const PBKDF2_ALGORITHM = { name: "PBKDF2" };
|
|
1599
1292
|
const HASH_ALGORITHM = { name: "HMAC" };
|
|
1600
1293
|
const HASH_FUNCTION = "SHA-1";
|
|
1294
|
+
const PBKDF2_ITERATIONS = 1000;
|
|
1601
1295
|
const BASE_KEY_ALGORITHM = Object.assign({ hash: HASH_ALGORITHM }, PBKDF2_ALGORITHM);
|
|
1602
|
-
const DERIVED_BITS_ALGORITHM = Object.assign({ iterations:
|
|
1296
|
+
const DERIVED_BITS_ALGORITHM = Object.assign({ iterations: PBKDF2_ITERATIONS, hash: { name: HASH_FUNCTION } }, PBKDF2_ALGORITHM);
|
|
1603
1297
|
const DERIVED_BITS_USAGE = ["deriveBits"];
|
|
1604
1298
|
const SALT_LENGTH = [8, 12, 16];
|
|
1605
1299
|
const KEY_LENGTH = [16, 24, 32];
|
|
1606
1300
|
const AUTHENTICATION_CODE_LENGTH = 10;
|
|
1607
|
-
const
|
|
1301
|
+
const PASSWORD_VERIFICATION_LENGTH = 2;
|
|
1608
1302
|
// deno-lint-ignore valid-typeof
|
|
1609
1303
|
const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE;
|
|
1610
1304
|
const subtle = CRYPTO_API_SUPPORTED && crypto.subtle;
|
|
1611
1305
|
const SUBTLE_API_SUPPORTED = CRYPTO_API_SUPPORTED && typeof subtle != UNDEFINED_TYPE;
|
|
1612
|
-
const codecBytes = codec.bytes;
|
|
1613
|
-
const Aes = cipher.aes;
|
|
1614
|
-
const CtrGladman = mode.ctrGladman;
|
|
1615
|
-
const HmacSha1 = misc.hmacSha1;
|
|
1616
1306
|
|
|
1617
|
-
let
|
|
1618
|
-
let
|
|
1307
|
+
let DERIVE_BITS_SUPPORTED = SUBTLE_API_SUPPORTED && typeof subtle.importKey == FUNCTION_TYPE && typeof subtle.deriveBits == FUNCTION_TYPE;
|
|
1308
|
+
let createEngine$1 = createEngine$2;
|
|
1619
1309
|
|
|
1620
1310
|
class AESDecryptionStream extends TransformStream {
|
|
1621
1311
|
|
|
@@ -1633,9 +1323,10 @@ class AESDecryptionStream extends TransformStream {
|
|
|
1633
1323
|
ready
|
|
1634
1324
|
} = aesCrypto;
|
|
1635
1325
|
if (password) {
|
|
1636
|
-
await createDecryptionKeys(aesCrypto, strength, password, subarray(chunk, 0, SALT_LENGTH[strength] +
|
|
1637
|
-
chunk = subarray(chunk, SALT_LENGTH[strength] +
|
|
1326
|
+
await createDecryptionKeys(aesCrypto, strength, password, subarray(chunk, 0, SALT_LENGTH[strength] + PASSWORD_VERIFICATION_LENGTH));
|
|
1327
|
+
chunk = subarray(chunk, SALT_LENGTH[strength] + PASSWORD_VERIFICATION_LENGTH);
|
|
1638
1328
|
if (checkPasswordOnly) {
|
|
1329
|
+
disposeEngine(aesCrypto);
|
|
1639
1330
|
controller.error(new Error(ERR_ABORT_CHECK_PASSWORD));
|
|
1640
1331
|
} else {
|
|
1641
1332
|
resolveReady();
|
|
@@ -1648,23 +1339,16 @@ class AESDecryptionStream extends TransformStream {
|
|
|
1648
1339
|
},
|
|
1649
1340
|
async flush(controller) {
|
|
1650
1341
|
const {
|
|
1651
|
-
|
|
1652
|
-
hmac,
|
|
1342
|
+
engine,
|
|
1653
1343
|
pendingInput,
|
|
1654
1344
|
ready
|
|
1655
1345
|
} = this;
|
|
1656
|
-
if (
|
|
1346
|
+
if (engine) {
|
|
1657
1347
|
await ready;
|
|
1658
|
-
const chunkToDecrypt = subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
|
|
1659
1348
|
const originalAuthenticationCode = subarray(pendingInput, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
hmac.update(encryptedChunk);
|
|
1664
|
-
const decryptedChunk = ctr.update(encryptedChunk);
|
|
1665
|
-
decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
|
|
1666
|
-
}
|
|
1667
|
-
const authenticationCode = subarray(fromBits(codecBytes, hmac.digest()), 0, AUTHENTICATION_CODE_LENGTH);
|
|
1349
|
+
const decryptedChunkArray = new Uint8Array(subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH));
|
|
1350
|
+
engine.process(decryptedChunkArray, true);
|
|
1351
|
+
const authenticationCode = engine.digest();
|
|
1668
1352
|
let invalidAuthenticationCode = pendingInput.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
|
|
1669
1353
|
for (let indexByte = 0; indexByte < AUTHENTICATION_CODE_LENGTH; indexByte++) {
|
|
1670
1354
|
invalidAuthenticationCode |= authenticationCode[indexByte] ^ originalAuthenticationCode[indexByte];
|
|
@@ -1674,6 +1358,9 @@ class AESDecryptionStream extends TransformStream {
|
|
|
1674
1358
|
}
|
|
1675
1359
|
controller.enqueue(decryptedChunkArray);
|
|
1676
1360
|
}
|
|
1361
|
+
},
|
|
1362
|
+
cancel() {
|
|
1363
|
+
disposeEngine(this);
|
|
1677
1364
|
}
|
|
1678
1365
|
});
|
|
1679
1366
|
}
|
|
@@ -1703,31 +1390,33 @@ class AESEncryptionStream extends TransformStream {
|
|
|
1703
1390
|
}
|
|
1704
1391
|
const output = new Uint8Array(preamble.length + chunk.length - (chunk.length % BLOCK_LENGTH));
|
|
1705
1392
|
output.set(preamble, 0);
|
|
1706
|
-
controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0));
|
|
1393
|
+
controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0, false));
|
|
1707
1394
|
},
|
|
1708
1395
|
async flush(controller) {
|
|
1709
1396
|
const {
|
|
1710
|
-
|
|
1711
|
-
hmac,
|
|
1397
|
+
engine,
|
|
1712
1398
|
pendingInput,
|
|
1713
1399
|
ready
|
|
1714
1400
|
} = this;
|
|
1715
|
-
if (
|
|
1401
|
+
if (engine) {
|
|
1716
1402
|
await ready;
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
hmac.update(encryptedChunk);
|
|
1721
|
-
encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
|
|
1722
|
-
}
|
|
1723
|
-
const authenticationCode = fromBits(codecBytes, hmac.digest()).slice(0, AUTHENTICATION_CODE_LENGTH);
|
|
1403
|
+
const encryptedChunkArray = new Uint8Array(pendingInput);
|
|
1404
|
+
engine.process(encryptedChunkArray, false);
|
|
1405
|
+
const authenticationCode = subarray(engine.digest(), 0, AUTHENTICATION_CODE_LENGTH);
|
|
1724
1406
|
controller.enqueue(concat(encryptedChunkArray, authenticationCode));
|
|
1725
1407
|
}
|
|
1408
|
+
},
|
|
1409
|
+
cancel() {
|
|
1410
|
+
disposeEngine(this);
|
|
1726
1411
|
}
|
|
1727
1412
|
});
|
|
1728
1413
|
}
|
|
1729
1414
|
}
|
|
1730
1415
|
|
|
1416
|
+
function setAESEngine(createEngineFunction) {
|
|
1417
|
+
createEngine$1 = createEngineFunction || createEngine$2;
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1731
1420
|
function initAesCrypto(aesCrypto, password, rawPassword, encryptionStrength) {
|
|
1732
1421
|
Object.assign(aesCrypto, {
|
|
1733
1422
|
ready: new Promise(resolve => aesCrypto.resolveReady = resolve),
|
|
@@ -1737,30 +1426,23 @@ function initAesCrypto(aesCrypto, password, rawPassword, encryptionStrength) {
|
|
|
1737
1426
|
});
|
|
1738
1427
|
}
|
|
1739
1428
|
|
|
1740
|
-
function append(aesCrypto, input, output, paddingStart, paddingEnd,
|
|
1429
|
+
function append(aesCrypto, input, output, paddingStart, paddingEnd, decrypt) {
|
|
1741
1430
|
const {
|
|
1742
|
-
|
|
1743
|
-
hmac,
|
|
1431
|
+
engine,
|
|
1744
1432
|
pendingInput
|
|
1745
1433
|
} = aesCrypto;
|
|
1746
1434
|
if (pendingInput.length) {
|
|
1747
1435
|
input = concat(pendingInput, input);
|
|
1748
1436
|
}
|
|
1749
1437
|
const inputLength = input.length - paddingEnd;
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
const
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
if (!verifyAuthenticationCode) {
|
|
1759
|
-
hmac.update(outputChunk);
|
|
1760
|
-
}
|
|
1761
|
-
output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
|
|
1762
|
-
}
|
|
1763
|
-
aesCrypto.pendingInput = subarray(input, offset);
|
|
1438
|
+
const alignedLength = inputLength - (inputLength % BLOCK_LENGTH);
|
|
1439
|
+
output = expand(output, paddingStart + alignedLength);
|
|
1440
|
+
if (alignedLength) {
|
|
1441
|
+
const chunk = subarray(output, paddingStart, paddingStart + alignedLength);
|
|
1442
|
+
chunk.set(subarray(input, 0, alignedLength));
|
|
1443
|
+
engine.process(chunk, decrypt);
|
|
1444
|
+
}
|
|
1445
|
+
aesCrypto.pendingInput = subarray(input, alignedLength);
|
|
1764
1446
|
return output;
|
|
1765
1447
|
}
|
|
1766
1448
|
|
|
@@ -1768,10 +1450,17 @@ async function createDecryptionKeys(decrypt, strength, password, preamble) {
|
|
|
1768
1450
|
const passwordVerificationKey = await createKeys$1(decrypt, strength, password, subarray(preamble, 0, SALT_LENGTH[strength]));
|
|
1769
1451
|
const passwordVerification = subarray(preamble, SALT_LENGTH[strength]);
|
|
1770
1452
|
if (passwordVerificationKey[0] != passwordVerification[0] || passwordVerificationKey[1] != passwordVerification[1]) {
|
|
1453
|
+
disposeEngine(decrypt);
|
|
1771
1454
|
throw new Error(ERR_INVALID_PASSWORD);
|
|
1772
1455
|
}
|
|
1773
1456
|
}
|
|
1774
1457
|
|
|
1458
|
+
function disposeEngine({ engine }) {
|
|
1459
|
+
if (engine && engine.dispose) {
|
|
1460
|
+
engine.dispose();
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1775
1464
|
async function createEncryptionKeys(encrypt, strength, password) {
|
|
1776
1465
|
const salt = getRandomValues(new Uint8Array(SALT_LENGTH[strength]));
|
|
1777
1466
|
const passwordVerification = await createKeys$1(encrypt, strength, password, salt);
|
|
@@ -1780,48 +1469,22 @@ async function createEncryptionKeys(encrypt, strength, password) {
|
|
|
1780
1469
|
|
|
1781
1470
|
async function createKeys$1(aesCrypto, strength, password, salt) {
|
|
1782
1471
|
aesCrypto.password = null;
|
|
1783
|
-
const
|
|
1784
|
-
const
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
const authentication = toBits(codecBytes, subarray(compositeKey, KEY_LENGTH[strength], KEY_LENGTH[strength] * 2));
|
|
1788
|
-
const passwordVerification = subarray(compositeKey, KEY_LENGTH[strength] * 2);
|
|
1789
|
-
Object.assign(aesCrypto, {
|
|
1790
|
-
keys: {
|
|
1791
|
-
key,
|
|
1792
|
-
authentication,
|
|
1793
|
-
passwordVerification
|
|
1794
|
-
},
|
|
1795
|
-
ctr: new CtrGladman(new Aes(key), Array.from(COUNTER_DEFAULT_VALUE)),
|
|
1796
|
-
hmac: new HmacSha1(authentication)
|
|
1797
|
-
});
|
|
1798
|
-
return passwordVerification;
|
|
1472
|
+
const keyLength = KEY_LENGTH[strength];
|
|
1473
|
+
const compositeKey = await deriveKey(password, salt, keyLength * 2 + PASSWORD_VERIFICATION_LENGTH);
|
|
1474
|
+
aesCrypto.engine = createEngine$1(subarray(compositeKey, 0, keyLength), subarray(compositeKey, keyLength, keyLength * 2));
|
|
1475
|
+
return subarray(compositeKey, keyLength * 2);
|
|
1799
1476
|
}
|
|
1800
1477
|
|
|
1801
|
-
async function
|
|
1802
|
-
if (IMPORT_KEY_SUPPORTED) {
|
|
1803
|
-
try {
|
|
1804
|
-
return await subtle.importKey(format, password, algorithm, extractable, keyUsages);
|
|
1805
|
-
} catch {
|
|
1806
|
-
IMPORT_KEY_SUPPORTED = false;
|
|
1807
|
-
return misc.importKey(password);
|
|
1808
|
-
}
|
|
1809
|
-
} else {
|
|
1810
|
-
return misc.importKey(password);
|
|
1811
|
-
}
|
|
1812
|
-
}
|
|
1813
|
-
|
|
1814
|
-
async function deriveBits(algorithm, baseKey, length) {
|
|
1478
|
+
async function deriveKey(password, salt, length) {
|
|
1815
1479
|
if (DERIVE_BITS_SUPPORTED) {
|
|
1816
1480
|
try {
|
|
1817
|
-
|
|
1481
|
+
const baseKey = await subtle.importKey(RAW_FORMAT, password, BASE_KEY_ALGORITHM, false, DERIVED_BITS_USAGE);
|
|
1482
|
+
return new Uint8Array(await subtle.deriveBits(Object.assign({ salt }, DERIVED_BITS_ALGORITHM), baseKey, length * 8));
|
|
1818
1483
|
} catch {
|
|
1819
1484
|
DERIVE_BITS_SUPPORTED = false;
|
|
1820
|
-
return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
|
|
1821
1485
|
}
|
|
1822
|
-
} else {
|
|
1823
|
-
return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
|
|
1824
1486
|
}
|
|
1487
|
+
return pbkdf2(password, salt, PBKDF2_ITERATIONS, length);
|
|
1825
1488
|
}
|
|
1826
1489
|
|
|
1827
1490
|
function encodePassword(password, rawPassword) {
|
|
@@ -1845,13 +1508,6 @@ function subarray(array, begin, end) {
|
|
|
1845
1508
|
return array.subarray(begin, end);
|
|
1846
1509
|
}
|
|
1847
1510
|
|
|
1848
|
-
function fromBits(codecBytes, chunk) {
|
|
1849
|
-
return codecBytes.fromBits(chunk);
|
|
1850
|
-
}
|
|
1851
|
-
function toBits(codecBytes, chunk) {
|
|
1852
|
-
return codecBytes.toBits(chunk);
|
|
1853
|
-
}
|
|
1854
|
-
|
|
1855
1511
|
/*
|
|
1856
1512
|
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
1857
1513
|
|
|
@@ -2795,11 +2451,18 @@ async function supportsDeflate(config) {
|
|
|
2795
2451
|
return true;
|
|
2796
2452
|
}
|
|
2797
2453
|
if (FallbackStream) {
|
|
2454
|
+
return await loadModule(config);
|
|
2455
|
+
}
|
|
2456
|
+
return false;
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2459
|
+
async function loadModule(config) {
|
|
2460
|
+
if (initModule$1) {
|
|
2798
2461
|
try {
|
|
2799
2462
|
await initModule$1(config);
|
|
2800
2463
|
return true;
|
|
2801
2464
|
} catch {
|
|
2802
|
-
|
|
2465
|
+
// ignored
|
|
2803
2466
|
}
|
|
2804
2467
|
}
|
|
2805
2468
|
return false;
|
|
@@ -2842,27 +2505,29 @@ class CodecWorker {
|
|
|
2842
2505
|
terminate() {
|
|
2843
2506
|
return new Promise(resolve => {
|
|
2844
2507
|
const { worker, busy } = workerData;
|
|
2845
|
-
if (
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2508
|
+
if (busy) {
|
|
2509
|
+
workerData.terminateResolvers = workerData.terminateResolvers || [];
|
|
2510
|
+
workerData.terminateResolvers.push(resolve);
|
|
2511
|
+
} else {
|
|
2512
|
+
if (worker) {
|
|
2849
2513
|
worker.terminate();
|
|
2850
|
-
|
|
2514
|
+
workerData.worker = null;
|
|
2851
2515
|
}
|
|
2852
|
-
workerData.interface = null;
|
|
2853
|
-
} else {
|
|
2854
2516
|
resolve();
|
|
2855
2517
|
}
|
|
2518
|
+
workerData.interface = null;
|
|
2856
2519
|
});
|
|
2857
2520
|
},
|
|
2858
2521
|
onTaskFinished() {
|
|
2859
2522
|
if (workerData.busy) {
|
|
2860
|
-
const {
|
|
2861
|
-
if (
|
|
2862
|
-
workerData.
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2523
|
+
const { terminateResolvers, worker } = workerData;
|
|
2524
|
+
if (terminateResolvers) {
|
|
2525
|
+
workerData.terminateResolvers = null;
|
|
2526
|
+
if (worker) {
|
|
2527
|
+
workerData.terminated = true;
|
|
2528
|
+
worker.terminate();
|
|
2529
|
+
}
|
|
2530
|
+
terminateResolvers.forEach(resolve => resolve());
|
|
2866
2531
|
}
|
|
2867
2532
|
workerData.busy = false;
|
|
2868
2533
|
onTaskFinished(workerData);
|
|
@@ -2918,28 +2583,23 @@ function createWorkerInterface(workerData, config) {
|
|
|
2918
2583
|
}
|
|
2919
2584
|
|
|
2920
2585
|
async function runWorker$1({ options, readable, writable, onTaskFinished, workerOptions }, config) {
|
|
2921
|
-
let codecStream, chunkStream;
|
|
2586
|
+
let codecStream, chunkStream, modulePromise;
|
|
2922
2587
|
try {
|
|
2923
2588
|
if (options.compressed && !options.format) {
|
|
2924
2589
|
const deflate = options.codecType.startsWith(CODEC_DEFLATE);
|
|
2925
2590
|
const FallbackStream = deflate ? config.CompressionStreamFallback : config.DecompressionStreamFallback;
|
|
2926
2591
|
const NativeStream = deflate ? config.CompressionStream : config.DecompressionStream;
|
|
2927
2592
|
if (!options.useCompressionStream) {
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
} catch {
|
|
2931
|
-
if (!FallbackStream || FallbackStream.requiresModule) {
|
|
2932
|
-
options.useCompressionStream = true;
|
|
2933
|
-
}
|
|
2593
|
+
if (!await moduleLoaded() && (!FallbackStream || FallbackStream.requiresModule)) {
|
|
2594
|
+
options.useCompressionStream = true;
|
|
2934
2595
|
}
|
|
2935
2596
|
} else if (FallbackStream && FallbackStream.requiresModule && !supportsDeflateRaw(NativeStream)) {
|
|
2936
|
-
|
|
2937
|
-
await initModule$1(config);
|
|
2938
|
-
} catch {
|
|
2939
|
-
// ignored
|
|
2940
|
-
}
|
|
2597
|
+
await moduleLoaded();
|
|
2941
2598
|
}
|
|
2942
2599
|
}
|
|
2600
|
+
if (options.encrypted && !options.zipCrypto) {
|
|
2601
|
+
await moduleLoaded();
|
|
2602
|
+
}
|
|
2943
2603
|
codecStream = new CodecStream(options, config);
|
|
2944
2604
|
chunkStream = new ChunkStream(getChunkSize(config));
|
|
2945
2605
|
await readable
|
|
@@ -2972,6 +2632,13 @@ async function runWorker$1({ options, readable, writable, onTaskFinished, worker
|
|
|
2972
2632
|
} finally {
|
|
2973
2633
|
onTaskFinished();
|
|
2974
2634
|
}
|
|
2635
|
+
|
|
2636
|
+
function moduleLoaded() {
|
|
2637
|
+
if (!modulePromise) {
|
|
2638
|
+
modulePromise = loadModule(config);
|
|
2639
|
+
}
|
|
2640
|
+
return modulePromise;
|
|
2641
|
+
}
|
|
2975
2642
|
}
|
|
2976
2643
|
|
|
2977
2644
|
/*
|
|
@@ -4108,16 +3775,14 @@ async function initHttpReader(httpReader, sendRequest, getRequestData) {
|
|
|
4108
3775
|
combineSizeEocd
|
|
4109
3776
|
} = httpReader;
|
|
4110
3777
|
if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == UNDEFINED_TYPE || preventHeadRequest)) {
|
|
4111
|
-
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -
|
|
3778
|
+
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -65557 : undefined));
|
|
4112
3779
|
const acceptRanges = response.headers.get(HTTP_HEADER_ACCEPT_RANGES);
|
|
4113
3780
|
if (!forceRangeRequests && (!acceptRanges || acceptRanges.toLowerCase() != HTTP_RANGE_UNIT)) {
|
|
4114
3781
|
throw new Error(ERR_HTTP_RANGE);
|
|
4115
3782
|
} else {
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
httpReader.eocdCache = eocdCache;
|
|
4120
|
-
}
|
|
3783
|
+
let eocdCache;
|
|
3784
|
+
if (combineSizeEocd && response.status == 206) {
|
|
3785
|
+
eocdCache = new Uint8Array(await response.arrayBuffer());
|
|
4121
3786
|
}
|
|
4122
3787
|
setResourceValidators(httpReader, response);
|
|
4123
3788
|
const contentSize = getContentRangeSize(response);
|
|
@@ -4126,6 +3791,9 @@ async function initHttpReader(httpReader, sendRequest, getRequestData) {
|
|
|
4126
3791
|
} else {
|
|
4127
3792
|
httpReader.size = contentSize;
|
|
4128
3793
|
}
|
|
3794
|
+
if (eocdCache && eocdCache.length && getContentRangeOffset(response) === httpReader.size - eocdCache.length) {
|
|
3795
|
+
httpReader.eocdCache = eocdCache;
|
|
3796
|
+
}
|
|
4129
3797
|
}
|
|
4130
3798
|
} else {
|
|
4131
3799
|
await getContentLength(httpReader, sendRequest, getRequestData);
|
|
@@ -4141,25 +3809,23 @@ async function readUint8ArrayHttpReader(httpReader, index, length, sendRequest,
|
|
|
4141
3809
|
options
|
|
4142
3810
|
} = httpReader;
|
|
4143
3811
|
if (useRangeHeader || forceRangeRequests) {
|
|
4144
|
-
if (eocdCache && index == size - END_OF_CENTRAL_DIR_LENGTH && length == END_OF_CENTRAL_DIR_LENGTH) {
|
|
4145
|
-
return eocdCache;
|
|
4146
|
-
}
|
|
4147
3812
|
if (index >= size || length === 0) {
|
|
4148
3813
|
return EMPTY_UINT8_ARRAY;
|
|
4149
3814
|
} else {
|
|
4150
3815
|
if (index + length > size) {
|
|
4151
3816
|
length = size - index;
|
|
4152
3817
|
}
|
|
3818
|
+
if (eocdCache && index >= size - eocdCache.length) {
|
|
3819
|
+
const cacheIndex = index - (size - eocdCache.length);
|
|
3820
|
+
return eocdCache.slice(cacheIndex, cacheIndex + length);
|
|
3821
|
+
}
|
|
4153
3822
|
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, index, length));
|
|
4154
3823
|
if (response.status != 206) {
|
|
4155
3824
|
throw new Error(ERR_HTTP_RANGE);
|
|
4156
3825
|
}
|
|
4157
|
-
const
|
|
4158
|
-
if (
|
|
4159
|
-
|
|
4160
|
-
if (!Number.isNaN(rangeStart) && rangeStart != index) {
|
|
4161
|
-
throw new Error(ERR_HTTP_RANGE);
|
|
4162
|
-
}
|
|
3826
|
+
const rangeStart = getContentRangeOffset(response);
|
|
3827
|
+
if (rangeStart !== UNDEFINED_VALUE && rangeStart != index) {
|
|
3828
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
4163
3829
|
}
|
|
4164
3830
|
checkResourceValidators(httpReader, response);
|
|
4165
3831
|
setResourceValidators(httpReader, response);
|
|
@@ -4219,12 +3885,9 @@ function createRangeReadable(httpReader, offset, size) {
|
|
|
4219
3885
|
if (response.status != 206) {
|
|
4220
3886
|
throw new Error(ERR_HTTP_RANGE);
|
|
4221
3887
|
}
|
|
4222
|
-
const
|
|
4223
|
-
if (
|
|
4224
|
-
|
|
4225
|
-
if (!Number.isNaN(rangeStart) && rangeStart != windowOffset) {
|
|
4226
|
-
throw new Error(ERR_HTTP_RANGE);
|
|
4227
|
-
}
|
|
3888
|
+
const rangeStart = getContentRangeOffset(response);
|
|
3889
|
+
if (rangeStart !== UNDEFINED_VALUE && rangeStart != windowOffset) {
|
|
3890
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
4228
3891
|
}
|
|
4229
3892
|
checkResourceValidators(httpReader, response);
|
|
4230
3893
|
setResourceValidators(httpReader, response);
|
|
@@ -4240,6 +3903,16 @@ function createRangeReadable(httpReader, offset, size) {
|
|
|
4240
3903
|
}
|
|
4241
3904
|
}
|
|
4242
3905
|
|
|
3906
|
+
function getContentRangeOffset(response) {
|
|
3907
|
+
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
3908
|
+
if (contentRangeHeader) {
|
|
3909
|
+
const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
|
|
3910
|
+
if (!Number.isNaN(rangeStart)) {
|
|
3911
|
+
return rangeStart;
|
|
3912
|
+
}
|
|
3913
|
+
}
|
|
3914
|
+
}
|
|
3915
|
+
|
|
4243
3916
|
function getContentRangeSize(response) {
|
|
4244
3917
|
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
4245
3918
|
if (contentRangeHeader) {
|
|
@@ -5020,7 +4693,7 @@ class ZipReader {
|
|
|
5020
4693
|
Object.assign(this, {
|
|
5021
4694
|
reader: new GenericReader(reader),
|
|
5022
4695
|
options,
|
|
5023
|
-
readRanges: new
|
|
4696
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
5024
4697
|
});
|
|
5025
4698
|
}
|
|
5026
4699
|
|
|
@@ -5665,7 +5338,6 @@ class ZipEntry {
|
|
|
5665
5338
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5666
5339
|
}
|
|
5667
5340
|
const size = compressedSize;
|
|
5668
|
-
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5669
5341
|
const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
|
|
5670
5342
|
throwIfAborted(signal);
|
|
5671
5343
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
@@ -5739,6 +5411,7 @@ class ZipEntry {
|
|
|
5739
5411
|
writer = new GenericWriter(writer);
|
|
5740
5412
|
await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
|
|
5741
5413
|
({ writable } = writer);
|
|
5414
|
+
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5742
5415
|
const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5743
5416
|
if (writtenSize != outputSize) {
|
|
5744
5417
|
throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
|
|
@@ -6174,14 +5847,61 @@ async function detectOverlappingEntry({
|
|
|
6174
5847
|
end: dataOffset + compressedSize + dataDescriptorLength,
|
|
6175
5848
|
fileEntry
|
|
6176
5849
|
};
|
|
6177
|
-
|
|
6178
|
-
|
|
5850
|
+
const { indexes, sortedRanges, pendingRanges } = readRanges;
|
|
5851
|
+
if (!indexes.has(index)) {
|
|
5852
|
+
const overlappingRange = findOverlappingRange(sortedRanges, range) || pendingRanges.find(otherRange => rangesOverlap(range, otherRange));
|
|
5853
|
+
if (overlappingRange) {
|
|
6179
5854
|
const error = new Error(ERR_OVERLAPPING_ENTRY);
|
|
6180
|
-
error.overlappingEntry =
|
|
5855
|
+
error.overlappingEntry = overlappingRange.fileEntry;
|
|
6181
5856
|
throw error;
|
|
6182
5857
|
}
|
|
5858
|
+
indexes.add(index);
|
|
5859
|
+
pendingRanges.push(range);
|
|
5860
|
+
if (pendingRanges.length * pendingRanges.length > sortedRanges.length) {
|
|
5861
|
+
pendingRanges.sort((range, otherRange) => range.start - otherRange.start);
|
|
5862
|
+
readRanges.sortedRanges = mergeRanges(sortedRanges, pendingRanges);
|
|
5863
|
+
pendingRanges.length = 0;
|
|
5864
|
+
}
|
|
5865
|
+
}
|
|
5866
|
+
}
|
|
5867
|
+
|
|
5868
|
+
function findOverlappingRange(sortedRanges, range) {
|
|
5869
|
+
let low = 0;
|
|
5870
|
+
let high = sortedRanges.length;
|
|
5871
|
+
while (low < high) {
|
|
5872
|
+
const middle = (low + high) >>> 1;
|
|
5873
|
+
if (sortedRanges[middle].start < range.start) {
|
|
5874
|
+
low = middle + 1;
|
|
5875
|
+
} else {
|
|
5876
|
+
high = middle;
|
|
5877
|
+
}
|
|
5878
|
+
}
|
|
5879
|
+
const previousRange = sortedRanges[low - 1];
|
|
5880
|
+
const nextRange = sortedRanges[low];
|
|
5881
|
+
if (previousRange && rangesOverlap(range, previousRange)) {
|
|
5882
|
+
return previousRange;
|
|
5883
|
+
}
|
|
5884
|
+
if (nextRange && rangesOverlap(range, nextRange)) {
|
|
5885
|
+
return nextRange;
|
|
5886
|
+
}
|
|
5887
|
+
}
|
|
5888
|
+
|
|
5889
|
+
function rangesOverlap(range, otherRange) {
|
|
5890
|
+
return range.start < otherRange.end && otherRange.start < range.end;
|
|
5891
|
+
}
|
|
5892
|
+
|
|
5893
|
+
function mergeRanges(sortedRanges, pendingRanges) {
|
|
5894
|
+
const mergedRanges = [];
|
|
5895
|
+
let indexSorted = 0;
|
|
5896
|
+
let indexPending = 0;
|
|
5897
|
+
while (indexSorted < sortedRanges.length || indexPending < pendingRanges.length) {
|
|
5898
|
+
if (indexPending == pendingRanges.length || (indexSorted < sortedRanges.length && sortedRanges[indexSorted].start < pendingRanges[indexPending].start)) {
|
|
5899
|
+
mergedRanges.push(sortedRanges[indexSorted++]);
|
|
5900
|
+
} else {
|
|
5901
|
+
mergedRanges.push(pendingRanges[indexPending++]);
|
|
5902
|
+
}
|
|
6183
5903
|
}
|
|
6184
|
-
|
|
5904
|
+
return mergedRanges;
|
|
6185
5905
|
}
|
|
6186
5906
|
|
|
6187
5907
|
function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
|
|
@@ -6759,7 +6479,6 @@ class ZipWriter {
|
|
|
6759
6479
|
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6760
6480
|
rawExtraField,
|
|
6761
6481
|
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6762
|
-
extendedTimestamp: false,
|
|
6763
6482
|
headerArray,
|
|
6764
6483
|
headerView
|
|
6765
6484
|
});
|
|
@@ -7503,7 +7222,7 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
|
|
|
7503
7222
|
}
|
|
7504
7223
|
}
|
|
7505
7224
|
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
|
|
7506
|
-
if (emptyEntry &&
|
|
7225
|
+
if (emptyEntry && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
|
|
7507
7226
|
dataDescriptor = false;
|
|
7508
7227
|
}
|
|
7509
7228
|
const zip64UncompressedSize = zip64Enabled || unknownSize || uncompressedSize >= MAX_32_BITS;
|
|
@@ -9015,7 +8734,7 @@ function formatSupported(StreamClass, format) {
|
|
|
9015
8734
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9016
8735
|
*/
|
|
9017
8736
|
|
|
9018
|
-
const VERSION = "2.
|
|
8737
|
+
const VERSION = "2.14.1";
|
|
9019
8738
|
|
|
9020
8739
|
/*
|
|
9021
8740
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -9499,13 +9218,13 @@ const FORMAT_DEFLATE_RAW = "deflate-raw";
|
|
|
9499
9218
|
const FORMAT_DEFLATE64_RAW = "deflate64-raw";
|
|
9500
9219
|
const FORMAT_GZIP = "gzip";
|
|
9501
9220
|
|
|
9502
|
-
let wasm, malloc, free, memory, initError;
|
|
9221
|
+
let wasm$1, malloc, free, memory, initError;
|
|
9503
9222
|
|
|
9504
|
-
function setWasmExports(wasmAPI) {
|
|
9505
|
-
wasm = wasmAPI;
|
|
9506
|
-
({ malloc, free, memory } = wasm);
|
|
9223
|
+
function setWasmExports$1(wasmAPI) {
|
|
9224
|
+
wasm$1 = wasmAPI;
|
|
9225
|
+
({ malloc, free, memory } = wasm$1);
|
|
9507
9226
|
if (typeof malloc !== "function" || typeof free !== "function" || !memory) {
|
|
9508
|
-
wasm = malloc = free = memory = null;
|
|
9227
|
+
wasm$1 = malloc = free = memory = null;
|
|
9509
9228
|
throw new Error("Invalid WASM module");
|
|
9510
9229
|
}
|
|
9511
9230
|
}
|
|
@@ -9514,12 +9233,12 @@ function setInitError(error) {
|
|
|
9514
9233
|
initError = error;
|
|
9515
9234
|
}
|
|
9516
9235
|
|
|
9517
|
-
function resetWasmExports() {
|
|
9518
|
-
wasm = malloc = free = memory = initError = null;
|
|
9236
|
+
function resetWasmExports$1() {
|
|
9237
|
+
wasm$1 = malloc = free = memory = initError = null;
|
|
9519
9238
|
}
|
|
9520
9239
|
|
|
9521
9240
|
function _make(isCompress, type, options = {}) {
|
|
9522
|
-
if (!wasm) {
|
|
9241
|
+
if (!wasm$1) {
|
|
9523
9242
|
const error = new Error("WASM module not loaded");
|
|
9524
9243
|
error.cause = initError;
|
|
9525
9244
|
throw error;
|
|
@@ -9538,37 +9257,36 @@ function _make(isCompress, type, options = {}) {
|
|
|
9538
9257
|
if (!this.out || !this.in) {
|
|
9539
9258
|
throw new Error("allocation failed");
|
|
9540
9259
|
}
|
|
9541
|
-
this._scratch = new Uint8Array(outBufferSize);
|
|
9542
9260
|
if (isCompress) {
|
|
9543
|
-
this._process = wasm.deflate_process;
|
|
9544
|
-
this._last_consumed = wasm.deflate_last_consumed;
|
|
9545
|
-
this._end = wasm.deflate_end;
|
|
9546
|
-
this.streamHandle = wasm.deflate_new();
|
|
9261
|
+
this._process = wasm$1.deflate_process;
|
|
9262
|
+
this._last_consumed = wasm$1.deflate_last_consumed;
|
|
9263
|
+
this._end = wasm$1.deflate_end;
|
|
9264
|
+
this.streamHandle = wasm$1.deflate_new();
|
|
9547
9265
|
if (type === FORMAT_GZIP) {
|
|
9548
|
-
result = wasm.deflate_init_gzip(this.streamHandle, level);
|
|
9266
|
+
result = wasm$1.deflate_init_gzip(this.streamHandle, level);
|
|
9549
9267
|
} else if (type === FORMAT_DEFLATE_RAW) {
|
|
9550
|
-
result = wasm.deflate_init_raw(this.streamHandle, level);
|
|
9268
|
+
result = wasm$1.deflate_init_raw(this.streamHandle, level);
|
|
9551
9269
|
} else {
|
|
9552
|
-
result = wasm.deflate_init(this.streamHandle, level);
|
|
9270
|
+
result = wasm$1.deflate_init(this.streamHandle, level);
|
|
9553
9271
|
}
|
|
9554
9272
|
} else {
|
|
9555
9273
|
if (type === FORMAT_DEFLATE64_RAW) {
|
|
9556
|
-
this._process = wasm.inflate9_process;
|
|
9557
|
-
this._last_consumed = wasm.inflate9_last_consumed;
|
|
9558
|
-
this._end = wasm.inflate9_end;
|
|
9559
|
-
this.streamHandle = wasm.inflate9_new();
|
|
9560
|
-
result = wasm.inflate9_init_raw(this.streamHandle);
|
|
9274
|
+
this._process = wasm$1.inflate9_process;
|
|
9275
|
+
this._last_consumed = wasm$1.inflate9_last_consumed;
|
|
9276
|
+
this._end = wasm$1.inflate9_end;
|
|
9277
|
+
this.streamHandle = wasm$1.inflate9_new();
|
|
9278
|
+
result = wasm$1.inflate9_init_raw(this.streamHandle);
|
|
9561
9279
|
} else {
|
|
9562
|
-
this._process = wasm.inflate_process;
|
|
9563
|
-
this._last_consumed = wasm.inflate_last_consumed;
|
|
9564
|
-
this._end = wasm.inflate_end;
|
|
9565
|
-
this.streamHandle = wasm.inflate_new();
|
|
9280
|
+
this._process = wasm$1.inflate_process;
|
|
9281
|
+
this._last_consumed = wasm$1.inflate_last_consumed;
|
|
9282
|
+
this._end = wasm$1.inflate_end;
|
|
9283
|
+
this.streamHandle = wasm$1.inflate_new();
|
|
9566
9284
|
if (type === FORMAT_DEFLATE_RAW) {
|
|
9567
|
-
result = wasm.inflate_init_raw(this.streamHandle);
|
|
9285
|
+
result = wasm$1.inflate_init_raw(this.streamHandle);
|
|
9568
9286
|
} else if (type === FORMAT_GZIP) {
|
|
9569
|
-
result = wasm.inflate_init_gzip(this.streamHandle);
|
|
9287
|
+
result = wasm$1.inflate_init_gzip(this.streamHandle);
|
|
9570
9288
|
} else {
|
|
9571
|
-
result = wasm.inflate_init(this.streamHandle);
|
|
9289
|
+
result = wasm$1.inflate_init(this.streamHandle);
|
|
9572
9290
|
}
|
|
9573
9291
|
}
|
|
9574
9292
|
}
|
|
@@ -9587,7 +9305,6 @@ function _make(isCompress, type, options = {}) {
|
|
|
9587
9305
|
const process = this._process;
|
|
9588
9306
|
const last_consumed = this._last_consumed;
|
|
9589
9307
|
const out = this.out;
|
|
9590
|
-
const scratch = this._scratch;
|
|
9591
9308
|
let offset = 0;
|
|
9592
9309
|
while (offset < buffer.length) {
|
|
9593
9310
|
const toRead = Math.min(buffer.length - offset, 32 * 1024);
|
|
@@ -9612,8 +9329,7 @@ function _make(isCompress, type, options = {}) {
|
|
|
9612
9329
|
}
|
|
9613
9330
|
const prod = result & 0x00ffffff;
|
|
9614
9331
|
if (prod) {
|
|
9615
|
-
|
|
9616
|
-
controller.enqueue(scratch.slice(0, prod));
|
|
9332
|
+
controller.enqueue(heap.slice(out, out + prod));
|
|
9617
9333
|
}
|
|
9618
9334
|
const consumed = last_consumed(this.streamHandle);
|
|
9619
9335
|
if (consumed === 0 && prod === 0) {
|
|
@@ -9631,7 +9347,6 @@ function _make(isCompress, type, options = {}) {
|
|
|
9631
9347
|
const heap = new Uint8Array(memory.buffer);
|
|
9632
9348
|
const process = this._process;
|
|
9633
9349
|
const out = this.out;
|
|
9634
|
-
const scratch = this._scratch;
|
|
9635
9350
|
while (true) {
|
|
9636
9351
|
const result = process(this.streamHandle, 0, 0, out, outBufferSize, 4);
|
|
9637
9352
|
const code = (result >> 24) & 0xff;
|
|
@@ -9641,8 +9356,7 @@ function _make(isCompress, type, options = {}) {
|
|
|
9641
9356
|
}
|
|
9642
9357
|
const produced = result & 0x00ffffff;
|
|
9643
9358
|
if (produced) {
|
|
9644
|
-
|
|
9645
|
-
controller.enqueue(scratch.slice(0, produced));
|
|
9359
|
+
controller.enqueue(heap.slice(out, out + produced));
|
|
9646
9360
|
}
|
|
9647
9361
|
if (code === 1 || produced === 0) {
|
|
9648
9362
|
break;
|
|
@@ -9703,6 +9417,105 @@ DecompressionStreamZlib.requiresModule = true;
|
|
|
9703
9417
|
CompressionStreamZlib.supportedFormats = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP];
|
|
9704
9418
|
DecompressionStreamZlib.supportedFormats = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP, FORMAT_DEFLATE64_RAW];
|
|
9705
9419
|
|
|
9420
|
+
/*
|
|
9421
|
+
Copyright (c) 2026 Gildas Lormeau. All rights reserved.
|
|
9422
|
+
|
|
9423
|
+
Redistribution and use in source and binary forms, with or without
|
|
9424
|
+
modification, are permitted provided that the following conditions are met:
|
|
9425
|
+
|
|
9426
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
9427
|
+
this list of conditions and the following disclaimer.
|
|
9428
|
+
|
|
9429
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
9430
|
+
notice, this list of conditions and the following disclaimer in
|
|
9431
|
+
the documentation and/or other materials provided with the distribution.
|
|
9432
|
+
|
|
9433
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
9434
|
+
derived from this software without specific prior written permission.
|
|
9435
|
+
|
|
9436
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
9437
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
9438
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
9439
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
9440
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
9441
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
9442
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
9443
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
9444
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
9445
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9446
|
+
*/
|
|
9447
|
+
|
|
9448
|
+
|
|
9449
|
+
const BUFFER_LENGTH = 64 * 1024;
|
|
9450
|
+
const DIGEST_LENGTH = 20;
|
|
9451
|
+
|
|
9452
|
+
let wasm, buffer;
|
|
9453
|
+
|
|
9454
|
+
function setWasmExports(wasmAPI) {
|
|
9455
|
+
// deno-lint-ignore valid-typeof
|
|
9456
|
+
if (typeof wasmAPI.aes_hmac_new == FUNCTION_TYPE) {
|
|
9457
|
+
wasm = wasmAPI;
|
|
9458
|
+
buffer = 0;
|
|
9459
|
+
}
|
|
9460
|
+
}
|
|
9461
|
+
|
|
9462
|
+
function resetWasmExports() {
|
|
9463
|
+
wasm = null;
|
|
9464
|
+
buffer = 0;
|
|
9465
|
+
}
|
|
9466
|
+
|
|
9467
|
+
function createEngine(key, authenticationKey) {
|
|
9468
|
+
const exports = wasm;
|
|
9469
|
+
let context = exports ? createContext(exports, key, authenticationKey) : 0;
|
|
9470
|
+
if (!context) {
|
|
9471
|
+
return createEngine$2(key, authenticationKey);
|
|
9472
|
+
}
|
|
9473
|
+
const scratch = buffer;
|
|
9474
|
+
return {
|
|
9475
|
+
process(data, decrypt) {
|
|
9476
|
+
for (let offset = 0; offset < data.length; offset += BUFFER_LENGTH) {
|
|
9477
|
+
const chunk = data.subarray(offset, offset + BUFFER_LENGTH);
|
|
9478
|
+
const heap = getHeap(exports);
|
|
9479
|
+
heap.set(chunk, scratch);
|
|
9480
|
+
exports.aes_hmac_process(context, scratch, chunk.length, decrypt ? 1 : 0);
|
|
9481
|
+
chunk.set(heap.subarray(scratch, scratch + chunk.length));
|
|
9482
|
+
}
|
|
9483
|
+
},
|
|
9484
|
+
digest() {
|
|
9485
|
+
exports.aes_hmac_end(context, scratch);
|
|
9486
|
+
context = 0;
|
|
9487
|
+
return getHeap(exports).slice(scratch, scratch + DIGEST_LENGTH);
|
|
9488
|
+
},
|
|
9489
|
+
dispose() {
|
|
9490
|
+
if (context) {
|
|
9491
|
+
exports.aes_hmac_end(context, 0);
|
|
9492
|
+
context = 0;
|
|
9493
|
+
}
|
|
9494
|
+
}
|
|
9495
|
+
};
|
|
9496
|
+
}
|
|
9497
|
+
|
|
9498
|
+
function createContext(exports, key, authenticationKey) {
|
|
9499
|
+
if (!buffer) {
|
|
9500
|
+
buffer = exports.malloc(BUFFER_LENGTH);
|
|
9501
|
+
}
|
|
9502
|
+
const context = buffer ? exports.aes_hmac_new() : 0;
|
|
9503
|
+
if (context) {
|
|
9504
|
+
const heap = getHeap(exports);
|
|
9505
|
+
heap.set(key, buffer);
|
|
9506
|
+
heap.set(authenticationKey, buffer + key.length);
|
|
9507
|
+
if (exports.aes_hmac_init(context, buffer, key.length, buffer + key.length, authenticationKey.length)) {
|
|
9508
|
+
exports.aes_hmac_end(context, 0);
|
|
9509
|
+
return 0;
|
|
9510
|
+
}
|
|
9511
|
+
}
|
|
9512
|
+
return context;
|
|
9513
|
+
}
|
|
9514
|
+
|
|
9515
|
+
function getHeap(exports) {
|
|
9516
|
+
return new Uint8Array(exports.memory.buffer);
|
|
9517
|
+
}
|
|
9518
|
+
|
|
9706
9519
|
/*
|
|
9707
9520
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
9708
9521
|
|
|
@@ -9764,11 +9577,13 @@ async function instantiateModule(wasmURI, baseURI) {
|
|
|
9764
9577
|
}
|
|
9765
9578
|
}
|
|
9766
9579
|
const wasmInstance = await WebAssembly.instantiate(arrayBuffer);
|
|
9580
|
+
setWasmExports$1(wasmInstance.instance.exports);
|
|
9767
9581
|
setWasmExports(wasmInstance.instance.exports);
|
|
9768
9582
|
}
|
|
9769
9583
|
|
|
9770
9584
|
function resetWasmModule() {
|
|
9771
9585
|
initializedModule = false;
|
|
9586
|
+
resetWasmExports$1();
|
|
9772
9587
|
resetWasmExports();
|
|
9773
9588
|
}
|
|
9774
9589
|
|
|
@@ -9814,6 +9629,7 @@ function arrayBufferFromDataURI(dataURI) {
|
|
|
9814
9629
|
|
|
9815
9630
|
let modulePromise;
|
|
9816
9631
|
|
|
9632
|
+
setAESEngine(createEngine);
|
|
9817
9633
|
configureWorker({
|
|
9818
9634
|
initModule: config => {
|
|
9819
9635
|
if (!modulePromise) {
|