single-file-core 1.5.91 → 1.5.92
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/core/helper.js +3 -1
- package/core/lib/sha.js +242 -0
- package/package.json +1 -1
package/core/helper.js
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import * as cssUnescape from "./../vendor/css-unescape.js";
|
|
25
|
+
import * as sha from "./lib/sha.js";
|
|
25
26
|
import * as hooksFrames from "./../processors/hooks/content/content-hooks-frames.js";
|
|
26
27
|
import * as infobar from "./infobar.js";
|
|
27
28
|
import {
|
|
@@ -793,7 +794,8 @@ function getContentSize(content) {
|
|
|
793
794
|
|
|
794
795
|
async function digest(algo, text) {
|
|
795
796
|
try {
|
|
796
|
-
const
|
|
797
|
+
const data = new TextEncoder("utf-8").encode(text);
|
|
798
|
+
const hash = globalThis.crypto && crypto.subtle ? await crypto.subtle.digest(algo, data) : sha.digest(algo, data);
|
|
797
799
|
return hex(hash);
|
|
798
800
|
// eslint-disable-next-line no-unused-vars
|
|
799
801
|
} catch (error) {
|
package/core/lib/sha.js
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2010-2026 Gildas Lormeau
|
|
3
|
+
* contact : gildas.lormeau <at> gmail.com
|
|
4
|
+
*
|
|
5
|
+
* This file is part of SingleFile.
|
|
6
|
+
*
|
|
7
|
+
* The code in this file is free software: you can redistribute it and/or
|
|
8
|
+
* modify it under the terms of the GNU Affero General Public License
|
|
9
|
+
* (GNU AGPL) as published by the Free Software Foundation, either version 3
|
|
10
|
+
* of the License, or (at your option) any later version.
|
|
11
|
+
*
|
|
12
|
+
* The code in this file is distributed in the hope that it will be useful,
|
|
13
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
|
|
15
|
+
* General Public License for more details.
|
|
16
|
+
*
|
|
17
|
+
* As additional permission under GNU AGPL version 3 section 7, you may
|
|
18
|
+
* distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
|
|
19
|
+
* AGPL normally required by section 4, provided you include this license
|
|
20
|
+
* notice and a URL through which recipients can access the Corresponding
|
|
21
|
+
* Source.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
const H1 = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
|
|
25
|
+
const H256 = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
|
|
26
|
+
const K256 = [
|
|
27
|
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
28
|
+
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
29
|
+
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
30
|
+
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
|
31
|
+
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
|
32
|
+
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
33
|
+
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
|
34
|
+
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
|
35
|
+
];
|
|
36
|
+
const H384 = [
|
|
37
|
+
0xcbbb9d5dc1059ed8n, 0x629a292a367cd507n, 0x9159015a3070dd17n, 0x152fecd8f70e5939n,
|
|
38
|
+
0x67332667ffc00b31n, 0x8eb44a8768581511n, 0xdb0c2e0d64f98fa7n, 0x47b5481dbefa4fa4n
|
|
39
|
+
];
|
|
40
|
+
const H512 = [
|
|
41
|
+
0x6a09e667f3bcc908n, 0xbb67ae8584caa73bn, 0x3c6ef372fe94f82bn, 0xa54ff53a5f1d36f1n,
|
|
42
|
+
0x510e527fade682d1n, 0x9b05688c2b3e6c1fn, 0x1f83d9abfb41bd6bn, 0x5be0cd19137e2179n
|
|
43
|
+
];
|
|
44
|
+
const K512 = [
|
|
45
|
+
0x428a2f98d728ae22n, 0x7137449123ef65cdn, 0xb5c0fbcfec4d3b2fn, 0xe9b5dba58189dbbcn,
|
|
46
|
+
0x3956c25bf348b538n, 0x59f111f1b605d019n, 0x923f82a4af194f9bn, 0xab1c5ed5da6d8118n,
|
|
47
|
+
0xd807aa98a3030242n, 0x12835b0145706fben, 0x243185be4ee4b28cn, 0x550c7dc3d5ffb4e2n,
|
|
48
|
+
0x72be5d74f27b896fn, 0x80deb1fe3b1696b1n, 0x9bdc06a725c71235n, 0xc19bf174cf692694n,
|
|
49
|
+
0xe49b69c19ef14ad2n, 0xefbe4786384f25e3n, 0x0fc19dc68b8cd5b5n, 0x240ca1cc77ac9c65n,
|
|
50
|
+
0x2de92c6f592b0275n, 0x4a7484aa6ea6e483n, 0x5cb0a9dcbd41fbd4n, 0x76f988da831153b5n,
|
|
51
|
+
0x983e5152ee66dfabn, 0xa831c66d2db43210n, 0xb00327c898fb213fn, 0xbf597fc7beef0ee4n,
|
|
52
|
+
0xc6e00bf33da88fc2n, 0xd5a79147930aa725n, 0x06ca6351e003826fn, 0x142929670a0e6e70n,
|
|
53
|
+
0x27b70a8546d22ffcn, 0x2e1b21385c26c926n, 0x4d2c6dfc5ac42aedn, 0x53380d139d95b3dfn,
|
|
54
|
+
0x650a73548baf63den, 0x766a0abb3c77b2a8n, 0x81c2c92e47edaee6n, 0x92722c851482353bn,
|
|
55
|
+
0xa2bfe8a14cf10364n, 0xa81a664bbc423001n, 0xc24b8b70d0f89791n, 0xc76c51a30654be30n,
|
|
56
|
+
0xd192e819d6ef5218n, 0xd69906245565a910n, 0xf40e35855771202an, 0x106aa07032bbd1b8n,
|
|
57
|
+
0x19a4c116b8d2d0c8n, 0x1e376c085141ab53n, 0x2748774cdf8eeb99n, 0x34b0bcb5e19b48a8n,
|
|
58
|
+
0x391c0cb3c5c95a63n, 0x4ed8aa4ae3418acbn, 0x5b9cca4f7763e373n, 0x682e6ff3d6b2b8a3n,
|
|
59
|
+
0x748f82ee5defb2fcn, 0x78a5636f43172f60n, 0x84c87814a1f0ab72n, 0x8cc702081a6439ecn,
|
|
60
|
+
0x90befffa23631e28n, 0xa4506cebde82bde9n, 0xbef9a3f7b2c67915n, 0xc67178f2e372532bn,
|
|
61
|
+
0xca273eceea26619cn, 0xd186b8c721c0c207n, 0xeada7dd6cde0eb1en, 0xf57d4f7fee6ed178n,
|
|
62
|
+
0x06f067aa72176fban, 0x0a637dc5a2c898a6n, 0x113f9804bef90daen, 0x1b710b35131c471bn,
|
|
63
|
+
0x28db77f523047d84n, 0x32caab7b40c72493n, 0x3c9ebe0a15c9bebcn, 0x431d67c49c100d4cn,
|
|
64
|
+
0x4cc5d4becb3e42b6n, 0x597f299cfc657e2an, 0x5fcb6fab3ad6faecn, 0x6c44198c4a475817n
|
|
65
|
+
];
|
|
66
|
+
const MASK_64 = 0xffffffffffffffffn;
|
|
67
|
+
|
|
68
|
+
export {
|
|
69
|
+
digest
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
function digest(algorithm, data) {
|
|
73
|
+
if (algorithm == "SHA-1") {
|
|
74
|
+
return digestSha1(data);
|
|
75
|
+
} else if (algorithm == "SHA-256") {
|
|
76
|
+
return digestSha256(data);
|
|
77
|
+
} else if (algorithm == "SHA-384") {
|
|
78
|
+
return digestSha512(data, H384, 6);
|
|
79
|
+
} else if (algorithm == "SHA-512") {
|
|
80
|
+
return digestSha512(data, H512, 8);
|
|
81
|
+
} else {
|
|
82
|
+
throw new Error("Unsupported algorithm: " + algorithm);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function digestSha1(data) {
|
|
87
|
+
const state = Int32Array.from(H1);
|
|
88
|
+
const schedule = new Int32Array(80);
|
|
89
|
+
const view = padMessage(data, 64);
|
|
90
|
+
for (let blockOffset = 0; blockOffset < view.byteLength; blockOffset += 64) {
|
|
91
|
+
for (let index = 0; index < 16; index++) {
|
|
92
|
+
schedule[index] = view.getUint32(blockOffset + index * 4);
|
|
93
|
+
}
|
|
94
|
+
for (let index = 16; index < 80; index++) {
|
|
95
|
+
const value = schedule[index - 3] ^ schedule[index - 8] ^ schedule[index - 14] ^ schedule[index - 16];
|
|
96
|
+
schedule[index] = (value << 1) | (value >>> 31);
|
|
97
|
+
}
|
|
98
|
+
let [a, b, c, d, e] = state;
|
|
99
|
+
for (let index = 0; index < 80; index++) {
|
|
100
|
+
let mix, constant;
|
|
101
|
+
if (index < 20) {
|
|
102
|
+
mix = (b & c) | (~b & d);
|
|
103
|
+
constant = 0x5a827999;
|
|
104
|
+
} else if (index < 40) {
|
|
105
|
+
mix = b ^ c ^ d;
|
|
106
|
+
constant = 0x6ed9eba1;
|
|
107
|
+
} else if (index < 60) {
|
|
108
|
+
mix = (b & c) | (b & d) | (c & d);
|
|
109
|
+
constant = 0x8f1bbcdc;
|
|
110
|
+
} else {
|
|
111
|
+
mix = b ^ c ^ d;
|
|
112
|
+
constant = 0xca62c1d6;
|
|
113
|
+
}
|
|
114
|
+
const value = (((a << 5) | (a >>> 27)) + mix + e + constant + schedule[index]) | 0;
|
|
115
|
+
e = d;
|
|
116
|
+
d = c;
|
|
117
|
+
c = (b << 30) | (b >>> 2);
|
|
118
|
+
b = a;
|
|
119
|
+
a = value;
|
|
120
|
+
}
|
|
121
|
+
state[0] += a;
|
|
122
|
+
state[1] += b;
|
|
123
|
+
state[2] += c;
|
|
124
|
+
state[3] += d;
|
|
125
|
+
state[4] += e;
|
|
126
|
+
}
|
|
127
|
+
return serializeState32(state);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function digestSha256(data) {
|
|
131
|
+
const state = Int32Array.from(H256);
|
|
132
|
+
const schedule = new Int32Array(64);
|
|
133
|
+
const view = padMessage(data, 64);
|
|
134
|
+
for (let blockOffset = 0; blockOffset < view.byteLength; blockOffset += 64) {
|
|
135
|
+
for (let index = 0; index < 16; index++) {
|
|
136
|
+
schedule[index] = view.getUint32(blockOffset + index * 4);
|
|
137
|
+
}
|
|
138
|
+
for (let index = 16; index < 64; index++) {
|
|
139
|
+
const value0 = schedule[index - 15];
|
|
140
|
+
const value1 = schedule[index - 2];
|
|
141
|
+
const sigma0 = rotateRight32(value0, 7) ^ rotateRight32(value0, 18) ^ (value0 >>> 3);
|
|
142
|
+
const sigma1 = rotateRight32(value1, 17) ^ rotateRight32(value1, 19) ^ (value1 >>> 10);
|
|
143
|
+
schedule[index] = schedule[index - 16] + sigma0 + schedule[index - 7] + sigma1;
|
|
144
|
+
}
|
|
145
|
+
let [a, b, c, d, e, f, g, h] = state;
|
|
146
|
+
for (let index = 0; index < 64; index++) {
|
|
147
|
+
const sum1 = rotateRight32(e, 6) ^ rotateRight32(e, 11) ^ rotateRight32(e, 25);
|
|
148
|
+
const choice = (e & f) ^ (~e & g);
|
|
149
|
+
const value1 = (h + sum1 + choice + K256[index] + schedule[index]) | 0;
|
|
150
|
+
const sum0 = rotateRight32(a, 2) ^ rotateRight32(a, 13) ^ rotateRight32(a, 22);
|
|
151
|
+
const majority = (a & b) ^ (a & c) ^ (b & c);
|
|
152
|
+
const value2 = (sum0 + majority) | 0;
|
|
153
|
+
h = g;
|
|
154
|
+
g = f;
|
|
155
|
+
f = e;
|
|
156
|
+
e = (d + value1) | 0;
|
|
157
|
+
d = c;
|
|
158
|
+
c = b;
|
|
159
|
+
b = a;
|
|
160
|
+
a = (value1 + value2) | 0;
|
|
161
|
+
}
|
|
162
|
+
state[0] += a;
|
|
163
|
+
state[1] += b;
|
|
164
|
+
state[2] += c;
|
|
165
|
+
state[3] += d;
|
|
166
|
+
state[4] += e;
|
|
167
|
+
state[5] += f;
|
|
168
|
+
state[6] += g;
|
|
169
|
+
state[7] += h;
|
|
170
|
+
}
|
|
171
|
+
return serializeState32(state);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function digestSha512(data, initialState, stateLength) {
|
|
175
|
+
const state = Array.from(initialState);
|
|
176
|
+
const schedule = new Array(80);
|
|
177
|
+
const view = padMessage(data, 128);
|
|
178
|
+
for (let blockOffset = 0; blockOffset < view.byteLength; blockOffset += 128) {
|
|
179
|
+
for (let index = 0; index < 16; index++) {
|
|
180
|
+
schedule[index] = (BigInt(view.getUint32(blockOffset + index * 8)) << 32n) | BigInt(view.getUint32(blockOffset + index * 8 + 4));
|
|
181
|
+
}
|
|
182
|
+
for (let index = 16; index < 80; index++) {
|
|
183
|
+
const value0 = schedule[index - 15];
|
|
184
|
+
const value1 = schedule[index - 2];
|
|
185
|
+
const sigma0 = rotateRight64(value0, 1n) ^ rotateRight64(value0, 8n) ^ (value0 >> 7n);
|
|
186
|
+
const sigma1 = rotateRight64(value1, 19n) ^ rotateRight64(value1, 61n) ^ (value1 >> 6n);
|
|
187
|
+
schedule[index] = (schedule[index - 16] + sigma0 + schedule[index - 7] + sigma1) & MASK_64;
|
|
188
|
+
}
|
|
189
|
+
let [a, b, c, d, e, f, g, h] = state;
|
|
190
|
+
for (let index = 0; index < 80; index++) {
|
|
191
|
+
const sum1 = rotateRight64(e, 14n) ^ rotateRight64(e, 18n) ^ rotateRight64(e, 41n);
|
|
192
|
+
const choice = (e & f) ^ (~e & g);
|
|
193
|
+
const value1 = (h + sum1 + choice + K512[index] + schedule[index]) & MASK_64;
|
|
194
|
+
const sum0 = rotateRight64(a, 28n) ^ rotateRight64(a, 34n) ^ rotateRight64(a, 39n);
|
|
195
|
+
const majority = (a & b) ^ (a & c) ^ (b & c);
|
|
196
|
+
const value2 = (sum0 + majority) & MASK_64;
|
|
197
|
+
h = g;
|
|
198
|
+
g = f;
|
|
199
|
+
f = e;
|
|
200
|
+
e = (d + value1) & MASK_64;
|
|
201
|
+
d = c;
|
|
202
|
+
c = b;
|
|
203
|
+
b = a;
|
|
204
|
+
a = (value1 + value2) & MASK_64;
|
|
205
|
+
}
|
|
206
|
+
const values = [a, b, c, d, e, f, g, h];
|
|
207
|
+
values.forEach((value, index) => state[index] = (state[index] + value) & MASK_64);
|
|
208
|
+
}
|
|
209
|
+
const buffer = new ArrayBuffer(stateLength * 8);
|
|
210
|
+
const outputView = new DataView(buffer);
|
|
211
|
+
for (let index = 0; index < stateLength; index++) {
|
|
212
|
+
outputView.setUint32(index * 8, Number(state[index] >> 32n));
|
|
213
|
+
outputView.setUint32(index * 8 + 4, Number(state[index] & 0xffffffffn));
|
|
214
|
+
}
|
|
215
|
+
return buffer;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function padMessage(data, blockLength) {
|
|
219
|
+
const paddedLength = Math.ceil((data.length + 1 + blockLength / 8) / blockLength) * blockLength;
|
|
220
|
+
const padded = new Uint8Array(paddedLength);
|
|
221
|
+
padded.set(data);
|
|
222
|
+
padded[data.length] = 0x80;
|
|
223
|
+
const view = new DataView(padded.buffer);
|
|
224
|
+
view.setUint32(paddedLength - 8, Math.floor(data.length / 0x20000000));
|
|
225
|
+
view.setUint32(paddedLength - 4, data.length << 3);
|
|
226
|
+
return view;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function rotateRight32(value, count) {
|
|
230
|
+
return (value >>> count) | (value << (32 - count));
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function rotateRight64(value, count) {
|
|
234
|
+
return ((value >> count) | (value << (64n - count))) & MASK_64;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function serializeState32(state) {
|
|
238
|
+
const buffer = new ArrayBuffer(state.length * 4);
|
|
239
|
+
const view = new DataView(buffer);
|
|
240
|
+
state.forEach((value, index) => view.setUint32(index * 4, value));
|
|
241
|
+
return buffer;
|
|
242
|
+
}
|