@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
|
/*
|
|
@@ -4128,16 +3795,14 @@ async function initHttpReader(httpReader, sendRequest, getRequestData) {
|
|
|
4128
3795
|
combineSizeEocd
|
|
4129
3796
|
} = httpReader;
|
|
4130
3797
|
if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == UNDEFINED_TYPE || preventHeadRequest)) {
|
|
4131
|
-
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -
|
|
3798
|
+
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -65557 : undefined));
|
|
4132
3799
|
const acceptRanges = response.headers.get(HTTP_HEADER_ACCEPT_RANGES);
|
|
4133
3800
|
if (!forceRangeRequests && (!acceptRanges || acceptRanges.toLowerCase() != HTTP_RANGE_UNIT)) {
|
|
4134
3801
|
throw new Error(ERR_HTTP_RANGE);
|
|
4135
3802
|
} else {
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
httpReader.eocdCache = eocdCache;
|
|
4140
|
-
}
|
|
3803
|
+
let eocdCache;
|
|
3804
|
+
if (combineSizeEocd && response.status == 206) {
|
|
3805
|
+
eocdCache = new Uint8Array(await response.arrayBuffer());
|
|
4141
3806
|
}
|
|
4142
3807
|
setResourceValidators(httpReader, response);
|
|
4143
3808
|
const contentSize = getContentRangeSize(response);
|
|
@@ -4146,6 +3811,9 @@ async function initHttpReader(httpReader, sendRequest, getRequestData) {
|
|
|
4146
3811
|
} else {
|
|
4147
3812
|
httpReader.size = contentSize;
|
|
4148
3813
|
}
|
|
3814
|
+
if (eocdCache && eocdCache.length && getContentRangeOffset(response) === httpReader.size - eocdCache.length) {
|
|
3815
|
+
httpReader.eocdCache = eocdCache;
|
|
3816
|
+
}
|
|
4149
3817
|
}
|
|
4150
3818
|
} else {
|
|
4151
3819
|
await getContentLength(httpReader, sendRequest, getRequestData);
|
|
@@ -4161,25 +3829,23 @@ async function readUint8ArrayHttpReader(httpReader, index, length, sendRequest,
|
|
|
4161
3829
|
options
|
|
4162
3830
|
} = httpReader;
|
|
4163
3831
|
if (useRangeHeader || forceRangeRequests) {
|
|
4164
|
-
if (eocdCache && index == size - END_OF_CENTRAL_DIR_LENGTH && length == END_OF_CENTRAL_DIR_LENGTH) {
|
|
4165
|
-
return eocdCache;
|
|
4166
|
-
}
|
|
4167
3832
|
if (index >= size || length === 0) {
|
|
4168
3833
|
return EMPTY_UINT8_ARRAY;
|
|
4169
3834
|
} else {
|
|
4170
3835
|
if (index + length > size) {
|
|
4171
3836
|
length = size - index;
|
|
4172
3837
|
}
|
|
3838
|
+
if (eocdCache && index >= size - eocdCache.length) {
|
|
3839
|
+
const cacheIndex = index - (size - eocdCache.length);
|
|
3840
|
+
return eocdCache.slice(cacheIndex, cacheIndex + length);
|
|
3841
|
+
}
|
|
4173
3842
|
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, index, length));
|
|
4174
3843
|
if (response.status != 206) {
|
|
4175
3844
|
throw new Error(ERR_HTTP_RANGE);
|
|
4176
3845
|
}
|
|
4177
|
-
const
|
|
4178
|
-
if (
|
|
4179
|
-
|
|
4180
|
-
if (!Number.isNaN(rangeStart) && rangeStart != index) {
|
|
4181
|
-
throw new Error(ERR_HTTP_RANGE);
|
|
4182
|
-
}
|
|
3846
|
+
const rangeStart = getContentRangeOffset(response);
|
|
3847
|
+
if (rangeStart !== UNDEFINED_VALUE && rangeStart != index) {
|
|
3848
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
4183
3849
|
}
|
|
4184
3850
|
checkResourceValidators(httpReader, response);
|
|
4185
3851
|
setResourceValidators(httpReader, response);
|
|
@@ -4239,12 +3905,9 @@ function createRangeReadable(httpReader, offset, size) {
|
|
|
4239
3905
|
if (response.status != 206) {
|
|
4240
3906
|
throw new Error(ERR_HTTP_RANGE);
|
|
4241
3907
|
}
|
|
4242
|
-
const
|
|
4243
|
-
if (
|
|
4244
|
-
|
|
4245
|
-
if (!Number.isNaN(rangeStart) && rangeStart != windowOffset) {
|
|
4246
|
-
throw new Error(ERR_HTTP_RANGE);
|
|
4247
|
-
}
|
|
3908
|
+
const rangeStart = getContentRangeOffset(response);
|
|
3909
|
+
if (rangeStart !== UNDEFINED_VALUE && rangeStart != windowOffset) {
|
|
3910
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
4248
3911
|
}
|
|
4249
3912
|
checkResourceValidators(httpReader, response);
|
|
4250
3913
|
setResourceValidators(httpReader, response);
|
|
@@ -4260,6 +3923,16 @@ function createRangeReadable(httpReader, offset, size) {
|
|
|
4260
3923
|
}
|
|
4261
3924
|
}
|
|
4262
3925
|
|
|
3926
|
+
function getContentRangeOffset(response) {
|
|
3927
|
+
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
3928
|
+
if (contentRangeHeader) {
|
|
3929
|
+
const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
|
|
3930
|
+
if (!Number.isNaN(rangeStart)) {
|
|
3931
|
+
return rangeStart;
|
|
3932
|
+
}
|
|
3933
|
+
}
|
|
3934
|
+
}
|
|
3935
|
+
|
|
4263
3936
|
function getContentRangeSize(response) {
|
|
4264
3937
|
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
4265
3938
|
if (contentRangeHeader) {
|
|
@@ -5040,7 +4713,7 @@ class ZipReader {
|
|
|
5040
4713
|
Object.assign(this, {
|
|
5041
4714
|
reader: new GenericReader(reader),
|
|
5042
4715
|
options,
|
|
5043
|
-
readRanges: new
|
|
4716
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
5044
4717
|
});
|
|
5045
4718
|
}
|
|
5046
4719
|
|
|
@@ -5685,7 +5358,6 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5685
5358
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5686
5359
|
}
|
|
5687
5360
|
const size = compressedSize;
|
|
5688
|
-
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5689
5361
|
const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
|
|
5690
5362
|
throwIfAborted(signal);
|
|
5691
5363
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
@@ -5759,6 +5431,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5759
5431
|
writer = new GenericWriter(writer);
|
|
5760
5432
|
await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
|
|
5761
5433
|
({ writable } = writer);
|
|
5434
|
+
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5762
5435
|
const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5763
5436
|
if (writtenSize != outputSize) {
|
|
5764
5437
|
throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
|
|
@@ -6194,14 +5867,61 @@ async function detectOverlappingEntry({
|
|
|
6194
5867
|
end: dataOffset + compressedSize + dataDescriptorLength,
|
|
6195
5868
|
fileEntry
|
|
6196
5869
|
};
|
|
6197
|
-
|
|
6198
|
-
|
|
5870
|
+
const { indexes, sortedRanges, pendingRanges } = readRanges;
|
|
5871
|
+
if (!indexes.has(index)) {
|
|
5872
|
+
const overlappingRange = findOverlappingRange(sortedRanges, range) || pendingRanges.find(otherRange => rangesOverlap(range, otherRange));
|
|
5873
|
+
if (overlappingRange) {
|
|
6199
5874
|
const error = new Error(ERR_OVERLAPPING_ENTRY);
|
|
6200
|
-
error.overlappingEntry =
|
|
5875
|
+
error.overlappingEntry = overlappingRange.fileEntry;
|
|
6201
5876
|
throw error;
|
|
6202
5877
|
}
|
|
5878
|
+
indexes.add(index);
|
|
5879
|
+
pendingRanges.push(range);
|
|
5880
|
+
if (pendingRanges.length * pendingRanges.length > sortedRanges.length) {
|
|
5881
|
+
pendingRanges.sort((range, otherRange) => range.start - otherRange.start);
|
|
5882
|
+
readRanges.sortedRanges = mergeRanges(sortedRanges, pendingRanges);
|
|
5883
|
+
pendingRanges.length = 0;
|
|
5884
|
+
}
|
|
5885
|
+
}
|
|
5886
|
+
}
|
|
5887
|
+
|
|
5888
|
+
function findOverlappingRange(sortedRanges, range) {
|
|
5889
|
+
let low = 0;
|
|
5890
|
+
let high = sortedRanges.length;
|
|
5891
|
+
while (low < high) {
|
|
5892
|
+
const middle = (low + high) >>> 1;
|
|
5893
|
+
if (sortedRanges[middle].start < range.start) {
|
|
5894
|
+
low = middle + 1;
|
|
5895
|
+
} else {
|
|
5896
|
+
high = middle;
|
|
5897
|
+
}
|
|
5898
|
+
}
|
|
5899
|
+
const previousRange = sortedRanges[low - 1];
|
|
5900
|
+
const nextRange = sortedRanges[low];
|
|
5901
|
+
if (previousRange && rangesOverlap(range, previousRange)) {
|
|
5902
|
+
return previousRange;
|
|
5903
|
+
}
|
|
5904
|
+
if (nextRange && rangesOverlap(range, nextRange)) {
|
|
5905
|
+
return nextRange;
|
|
5906
|
+
}
|
|
5907
|
+
}
|
|
5908
|
+
|
|
5909
|
+
function rangesOverlap(range, otherRange) {
|
|
5910
|
+
return range.start < otherRange.end && otherRange.start < range.end;
|
|
5911
|
+
}
|
|
5912
|
+
|
|
5913
|
+
function mergeRanges(sortedRanges, pendingRanges) {
|
|
5914
|
+
const mergedRanges = [];
|
|
5915
|
+
let indexSorted = 0;
|
|
5916
|
+
let indexPending = 0;
|
|
5917
|
+
while (indexSorted < sortedRanges.length || indexPending < pendingRanges.length) {
|
|
5918
|
+
if (indexPending == pendingRanges.length || (indexSorted < sortedRanges.length && sortedRanges[indexSorted].start < pendingRanges[indexPending].start)) {
|
|
5919
|
+
mergedRanges.push(sortedRanges[indexSorted++]);
|
|
5920
|
+
} else {
|
|
5921
|
+
mergedRanges.push(pendingRanges[indexPending++]);
|
|
5922
|
+
}
|
|
6203
5923
|
}
|
|
6204
|
-
|
|
5924
|
+
return mergedRanges;
|
|
6205
5925
|
}
|
|
6206
5926
|
|
|
6207
5927
|
function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
|
|
@@ -6779,7 +6499,6 @@ class ZipWriter {
|
|
|
6779
6499
|
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6780
6500
|
rawExtraField,
|
|
6781
6501
|
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6782
|
-
extendedTimestamp: false,
|
|
6783
6502
|
headerArray,
|
|
6784
6503
|
headerView
|
|
6785
6504
|
});
|
|
@@ -7523,7 +7242,7 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
|
|
|
7523
7242
|
}
|
|
7524
7243
|
}
|
|
7525
7244
|
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
|
|
7526
|
-
if (emptyEntry &&
|
|
7245
|
+
if (emptyEntry && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
|
|
7527
7246
|
dataDescriptor = false;
|
|
7528
7247
|
}
|
|
7529
7248
|
const zip64UncompressedSize = zip64Enabled || unknownSize || uncompressedSize >= MAX_32_BITS;
|
|
@@ -9133,7 +8852,7 @@ function formatSupported(StreamClass, format) {
|
|
|
9133
8852
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9134
8853
|
*/
|
|
9135
8854
|
|
|
9136
|
-
const VERSION = "2.
|
|
8855
|
+
const VERSION = "2.14.1";
|
|
9137
8856
|
|
|
9138
8857
|
/*
|
|
9139
8858
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -9617,13 +9336,13 @@ const FORMAT_DEFLATE_RAW = "deflate-raw";
|
|
|
9617
9336
|
const FORMAT_DEFLATE64_RAW = "deflate64-raw";
|
|
9618
9337
|
const FORMAT_GZIP = "gzip";
|
|
9619
9338
|
|
|
9620
|
-
let wasm, malloc, free, memory, initError;
|
|
9339
|
+
let wasm$1, malloc, free, memory, initError;
|
|
9621
9340
|
|
|
9622
|
-
function setWasmExports(wasmAPI) {
|
|
9623
|
-
wasm = wasmAPI;
|
|
9624
|
-
({ malloc, free, memory } = wasm);
|
|
9341
|
+
function setWasmExports$1(wasmAPI) {
|
|
9342
|
+
wasm$1 = wasmAPI;
|
|
9343
|
+
({ malloc, free, memory } = wasm$1);
|
|
9625
9344
|
if (typeof malloc !== "function" || typeof free !== "function" || !memory) {
|
|
9626
|
-
wasm = malloc = free = memory = null;
|
|
9345
|
+
wasm$1 = malloc = free = memory = null;
|
|
9627
9346
|
throw new Error("Invalid WASM module");
|
|
9628
9347
|
}
|
|
9629
9348
|
}
|
|
@@ -9632,12 +9351,12 @@ function setInitError(error) {
|
|
|
9632
9351
|
initError = error;
|
|
9633
9352
|
}
|
|
9634
9353
|
|
|
9635
|
-
function resetWasmExports() {
|
|
9636
|
-
wasm = malloc = free = memory = initError = null;
|
|
9354
|
+
function resetWasmExports$1() {
|
|
9355
|
+
wasm$1 = malloc = free = memory = initError = null;
|
|
9637
9356
|
}
|
|
9638
9357
|
|
|
9639
9358
|
function _make(isCompress, type, options = {}) {
|
|
9640
|
-
if (!wasm) {
|
|
9359
|
+
if (!wasm$1) {
|
|
9641
9360
|
const error = new Error("WASM module not loaded");
|
|
9642
9361
|
error.cause = initError;
|
|
9643
9362
|
throw error;
|
|
@@ -9656,37 +9375,36 @@ function _make(isCompress, type, options = {}) {
|
|
|
9656
9375
|
if (!this.out || !this.in) {
|
|
9657
9376
|
throw new Error("allocation failed");
|
|
9658
9377
|
}
|
|
9659
|
-
this._scratch = new Uint8Array(outBufferSize);
|
|
9660
9378
|
if (isCompress) {
|
|
9661
|
-
this._process = wasm.deflate_process;
|
|
9662
|
-
this._last_consumed = wasm.deflate_last_consumed;
|
|
9663
|
-
this._end = wasm.deflate_end;
|
|
9664
|
-
this.streamHandle = wasm.deflate_new();
|
|
9379
|
+
this._process = wasm$1.deflate_process;
|
|
9380
|
+
this._last_consumed = wasm$1.deflate_last_consumed;
|
|
9381
|
+
this._end = wasm$1.deflate_end;
|
|
9382
|
+
this.streamHandle = wasm$1.deflate_new();
|
|
9665
9383
|
if (type === FORMAT_GZIP) {
|
|
9666
|
-
result = wasm.deflate_init_gzip(this.streamHandle, level);
|
|
9384
|
+
result = wasm$1.deflate_init_gzip(this.streamHandle, level);
|
|
9667
9385
|
} else if (type === FORMAT_DEFLATE_RAW) {
|
|
9668
|
-
result = wasm.deflate_init_raw(this.streamHandle, level);
|
|
9386
|
+
result = wasm$1.deflate_init_raw(this.streamHandle, level);
|
|
9669
9387
|
} else {
|
|
9670
|
-
result = wasm.deflate_init(this.streamHandle, level);
|
|
9388
|
+
result = wasm$1.deflate_init(this.streamHandle, level);
|
|
9671
9389
|
}
|
|
9672
9390
|
} else {
|
|
9673
9391
|
if (type === FORMAT_DEFLATE64_RAW) {
|
|
9674
|
-
this._process = wasm.inflate9_process;
|
|
9675
|
-
this._last_consumed = wasm.inflate9_last_consumed;
|
|
9676
|
-
this._end = wasm.inflate9_end;
|
|
9677
|
-
this.streamHandle = wasm.inflate9_new();
|
|
9678
|
-
result = wasm.inflate9_init_raw(this.streamHandle);
|
|
9392
|
+
this._process = wasm$1.inflate9_process;
|
|
9393
|
+
this._last_consumed = wasm$1.inflate9_last_consumed;
|
|
9394
|
+
this._end = wasm$1.inflate9_end;
|
|
9395
|
+
this.streamHandle = wasm$1.inflate9_new();
|
|
9396
|
+
result = wasm$1.inflate9_init_raw(this.streamHandle);
|
|
9679
9397
|
} else {
|
|
9680
|
-
this._process = wasm.inflate_process;
|
|
9681
|
-
this._last_consumed = wasm.inflate_last_consumed;
|
|
9682
|
-
this._end = wasm.inflate_end;
|
|
9683
|
-
this.streamHandle = wasm.inflate_new();
|
|
9398
|
+
this._process = wasm$1.inflate_process;
|
|
9399
|
+
this._last_consumed = wasm$1.inflate_last_consumed;
|
|
9400
|
+
this._end = wasm$1.inflate_end;
|
|
9401
|
+
this.streamHandle = wasm$1.inflate_new();
|
|
9684
9402
|
if (type === FORMAT_DEFLATE_RAW) {
|
|
9685
|
-
result = wasm.inflate_init_raw(this.streamHandle);
|
|
9403
|
+
result = wasm$1.inflate_init_raw(this.streamHandle);
|
|
9686
9404
|
} else if (type === FORMAT_GZIP) {
|
|
9687
|
-
result = wasm.inflate_init_gzip(this.streamHandle);
|
|
9405
|
+
result = wasm$1.inflate_init_gzip(this.streamHandle);
|
|
9688
9406
|
} else {
|
|
9689
|
-
result = wasm.inflate_init(this.streamHandle);
|
|
9407
|
+
result = wasm$1.inflate_init(this.streamHandle);
|
|
9690
9408
|
}
|
|
9691
9409
|
}
|
|
9692
9410
|
}
|
|
@@ -9705,7 +9423,6 @@ function _make(isCompress, type, options = {}) {
|
|
|
9705
9423
|
const process = this._process;
|
|
9706
9424
|
const last_consumed = this._last_consumed;
|
|
9707
9425
|
const out = this.out;
|
|
9708
|
-
const scratch = this._scratch;
|
|
9709
9426
|
let offset = 0;
|
|
9710
9427
|
while (offset < buffer.length) {
|
|
9711
9428
|
const toRead = Math.min(buffer.length - offset, 32 * 1024);
|
|
@@ -9730,8 +9447,7 @@ function _make(isCompress, type, options = {}) {
|
|
|
9730
9447
|
}
|
|
9731
9448
|
const prod = result & 0x00ffffff;
|
|
9732
9449
|
if (prod) {
|
|
9733
|
-
|
|
9734
|
-
controller.enqueue(scratch.slice(0, prod));
|
|
9450
|
+
controller.enqueue(heap.slice(out, out + prod));
|
|
9735
9451
|
}
|
|
9736
9452
|
const consumed = last_consumed(this.streamHandle);
|
|
9737
9453
|
if (consumed === 0 && prod === 0) {
|
|
@@ -9749,7 +9465,6 @@ function _make(isCompress, type, options = {}) {
|
|
|
9749
9465
|
const heap = new Uint8Array(memory.buffer);
|
|
9750
9466
|
const process = this._process;
|
|
9751
9467
|
const out = this.out;
|
|
9752
|
-
const scratch = this._scratch;
|
|
9753
9468
|
while (true) {
|
|
9754
9469
|
const result = process(this.streamHandle, 0, 0, out, outBufferSize, 4);
|
|
9755
9470
|
const code = (result >> 24) & 0xff;
|
|
@@ -9759,8 +9474,7 @@ function _make(isCompress, type, options = {}) {
|
|
|
9759
9474
|
}
|
|
9760
9475
|
const produced = result & 0x00ffffff;
|
|
9761
9476
|
if (produced) {
|
|
9762
|
-
|
|
9763
|
-
controller.enqueue(scratch.slice(0, produced));
|
|
9477
|
+
controller.enqueue(heap.slice(out, out + produced));
|
|
9764
9478
|
}
|
|
9765
9479
|
if (code === 1 || produced === 0) {
|
|
9766
9480
|
break;
|
|
@@ -9821,6 +9535,105 @@ DecompressionStreamZlib.requiresModule = true;
|
|
|
9821
9535
|
CompressionStreamZlib.supportedFormats = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP];
|
|
9822
9536
|
DecompressionStreamZlib.supportedFormats = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP, FORMAT_DEFLATE64_RAW];
|
|
9823
9537
|
|
|
9538
|
+
/*
|
|
9539
|
+
Copyright (c) 2026 Gildas Lormeau. All rights reserved.
|
|
9540
|
+
|
|
9541
|
+
Redistribution and use in source and binary forms, with or without
|
|
9542
|
+
modification, are permitted provided that the following conditions are met:
|
|
9543
|
+
|
|
9544
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
9545
|
+
this list of conditions and the following disclaimer.
|
|
9546
|
+
|
|
9547
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
9548
|
+
notice, this list of conditions and the following disclaimer in
|
|
9549
|
+
the documentation and/or other materials provided with the distribution.
|
|
9550
|
+
|
|
9551
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
9552
|
+
derived from this software without specific prior written permission.
|
|
9553
|
+
|
|
9554
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
9555
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
9556
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
9557
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
9558
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
9559
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
9560
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
9561
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
9562
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
9563
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9564
|
+
*/
|
|
9565
|
+
|
|
9566
|
+
|
|
9567
|
+
const BUFFER_LENGTH = 64 * 1024;
|
|
9568
|
+
const DIGEST_LENGTH = 20;
|
|
9569
|
+
|
|
9570
|
+
let wasm, buffer;
|
|
9571
|
+
|
|
9572
|
+
function setWasmExports(wasmAPI) {
|
|
9573
|
+
// deno-lint-ignore valid-typeof
|
|
9574
|
+
if (typeof wasmAPI.aes_hmac_new == FUNCTION_TYPE) {
|
|
9575
|
+
wasm = wasmAPI;
|
|
9576
|
+
buffer = 0;
|
|
9577
|
+
}
|
|
9578
|
+
}
|
|
9579
|
+
|
|
9580
|
+
function resetWasmExports() {
|
|
9581
|
+
wasm = null;
|
|
9582
|
+
buffer = 0;
|
|
9583
|
+
}
|
|
9584
|
+
|
|
9585
|
+
function createEngine(key, authenticationKey) {
|
|
9586
|
+
const exports = wasm;
|
|
9587
|
+
let context = exports ? createContext(exports, key, authenticationKey) : 0;
|
|
9588
|
+
if (!context) {
|
|
9589
|
+
return createEngine$2(key, authenticationKey);
|
|
9590
|
+
}
|
|
9591
|
+
const scratch = buffer;
|
|
9592
|
+
return {
|
|
9593
|
+
process(data, decrypt) {
|
|
9594
|
+
for (let offset = 0; offset < data.length; offset += BUFFER_LENGTH) {
|
|
9595
|
+
const chunk = data.subarray(offset, offset + BUFFER_LENGTH);
|
|
9596
|
+
const heap = getHeap(exports);
|
|
9597
|
+
heap.set(chunk, scratch);
|
|
9598
|
+
exports.aes_hmac_process(context, scratch, chunk.length, decrypt ? 1 : 0);
|
|
9599
|
+
chunk.set(heap.subarray(scratch, scratch + chunk.length));
|
|
9600
|
+
}
|
|
9601
|
+
},
|
|
9602
|
+
digest() {
|
|
9603
|
+
exports.aes_hmac_end(context, scratch);
|
|
9604
|
+
context = 0;
|
|
9605
|
+
return getHeap(exports).slice(scratch, scratch + DIGEST_LENGTH);
|
|
9606
|
+
},
|
|
9607
|
+
dispose() {
|
|
9608
|
+
if (context) {
|
|
9609
|
+
exports.aes_hmac_end(context, 0);
|
|
9610
|
+
context = 0;
|
|
9611
|
+
}
|
|
9612
|
+
}
|
|
9613
|
+
};
|
|
9614
|
+
}
|
|
9615
|
+
|
|
9616
|
+
function createContext(exports, key, authenticationKey) {
|
|
9617
|
+
if (!buffer) {
|
|
9618
|
+
buffer = exports.malloc(BUFFER_LENGTH);
|
|
9619
|
+
}
|
|
9620
|
+
const context = buffer ? exports.aes_hmac_new() : 0;
|
|
9621
|
+
if (context) {
|
|
9622
|
+
const heap = getHeap(exports);
|
|
9623
|
+
heap.set(key, buffer);
|
|
9624
|
+
heap.set(authenticationKey, buffer + key.length);
|
|
9625
|
+
if (exports.aes_hmac_init(context, buffer, key.length, buffer + key.length, authenticationKey.length)) {
|
|
9626
|
+
exports.aes_hmac_end(context, 0);
|
|
9627
|
+
return 0;
|
|
9628
|
+
}
|
|
9629
|
+
}
|
|
9630
|
+
return context;
|
|
9631
|
+
}
|
|
9632
|
+
|
|
9633
|
+
function getHeap(exports) {
|
|
9634
|
+
return new Uint8Array(exports.memory.buffer);
|
|
9635
|
+
}
|
|
9636
|
+
|
|
9824
9637
|
/*
|
|
9825
9638
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
9826
9639
|
|
|
@@ -9882,11 +9695,13 @@ async function instantiateModule(wasmURI, baseURI) {
|
|
|
9882
9695
|
}
|
|
9883
9696
|
}
|
|
9884
9697
|
const wasmInstance = await WebAssembly.instantiate(arrayBuffer);
|
|
9698
|
+
setWasmExports$1(wasmInstance.instance.exports);
|
|
9885
9699
|
setWasmExports(wasmInstance.instance.exports);
|
|
9886
9700
|
}
|
|
9887
9701
|
|
|
9888
9702
|
function resetWasmModule() {
|
|
9889
9703
|
initializedModule = false;
|
|
9704
|
+
resetWasmExports$1();
|
|
9890
9705
|
resetWasmExports();
|
|
9891
9706
|
}
|
|
9892
9707
|
|
|
@@ -9932,6 +9747,7 @@ function arrayBufferFromDataURI(dataURI) {
|
|
|
9932
9747
|
|
|
9933
9748
|
let modulePromise;
|
|
9934
9749
|
|
|
9750
|
+
setAESEngine(createEngine);
|
|
9935
9751
|
configureWorker({
|
|
9936
9752
|
initModule: config => {
|
|
9937
9753
|
if (!modulePromise) {
|
|
@@ -10435,12 +10251,16 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
10435
10251
|
let directoryEntry = parent;
|
|
10436
10252
|
if (name) {
|
|
10437
10253
|
directoryEntry = parent.getChildByName(name);
|
|
10438
|
-
if (directoryEntry && !directoryEntry.directory) {
|
|
10254
|
+
if (directoryEntry && (!directoryEntry.directory || directoryEntry.data)) {
|
|
10439
10255
|
if (duplicates == DUPLICATES_KEEP_FIRST) {
|
|
10440
10256
|
continue;
|
|
10441
10257
|
} else if (duplicates == DUPLICATES_KEEP_LAST) {
|
|
10442
|
-
|
|
10443
|
-
|
|
10258
|
+
if (directoryEntry.directory) {
|
|
10259
|
+
directoryEntry.data = entry;
|
|
10260
|
+
} else {
|
|
10261
|
+
this.fs.remove(directoryEntry);
|
|
10262
|
+
directoryEntry = UNDEFINED_VALUE;
|
|
10263
|
+
}
|
|
10444
10264
|
} else {
|
|
10445
10265
|
throw new Error(ERR_DUPLICATE_IMPORTED_ENTRY);
|
|
10446
10266
|
}
|