@protontech/openpgp 6.1.1-patch.4 → 6.2.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/README.md +13 -2
- package/dist/lightweight/argon2id.min.mjs +2 -2
- package/dist/lightweight/argon2id.min.mjs.map +1 -1
- package/dist/lightweight/argon2id.mjs +4 -4
- package/dist/lightweight/legacy_ciphers.min.mjs +1 -1
- package/dist/lightweight/legacy_ciphers.min.mjs.map +1 -1
- package/dist/lightweight/legacy_ciphers.mjs +10 -10
- package/dist/lightweight/nacl-fast.min.mjs +3 -0
- package/dist/lightweight/nacl-fast.min.mjs.map +1 -0
- package/dist/lightweight/nacl-fast.mjs +1382 -0
- package/dist/lightweight/noble_curves.min.mjs +11 -12
- package/dist/lightweight/noble_curves.min.mjs.map +1 -1
- package/dist/lightweight/noble_curves.mjs +2175 -1752
- package/dist/lightweight/noble_hashes.min.mjs +2 -2
- package/dist/lightweight/noble_hashes.min.mjs.map +1 -1
- package/dist/lightweight/noble_hashes.mjs +80 -51
- package/dist/lightweight/noble_post_quantum.min.mjs +3 -4
- package/dist/lightweight/noble_post_quantum.min.mjs.map +1 -1
- package/dist/lightweight/noble_post_quantum.mjs +352 -10
- package/dist/lightweight/openpgp.min.mjs +3 -4
- package/dist/lightweight/openpgp.min.mjs.map +1 -1
- package/dist/lightweight/openpgp.mjs +998 -2820
- package/dist/lightweight/seek-bzip.min.mjs +2 -2
- package/dist/lightweight/seek-bzip.min.mjs.map +1 -1
- package/dist/lightweight/seek-bzip.mjs +780 -746
- package/dist/lightweight/sha512.min.mjs +4 -2
- package/dist/lightweight/sha512.min.mjs.map +1 -1
- package/dist/lightweight/sha512.mjs +672 -130
- package/dist/node/openpgp.cjs +10685 -10141
- package/dist/node/openpgp.min.cjs +14 -17
- package/dist/node/openpgp.min.cjs.map +1 -1
- package/dist/node/openpgp.min.mjs +14 -17
- package/dist/node/openpgp.min.mjs.map +1 -1
- package/dist/node/openpgp.mjs +10685 -10140
- package/dist/openpgp.js +11728 -11188
- package/dist/openpgp.min.js +14 -17
- package/dist/openpgp.min.js.map +1 -1
- package/dist/openpgp.min.mjs +14 -17
- package/dist/openpgp.min.mjs.map +1 -1
- package/dist/openpgp.mjs +11728 -11188
- package/{src → dist/types}/config/config.d.ts +1 -21
- package/{openpgp.d.ts → dist/types/index.d.ts} +94 -76
- package/dist/types/packet/grammar.d.ts +33 -0
- package/package.json +40 -39
- package/dist/lightweight/sha3.min.mjs +0 -4
- package/dist/lightweight/sha3.min.mjs.map +0 -1
- package/dist/lightweight/sha3.mjs +0 -401
- /package/{src → dist/types}/config/index.d.ts +0 -0
- /package/{src → dist/types}/enums.d.ts +0 -0
|
@@ -1,11 +1,231 @@
|
|
|
1
|
-
/*! OpenPGP.js v6.
|
|
1
|
+
/*! OpenPGP.js v6.2.1 - 2025-08-28 - this is LGPL licensed code, see LICENSE/our website https://openpgpjs.org/ for more information. */
|
|
2
2
|
const globalThis = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const crypto = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Utilities for hex, bytes, CSPRNG.
|
|
8
|
+
* @module
|
|
8
9
|
*/
|
|
10
|
+
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
11
|
+
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
|
12
|
+
// node.js versions earlier than v19 don't declare it in global scope.
|
|
13
|
+
// For node.js, package.json#exports field mapping rewrites import
|
|
14
|
+
// from `crypto` to `cryptoNode`, which imports native module.
|
|
15
|
+
// Makes the utils un-importable in browsers without a bundler.
|
|
16
|
+
// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
|
|
17
|
+
/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
|
|
18
|
+
function isBytes(a) {
|
|
19
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
|
20
|
+
}
|
|
21
|
+
/** Asserts something is positive integer. */
|
|
22
|
+
function anumber(n) {
|
|
23
|
+
if (!Number.isSafeInteger(n) || n < 0)
|
|
24
|
+
throw new Error('positive integer expected, got ' + n);
|
|
25
|
+
}
|
|
26
|
+
/** Asserts something is Uint8Array. */
|
|
27
|
+
function abytes(b, ...lengths) {
|
|
28
|
+
if (!isBytes(b))
|
|
29
|
+
throw new Error('Uint8Array expected');
|
|
30
|
+
if (lengths.length > 0 && !lengths.includes(b.length))
|
|
31
|
+
throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
|
|
32
|
+
}
|
|
33
|
+
/** Asserts something is hash */
|
|
34
|
+
function ahash(h) {
|
|
35
|
+
if (typeof h !== 'function' || typeof h.create !== 'function')
|
|
36
|
+
throw new Error('Hash should be wrapped by utils.createHasher');
|
|
37
|
+
anumber(h.outputLen);
|
|
38
|
+
anumber(h.blockLen);
|
|
39
|
+
}
|
|
40
|
+
/** Asserts a hash instance has not been destroyed / finished */
|
|
41
|
+
function aexists(instance, checkFinished = true) {
|
|
42
|
+
if (instance.destroyed)
|
|
43
|
+
throw new Error('Hash instance has been destroyed');
|
|
44
|
+
if (checkFinished && instance.finished)
|
|
45
|
+
throw new Error('Hash#digest() has already been called');
|
|
46
|
+
}
|
|
47
|
+
/** Asserts output is properly-sized byte array */
|
|
48
|
+
function aoutput(out, instance) {
|
|
49
|
+
abytes(out);
|
|
50
|
+
const min = instance.outputLen;
|
|
51
|
+
if (out.length < min) {
|
|
52
|
+
throw new Error('digestInto() expects output buffer of length at least ' + min);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** Cast u8 / u16 / u32 to u32. */
|
|
56
|
+
function u32(arr) {
|
|
57
|
+
return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
|
|
58
|
+
}
|
|
59
|
+
/** Zeroize a byte array. Warning: JS provides no guarantees. */
|
|
60
|
+
function clean(...arrays) {
|
|
61
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
62
|
+
arrays[i].fill(0);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Create DataView of an array for easy byte-level manipulation. */
|
|
66
|
+
function createView(arr) {
|
|
67
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
68
|
+
}
|
|
69
|
+
/** The rotate right (circular right shift) operation for uint32 */
|
|
70
|
+
function rotr(word, shift) {
|
|
71
|
+
return (word << (32 - shift)) | (word >>> shift);
|
|
72
|
+
}
|
|
73
|
+
/** The rotate left (circular left shift) operation for uint32 */
|
|
74
|
+
function rotl(word, shift) {
|
|
75
|
+
return (word << shift) | ((word >>> (32 - shift)) >>> 0);
|
|
76
|
+
}
|
|
77
|
+
/** Is current platform little-endian? Most are. Big-Endian platform: IBM */
|
|
78
|
+
const isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();
|
|
79
|
+
/** The byte swap operation for uint32 */
|
|
80
|
+
function byteSwap(word) {
|
|
81
|
+
return (((word << 24) & 0xff000000) |
|
|
82
|
+
((word << 8) & 0xff0000) |
|
|
83
|
+
((word >>> 8) & 0xff00) |
|
|
84
|
+
((word >>> 24) & 0xff));
|
|
85
|
+
}
|
|
86
|
+
/** In place byte swap for Uint32Array */
|
|
87
|
+
function byteSwap32(arr) {
|
|
88
|
+
for (let i = 0; i < arr.length; i++) {
|
|
89
|
+
arr[i] = byteSwap(arr[i]);
|
|
90
|
+
}
|
|
91
|
+
return arr;
|
|
92
|
+
}
|
|
93
|
+
const swap32IfBE = isLE
|
|
94
|
+
? (u) => u
|
|
95
|
+
: byteSwap32;
|
|
96
|
+
// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
|
|
97
|
+
const hasHexBuiltin = /* @__PURE__ */ (() =>
|
|
98
|
+
// @ts-ignore
|
|
99
|
+
typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();
|
|
100
|
+
// Array where index 0xf0 (240) is mapped to string 'f0'
|
|
101
|
+
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
|
102
|
+
/**
|
|
103
|
+
* Convert byte array to hex string. Uses built-in function, when available.
|
|
104
|
+
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
|
|
105
|
+
*/
|
|
106
|
+
function bytesToHex(bytes) {
|
|
107
|
+
abytes(bytes);
|
|
108
|
+
// @ts-ignore
|
|
109
|
+
if (hasHexBuiltin)
|
|
110
|
+
return bytes.toHex();
|
|
111
|
+
// pre-caching improves the speed 6x
|
|
112
|
+
let hex = '';
|
|
113
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
114
|
+
hex += hexes[bytes[i]];
|
|
115
|
+
}
|
|
116
|
+
return hex;
|
|
117
|
+
}
|
|
118
|
+
// We use optimized technique to convert hex string to byte array
|
|
119
|
+
const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
|
120
|
+
function asciiToBase16(ch) {
|
|
121
|
+
if (ch >= asciis._0 && ch <= asciis._9)
|
|
122
|
+
return ch - asciis._0; // '2' => 50-48
|
|
123
|
+
if (ch >= asciis.A && ch <= asciis.F)
|
|
124
|
+
return ch - (asciis.A - 10); // 'B' => 66-(65-10)
|
|
125
|
+
if (ch >= asciis.a && ch <= asciis.f)
|
|
126
|
+
return ch - (asciis.a - 10); // 'b' => 98-(97-10)
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Convert hex string to byte array. Uses built-in function, when available.
|
|
131
|
+
* @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
|
|
132
|
+
*/
|
|
133
|
+
function hexToBytes(hex) {
|
|
134
|
+
if (typeof hex !== 'string')
|
|
135
|
+
throw new Error('hex string expected, got ' + typeof hex);
|
|
136
|
+
// @ts-ignore
|
|
137
|
+
if (hasHexBuiltin)
|
|
138
|
+
return Uint8Array.fromHex(hex);
|
|
139
|
+
const hl = hex.length;
|
|
140
|
+
const al = hl / 2;
|
|
141
|
+
if (hl % 2)
|
|
142
|
+
throw new Error('hex string expected, got unpadded hex of length ' + hl);
|
|
143
|
+
const array = new Uint8Array(al);
|
|
144
|
+
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
|
145
|
+
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
|
146
|
+
const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
|
|
147
|
+
if (n1 === undefined || n2 === undefined) {
|
|
148
|
+
const char = hex[hi] + hex[hi + 1];
|
|
149
|
+
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
|
150
|
+
}
|
|
151
|
+
array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163
|
|
152
|
+
}
|
|
153
|
+
return array;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Converts string to bytes using UTF8 encoding.
|
|
157
|
+
* @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])
|
|
158
|
+
*/
|
|
159
|
+
function utf8ToBytes(str) {
|
|
160
|
+
if (typeof str !== 'string')
|
|
161
|
+
throw new Error('string expected');
|
|
162
|
+
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Normalizes (non-hex) string or Uint8Array to Uint8Array.
|
|
166
|
+
* Warning: when Uint8Array is passed, it would NOT get copied.
|
|
167
|
+
* Keep in mind for future mutable operations.
|
|
168
|
+
*/
|
|
169
|
+
function toBytes(data) {
|
|
170
|
+
if (typeof data === 'string')
|
|
171
|
+
data = utf8ToBytes(data);
|
|
172
|
+
abytes(data);
|
|
173
|
+
return data;
|
|
174
|
+
}
|
|
175
|
+
/** Copies several Uint8Arrays into one. */
|
|
176
|
+
function concatBytes(...arrays) {
|
|
177
|
+
let sum = 0;
|
|
178
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
179
|
+
const a = arrays[i];
|
|
180
|
+
abytes(a);
|
|
181
|
+
sum += a.length;
|
|
182
|
+
}
|
|
183
|
+
const res = new Uint8Array(sum);
|
|
184
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
185
|
+
const a = arrays[i];
|
|
186
|
+
res.set(a, pad);
|
|
187
|
+
pad += a.length;
|
|
188
|
+
}
|
|
189
|
+
return res;
|
|
190
|
+
}
|
|
191
|
+
/** For runtime check if class implements interface */
|
|
192
|
+
class Hash {
|
|
193
|
+
}
|
|
194
|
+
/** Wraps hash function, creating an interface on top of it */
|
|
195
|
+
function createHasher(hashCons) {
|
|
196
|
+
const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
|
|
197
|
+
const tmp = hashCons();
|
|
198
|
+
hashC.outputLen = tmp.outputLen;
|
|
199
|
+
hashC.blockLen = tmp.blockLen;
|
|
200
|
+
hashC.create = () => hashCons();
|
|
201
|
+
return hashC;
|
|
202
|
+
}
|
|
203
|
+
function createXOFer(hashCons) {
|
|
204
|
+
const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();
|
|
205
|
+
const tmp = hashCons({});
|
|
206
|
+
hashC.outputLen = tmp.outputLen;
|
|
207
|
+
hashC.blockLen = tmp.blockLen;
|
|
208
|
+
hashC.create = (opts) => hashCons(opts);
|
|
209
|
+
return hashC;
|
|
210
|
+
}
|
|
211
|
+
const wrapConstructor = createHasher;
|
|
212
|
+
/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */
|
|
213
|
+
function randomBytes(bytesLength = 32) {
|
|
214
|
+
if (crypto && typeof crypto.getRandomValues === 'function') {
|
|
215
|
+
return crypto.getRandomValues(new Uint8Array(bytesLength));
|
|
216
|
+
}
|
|
217
|
+
// Legacy Node.js compatibility
|
|
218
|
+
if (crypto && typeof crypto.randomBytes === 'function') {
|
|
219
|
+
return Uint8Array.from(crypto.randomBytes(bytesLength));
|
|
220
|
+
}
|
|
221
|
+
throw new Error('crypto.getRandomValues must be defined');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Internal Merkle-Damgard hash utils.
|
|
226
|
+
* @module
|
|
227
|
+
*/
|
|
228
|
+
/** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */
|
|
9
229
|
function setBigUint64(view, byteOffset, value, isLE) {
|
|
10
230
|
if (typeof view.setBigUint64 === 'function')
|
|
11
231
|
return view.setBigUint64(byteOffset, value, isLE);
|
|
@@ -18,14 +238,14 @@ function setBigUint64(view, byteOffset, value, isLE) {
|
|
|
18
238
|
view.setUint32(byteOffset + h, wh, isLE);
|
|
19
239
|
view.setUint32(byteOffset + l, wl, isLE);
|
|
20
240
|
}
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
241
|
+
/** Choice: a ? b : c */
|
|
242
|
+
function Chi(a, b, c) {
|
|
243
|
+
return (a & b) ^ (~a & c);
|
|
244
|
+
}
|
|
245
|
+
/** Majority function, true if any two inputs is true. */
|
|
246
|
+
function Maj(a, b, c) {
|
|
247
|
+
return (a & b) ^ (a & c) ^ (b & c);
|
|
248
|
+
}
|
|
29
249
|
/**
|
|
30
250
|
* Merkle-Damgard hash construction base class.
|
|
31
251
|
* Could be used to create MD5, RIPEMD, SHA1, SHA2.
|
|
@@ -33,21 +253,22 @@ const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
|
|
|
33
253
|
class HashMD extends Hash {
|
|
34
254
|
constructor(blockLen, outputLen, padOffset, isLE) {
|
|
35
255
|
super();
|
|
36
|
-
this.blockLen = blockLen;
|
|
37
|
-
this.outputLen = outputLen;
|
|
38
|
-
this.padOffset = padOffset;
|
|
39
|
-
this.isLE = isLE;
|
|
40
256
|
this.finished = false;
|
|
41
257
|
this.length = 0;
|
|
42
258
|
this.pos = 0;
|
|
43
259
|
this.destroyed = false;
|
|
260
|
+
this.blockLen = blockLen;
|
|
261
|
+
this.outputLen = outputLen;
|
|
262
|
+
this.padOffset = padOffset;
|
|
263
|
+
this.isLE = isLE;
|
|
44
264
|
this.buffer = new Uint8Array(blockLen);
|
|
45
265
|
this.view = createView(this.buffer);
|
|
46
266
|
}
|
|
47
267
|
update(data) {
|
|
48
268
|
aexists(this);
|
|
49
|
-
const { view, buffer, blockLen } = this;
|
|
50
269
|
data = toBytes(data);
|
|
270
|
+
abytes(data);
|
|
271
|
+
const { view, buffer, blockLen } = this;
|
|
51
272
|
const len = data.length;
|
|
52
273
|
for (let pos = 0; pos < len;) {
|
|
53
274
|
const take = Math.min(blockLen - this.pos, len - pos);
|
|
@@ -81,7 +302,7 @@ class HashMD extends Hash {
|
|
|
81
302
|
let { pos } = this;
|
|
82
303
|
// append the bit '1' to the message
|
|
83
304
|
buffer[pos++] = 0b10000000;
|
|
84
|
-
this.buffer.subarray(pos)
|
|
305
|
+
clean(this.buffer.subarray(pos));
|
|
85
306
|
// we have less than padOffset left in buffer, so we cannot put length in
|
|
86
307
|
// current block, need process it and pad again
|
|
87
308
|
if (this.padOffset > blockLen - pos) {
|
|
@@ -119,22 +340,105 @@ class HashMD extends Hash {
|
|
|
119
340
|
to || (to = new this.constructor());
|
|
120
341
|
to.set(...this.get());
|
|
121
342
|
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
343
|
+
to.destroyed = destroyed;
|
|
344
|
+
to.finished = finished;
|
|
122
345
|
to.length = length;
|
|
123
346
|
to.pos = pos;
|
|
124
|
-
to.finished = finished;
|
|
125
|
-
to.destroyed = destroyed;
|
|
126
347
|
if (length % blockLen)
|
|
127
348
|
to.buffer.set(buffer);
|
|
128
349
|
return to;
|
|
129
350
|
}
|
|
351
|
+
clone() {
|
|
352
|
+
return this._cloneInto();
|
|
353
|
+
}
|
|
130
354
|
}
|
|
355
|
+
/**
|
|
356
|
+
* Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.
|
|
357
|
+
* Check out `test/misc/sha2-gen-iv.js` for recomputation guide.
|
|
358
|
+
*/
|
|
359
|
+
/** Initial SHA256 state. Bits 0..32 of frac part of sqrt of primes 2..19 */
|
|
360
|
+
const SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
|
361
|
+
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
|
|
362
|
+
]);
|
|
363
|
+
/** Initial SHA224 state. Bits 32..64 of frac part of sqrt of primes 23..53 */
|
|
364
|
+
const SHA224_IV = /* @__PURE__ */ Uint32Array.from([
|
|
365
|
+
0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,
|
|
366
|
+
]);
|
|
367
|
+
/** Initial SHA384 state. Bits 0..64 of frac part of sqrt of primes 23..53 */
|
|
368
|
+
const SHA384_IV = /* @__PURE__ */ Uint32Array.from([
|
|
369
|
+
0xcbbb9d5d, 0xc1059ed8, 0x629a292a, 0x367cd507, 0x9159015a, 0x3070dd17, 0x152fecd8, 0xf70e5939,
|
|
370
|
+
0x67332667, 0xffc00b31, 0x8eb44a87, 0x68581511, 0xdb0c2e0d, 0x64f98fa7, 0x47b5481d, 0xbefa4fa4,
|
|
371
|
+
]);
|
|
372
|
+
/** Initial SHA512 state. Bits 0..64 of frac part of sqrt of primes 2..19 */
|
|
373
|
+
const SHA512_IV = /* @__PURE__ */ Uint32Array.from([
|
|
374
|
+
0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,
|
|
375
|
+
0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,
|
|
376
|
+
]);
|
|
131
377
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
378
|
+
/**
|
|
379
|
+
* Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
|
|
380
|
+
* @todo re-check https://issues.chromium.org/issues/42212588
|
|
381
|
+
* @module
|
|
382
|
+
*/
|
|
383
|
+
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
|
384
|
+
const _32n = /* @__PURE__ */ BigInt(32);
|
|
385
|
+
function fromBig(n, le = false) {
|
|
386
|
+
if (le)
|
|
387
|
+
return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
|
|
388
|
+
return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
|
389
|
+
}
|
|
390
|
+
function split(lst, le = false) {
|
|
391
|
+
const len = lst.length;
|
|
392
|
+
let Ah = new Uint32Array(len);
|
|
393
|
+
let Al = new Uint32Array(len);
|
|
394
|
+
for (let i = 0; i < len; i++) {
|
|
395
|
+
const { h, l } = fromBig(lst[i], le);
|
|
396
|
+
[Ah[i], Al[i]] = [h, l];
|
|
397
|
+
}
|
|
398
|
+
return [Ah, Al];
|
|
399
|
+
}
|
|
400
|
+
// for Shift in [0, 32)
|
|
401
|
+
const shrSH = (h, _l, s) => h >>> s;
|
|
402
|
+
const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
|
403
|
+
// Right rotate for Shift in [1, 32)
|
|
404
|
+
const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
|
|
405
|
+
const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
|
406
|
+
// Right rotate for Shift in (32, 64), NOTE: 32 is special case.
|
|
407
|
+
const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
|
|
408
|
+
const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
|
|
409
|
+
// Left rotate for Shift in [1, 32)
|
|
410
|
+
const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s));
|
|
411
|
+
const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s));
|
|
412
|
+
// Left rotate for Shift in (32, 64), NOTE: 32 is special case.
|
|
413
|
+
const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s));
|
|
414
|
+
const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s));
|
|
415
|
+
// JS uses 32-bit signed integers for bitwise operations which means we cannot
|
|
416
|
+
// simple take carry out of low bit sum by shift, we need to use division.
|
|
417
|
+
function add(Ah, Al, Bh, Bl) {
|
|
418
|
+
const l = (Al >>> 0) + (Bl >>> 0);
|
|
419
|
+
return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
|
|
420
|
+
}
|
|
421
|
+
// Addition with more than 2 elements
|
|
422
|
+
const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
|
423
|
+
const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
|
|
424
|
+
const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
|
425
|
+
const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
|
|
426
|
+
const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
|
427
|
+
const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.
|
|
431
|
+
* SHA256 is the fastest hash implementable in JS, even faster than Blake3.
|
|
432
|
+
* Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
|
|
433
|
+
* [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
|
434
|
+
* @module
|
|
435
|
+
*/
|
|
436
|
+
/**
|
|
437
|
+
* Round constants:
|
|
438
|
+
* First 32 bits of fractional parts of the cube roots of the first 64 primes 2..311)
|
|
439
|
+
*/
|
|
136
440
|
// prettier-ignore
|
|
137
|
-
const SHA256_K = /* @__PURE__ */
|
|
441
|
+
const SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
138
442
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
139
443
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
140
444
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
@@ -144,18 +448,11 @@ const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
|
|
144
448
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
|
145
449
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
|
146
450
|
]);
|
|
147
|
-
|
|
148
|
-
// first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19
|
|
149
|
-
// prettier-ignore
|
|
150
|
-
const SHA256_IV = /* @__PURE__ */ new Uint32Array([
|
|
151
|
-
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
|
152
|
-
]);
|
|
153
|
-
// Temporary buffer, not used to store anything between runs
|
|
154
|
-
// Named this way because it matches specification.
|
|
451
|
+
/** Reusable temporary buffer. "W" comes straight from spec. */
|
|
155
452
|
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
|
156
453
|
class SHA256 extends HashMD {
|
|
157
|
-
constructor() {
|
|
158
|
-
super(64,
|
|
454
|
+
constructor(outputLen = 32) {
|
|
455
|
+
super(64, outputLen, 8, false);
|
|
159
456
|
// We cannot use array here since array allows indexing by variable
|
|
160
457
|
// which means optimizer/compiler cannot use registers.
|
|
161
458
|
this.A = SHA256_IV[0] | 0;
|
|
@@ -221,41 +518,31 @@ class SHA256 extends HashMD {
|
|
|
221
518
|
this.set(A, B, C, D, E, F, G, H);
|
|
222
519
|
}
|
|
223
520
|
roundClean() {
|
|
224
|
-
SHA256_W
|
|
521
|
+
clean(SHA256_W);
|
|
225
522
|
}
|
|
226
523
|
destroy() {
|
|
227
524
|
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
|
228
|
-
this.buffer
|
|
525
|
+
clean(this.buffer);
|
|
229
526
|
}
|
|
230
527
|
}
|
|
231
|
-
// Constants from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
|
232
528
|
class SHA224 extends SHA256 {
|
|
233
529
|
constructor() {
|
|
234
|
-
super();
|
|
235
|
-
this.A =
|
|
236
|
-
this.B =
|
|
237
|
-
this.C =
|
|
238
|
-
this.D =
|
|
239
|
-
this.E =
|
|
240
|
-
this.F =
|
|
241
|
-
this.G =
|
|
242
|
-
this.H =
|
|
243
|
-
this.outputLen = 28;
|
|
530
|
+
super(28);
|
|
531
|
+
this.A = SHA224_IV[0] | 0;
|
|
532
|
+
this.B = SHA224_IV[1] | 0;
|
|
533
|
+
this.C = SHA224_IV[2] | 0;
|
|
534
|
+
this.D = SHA224_IV[3] | 0;
|
|
535
|
+
this.E = SHA224_IV[4] | 0;
|
|
536
|
+
this.F = SHA224_IV[5] | 0;
|
|
537
|
+
this.G = SHA224_IV[6] | 0;
|
|
538
|
+
this.H = SHA224_IV[7] | 0;
|
|
244
539
|
}
|
|
245
540
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
*/
|
|
250
|
-
const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
|
|
251
|
-
/**
|
|
252
|
-
* SHA2-224 hash function
|
|
253
|
-
*/
|
|
254
|
-
const sha224 = /* @__PURE__ */ wrapConstructor(() => new SHA224());
|
|
255
|
-
|
|
256
|
-
// Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
|
|
541
|
+
// SHA2-512 is slower than sha256 in js because u64 operations are slow.
|
|
542
|
+
// Round contants
|
|
543
|
+
// First 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409
|
|
257
544
|
// prettier-ignore
|
|
258
|
-
const
|
|
545
|
+
const K512 = /* @__PURE__ */ (() => split([
|
|
259
546
|
'0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',
|
|
260
547
|
'0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',
|
|
261
548
|
'0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',
|
|
@@ -277,32 +564,33 @@ const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64.split([
|
|
|
277
564
|
'0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',
|
|
278
565
|
'0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'
|
|
279
566
|
].map(n => BigInt(n))))();
|
|
280
|
-
|
|
567
|
+
const SHA512_Kh = /* @__PURE__ */ (() => K512[0])();
|
|
568
|
+
const SHA512_Kl = /* @__PURE__ */ (() => K512[1])();
|
|
569
|
+
// Reusable temporary buffers
|
|
281
570
|
const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
|
|
282
571
|
const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
|
|
283
572
|
class SHA512 extends HashMD {
|
|
284
|
-
constructor() {
|
|
285
|
-
super(128,
|
|
286
|
-
// We cannot use array here since array allows indexing by variable
|
|
287
|
-
//
|
|
288
|
-
// Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
|
|
573
|
+
constructor(outputLen = 64) {
|
|
574
|
+
super(128, outputLen, 16, false);
|
|
575
|
+
// We cannot use array here since array allows indexing by variable
|
|
576
|
+
// which means optimizer/compiler cannot use registers.
|
|
289
577
|
// h -- high 32 bits, l -- low 32 bits
|
|
290
|
-
this.Ah =
|
|
291
|
-
this.Al =
|
|
292
|
-
this.Bh =
|
|
293
|
-
this.Bl =
|
|
294
|
-
this.Ch =
|
|
295
|
-
this.Cl =
|
|
296
|
-
this.Dh =
|
|
297
|
-
this.Dl =
|
|
298
|
-
this.Eh =
|
|
299
|
-
this.El =
|
|
300
|
-
this.Fh =
|
|
301
|
-
this.Fl =
|
|
302
|
-
this.Gh =
|
|
303
|
-
this.Gl =
|
|
304
|
-
this.Hh =
|
|
305
|
-
this.Hl =
|
|
578
|
+
this.Ah = SHA512_IV[0] | 0;
|
|
579
|
+
this.Al = SHA512_IV[1] | 0;
|
|
580
|
+
this.Bh = SHA512_IV[2] | 0;
|
|
581
|
+
this.Bl = SHA512_IV[3] | 0;
|
|
582
|
+
this.Ch = SHA512_IV[4] | 0;
|
|
583
|
+
this.Cl = SHA512_IV[5] | 0;
|
|
584
|
+
this.Dh = SHA512_IV[6] | 0;
|
|
585
|
+
this.Dl = SHA512_IV[7] | 0;
|
|
586
|
+
this.Eh = SHA512_IV[8] | 0;
|
|
587
|
+
this.El = SHA512_IV[9] | 0;
|
|
588
|
+
this.Fh = SHA512_IV[10] | 0;
|
|
589
|
+
this.Fl = SHA512_IV[11] | 0;
|
|
590
|
+
this.Gh = SHA512_IV[12] | 0;
|
|
591
|
+
this.Gl = SHA512_IV[13] | 0;
|
|
592
|
+
this.Hh = SHA512_IV[14] | 0;
|
|
593
|
+
this.Hl = SHA512_IV[15] | 0;
|
|
306
594
|
}
|
|
307
595
|
// prettier-ignore
|
|
308
596
|
get() {
|
|
@@ -338,16 +626,16 @@ class SHA512 extends HashMD {
|
|
|
338
626
|
// s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)
|
|
339
627
|
const W15h = SHA512_W_H[i - 15] | 0;
|
|
340
628
|
const W15l = SHA512_W_L[i - 15] | 0;
|
|
341
|
-
const s0h =
|
|
342
|
-
const s0l =
|
|
629
|
+
const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7);
|
|
630
|
+
const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7);
|
|
343
631
|
// s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)
|
|
344
632
|
const W2h = SHA512_W_H[i - 2] | 0;
|
|
345
633
|
const W2l = SHA512_W_L[i - 2] | 0;
|
|
346
|
-
const s1h =
|
|
347
|
-
const s1l =
|
|
634
|
+
const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
|
|
635
|
+
const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
|
|
348
636
|
// SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];
|
|
349
|
-
const SUMl =
|
|
350
|
-
const SUMh =
|
|
637
|
+
const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
|
|
638
|
+
const SUMh = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
|
|
351
639
|
SHA512_W_H[i] = SUMh | 0;
|
|
352
640
|
SHA512_W_L[i] = SUMl | 0;
|
|
353
641
|
}
|
|
@@ -355,19 +643,19 @@ class SHA512 extends HashMD {
|
|
|
355
643
|
// Compression function main loop, 80 rounds
|
|
356
644
|
for (let i = 0; i < 80; i++) {
|
|
357
645
|
// S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)
|
|
358
|
-
const sigma1h =
|
|
359
|
-
const sigma1l =
|
|
646
|
+
const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41);
|
|
647
|
+
const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41);
|
|
360
648
|
//const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
|
|
361
649
|
const CHIh = (Eh & Fh) ^ (~Eh & Gh);
|
|
362
650
|
const CHIl = (El & Fl) ^ (~El & Gl);
|
|
363
651
|
// T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]
|
|
364
652
|
// prettier-ignore
|
|
365
|
-
const T1ll =
|
|
366
|
-
const T1h =
|
|
653
|
+
const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
|
|
654
|
+
const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
|
|
367
655
|
const T1l = T1ll | 0;
|
|
368
656
|
// S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)
|
|
369
|
-
const sigma0h =
|
|
370
|
-
const sigma0l =
|
|
657
|
+
const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39);
|
|
658
|
+
const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39);
|
|
371
659
|
const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);
|
|
372
660
|
const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);
|
|
373
661
|
Hh = Gh | 0;
|
|
@@ -376,61 +664,315 @@ class SHA512 extends HashMD {
|
|
|
376
664
|
Gl = Fl | 0;
|
|
377
665
|
Fh = Eh | 0;
|
|
378
666
|
Fl = El | 0;
|
|
379
|
-
({ h: Eh, l: El } =
|
|
667
|
+
({ h: Eh, l: El } = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
|
|
380
668
|
Dh = Ch | 0;
|
|
381
669
|
Dl = Cl | 0;
|
|
382
670
|
Ch = Bh | 0;
|
|
383
671
|
Cl = Bl | 0;
|
|
384
672
|
Bh = Ah | 0;
|
|
385
673
|
Bl = Al | 0;
|
|
386
|
-
const All =
|
|
387
|
-
Ah =
|
|
674
|
+
const All = add3L(T1l, sigma0l, MAJl);
|
|
675
|
+
Ah = add3H(All, T1h, sigma0h, MAJh);
|
|
388
676
|
Al = All | 0;
|
|
389
677
|
}
|
|
390
678
|
// Add the compressed chunk to the current hash value
|
|
391
|
-
({ h: Ah, l: Al } =
|
|
392
|
-
({ h: Bh, l: Bl } =
|
|
393
|
-
({ h: Ch, l: Cl } =
|
|
394
|
-
({ h: Dh, l: Dl } =
|
|
395
|
-
({ h: Eh, l: El } =
|
|
396
|
-
({ h: Fh, l: Fl } =
|
|
397
|
-
({ h: Gh, l: Gl } =
|
|
398
|
-
({ h: Hh, l: Hl } =
|
|
679
|
+
({ h: Ah, l: Al } = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
|
|
680
|
+
({ h: Bh, l: Bl } = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
|
|
681
|
+
({ h: Ch, l: Cl } = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
|
|
682
|
+
({ h: Dh, l: Dl } = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
|
|
683
|
+
({ h: Eh, l: El } = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
|
|
684
|
+
({ h: Fh, l: Fl } = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
|
|
685
|
+
({ h: Gh, l: Gl } = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
|
|
686
|
+
({ h: Hh, l: Hl } = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
|
|
399
687
|
this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
|
|
400
688
|
}
|
|
401
689
|
roundClean() {
|
|
402
|
-
SHA512_W_H
|
|
403
|
-
SHA512_W_L.fill(0);
|
|
690
|
+
clean(SHA512_W_H, SHA512_W_L);
|
|
404
691
|
}
|
|
405
692
|
destroy() {
|
|
406
|
-
this.buffer
|
|
693
|
+
clean(this.buffer);
|
|
407
694
|
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
408
695
|
}
|
|
409
696
|
}
|
|
410
697
|
class SHA384 extends SHA512 {
|
|
411
698
|
constructor() {
|
|
699
|
+
super(48);
|
|
700
|
+
this.Ah = SHA384_IV[0] | 0;
|
|
701
|
+
this.Al = SHA384_IV[1] | 0;
|
|
702
|
+
this.Bh = SHA384_IV[2] | 0;
|
|
703
|
+
this.Bl = SHA384_IV[3] | 0;
|
|
704
|
+
this.Ch = SHA384_IV[4] | 0;
|
|
705
|
+
this.Cl = SHA384_IV[5] | 0;
|
|
706
|
+
this.Dh = SHA384_IV[6] | 0;
|
|
707
|
+
this.Dl = SHA384_IV[7] | 0;
|
|
708
|
+
this.Eh = SHA384_IV[8] | 0;
|
|
709
|
+
this.El = SHA384_IV[9] | 0;
|
|
710
|
+
this.Fh = SHA384_IV[10] | 0;
|
|
711
|
+
this.Fl = SHA384_IV[11] | 0;
|
|
712
|
+
this.Gh = SHA384_IV[12] | 0;
|
|
713
|
+
this.Gl = SHA384_IV[13] | 0;
|
|
714
|
+
this.Hh = SHA384_IV[14] | 0;
|
|
715
|
+
this.Hl = SHA384_IV[15] | 0;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* SHA2-256 hash function from RFC 4634.
|
|
720
|
+
*
|
|
721
|
+
* It is the fastest JS hash, even faster than Blake3.
|
|
722
|
+
* To break sha256 using birthday attack, attackers need to try 2^128 hashes.
|
|
723
|
+
* BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
|
|
724
|
+
*/
|
|
725
|
+
const sha256$1 = /* @__PURE__ */ createHasher(() => new SHA256());
|
|
726
|
+
/** SHA2-224 hash function from RFC 4634 */
|
|
727
|
+
const sha224$1 = /* @__PURE__ */ createHasher(() => new SHA224());
|
|
728
|
+
/** SHA2-512 hash function from RFC 4634. */
|
|
729
|
+
const sha512$1 = /* @__PURE__ */ createHasher(() => new SHA512());
|
|
730
|
+
/** SHA2-384 hash function from RFC 4634. */
|
|
731
|
+
const sha384$1 = /* @__PURE__ */ createHasher(() => new SHA384());
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* SHA3 (keccak) hash function, based on a new "Sponge function" design.
|
|
735
|
+
* Different from older hashes, the internal state is bigger than output size.
|
|
736
|
+
*
|
|
737
|
+
* Check out [FIPS-202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf),
|
|
738
|
+
* [Website](https://keccak.team/keccak.html),
|
|
739
|
+
* [the differences between SHA-3 and Keccak](https://crypto.stackexchange.com/questions/15727/what-are-the-key-differences-between-the-draft-sha-3-standard-and-the-keccak-sub).
|
|
740
|
+
*
|
|
741
|
+
* Check out `sha3-addons` module for cSHAKE, k12, and others.
|
|
742
|
+
* @module
|
|
743
|
+
*/
|
|
744
|
+
// No __PURE__ annotations in sha3 header:
|
|
745
|
+
// EVERYTHING is in fact used on every export.
|
|
746
|
+
// Various per round constants calculations
|
|
747
|
+
const _0n = BigInt(0);
|
|
748
|
+
const _1n = BigInt(1);
|
|
749
|
+
const _2n = BigInt(2);
|
|
750
|
+
const _7n = BigInt(7);
|
|
751
|
+
const _256n = BigInt(256);
|
|
752
|
+
const _0x71n = BigInt(0x71);
|
|
753
|
+
const SHA3_PI = [];
|
|
754
|
+
const SHA3_ROTL = [];
|
|
755
|
+
const _SHA3_IOTA = [];
|
|
756
|
+
for (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) {
|
|
757
|
+
// Pi
|
|
758
|
+
[x, y] = [y, (2 * x + 3 * y) % 5];
|
|
759
|
+
SHA3_PI.push(2 * (5 * y + x));
|
|
760
|
+
// Rotational
|
|
761
|
+
SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64);
|
|
762
|
+
// Iota
|
|
763
|
+
let t = _0n;
|
|
764
|
+
for (let j = 0; j < 7; j++) {
|
|
765
|
+
R = ((R << _1n) ^ ((R >> _7n) * _0x71n)) % _256n;
|
|
766
|
+
if (R & _2n)
|
|
767
|
+
t ^= _1n << ((_1n << /* @__PURE__ */ BigInt(j)) - _1n);
|
|
768
|
+
}
|
|
769
|
+
_SHA3_IOTA.push(t);
|
|
770
|
+
}
|
|
771
|
+
const IOTAS = split(_SHA3_IOTA, true);
|
|
772
|
+
const SHA3_IOTA_H = IOTAS[0];
|
|
773
|
+
const SHA3_IOTA_L = IOTAS[1];
|
|
774
|
+
// Left rotation (without 0, 32, 64)
|
|
775
|
+
const rotlH = (h, l, s) => (s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s));
|
|
776
|
+
const rotlL = (h, l, s) => (s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s));
|
|
777
|
+
/** `keccakf1600` internal function, additionally allows to adjust round count. */
|
|
778
|
+
function keccakP(s, rounds = 24) {
|
|
779
|
+
const B = new Uint32Array(5 * 2);
|
|
780
|
+
// NOTE: all indices are x2 since we store state as u32 instead of u64 (bigints to slow in js)
|
|
781
|
+
for (let round = 24 - rounds; round < 24; round++) {
|
|
782
|
+
// Theta θ
|
|
783
|
+
for (let x = 0; x < 10; x++)
|
|
784
|
+
B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];
|
|
785
|
+
for (let x = 0; x < 10; x += 2) {
|
|
786
|
+
const idx1 = (x + 8) % 10;
|
|
787
|
+
const idx0 = (x + 2) % 10;
|
|
788
|
+
const B0 = B[idx0];
|
|
789
|
+
const B1 = B[idx0 + 1];
|
|
790
|
+
const Th = rotlH(B0, B1, 1) ^ B[idx1];
|
|
791
|
+
const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1];
|
|
792
|
+
for (let y = 0; y < 50; y += 10) {
|
|
793
|
+
s[x + y] ^= Th;
|
|
794
|
+
s[x + y + 1] ^= Tl;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
// Rho (ρ) and Pi (π)
|
|
798
|
+
let curH = s[2];
|
|
799
|
+
let curL = s[3];
|
|
800
|
+
for (let t = 0; t < 24; t++) {
|
|
801
|
+
const shift = SHA3_ROTL[t];
|
|
802
|
+
const Th = rotlH(curH, curL, shift);
|
|
803
|
+
const Tl = rotlL(curH, curL, shift);
|
|
804
|
+
const PI = SHA3_PI[t];
|
|
805
|
+
curH = s[PI];
|
|
806
|
+
curL = s[PI + 1];
|
|
807
|
+
s[PI] = Th;
|
|
808
|
+
s[PI + 1] = Tl;
|
|
809
|
+
}
|
|
810
|
+
// Chi (χ)
|
|
811
|
+
for (let y = 0; y < 50; y += 10) {
|
|
812
|
+
for (let x = 0; x < 10; x++)
|
|
813
|
+
B[x] = s[y + x];
|
|
814
|
+
for (let x = 0; x < 10; x++)
|
|
815
|
+
s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10];
|
|
816
|
+
}
|
|
817
|
+
// Iota (ι)
|
|
818
|
+
s[0] ^= SHA3_IOTA_H[round];
|
|
819
|
+
s[1] ^= SHA3_IOTA_L[round];
|
|
820
|
+
}
|
|
821
|
+
clean(B);
|
|
822
|
+
}
|
|
823
|
+
/** Keccak sponge function. */
|
|
824
|
+
class Keccak extends Hash {
|
|
825
|
+
// NOTE: we accept arguments in bytes instead of bits here.
|
|
826
|
+
constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) {
|
|
412
827
|
super();
|
|
413
|
-
|
|
414
|
-
this.
|
|
415
|
-
this.
|
|
416
|
-
this.
|
|
417
|
-
this.
|
|
418
|
-
this.
|
|
419
|
-
this.
|
|
420
|
-
this.
|
|
421
|
-
this.
|
|
422
|
-
this.
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
this.
|
|
430
|
-
this.
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
828
|
+
this.pos = 0;
|
|
829
|
+
this.posOut = 0;
|
|
830
|
+
this.finished = false;
|
|
831
|
+
this.destroyed = false;
|
|
832
|
+
this.enableXOF = false;
|
|
833
|
+
this.blockLen = blockLen;
|
|
834
|
+
this.suffix = suffix;
|
|
835
|
+
this.outputLen = outputLen;
|
|
836
|
+
this.enableXOF = enableXOF;
|
|
837
|
+
this.rounds = rounds;
|
|
838
|
+
// Can be passed from user as dkLen
|
|
839
|
+
anumber(outputLen);
|
|
840
|
+
// 1600 = 5x5 matrix of 64bit. 1600 bits === 200 bytes
|
|
841
|
+
// 0 < blockLen < 200
|
|
842
|
+
if (!(0 < blockLen && blockLen < 200))
|
|
843
|
+
throw new Error('only keccak-f1600 function is supported');
|
|
844
|
+
this.state = new Uint8Array(200);
|
|
845
|
+
this.state32 = u32(this.state);
|
|
846
|
+
}
|
|
847
|
+
clone() {
|
|
848
|
+
return this._cloneInto();
|
|
849
|
+
}
|
|
850
|
+
keccak() {
|
|
851
|
+
swap32IfBE(this.state32);
|
|
852
|
+
keccakP(this.state32, this.rounds);
|
|
853
|
+
swap32IfBE(this.state32);
|
|
854
|
+
this.posOut = 0;
|
|
855
|
+
this.pos = 0;
|
|
856
|
+
}
|
|
857
|
+
update(data) {
|
|
858
|
+
aexists(this);
|
|
859
|
+
data = toBytes(data);
|
|
860
|
+
abytes(data);
|
|
861
|
+
const { blockLen, state } = this;
|
|
862
|
+
const len = data.length;
|
|
863
|
+
for (let pos = 0; pos < len;) {
|
|
864
|
+
const take = Math.min(blockLen - this.pos, len - pos);
|
|
865
|
+
for (let i = 0; i < take; i++)
|
|
866
|
+
state[this.pos++] ^= data[pos++];
|
|
867
|
+
if (this.pos === blockLen)
|
|
868
|
+
this.keccak();
|
|
869
|
+
}
|
|
870
|
+
return this;
|
|
871
|
+
}
|
|
872
|
+
finish() {
|
|
873
|
+
if (this.finished)
|
|
874
|
+
return;
|
|
875
|
+
this.finished = true;
|
|
876
|
+
const { state, suffix, pos, blockLen } = this;
|
|
877
|
+
// Do the padding
|
|
878
|
+
state[pos] ^= suffix;
|
|
879
|
+
if ((suffix & 0x80) !== 0 && pos === blockLen - 1)
|
|
880
|
+
this.keccak();
|
|
881
|
+
state[blockLen - 1] ^= 0x80;
|
|
882
|
+
this.keccak();
|
|
883
|
+
}
|
|
884
|
+
writeInto(out) {
|
|
885
|
+
aexists(this, false);
|
|
886
|
+
abytes(out);
|
|
887
|
+
this.finish();
|
|
888
|
+
const bufferOut = this.state;
|
|
889
|
+
const { blockLen } = this;
|
|
890
|
+
for (let pos = 0, len = out.length; pos < len;) {
|
|
891
|
+
if (this.posOut >= blockLen)
|
|
892
|
+
this.keccak();
|
|
893
|
+
const take = Math.min(blockLen - this.posOut, len - pos);
|
|
894
|
+
out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
|
|
895
|
+
this.posOut += take;
|
|
896
|
+
pos += take;
|
|
897
|
+
}
|
|
898
|
+
return out;
|
|
899
|
+
}
|
|
900
|
+
xofInto(out) {
|
|
901
|
+
// Sha3/Keccak usage with XOF is probably mistake, only SHAKE instances can do XOF
|
|
902
|
+
if (!this.enableXOF)
|
|
903
|
+
throw new Error('XOF is not possible for this instance');
|
|
904
|
+
return this.writeInto(out);
|
|
905
|
+
}
|
|
906
|
+
xof(bytes) {
|
|
907
|
+
anumber(bytes);
|
|
908
|
+
return this.xofInto(new Uint8Array(bytes));
|
|
909
|
+
}
|
|
910
|
+
digestInto(out) {
|
|
911
|
+
aoutput(out, this);
|
|
912
|
+
if (this.finished)
|
|
913
|
+
throw new Error('digest() was already called');
|
|
914
|
+
this.writeInto(out);
|
|
915
|
+
this.destroy();
|
|
916
|
+
return out;
|
|
917
|
+
}
|
|
918
|
+
digest() {
|
|
919
|
+
return this.digestInto(new Uint8Array(this.outputLen));
|
|
920
|
+
}
|
|
921
|
+
destroy() {
|
|
922
|
+
this.destroyed = true;
|
|
923
|
+
clean(this.state);
|
|
924
|
+
}
|
|
925
|
+
_cloneInto(to) {
|
|
926
|
+
const { blockLen, suffix, outputLen, rounds, enableXOF } = this;
|
|
927
|
+
to || (to = new Keccak(blockLen, suffix, outputLen, enableXOF, rounds));
|
|
928
|
+
to.state32.set(this.state32);
|
|
929
|
+
to.pos = this.pos;
|
|
930
|
+
to.posOut = this.posOut;
|
|
931
|
+
to.finished = this.finished;
|
|
932
|
+
to.rounds = rounds;
|
|
933
|
+
// Suffix can change in cSHAKE
|
|
934
|
+
to.suffix = suffix;
|
|
935
|
+
to.outputLen = outputLen;
|
|
936
|
+
to.enableXOF = enableXOF;
|
|
937
|
+
to.destroyed = this.destroyed;
|
|
938
|
+
return to;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
const gen = (suffix, blockLen, outputLen) => createHasher(() => new Keccak(blockLen, suffix, outputLen));
|
|
942
|
+
/** SHA3-256 hash function. Different from keccak-256. */
|
|
943
|
+
const sha3_256 = /* @__PURE__ */ (() => gen(0x06, 136, 256 / 8))();
|
|
944
|
+
/** SHA3-512 hash function. */
|
|
945
|
+
const sha3_512 = /* @__PURE__ */ (() => gen(0x06, 72, 512 / 8))();
|
|
946
|
+
const genShake = (suffix, blockLen, outputLen) => createXOFer((opts = {}) => new Keccak(blockLen, suffix, opts.dkLen === undefined ? outputLen : opts.dkLen, true));
|
|
947
|
+
/** SHAKE256 XOF with 256-bit security. */
|
|
948
|
+
const shake256 = /* @__PURE__ */ (() => genShake(0x1f, 136, 256 / 8))();
|
|
949
|
+
|
|
950
|
+
/**
|
|
951
|
+
* SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
|
|
952
|
+
*
|
|
953
|
+
* To break sha256 using birthday attack, attackers need to try 2^128 hashes.
|
|
954
|
+
* BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
|
|
955
|
+
*
|
|
956
|
+
* Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
|
957
|
+
* @module
|
|
958
|
+
* @deprecated
|
|
959
|
+
*/
|
|
960
|
+
/** @deprecated Use import from `noble/hashes/sha2` module */
|
|
961
|
+
const sha256 = sha256$1;
|
|
962
|
+
/** @deprecated Use import from `noble/hashes/sha2` module */
|
|
963
|
+
const sha224 = sha224$1;
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* SHA2-512 a.k.a. sha512 and sha384. It is slower than sha256 in js because u64 operations are slow.
|
|
967
|
+
*
|
|
968
|
+
* Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
|
|
969
|
+
* [the paper on truncated SHA512/256](https://eprint.iacr.org/2010/548.pdf).
|
|
970
|
+
* @module
|
|
971
|
+
* @deprecated
|
|
972
|
+
*/
|
|
973
|
+
/** @deprecated Use import from `noble/hashes/sha2` module */
|
|
974
|
+
const sha512 = sha512$1;
|
|
975
|
+
/** @deprecated Use import from `noble/hashes/sha2` module */
|
|
976
|
+
const sha384 = sha384$1;
|
|
435
977
|
|
|
436
|
-
export { Chi as C,
|
|
978
|
+
export { Chi as C, Hash as H, Maj as M, abytes as a, bytesToHex as b, concatBytes as c, anumber as d, ahash as e, clean as f, aexists as g, hexToBytes as h, isBytes as i, sha384$1 as j, sha512$1 as k, createHasher as l, shake256 as m, sha256 as n, sha384 as o, sha512 as p, HashMD as q, randomBytes as r, sha256$1 as s, toBytes as t, rotl as u, sha3_512 as v, wrapConstructor as w, sha3_256 as x, sha224 as y };
|