shogun-core 5.2.0 → 5.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/dist/browser/defaultVendors-node_modules_hpke_chacha20poly1305_esm_mod_js.shogun-core.js +1220 -0
- package/dist/browser/defaultVendors-node_modules_hpke_chacha20poly1305_esm_mod_js.shogun-core.js.map +1 -0
- package/dist/browser/defaultVendors-node_modules_hpke_hybridkem-x-wing_esm_mod_js.shogun-core.js +844 -0
- package/dist/browser/defaultVendors-node_modules_hpke_hybridkem-x-wing_esm_mod_js.shogun-core.js.map +1 -0
- package/dist/browser/defaultVendors-node_modules_mlkem_esm_mod_js.shogun-core.js +2335 -0
- package/dist/browser/defaultVendors-node_modules_mlkem_esm_mod_js.shogun-core.js.map +1 -0
- package/dist/browser/defaultVendors-node_modules_noble_ciphers_chacha_js.shogun-core.js +999 -0
- package/dist/browser/defaultVendors-node_modules_noble_ciphers_chacha_js.shogun-core.js.map +1 -0
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_abstract_curve_js-node_modules_noble_curves_esm_-1ce4ed.shogun-core.js +1651 -0
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_abstract_curve_js-node_modules_noble_curves_esm_-1ce4ed.shogun-core.js.map +1 -0
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_abstract_edwards_js-node_modules_noble_curves_es-a82056.shogun-core.js +825 -0
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_abstract_edwards_js-node_modules_noble_curves_es-a82056.shogun-core.js.map +1 -0
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_ed25519_js.shogun-core.js +508 -0
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_ed25519_js.shogun-core.js.map +1 -0
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_ed448_js.shogun-core.js +747 -0
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_ed448_js.shogun-core.js.map +1 -0
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_nist_js.shogun-core.js +1608 -0
- package/dist/browser/defaultVendors-node_modules_noble_curves_esm_nist_js.shogun-core.js.map +1 -0
- package/dist/browser/defaultVendors-node_modules_noble_post-quantum_ml-dsa_js.shogun-core.js +2117 -0
- package/dist/browser/defaultVendors-node_modules_noble_post-quantum_ml-dsa_js.shogun-core.js.map +1 -0
- package/dist/browser/defaultVendors-node_modules_openpgp_dist_openpgp_min_mjs.shogun-core.js +86 -0
- package/dist/browser/defaultVendors-node_modules_openpgp_dist_openpgp_min_mjs.shogun-core.js.map +1 -0
- package/dist/browser/node_modules_hpke_ml-kem_esm_mod_js.shogun-core.js +539 -0
- package/dist/browser/node_modules_hpke_ml-kem_esm_mod_js.shogun-core.js.map +1 -0
- package/dist/browser/shogun-core.js +160386 -0
- package/dist/browser/shogun-core.js.map +1 -0
- package/dist/config/simplified-config.js +236 -0
- package/dist/core.js +329 -0
- package/dist/crypto/asymmetric.js +99 -0
- package/dist/crypto/double-ratchet.js +370 -0
- package/dist/crypto/file-encryption.js +213 -0
- package/dist/crypto/hashing.js +87 -0
- package/dist/crypto/index.js +34 -0
- package/dist/crypto/mls-codec.js +202 -0
- package/dist/crypto/mls.js +550 -0
- package/dist/crypto/pgp.js +390 -0
- package/dist/crypto/random-generation.js +341 -0
- package/dist/crypto/sframe.js +350 -0
- package/dist/crypto/signal-protocol.js +376 -0
- package/dist/crypto/symmetric.js +91 -0
- package/dist/crypto/types.js +2 -0
- package/dist/crypto/utils.js +140 -0
- package/dist/examples/auth-test.js +253 -0
- package/dist/examples/crypto-identity-example.js +151 -0
- package/dist/examples/crypto-working-test.js +83 -0
- package/dist/examples/double-ratchet-test.js +155 -0
- package/dist/examples/mls-advanced-example.js +294 -0
- package/dist/examples/mls-sframe-test.js +304 -0
- package/dist/examples/pgp-example.js +200 -0
- package/dist/examples/quick-auth-test.js +61 -0
- package/dist/examples/random-generation-test.js +151 -0
- package/dist/examples/signal-protocol-test.js +38 -0
- package/dist/examples/simple-api-test.js +114 -0
- package/dist/examples/simple-crypto-identity-example.js +84 -0
- package/dist/examples/timeout-test.js +227 -0
- package/dist/examples/zkproof-credentials-example.js +212 -0
- package/dist/examples/zkproof-example.js +201 -0
- package/dist/gundb/api.js +435 -0
- package/dist/gundb/crypto.js +283 -0
- package/dist/gundb/db.js +1946 -0
- package/dist/gundb/derive.js +232 -0
- package/dist/gundb/errors.js +76 -0
- package/dist/gundb/index.js +22 -0
- package/dist/gundb/rxjs.js +447 -0
- package/dist/gundb/types.js +5 -0
- package/dist/index.js +58 -0
- package/dist/interfaces/common.js +2 -0
- package/dist/interfaces/events.js +40 -0
- package/dist/interfaces/plugin.js +2 -0
- package/dist/interfaces/shogun.js +37 -0
- package/dist/managers/AuthManager.js +226 -0
- package/dist/managers/CoreInitializer.js +228 -0
- package/dist/managers/CryptoIdentityManager.js +366 -0
- package/dist/managers/EventManager.js +70 -0
- package/dist/managers/PluginManager.js +299 -0
- package/dist/plugins/base.js +50 -0
- package/dist/plugins/index.js +32 -0
- package/dist/plugins/nostr/index.js +20 -0
- package/dist/plugins/nostr/nostrConnector.js +419 -0
- package/dist/plugins/nostr/nostrConnectorPlugin.js +453 -0
- package/dist/plugins/nostr/nostrSigner.js +319 -0
- package/dist/plugins/nostr/types.js +2 -0
- package/dist/plugins/smartwallet/index.js +18 -0
- package/dist/plugins/smartwallet/smartWalletPlugin.js +511 -0
- package/dist/plugins/smartwallet/types.js +2 -0
- package/dist/plugins/web3/index.js +20 -0
- package/dist/plugins/web3/types.js +2 -0
- package/dist/plugins/web3/web3Connector.js +533 -0
- package/dist/plugins/web3/web3ConnectorPlugin.js +455 -0
- package/dist/plugins/web3/web3Signer.js +314 -0
- package/dist/plugins/webauthn/index.js +19 -0
- package/dist/plugins/webauthn/types.js +14 -0
- package/dist/plugins/webauthn/webauthn.js +496 -0
- package/dist/plugins/webauthn/webauthnPlugin.js +489 -0
- package/dist/plugins/webauthn/webauthnSigner.js +310 -0
- package/dist/plugins/zkproof/index.js +53 -0
- package/dist/plugins/zkproof/types.js +2 -0
- package/dist/plugins/zkproof/zkCredentials.js +213 -0
- package/dist/plugins/zkproof/zkProofConnector.js +198 -0
- package/dist/plugins/zkproof/zkProofPlugin.js +272 -0
- package/dist/storage/storage.js +145 -0
- package/dist/types/config/simplified-config.d.ts +114 -0
- package/dist/types/core.d.ts +305 -0
- package/dist/types/crypto/asymmetric.d.ts +6 -0
- package/dist/types/crypto/double-ratchet.d.ts +22 -0
- package/dist/types/crypto/file-encryption.d.ts +19 -0
- package/dist/types/crypto/hashing.d.ts +9 -0
- package/dist/types/crypto/index.d.ts +13 -0
- package/dist/types/crypto/mls-codec.d.ts +39 -0
- package/dist/types/crypto/mls.d.ts +130 -0
- package/dist/types/crypto/pgp.d.ts +95 -0
- package/dist/types/crypto/random-generation.d.ts +35 -0
- package/dist/types/crypto/sframe.d.ts +102 -0
- package/dist/types/crypto/signal-protocol.d.ts +26 -0
- package/dist/types/crypto/symmetric.d.ts +9 -0
- package/dist/types/crypto/types.d.ts +144 -0
- package/dist/types/crypto/utils.d.ts +22 -0
- package/dist/types/examples/auth-test.d.ts +8 -0
- package/dist/types/examples/crypto-identity-example.d.ts +5 -0
- package/dist/types/examples/crypto-working-test.d.ts +1 -0
- package/dist/types/examples/double-ratchet-test.d.ts +1 -0
- package/dist/types/examples/mls-advanced-example.d.ts +53 -0
- package/dist/types/examples/mls-sframe-test.d.ts +1 -0
- package/dist/types/examples/pgp-example.d.ts +75 -0
- package/dist/types/examples/quick-auth-test.d.ts +8 -0
- package/dist/types/examples/random-generation-test.d.ts +1 -0
- package/dist/types/examples/signal-protocol-test.d.ts +1 -0
- package/dist/types/examples/simple-api-test.d.ts +10 -0
- package/dist/types/examples/simple-crypto-identity-example.d.ts +6 -0
- package/dist/types/examples/timeout-test.d.ts +8 -0
- package/dist/types/examples/zkproof-credentials-example.d.ts +12 -0
- package/dist/types/examples/zkproof-example.d.ts +11 -0
- package/dist/types/gundb/api.d.ts +185 -0
- package/dist/types/gundb/crypto.d.ts +95 -0
- package/dist/types/gundb/db.d.ts +397 -0
- package/dist/types/gundb/derive.d.ts +21 -0
- package/dist/types/gundb/errors.d.ts +42 -0
- package/dist/types/gundb/index.d.ts +3 -0
- package/dist/types/gundb/rxjs.d.ts +110 -0
- package/dist/types/gundb/types.d.ts +255 -0
- package/dist/types/index.d.ts +16 -0
- package/dist/types/interfaces/common.d.ts +85 -0
- package/dist/types/interfaces/events.d.ts +131 -0
- package/dist/types/interfaces/plugin.d.ts +162 -0
- package/dist/types/interfaces/shogun.d.ts +208 -0
- package/dist/types/managers/AuthManager.d.ts +72 -0
- package/dist/types/managers/CoreInitializer.d.ts +40 -0
- package/dist/types/managers/CryptoIdentityManager.d.ts +102 -0
- package/dist/types/managers/EventManager.d.ts +49 -0
- package/dist/types/managers/PluginManager.d.ts +145 -0
- package/dist/types/plugins/base.d.ts +35 -0
- package/dist/types/plugins/index.d.ts +18 -0
- package/dist/types/plugins/nostr/index.d.ts +4 -0
- package/dist/types/plugins/nostr/nostrConnector.d.ts +119 -0
- package/dist/types/plugins/nostr/nostrConnectorPlugin.d.ts +163 -0
- package/dist/types/plugins/nostr/nostrSigner.d.ts +105 -0
- package/dist/types/plugins/nostr/types.d.ts +122 -0
- package/dist/types/plugins/smartwallet/index.d.ts +2 -0
- package/dist/types/plugins/smartwallet/smartWalletPlugin.d.ts +67 -0
- package/dist/types/plugins/smartwallet/types.d.ts +80 -0
- package/dist/types/plugins/web3/index.d.ts +4 -0
- package/dist/types/plugins/web3/types.d.ts +107 -0
- package/dist/types/plugins/web3/web3Connector.d.ts +129 -0
- package/dist/types/plugins/web3/web3ConnectorPlugin.d.ts +160 -0
- package/dist/types/plugins/web3/web3Signer.d.ts +114 -0
- package/dist/types/plugins/webauthn/index.d.ts +3 -0
- package/dist/types/plugins/webauthn/types.d.ts +183 -0
- package/dist/types/plugins/webauthn/webauthn.d.ts +129 -0
- package/dist/types/plugins/webauthn/webauthnPlugin.d.ts +179 -0
- package/dist/types/plugins/webauthn/webauthnSigner.d.ts +91 -0
- package/dist/types/plugins/zkproof/index.d.ts +48 -0
- package/dist/types/plugins/zkproof/types.d.ts +123 -0
- package/dist/types/plugins/zkproof/zkCredentials.d.ts +112 -0
- package/dist/types/plugins/zkproof/zkProofConnector.d.ts +46 -0
- package/dist/types/plugins/zkproof/zkProofPlugin.d.ts +76 -0
- package/dist/types/storage/storage.d.ts +51 -0
- package/dist/types/utils/errorHandler.d.ts +119 -0
- package/dist/types/utils/eventEmitter.d.ts +39 -0
- package/dist/types/utils/seedPhrase.d.ts +50 -0
- package/dist/types/utils/validation.d.ts +27 -0
- package/dist/utils/errorHandler.js +246 -0
- package/dist/utils/eventEmitter.js +79 -0
- package/dist/utils/seedPhrase.js +97 -0
- package/dist/utils/validation.js +81 -0
- package/package.json +10 -1
package/dist/browser/defaultVendors-node_modules_hpke_chacha20poly1305_esm_mod_js.shogun-core.js
ADDED
|
@@ -0,0 +1,1220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
(this["webpackChunkShogunCore"] = this["webpackChunkShogunCore"] || []).push([["defaultVendors-node_modules_hpke_chacha20poly1305_esm_mod_js"],{
|
|
3
|
+
|
|
4
|
+
/***/ "./node_modules/@hpke/chacha20poly1305/esm/mod.js":
|
|
5
|
+
/*!********************************************************************!*\
|
|
6
|
+
!*** ./node_modules/@hpke/chacha20poly1305/esm/mod.js + 5 modules ***!
|
|
7
|
+
\********************************************************************/
|
|
8
|
+
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
|
9
|
+
|
|
10
|
+
// ESM COMPAT FLAG
|
|
11
|
+
__webpack_require__.r(__webpack_exports__);
|
|
12
|
+
|
|
13
|
+
// EXPORTS
|
|
14
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
15
|
+
Chacha20Poly1305: () => (/* reexport */ Chacha20Poly1305)
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
;// ./node_modules/@hpke/chacha20poly1305/esm/src/chacha/utils.js
|
|
19
|
+
/**
|
|
20
|
+
* This file is based on noble-ciphers (https://github.com/paulmillr/noble-ciphers).
|
|
21
|
+
*
|
|
22
|
+
* noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com)
|
|
23
|
+
*
|
|
24
|
+
* The original file is located at:
|
|
25
|
+
* https://github.com/paulmillr/noble-ciphers/blob/749cdf9cd07ebdd19e9b957d0f172f1045179695/src/utils.ts
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Utilities for hex, bytes, CSPRNG.
|
|
29
|
+
* @module
|
|
30
|
+
*/
|
|
31
|
+
/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
|
|
32
|
+
function isBytes(a) {
|
|
33
|
+
return a instanceof Uint8Array ||
|
|
34
|
+
(ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array");
|
|
35
|
+
}
|
|
36
|
+
/** Asserts something is boolean. */
|
|
37
|
+
function abool(b) {
|
|
38
|
+
if (typeof b !== "boolean")
|
|
39
|
+
throw new Error(`boolean expected, not ${b}`);
|
|
40
|
+
}
|
|
41
|
+
/** Asserts something is positive integer. */
|
|
42
|
+
function anumber(n) {
|
|
43
|
+
if (!Number.isSafeInteger(n) || n < 0) {
|
|
44
|
+
throw new Error("positive integer expected, got " + n);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Asserts something is Uint8Array. */
|
|
48
|
+
function abytes(value, length, title = "") {
|
|
49
|
+
const bytes = isBytes(value);
|
|
50
|
+
const len = value?.length;
|
|
51
|
+
const needsLen = length !== undefined;
|
|
52
|
+
if (!bytes || (needsLen && len !== length)) {
|
|
53
|
+
const prefix = title && `"${title}" `;
|
|
54
|
+
const ofLen = needsLen ? ` of length ${length}` : "";
|
|
55
|
+
const got = bytes ? `length=${len}` : `type=${typeof value}`;
|
|
56
|
+
throw new Error(prefix + "expected Uint8Array" + ofLen + ", got " + got);
|
|
57
|
+
}
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
/** Asserts a hash instance has not been destroyed / finished */
|
|
61
|
+
// deno-lint-ignore no-explicit-any
|
|
62
|
+
function aexists(instance, checkFinished = true) {
|
|
63
|
+
if (instance.destroyed)
|
|
64
|
+
throw new Error("Hash instance has been destroyed");
|
|
65
|
+
if (checkFinished && instance.finished) {
|
|
66
|
+
throw new Error("Hash#digest() has already been called");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/** Asserts output is properly-sized byte array */
|
|
70
|
+
// deno-lint-ignore no-explicit-any
|
|
71
|
+
function aoutput(out, instance) {
|
|
72
|
+
abytes(out, undefined, "output");
|
|
73
|
+
const min = instance.outputLen;
|
|
74
|
+
if (out.length < min) {
|
|
75
|
+
throw new Error("digestInto() expects output buffer of length at least " + min);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Cast u8 / u16 / u32 to u8. */
|
|
79
|
+
function u8(arr) {
|
|
80
|
+
return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
81
|
+
}
|
|
82
|
+
/** Cast u8 / u16 / u32 to u32. */
|
|
83
|
+
function u32(arr) {
|
|
84
|
+
return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
|
|
85
|
+
}
|
|
86
|
+
/** Zeroize a byte array. Warning: JS provides no guarantees. */
|
|
87
|
+
function clean(...arrays) {
|
|
88
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
89
|
+
arrays[i].fill(0);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/** Create DataView of an array for easy byte-level manipulation. */
|
|
93
|
+
function createView(arr) {
|
|
94
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
95
|
+
}
|
|
96
|
+
/** Is current platform little-endian? Most are. Big-Endian platform: IBM */
|
|
97
|
+
const isLE =
|
|
98
|
+
/* @__PURE__ */ (() => new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();
|
|
99
|
+
// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
|
|
100
|
+
const hasHexBuiltin = /* @__PURE__ */ (() =>
|
|
101
|
+
// @ts-ignore: to use toHex
|
|
102
|
+
typeof Uint8Array.from([]).toHex === "function" &&
|
|
103
|
+
// @ts-ignore: to use fromHex
|
|
104
|
+
typeof Uint8Array.fromHex === "function")();
|
|
105
|
+
// Array where index 0xf0 (240) is mapped to string 'f0'
|
|
106
|
+
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
107
|
+
/**
|
|
108
|
+
* Convert byte array to hex string. Uses built-in function, when available.
|
|
109
|
+
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
|
|
110
|
+
*/
|
|
111
|
+
function bytesToHex(bytes) {
|
|
112
|
+
abytes(bytes);
|
|
113
|
+
// @ts-ignore: to use toHex
|
|
114
|
+
if (hasHexBuiltin)
|
|
115
|
+
return bytes.toHex();
|
|
116
|
+
// pre-caching improves the speed 6x
|
|
117
|
+
let hex = "";
|
|
118
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
119
|
+
hex += hexes[bytes[i]];
|
|
120
|
+
}
|
|
121
|
+
return hex;
|
|
122
|
+
}
|
|
123
|
+
// We use optimized technique to convert hex string to byte array
|
|
124
|
+
const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
|
125
|
+
function asciiToBase16(ch) {
|
|
126
|
+
if (ch >= asciis._0 && ch <= asciis._9)
|
|
127
|
+
return ch - asciis._0; // '2' => 50-48
|
|
128
|
+
if (ch >= asciis.A && ch <= asciis.F)
|
|
129
|
+
return ch - (asciis.A - 10); // 'B' => 66-(65-10)
|
|
130
|
+
if (ch >= asciis.a && ch <= asciis.f)
|
|
131
|
+
return ch - (asciis.a - 10); // 'b' => 98-(97-10)
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Convert hex string to byte array. Uses built-in function, when available.
|
|
136
|
+
* @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
|
|
137
|
+
*/
|
|
138
|
+
function hexToBytes(hex) {
|
|
139
|
+
if (typeof hex !== "string") {
|
|
140
|
+
throw new Error("hex string expected, got " + typeof hex);
|
|
141
|
+
}
|
|
142
|
+
// @ts-ignore: to use fromHex
|
|
143
|
+
if (hasHexBuiltin)
|
|
144
|
+
return Uint8Array.fromHex(hex);
|
|
145
|
+
const hl = hex.length;
|
|
146
|
+
const al = hl / 2;
|
|
147
|
+
if (hl % 2) {
|
|
148
|
+
throw new Error("hex string expected, got unpadded hex of length " + hl);
|
|
149
|
+
}
|
|
150
|
+
const array = new Uint8Array(al);
|
|
151
|
+
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
|
152
|
+
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
|
153
|
+
const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
|
|
154
|
+
if (n1 === undefined || n2 === undefined) {
|
|
155
|
+
const char = hex[hi] + hex[hi + 1];
|
|
156
|
+
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' +
|
|
157
|
+
hi);
|
|
158
|
+
}
|
|
159
|
+
array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163
|
|
160
|
+
}
|
|
161
|
+
return array;
|
|
162
|
+
}
|
|
163
|
+
// Used in micro
|
|
164
|
+
function hexToNumber(hex) {
|
|
165
|
+
if (typeof hex !== "string") {
|
|
166
|
+
throw new Error("hex string expected, got " + typeof hex);
|
|
167
|
+
}
|
|
168
|
+
return BigInt(hex === "" ? "0" : "0x" + hex); // Big Endian
|
|
169
|
+
}
|
|
170
|
+
// Used in ff1
|
|
171
|
+
// BE: Big Endian, LE: Little Endian
|
|
172
|
+
function bytesToNumberBE(bytes) {
|
|
173
|
+
return hexToNumber(bytesToHex(bytes));
|
|
174
|
+
}
|
|
175
|
+
// Used in micro, ff1
|
|
176
|
+
function numberToBytesBE(n, len) {
|
|
177
|
+
return hexToBytes(n.toString(16).padStart(len * 2, "0"));
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Converts string to bytes using UTF8 encoding.
|
|
181
|
+
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
|
182
|
+
*/
|
|
183
|
+
function utf8ToBytes(str) {
|
|
184
|
+
if (typeof str !== "string")
|
|
185
|
+
throw new Error("string expected");
|
|
186
|
+
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Converts bytes to string using UTF8 encoding.
|
|
190
|
+
* @example bytesToUtf8(new Uint8Array([97, 98, 99])) // 'abc'
|
|
191
|
+
*/
|
|
192
|
+
function bytesToUtf8(bytes) {
|
|
193
|
+
return new TextDecoder().decode(bytes);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Checks if two U8A use same underlying buffer and overlaps.
|
|
197
|
+
* This is invalid and can corrupt data.
|
|
198
|
+
*/
|
|
199
|
+
function overlapBytes(a, b) {
|
|
200
|
+
return (a.buffer === b.buffer && // best we can do, may fail with an obscure Proxy
|
|
201
|
+
a.byteOffset < b.byteOffset + b.byteLength && // a starts before b end
|
|
202
|
+
b.byteOffset < a.byteOffset + a.byteLength // b starts before a end
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* If input and output overlap and input starts before output, we will overwrite end of input before
|
|
207
|
+
* we start processing it, so this is not supported for most ciphers (except chacha/salse, which designed with this)
|
|
208
|
+
*/
|
|
209
|
+
function complexOverlapBytes(input, output) {
|
|
210
|
+
// This is very cursed. It works somehow, but I'm completely unsure,
|
|
211
|
+
// reasoning about overlapping aligned windows is very hard.
|
|
212
|
+
if (overlapBytes(input, output) && input.byteOffset < output.byteOffset) {
|
|
213
|
+
throw new Error("complex overlap of input and output is not supported");
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Copies several Uint8Arrays into one.
|
|
218
|
+
*/
|
|
219
|
+
function concatBytes(...arrays) {
|
|
220
|
+
let sum = 0;
|
|
221
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
222
|
+
const a = arrays[i];
|
|
223
|
+
abytes(a);
|
|
224
|
+
sum += a.length;
|
|
225
|
+
}
|
|
226
|
+
const res = new Uint8Array(sum);
|
|
227
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
228
|
+
const a = arrays[i];
|
|
229
|
+
res.set(a, pad);
|
|
230
|
+
pad += a.length;
|
|
231
|
+
}
|
|
232
|
+
return res;
|
|
233
|
+
}
|
|
234
|
+
function checkOpts(defaults, opts) {
|
|
235
|
+
if (opts == null || typeof opts !== "object") {
|
|
236
|
+
throw new Error("options must be defined");
|
|
237
|
+
}
|
|
238
|
+
const merged = Object.assign(defaults, opts);
|
|
239
|
+
return merged;
|
|
240
|
+
}
|
|
241
|
+
/** Compares 2 uint8array-s in kinda constant time. */
|
|
242
|
+
function equalBytes(a, b) {
|
|
243
|
+
if (a.length !== b.length)
|
|
244
|
+
return false;
|
|
245
|
+
let diff = 0;
|
|
246
|
+
for (let i = 0; i < a.length; i++)
|
|
247
|
+
diff |= a[i] ^ b[i];
|
|
248
|
+
return diff === 0;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Wraps a cipher: validates args, ensures encrypt() can only be called once.
|
|
252
|
+
* @__NO_SIDE_EFFECTS__
|
|
253
|
+
*/
|
|
254
|
+
// deno-lint-ignore no-explicit-any
|
|
255
|
+
const wrapCipher = (params, constructor) => {
|
|
256
|
+
// deno-lint-ignore no-explicit-any
|
|
257
|
+
function wrappedCipher(key, ...args) {
|
|
258
|
+
// Validate key
|
|
259
|
+
abytes(key, undefined, "key");
|
|
260
|
+
// Big-Endian hardware is rare. Just in case someone still decides to run ciphers:
|
|
261
|
+
if (!isLE) {
|
|
262
|
+
throw new Error("Non little-endian hardware is not yet supported");
|
|
263
|
+
}
|
|
264
|
+
// Validate nonce if nonceLength is present
|
|
265
|
+
if (params.nonceLength !== undefined) {
|
|
266
|
+
const nonce = args[0];
|
|
267
|
+
abytes(nonce, params.varSizeNonce ? undefined : params.nonceLength, "nonce");
|
|
268
|
+
}
|
|
269
|
+
// Validate AAD if tagLength present
|
|
270
|
+
const tagl = params.tagLength;
|
|
271
|
+
if (tagl && args[1] !== undefined)
|
|
272
|
+
abytes(args[1], undefined, "AAD");
|
|
273
|
+
const cipher = constructor(key, ...args);
|
|
274
|
+
const checkOutput = (fnLength, output) => {
|
|
275
|
+
if (output !== undefined) {
|
|
276
|
+
if (fnLength !== 2)
|
|
277
|
+
throw new Error("cipher output not supported");
|
|
278
|
+
abytes(output, undefined, "output");
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
// Create wrapped cipher with validation and single-use encryption
|
|
282
|
+
let called = false;
|
|
283
|
+
const wrCipher = {
|
|
284
|
+
encrypt(data, output) {
|
|
285
|
+
if (called) {
|
|
286
|
+
throw new Error("cannot encrypt() twice with same key + nonce");
|
|
287
|
+
}
|
|
288
|
+
called = true;
|
|
289
|
+
abytes(data);
|
|
290
|
+
checkOutput(cipher.encrypt.length, output);
|
|
291
|
+
return cipher.encrypt(data, output);
|
|
292
|
+
},
|
|
293
|
+
decrypt(data, output) {
|
|
294
|
+
abytes(data);
|
|
295
|
+
if (tagl && data.length < tagl) {
|
|
296
|
+
throw new Error('"ciphertext" expected length bigger than tagLength=' + tagl);
|
|
297
|
+
}
|
|
298
|
+
checkOutput(cipher.decrypt.length, output);
|
|
299
|
+
return cipher.decrypt(data, output);
|
|
300
|
+
},
|
|
301
|
+
};
|
|
302
|
+
return wrCipher;
|
|
303
|
+
}
|
|
304
|
+
Object.assign(wrappedCipher, params);
|
|
305
|
+
return wrappedCipher;
|
|
306
|
+
};
|
|
307
|
+
/**
|
|
308
|
+
* By default, returns u8a of length.
|
|
309
|
+
* When out is available, it checks it for validity and uses it.
|
|
310
|
+
*/
|
|
311
|
+
function getOutput(expectedLength, out, onlyAligned = true) {
|
|
312
|
+
if (out === undefined)
|
|
313
|
+
return new Uint8Array(expectedLength);
|
|
314
|
+
if (out.length !== expectedLength) {
|
|
315
|
+
throw new Error('"output" expected Uint8Array of length ' + expectedLength + ", got: " +
|
|
316
|
+
out.length);
|
|
317
|
+
}
|
|
318
|
+
if (onlyAligned && !isAligned32(out)) {
|
|
319
|
+
throw new Error("invalid output, must be aligned");
|
|
320
|
+
}
|
|
321
|
+
return out;
|
|
322
|
+
}
|
|
323
|
+
function u64Lengths(dataLength, aadLength, isLE) {
|
|
324
|
+
abool(isLE);
|
|
325
|
+
const num = new Uint8Array(16);
|
|
326
|
+
const view = createView(num);
|
|
327
|
+
view.setBigUint64(0, BigInt(aadLength), isLE);
|
|
328
|
+
view.setBigUint64(8, BigInt(dataLength), isLE);
|
|
329
|
+
return num;
|
|
330
|
+
}
|
|
331
|
+
// Is byte array aligned to 4 byte offset (u32)?
|
|
332
|
+
function isAligned32(bytes) {
|
|
333
|
+
return bytes.byteOffset % 4 === 0;
|
|
334
|
+
}
|
|
335
|
+
// copy bytes to new u8a (aligned). Because Buffer.slice is broken.
|
|
336
|
+
function copyBytes(bytes) {
|
|
337
|
+
return Uint8Array.from(bytes);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
;// ./node_modules/@hpke/chacha20poly1305/esm/src/chacha/_arx.js
|
|
341
|
+
/**
|
|
342
|
+
* This file is based on noble-ciphers (https://github.com/paulmillr/noble-ciphers).
|
|
343
|
+
*
|
|
344
|
+
* noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com)
|
|
345
|
+
*
|
|
346
|
+
* The original file is located at:
|
|
347
|
+
* https://github.com/paulmillr/noble-ciphers/blob/749cdf9cd07ebdd19e9b957d0f172f1045179695/src/_arx.ts
|
|
348
|
+
*/
|
|
349
|
+
/**
|
|
350
|
+
* Basic utils for ARX (add-rotate-xor) salsa and chacha ciphers.
|
|
351
|
+
|
|
352
|
+
RFC8439 requires multi-step cipher stream, where
|
|
353
|
+
authKey starts with counter: 0, actual msg with counter: 1.
|
|
354
|
+
|
|
355
|
+
For this, we need a way to re-use nonce / counter:
|
|
356
|
+
|
|
357
|
+
const counter = new Uint8Array(4);
|
|
358
|
+
chacha(..., counter, ...); // counter is now 1
|
|
359
|
+
chacha(..., counter, ...); // counter is now 2
|
|
360
|
+
|
|
361
|
+
This is complicated:
|
|
362
|
+
|
|
363
|
+
- 32-bit counters are enough, no need for 64-bit: max ArrayBuffer size in JS is 4GB
|
|
364
|
+
- Original papers don't allow mutating counters
|
|
365
|
+
- Counter overflow is undefined [^1]
|
|
366
|
+
- Idea A: allow providing (nonce | counter) instead of just nonce, re-use it
|
|
367
|
+
- Caveat: Cannot be re-used through all cases:
|
|
368
|
+
- * chacha has (counter | nonce)
|
|
369
|
+
- * xchacha has (nonce16 | counter | nonce16)
|
|
370
|
+
- Idea B: separate nonce / counter and provide separate API for counter re-use
|
|
371
|
+
- Caveat: there are different counter sizes depending on an algorithm.
|
|
372
|
+
- salsa & chacha also differ in structures of key & sigma:
|
|
373
|
+
salsa20: s[0] | k(4) | s[1] | nonce(2) | cnt(2) | s[2] | k(4) | s[3]
|
|
374
|
+
chacha: s(4) | k(8) | cnt(1) | nonce(3)
|
|
375
|
+
chacha20orig: s(4) | k(8) | cnt(2) | nonce(2)
|
|
376
|
+
- Idea C: helper method such as `setSalsaState(key, nonce, sigma, data)`
|
|
377
|
+
- Caveat: we can't re-use counter array
|
|
378
|
+
|
|
379
|
+
xchacha [^2] uses the subkey and remaining 8 byte nonce with ChaCha20 as normal
|
|
380
|
+
(prefixed by 4 NUL bytes, since [RFC8439] specifies a 12-byte nonce).
|
|
381
|
+
|
|
382
|
+
[^1]: https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU/
|
|
383
|
+
[^2]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#appendix-A.2
|
|
384
|
+
|
|
385
|
+
* @module
|
|
386
|
+
*/
|
|
387
|
+
|
|
388
|
+
// Can't use similar utils.utf8ToBytes, because it uses `TextEncoder` - not available in all envs
|
|
389
|
+
const _utf8ToBytes = (str) => Uint8Array.from(str.split("").map((c) => c.charCodeAt(0)));
|
|
390
|
+
const sigma16 = _utf8ToBytes("expand 16-byte k");
|
|
391
|
+
const sigma32 = _utf8ToBytes("expand 32-byte k");
|
|
392
|
+
const sigma16_32 = u32(sigma16);
|
|
393
|
+
const sigma32_32 = u32(sigma32);
|
|
394
|
+
/** Rotate left. */
|
|
395
|
+
function rotl(a, b) {
|
|
396
|
+
return (a << b) | (a >>> (32 - b));
|
|
397
|
+
}
|
|
398
|
+
// Is byte array aligned to 4 byte offset (u32)?
|
|
399
|
+
function _arx_isAligned32(b) {
|
|
400
|
+
return b.byteOffset % 4 === 0;
|
|
401
|
+
}
|
|
402
|
+
// Salsa and Chacha block length is always 512-bit
|
|
403
|
+
const BLOCK_LEN = 64;
|
|
404
|
+
const BLOCK_LEN32 = 16;
|
|
405
|
+
// new Uint32Array([2**32]) // => Uint32Array(1) [ 0 ]
|
|
406
|
+
// new Uint32Array([2**32-1]) // => Uint32Array(1) [ 4294967295 ]
|
|
407
|
+
const MAX_COUNTER = 2 ** 32 - 1;
|
|
408
|
+
const U32_EMPTY = Uint32Array.of();
|
|
409
|
+
function runCipher(core, sigma, key, nonce, data, output, counter, rounds) {
|
|
410
|
+
const len = data.length;
|
|
411
|
+
const block = new Uint8Array(BLOCK_LEN);
|
|
412
|
+
const b32 = u32(block);
|
|
413
|
+
// Make sure that buffers aligned to 4 bytes
|
|
414
|
+
const isAligned = _arx_isAligned32(data) && _arx_isAligned32(output);
|
|
415
|
+
const d32 = isAligned ? u32(data) : U32_EMPTY;
|
|
416
|
+
const o32 = isAligned ? u32(output) : U32_EMPTY;
|
|
417
|
+
for (let pos = 0; pos < len; counter++) {
|
|
418
|
+
core(sigma, key, nonce, b32, counter, rounds);
|
|
419
|
+
if (counter >= MAX_COUNTER)
|
|
420
|
+
throw new Error("arx: counter overflow");
|
|
421
|
+
const take = Math.min(BLOCK_LEN, len - pos);
|
|
422
|
+
// aligned to 4 bytes
|
|
423
|
+
if (isAligned && take === BLOCK_LEN) {
|
|
424
|
+
const pos32 = pos / 4;
|
|
425
|
+
if (pos % 4 !== 0)
|
|
426
|
+
throw new Error("arx: invalid block position");
|
|
427
|
+
for (let j = 0, posj; j < BLOCK_LEN32; j++) {
|
|
428
|
+
posj = pos32 + j;
|
|
429
|
+
o32[posj] = d32[posj] ^ b32[j];
|
|
430
|
+
}
|
|
431
|
+
pos += BLOCK_LEN;
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
for (let j = 0, posj; j < take; j++) {
|
|
435
|
+
posj = pos + j;
|
|
436
|
+
output[posj] = data[posj] ^ block[j];
|
|
437
|
+
}
|
|
438
|
+
pos += take;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
/** Creates ARX-like (ChaCha, Salsa) cipher stream from core function. */
|
|
442
|
+
function createCipher(core, opts) {
|
|
443
|
+
const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = checkOpts({
|
|
444
|
+
allowShortKeys: false,
|
|
445
|
+
counterLength: 8,
|
|
446
|
+
counterRight: false,
|
|
447
|
+
rounds: 20,
|
|
448
|
+
}, opts);
|
|
449
|
+
if (typeof core !== "function")
|
|
450
|
+
throw new Error("core must be a function");
|
|
451
|
+
anumber(counterLength);
|
|
452
|
+
anumber(rounds);
|
|
453
|
+
abool(counterRight);
|
|
454
|
+
abool(allowShortKeys);
|
|
455
|
+
return (key, nonce, data, output, counter = 0) => {
|
|
456
|
+
abytes(key, undefined, "key");
|
|
457
|
+
abytes(nonce, undefined, "nonce");
|
|
458
|
+
abytes(data, undefined, "data");
|
|
459
|
+
const len = data.length;
|
|
460
|
+
if (output === undefined)
|
|
461
|
+
output = new Uint8Array(len);
|
|
462
|
+
abytes(output, undefined, "output");
|
|
463
|
+
anumber(counter);
|
|
464
|
+
if (counter < 0 || counter >= MAX_COUNTER) {
|
|
465
|
+
throw new Error("arx: counter overflow");
|
|
466
|
+
}
|
|
467
|
+
if (output.length < len) {
|
|
468
|
+
throw new Error(`arx: output (${output.length}) is shorter than data (${len})`);
|
|
469
|
+
}
|
|
470
|
+
const toClean = [];
|
|
471
|
+
// Key & sigma
|
|
472
|
+
// key=16 -> sigma16, k=key|key
|
|
473
|
+
// key=32 -> sigma32, k=key
|
|
474
|
+
const l = key.length;
|
|
475
|
+
let k;
|
|
476
|
+
let sigma;
|
|
477
|
+
if (l === 32) {
|
|
478
|
+
toClean.push(k = copyBytes(key));
|
|
479
|
+
sigma = sigma32_32;
|
|
480
|
+
}
|
|
481
|
+
else if (l === 16 && allowShortKeys) {
|
|
482
|
+
k = new Uint8Array(32);
|
|
483
|
+
k.set(key);
|
|
484
|
+
k.set(key, 16);
|
|
485
|
+
sigma = sigma16_32;
|
|
486
|
+
toClean.push(k);
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
abytes(key, 32, "arx key");
|
|
490
|
+
throw new Error("invalid key size");
|
|
491
|
+
// throw new Error(`"arx key" expected Uint8Array of length 32, got length=${l}`);
|
|
492
|
+
}
|
|
493
|
+
// Nonce
|
|
494
|
+
// salsa20: 8 (8-byte counter)
|
|
495
|
+
// chacha20orig: 8 (8-byte counter)
|
|
496
|
+
// chacha20: 12 (4-byte counter)
|
|
497
|
+
// xsalsa20: 24 (16 -> hsalsa, 8 -> old nonce)
|
|
498
|
+
// xchacha20: 24 (16 -> hchacha, 8 -> old nonce)
|
|
499
|
+
// Align nonce to 4 bytes
|
|
500
|
+
if (!_arx_isAligned32(nonce))
|
|
501
|
+
toClean.push(nonce = copyBytes(nonce));
|
|
502
|
+
const k32 = u32(k);
|
|
503
|
+
// hsalsa & hchacha: handle extended nonce
|
|
504
|
+
if (extendNonceFn) {
|
|
505
|
+
if (nonce.length !== 24) {
|
|
506
|
+
throw new Error(`arx: extended nonce must be 24 bytes`);
|
|
507
|
+
}
|
|
508
|
+
extendNonceFn(sigma, k32, u32(nonce.subarray(0, 16)), k32);
|
|
509
|
+
nonce = nonce.subarray(16);
|
|
510
|
+
}
|
|
511
|
+
// Handle nonce counter
|
|
512
|
+
const nonceNcLen = 16 - counterLength;
|
|
513
|
+
if (nonceNcLen !== nonce.length) {
|
|
514
|
+
throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`);
|
|
515
|
+
}
|
|
516
|
+
// Pad counter when nonce is 64 bit
|
|
517
|
+
if (nonceNcLen !== 12) {
|
|
518
|
+
const nc = new Uint8Array(12);
|
|
519
|
+
nc.set(nonce, counterRight ? 0 : 12 - nonce.length);
|
|
520
|
+
nonce = nc;
|
|
521
|
+
toClean.push(nonce);
|
|
522
|
+
}
|
|
523
|
+
const n32 = u32(nonce);
|
|
524
|
+
runCipher(core, sigma, k32, n32, data, output, counter, rounds);
|
|
525
|
+
clean(...toClean);
|
|
526
|
+
return output;
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
;// ./node_modules/@hpke/chacha20poly1305/esm/src/chacha/_poly1305.js
|
|
531
|
+
/**
|
|
532
|
+
* This file is based on noble-ciphers (https://github.com/paulmillr/noble-ciphers).
|
|
533
|
+
*
|
|
534
|
+
* noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com)
|
|
535
|
+
*
|
|
536
|
+
* The original file is located at:
|
|
537
|
+
* https://github.com/paulmillr/noble-ciphers/blob/749cdf9cd07ebdd19e9b957d0f172f1045179695/src/_poly1305.ts
|
|
538
|
+
*/
|
|
539
|
+
/**
|
|
540
|
+
* Poly1305 ([PDF](https://cr.yp.to/mac/poly1305-20050329.pdf),
|
|
541
|
+
* [wiki](https://en.wikipedia.org/wiki/Poly1305))
|
|
542
|
+
* is a fast and parallel secret-key message-authentication code suitable for
|
|
543
|
+
* a wide variety of applications. It was standardized in
|
|
544
|
+
* [RFC 8439](https://www.rfc-editor.org/rfc/rfc8439) and is now used in TLS 1.3.
|
|
545
|
+
*
|
|
546
|
+
* Polynomial MACs are not perfect for every situation:
|
|
547
|
+
* they lack Random Key Robustness: the MAC can be forged, and can't be used in PAKE schemes.
|
|
548
|
+
* See [invisible salamanders attack](https://keymaterial.net/2020/09/07/invisible-salamanders-in-aes-gcm-siv/).
|
|
549
|
+
* To combat invisible salamanders, `hash(key)` can be included in ciphertext,
|
|
550
|
+
* however, this would violate ciphertext indistinguishability:
|
|
551
|
+
* an attacker would know which key was used - so `HKDF(key, i)`
|
|
552
|
+
* could be used instead.
|
|
553
|
+
*
|
|
554
|
+
* Check out [original website](https://cr.yp.to/mac.html).
|
|
555
|
+
* Based on Public Domain [poly1305-donna](https://github.com/floodyberry/poly1305-donna).
|
|
556
|
+
* @module
|
|
557
|
+
*/
|
|
558
|
+
// prettier-ignore
|
|
559
|
+
|
|
560
|
+
function u8to16(a, i) {
|
|
561
|
+
return (a[i++] & 0xff) | ((a[i++] & 0xff) << 8);
|
|
562
|
+
}
|
|
563
|
+
// function bytesToNumberLE(bytes: Uint8Array): bigint {
|
|
564
|
+
// return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
|
|
565
|
+
// }
|
|
566
|
+
// /** Small version of `poly1305` without loop unrolling. Unused, provided for auditability. */
|
|
567
|
+
// function poly1305_small(msg: Uint8Array, key: Uint8Array): Uint8Array {
|
|
568
|
+
// abytes(msg);
|
|
569
|
+
// abytes(key, 32, "key");
|
|
570
|
+
// const POW_2_130_5 = BigInt(2) ** BigInt(130) - BigInt(5); // 2^130-5
|
|
571
|
+
// const POW_2_128_1 = BigInt(2) ** BigInt(128) - BigInt(1); // 2^128-1
|
|
572
|
+
// const CLAMP_R = BigInt("0x0ffffffc0ffffffc0ffffffc0fffffff");
|
|
573
|
+
// const r = bytesToNumberLE(key.subarray(0, 16)) & CLAMP_R;
|
|
574
|
+
// const s = bytesToNumberLE(key.subarray(16));
|
|
575
|
+
// // Process by 16 byte chunks
|
|
576
|
+
// let acc = BigInt(0);
|
|
577
|
+
// for (let i = 0; i < msg.length; i += 16) {
|
|
578
|
+
// const m = msg.subarray(i, i + 16);
|
|
579
|
+
// const n = bytesToNumberLE(m) | (BigInt(1) << BigInt(8 * m.length));
|
|
580
|
+
// acc = ((acc + n) * r) % POW_2_130_5;
|
|
581
|
+
// }
|
|
582
|
+
// const res = (acc + s) & POW_2_128_1;
|
|
583
|
+
// return numberToBytesBE(res, 16).reverse(); // LE
|
|
584
|
+
// }
|
|
585
|
+
// Can be used to replace `computeTag` in chacha.ts. Unused, provided for auditability.
|
|
586
|
+
// function poly1305_computeTag_small(
|
|
587
|
+
// authKey: Uint8Array,
|
|
588
|
+
// lengths: Uint8Array,
|
|
589
|
+
// ciphertext: Uint8Array,
|
|
590
|
+
// AAD?: Uint8Array,
|
|
591
|
+
// ): Uint8Array {
|
|
592
|
+
// const res = [];
|
|
593
|
+
// const updatePadded2 = (msg: Uint8Array) => {
|
|
594
|
+
// res.push(msg);
|
|
595
|
+
// const leftover = msg.length % 16;
|
|
596
|
+
// if (leftover) res.push(new Uint8Array(16).slice(leftover));
|
|
597
|
+
// };
|
|
598
|
+
// if (AAD) updatePadded2(AAD);
|
|
599
|
+
// updatePadded2(ciphertext);
|
|
600
|
+
// res.push(lengths);
|
|
601
|
+
// return poly1305_small(concatBytes(...res), authKey);
|
|
602
|
+
// }
|
|
603
|
+
/** Poly1305 class. Prefer poly1305() function instead. */
|
|
604
|
+
class Poly1305 {
|
|
605
|
+
// Can be speed-up using BigUint64Array, at the cost of complexity
|
|
606
|
+
constructor(key) {
|
|
607
|
+
Object.defineProperty(this, "blockLen", {
|
|
608
|
+
enumerable: true,
|
|
609
|
+
configurable: true,
|
|
610
|
+
writable: true,
|
|
611
|
+
value: 16
|
|
612
|
+
});
|
|
613
|
+
Object.defineProperty(this, "outputLen", {
|
|
614
|
+
enumerable: true,
|
|
615
|
+
configurable: true,
|
|
616
|
+
writable: true,
|
|
617
|
+
value: 16
|
|
618
|
+
});
|
|
619
|
+
Object.defineProperty(this, "buffer", {
|
|
620
|
+
enumerable: true,
|
|
621
|
+
configurable: true,
|
|
622
|
+
writable: true,
|
|
623
|
+
value: new Uint8Array(16)
|
|
624
|
+
});
|
|
625
|
+
Object.defineProperty(this, "r", {
|
|
626
|
+
enumerable: true,
|
|
627
|
+
configurable: true,
|
|
628
|
+
writable: true,
|
|
629
|
+
value: new Uint16Array(10)
|
|
630
|
+
}); // Allocating 1 array with .subarray() here is slower than 3
|
|
631
|
+
Object.defineProperty(this, "h", {
|
|
632
|
+
enumerable: true,
|
|
633
|
+
configurable: true,
|
|
634
|
+
writable: true,
|
|
635
|
+
value: new Uint16Array(10)
|
|
636
|
+
});
|
|
637
|
+
Object.defineProperty(this, "pad", {
|
|
638
|
+
enumerable: true,
|
|
639
|
+
configurable: true,
|
|
640
|
+
writable: true,
|
|
641
|
+
value: new Uint16Array(8)
|
|
642
|
+
});
|
|
643
|
+
Object.defineProperty(this, "pos", {
|
|
644
|
+
enumerable: true,
|
|
645
|
+
configurable: true,
|
|
646
|
+
writable: true,
|
|
647
|
+
value: 0
|
|
648
|
+
});
|
|
649
|
+
Object.defineProperty(this, "finished", {
|
|
650
|
+
enumerable: true,
|
|
651
|
+
configurable: true,
|
|
652
|
+
writable: true,
|
|
653
|
+
value: false
|
|
654
|
+
});
|
|
655
|
+
key = copyBytes(abytes(key, 32, "key"));
|
|
656
|
+
const t0 = u8to16(key, 0);
|
|
657
|
+
const t1 = u8to16(key, 2);
|
|
658
|
+
const t2 = u8to16(key, 4);
|
|
659
|
+
const t3 = u8to16(key, 6);
|
|
660
|
+
const t4 = u8to16(key, 8);
|
|
661
|
+
const t5 = u8to16(key, 10);
|
|
662
|
+
const t6 = u8to16(key, 12);
|
|
663
|
+
const t7 = u8to16(key, 14);
|
|
664
|
+
// https://github.com/floodyberry/poly1305-donna/blob/e6ad6e091d30d7f4ec2d4f978be1fcfcbce72781/poly1305-donna-16.h#L47
|
|
665
|
+
this.r[0] = t0 & 0x1fff;
|
|
666
|
+
this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
|
|
667
|
+
this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;
|
|
668
|
+
this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
|
|
669
|
+
this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;
|
|
670
|
+
this.r[5] = (t4 >>> 1) & 0x1ffe;
|
|
671
|
+
this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
|
|
672
|
+
this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;
|
|
673
|
+
this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
|
|
674
|
+
this.r[9] = (t7 >>> 5) & 0x007f;
|
|
675
|
+
for (let i = 0; i < 8; i++)
|
|
676
|
+
this.pad[i] = u8to16(key, 16 + 2 * i);
|
|
677
|
+
}
|
|
678
|
+
process(data, offset, isLast = false) {
|
|
679
|
+
const hibit = isLast ? 0 : 1 << 11;
|
|
680
|
+
const { h, r } = this;
|
|
681
|
+
const r0 = r[0];
|
|
682
|
+
const r1 = r[1];
|
|
683
|
+
const r2 = r[2];
|
|
684
|
+
const r3 = r[3];
|
|
685
|
+
const r4 = r[4];
|
|
686
|
+
const r5 = r[5];
|
|
687
|
+
const r6 = r[6];
|
|
688
|
+
const r7 = r[7];
|
|
689
|
+
const r8 = r[8];
|
|
690
|
+
const r9 = r[9];
|
|
691
|
+
const t0 = u8to16(data, offset + 0);
|
|
692
|
+
const t1 = u8to16(data, offset + 2);
|
|
693
|
+
const t2 = u8to16(data, offset + 4);
|
|
694
|
+
const t3 = u8to16(data, offset + 6);
|
|
695
|
+
const t4 = u8to16(data, offset + 8);
|
|
696
|
+
const t5 = u8to16(data, offset + 10);
|
|
697
|
+
const t6 = u8to16(data, offset + 12);
|
|
698
|
+
const t7 = u8to16(data, offset + 14);
|
|
699
|
+
const h0 = h[0] + (t0 & 0x1fff);
|
|
700
|
+
const h1 = h[1] + (((t0 >>> 13) | (t1 << 3)) & 0x1fff);
|
|
701
|
+
const h2 = h[2] + (((t1 >>> 10) | (t2 << 6)) & 0x1fff);
|
|
702
|
+
const h3 = h[3] + (((t2 >>> 7) | (t3 << 9)) & 0x1fff);
|
|
703
|
+
const h4 = h[4] + (((t3 >>> 4) | (t4 << 12)) & 0x1fff);
|
|
704
|
+
const h5 = h[5] + ((t4 >>> 1) & 0x1fff);
|
|
705
|
+
const h6 = h[6] + (((t4 >>> 14) | (t5 << 2)) & 0x1fff);
|
|
706
|
+
const h7 = h[7] + (((t5 >>> 11) | (t6 << 5)) & 0x1fff);
|
|
707
|
+
const h8 = h[8] + (((t6 >>> 8) | (t7 << 8)) & 0x1fff);
|
|
708
|
+
const h9 = h[9] + ((t7 >>> 5) | hibit);
|
|
709
|
+
let c = 0;
|
|
710
|
+
let d0 = c + h0 * r0 + h1 * (5 * r9) + h2 * (5 * r8) + h3 * (5 * r7) +
|
|
711
|
+
h4 * (5 * r6);
|
|
712
|
+
c = d0 >>> 13;
|
|
713
|
+
d0 &= 0x1fff;
|
|
714
|
+
d0 += h5 * (5 * r5) + h6 * (5 * r4) + h7 * (5 * r3) + h8 * (5 * r2) +
|
|
715
|
+
h9 * (5 * r1);
|
|
716
|
+
c += d0 >>> 13;
|
|
717
|
+
d0 &= 0x1fff;
|
|
718
|
+
let d1 = c + h0 * r1 + h1 * r0 + h2 * (5 * r9) + h3 * (5 * r8) +
|
|
719
|
+
h4 * (5 * r7);
|
|
720
|
+
c = d1 >>> 13;
|
|
721
|
+
d1 &= 0x1fff;
|
|
722
|
+
d1 += h5 * (5 * r6) + h6 * (5 * r5) + h7 * (5 * r4) + h8 * (5 * r3) +
|
|
723
|
+
h9 * (5 * r2);
|
|
724
|
+
c += d1 >>> 13;
|
|
725
|
+
d1 &= 0x1fff;
|
|
726
|
+
let d2 = c + h0 * r2 + h1 * r1 + h2 * r0 + h3 * (5 * r9) + h4 * (5 * r8);
|
|
727
|
+
c = d2 >>> 13;
|
|
728
|
+
d2 &= 0x1fff;
|
|
729
|
+
d2 += h5 * (5 * r7) + h6 * (5 * r6) + h7 * (5 * r5) + h8 * (5 * r4) +
|
|
730
|
+
h9 * (5 * r3);
|
|
731
|
+
c += d2 >>> 13;
|
|
732
|
+
d2 &= 0x1fff;
|
|
733
|
+
let d3 = c + h0 * r3 + h1 * r2 + h2 * r1 + h3 * r0 + h4 * (5 * r9);
|
|
734
|
+
c = d3 >>> 13;
|
|
735
|
+
d3 &= 0x1fff;
|
|
736
|
+
d3 += h5 * (5 * r8) + h6 * (5 * r7) + h7 * (5 * r6) + h8 * (5 * r5) +
|
|
737
|
+
h9 * (5 * r4);
|
|
738
|
+
c += d3 >>> 13;
|
|
739
|
+
d3 &= 0x1fff;
|
|
740
|
+
let d4 = c + h0 * r4 + h1 * r3 + h2 * r2 + h3 * r1 + h4 * r0;
|
|
741
|
+
c = d4 >>> 13;
|
|
742
|
+
d4 &= 0x1fff;
|
|
743
|
+
d4 += h5 * (5 * r9) + h6 * (5 * r8) + h7 * (5 * r7) + h8 * (5 * r6) +
|
|
744
|
+
h9 * (5 * r5);
|
|
745
|
+
c += d4 >>> 13;
|
|
746
|
+
d4 &= 0x1fff;
|
|
747
|
+
let d5 = c + h0 * r5 + h1 * r4 + h2 * r3 + h3 * r2 + h4 * r1;
|
|
748
|
+
c = d5 >>> 13;
|
|
749
|
+
d5 &= 0x1fff;
|
|
750
|
+
d5 += h5 * r0 + h6 * (5 * r9) + h7 * (5 * r8) + h8 * (5 * r7) +
|
|
751
|
+
h9 * (5 * r6);
|
|
752
|
+
c += d5 >>> 13;
|
|
753
|
+
d5 &= 0x1fff;
|
|
754
|
+
let d6 = c + h0 * r6 + h1 * r5 + h2 * r4 + h3 * r3 + h4 * r2;
|
|
755
|
+
c = d6 >>> 13;
|
|
756
|
+
d6 &= 0x1fff;
|
|
757
|
+
d6 += h5 * r1 + h6 * r0 + h7 * (5 * r9) + h8 * (5 * r8) + h9 * (5 * r7);
|
|
758
|
+
c += d6 >>> 13;
|
|
759
|
+
d6 &= 0x1fff;
|
|
760
|
+
let d7 = c + h0 * r7 + h1 * r6 + h2 * r5 + h3 * r4 + h4 * r3;
|
|
761
|
+
c = d7 >>> 13;
|
|
762
|
+
d7 &= 0x1fff;
|
|
763
|
+
d7 += h5 * r2 + h6 * r1 + h7 * r0 + h8 * (5 * r9) + h9 * (5 * r8);
|
|
764
|
+
c += d7 >>> 13;
|
|
765
|
+
d7 &= 0x1fff;
|
|
766
|
+
let d8 = c + h0 * r8 + h1 * r7 + h2 * r6 + h3 * r5 + h4 * r4;
|
|
767
|
+
c = d8 >>> 13;
|
|
768
|
+
d8 &= 0x1fff;
|
|
769
|
+
d8 += h5 * r3 + h6 * r2 + h7 * r1 + h8 * r0 + h9 * (5 * r9);
|
|
770
|
+
c += d8 >>> 13;
|
|
771
|
+
d8 &= 0x1fff;
|
|
772
|
+
let d9 = c + h0 * r9 + h1 * r8 + h2 * r7 + h3 * r6 + h4 * r5;
|
|
773
|
+
c = d9 >>> 13;
|
|
774
|
+
d9 &= 0x1fff;
|
|
775
|
+
d9 += h5 * r4 + h6 * r3 + h7 * r2 + h8 * r1 + h9 * r0;
|
|
776
|
+
c += d9 >>> 13;
|
|
777
|
+
d9 &= 0x1fff;
|
|
778
|
+
c = ((c << 2) + c) | 0;
|
|
779
|
+
c = (c + d0) | 0;
|
|
780
|
+
d0 = c & 0x1fff;
|
|
781
|
+
c = c >>> 13;
|
|
782
|
+
d1 += c;
|
|
783
|
+
h[0] = d0;
|
|
784
|
+
h[1] = d1;
|
|
785
|
+
h[2] = d2;
|
|
786
|
+
h[3] = d3;
|
|
787
|
+
h[4] = d4;
|
|
788
|
+
h[5] = d5;
|
|
789
|
+
h[6] = d6;
|
|
790
|
+
h[7] = d7;
|
|
791
|
+
h[8] = d8;
|
|
792
|
+
h[9] = d9;
|
|
793
|
+
}
|
|
794
|
+
finalize() {
|
|
795
|
+
const { h, pad } = this;
|
|
796
|
+
const g = new Uint16Array(10);
|
|
797
|
+
let c = h[1] >>> 13;
|
|
798
|
+
h[1] &= 0x1fff;
|
|
799
|
+
for (let i = 2; i < 10; i++) {
|
|
800
|
+
h[i] += c;
|
|
801
|
+
c = h[i] >>> 13;
|
|
802
|
+
h[i] &= 0x1fff;
|
|
803
|
+
}
|
|
804
|
+
h[0] += c * 5;
|
|
805
|
+
c = h[0] >>> 13;
|
|
806
|
+
h[0] &= 0x1fff;
|
|
807
|
+
h[1] += c;
|
|
808
|
+
c = h[1] >>> 13;
|
|
809
|
+
h[1] &= 0x1fff;
|
|
810
|
+
h[2] += c;
|
|
811
|
+
g[0] = h[0] + 5;
|
|
812
|
+
c = g[0] >>> 13;
|
|
813
|
+
g[0] &= 0x1fff;
|
|
814
|
+
for (let i = 1; i < 10; i++) {
|
|
815
|
+
g[i] = h[i] + c;
|
|
816
|
+
c = g[i] >>> 13;
|
|
817
|
+
g[i] &= 0x1fff;
|
|
818
|
+
}
|
|
819
|
+
g[9] -= 1 << 13;
|
|
820
|
+
let mask = (c ^ 1) - 1;
|
|
821
|
+
for (let i = 0; i < 10; i++)
|
|
822
|
+
g[i] &= mask;
|
|
823
|
+
mask = ~mask;
|
|
824
|
+
for (let i = 0; i < 10; i++)
|
|
825
|
+
h[i] = (h[i] & mask) | g[i];
|
|
826
|
+
h[0] = (h[0] | (h[1] << 13)) & 0xffff;
|
|
827
|
+
h[1] = ((h[1] >>> 3) | (h[2] << 10)) & 0xffff;
|
|
828
|
+
h[2] = ((h[2] >>> 6) | (h[3] << 7)) & 0xffff;
|
|
829
|
+
h[3] = ((h[3] >>> 9) | (h[4] << 4)) & 0xffff;
|
|
830
|
+
h[4] = ((h[4] >>> 12) | (h[5] << 1) | (h[6] << 14)) & 0xffff;
|
|
831
|
+
h[5] = ((h[6] >>> 2) | (h[7] << 11)) & 0xffff;
|
|
832
|
+
h[6] = ((h[7] >>> 5) | (h[8] << 8)) & 0xffff;
|
|
833
|
+
h[7] = ((h[8] >>> 8) | (h[9] << 5)) & 0xffff;
|
|
834
|
+
let f = h[0] + pad[0];
|
|
835
|
+
h[0] = f & 0xffff;
|
|
836
|
+
for (let i = 1; i < 8; i++) {
|
|
837
|
+
f = (((h[i] + pad[i]) | 0) + (f >>> 16)) | 0;
|
|
838
|
+
h[i] = f & 0xffff;
|
|
839
|
+
}
|
|
840
|
+
clean(g);
|
|
841
|
+
}
|
|
842
|
+
update(data) {
|
|
843
|
+
aexists(this);
|
|
844
|
+
abytes(data);
|
|
845
|
+
data = copyBytes(data);
|
|
846
|
+
const { buffer, blockLen } = this;
|
|
847
|
+
const len = data.length;
|
|
848
|
+
for (let pos = 0; pos < len;) {
|
|
849
|
+
const take = Math.min(blockLen - this.pos, len - pos);
|
|
850
|
+
// Fast path: we have at least one block in input
|
|
851
|
+
if (take === blockLen) {
|
|
852
|
+
for (; blockLen <= len - pos; pos += blockLen)
|
|
853
|
+
this.process(data, pos);
|
|
854
|
+
continue;
|
|
855
|
+
}
|
|
856
|
+
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
857
|
+
this.pos += take;
|
|
858
|
+
pos += take;
|
|
859
|
+
if (this.pos === blockLen) {
|
|
860
|
+
this.process(buffer, 0, false);
|
|
861
|
+
this.pos = 0;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
return this;
|
|
865
|
+
}
|
|
866
|
+
destroy() {
|
|
867
|
+
clean(this.h, this.r, this.buffer, this.pad);
|
|
868
|
+
}
|
|
869
|
+
digestInto(out) {
|
|
870
|
+
aexists(this);
|
|
871
|
+
aoutput(out, this);
|
|
872
|
+
this.finished = true;
|
|
873
|
+
const { buffer, h } = this;
|
|
874
|
+
let { pos } = this;
|
|
875
|
+
if (pos) {
|
|
876
|
+
buffer[pos++] = 1;
|
|
877
|
+
for (; pos < 16; pos++)
|
|
878
|
+
buffer[pos] = 0;
|
|
879
|
+
this.process(buffer, 0, true);
|
|
880
|
+
}
|
|
881
|
+
this.finalize();
|
|
882
|
+
let opos = 0;
|
|
883
|
+
for (let i = 0; i < 8; i++) {
|
|
884
|
+
out[opos++] = h[i] >>> 0;
|
|
885
|
+
out[opos++] = h[i] >>> 8;
|
|
886
|
+
}
|
|
887
|
+
return out;
|
|
888
|
+
}
|
|
889
|
+
digest() {
|
|
890
|
+
const { buffer, outputLen } = this;
|
|
891
|
+
this.digestInto(buffer);
|
|
892
|
+
const res = buffer.slice(0, outputLen);
|
|
893
|
+
this.destroy();
|
|
894
|
+
return res;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
function wrapConstructorWithKey(hashCons) {
|
|
898
|
+
const hashC = (msg, key) => hashCons(key).update(msg).digest();
|
|
899
|
+
const tmp = hashCons(new Uint8Array(32)); // tmp array, used just once below
|
|
900
|
+
hashC.outputLen = tmp.outputLen;
|
|
901
|
+
hashC.blockLen = tmp.blockLen;
|
|
902
|
+
hashC.create = (key) => hashCons(key);
|
|
903
|
+
return hashC;
|
|
904
|
+
}
|
|
905
|
+
/** Poly1305 MAC from RFC 8439. */
|
|
906
|
+
const poly1305 =
|
|
907
|
+
/** @__PURE__ */ (() => wrapConstructorWithKey((key) => new Poly1305(key)))();
|
|
908
|
+
|
|
909
|
+
;// ./node_modules/@hpke/chacha20poly1305/esm/src/chacha/chacha.js
|
|
910
|
+
/**
|
|
911
|
+
* This file is based on noble-ciphers (https://github.com/paulmillr/noble-ciphers).
|
|
912
|
+
*
|
|
913
|
+
* noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com)
|
|
914
|
+
*
|
|
915
|
+
* The original file is located at:
|
|
916
|
+
* https://github.com/paulmillr/noble-ciphers/blob/749cdf9cd07ebdd19e9b957d0f172f1045179695/src/chacha.ts
|
|
917
|
+
*/
|
|
918
|
+
/**
|
|
919
|
+
* ChaCha stream cipher, released
|
|
920
|
+
* in 2008. Developed after Salsa20, ChaCha aims to increase diffusion per round.
|
|
921
|
+
* It was standardized in [RFC 8439](https://www.rfc-editor.org/rfc/rfc8439) and
|
|
922
|
+
* is now used in TLS 1.3.
|
|
923
|
+
*
|
|
924
|
+
* [XChaCha20](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha)
|
|
925
|
+
* extended-nonce variant is also provided. Similar to XSalsa, it's safe to use with
|
|
926
|
+
* randomly-generated nonces.
|
|
927
|
+
*
|
|
928
|
+
* Check out [PDF](http://cr.yp.to/chacha/chacha-20080128.pdf) and
|
|
929
|
+
* [wiki](https://en.wikipedia.org/wiki/Salsa20) and
|
|
930
|
+
* [website](https://cr.yp.to/chacha.html).
|
|
931
|
+
*
|
|
932
|
+
* @module
|
|
933
|
+
*/
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
|
|
937
|
+
/**
|
|
938
|
+
* ChaCha core function. It is implemented twice:
|
|
939
|
+
* 1. Simple loop (chachaCore_small, hchacha_small)
|
|
940
|
+
* 2. Unrolled loop (chachaCore, hchacha) - 4x faster, but larger & harder to read
|
|
941
|
+
* The specific implementation is selected in `createCipher` below.
|
|
942
|
+
*/
|
|
943
|
+
function chachaCore(s, k, n, out, cnt, rounds = 20) {
|
|
944
|
+
const y00 = s[0], y01 = s[1], y02 = s[2], y03 = s[3], // "expa" "nd 3" "2-by" "te k"
|
|
945
|
+
y04 = k[0], y05 = k[1], y06 = k[2], y07 = k[3], // Key Key Key Key
|
|
946
|
+
y08 = k[4], y09 = k[5], y10 = k[6], y11 = k[7], // Key Key Key Key
|
|
947
|
+
y12 = cnt, y13 = n[0], y14 = n[1], y15 = n[2]; // Counter Counter Nonce Nonce
|
|
948
|
+
// Save state to temporary variables
|
|
949
|
+
let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15;
|
|
950
|
+
for (let r = 0; r < rounds; r += 2) {
|
|
951
|
+
x00 = (x00 + x04) | 0;
|
|
952
|
+
x12 = rotl(x12 ^ x00, 16);
|
|
953
|
+
x08 = (x08 + x12) | 0;
|
|
954
|
+
x04 = rotl(x04 ^ x08, 12);
|
|
955
|
+
x00 = (x00 + x04) | 0;
|
|
956
|
+
x12 = rotl(x12 ^ x00, 8);
|
|
957
|
+
x08 = (x08 + x12) | 0;
|
|
958
|
+
x04 = rotl(x04 ^ x08, 7);
|
|
959
|
+
x01 = (x01 + x05) | 0;
|
|
960
|
+
x13 = rotl(x13 ^ x01, 16);
|
|
961
|
+
x09 = (x09 + x13) | 0;
|
|
962
|
+
x05 = rotl(x05 ^ x09, 12);
|
|
963
|
+
x01 = (x01 + x05) | 0;
|
|
964
|
+
x13 = rotl(x13 ^ x01, 8);
|
|
965
|
+
x09 = (x09 + x13) | 0;
|
|
966
|
+
x05 = rotl(x05 ^ x09, 7);
|
|
967
|
+
x02 = (x02 + x06) | 0;
|
|
968
|
+
x14 = rotl(x14 ^ x02, 16);
|
|
969
|
+
x10 = (x10 + x14) | 0;
|
|
970
|
+
x06 = rotl(x06 ^ x10, 12);
|
|
971
|
+
x02 = (x02 + x06) | 0;
|
|
972
|
+
x14 = rotl(x14 ^ x02, 8);
|
|
973
|
+
x10 = (x10 + x14) | 0;
|
|
974
|
+
x06 = rotl(x06 ^ x10, 7);
|
|
975
|
+
x03 = (x03 + x07) | 0;
|
|
976
|
+
x15 = rotl(x15 ^ x03, 16);
|
|
977
|
+
x11 = (x11 + x15) | 0;
|
|
978
|
+
x07 = rotl(x07 ^ x11, 12);
|
|
979
|
+
x03 = (x03 + x07) | 0;
|
|
980
|
+
x15 = rotl(x15 ^ x03, 8);
|
|
981
|
+
x11 = (x11 + x15) | 0;
|
|
982
|
+
x07 = rotl(x07 ^ x11, 7);
|
|
983
|
+
x00 = (x00 + x05) | 0;
|
|
984
|
+
x15 = rotl(x15 ^ x00, 16);
|
|
985
|
+
x10 = (x10 + x15) | 0;
|
|
986
|
+
x05 = rotl(x05 ^ x10, 12);
|
|
987
|
+
x00 = (x00 + x05) | 0;
|
|
988
|
+
x15 = rotl(x15 ^ x00, 8);
|
|
989
|
+
x10 = (x10 + x15) | 0;
|
|
990
|
+
x05 = rotl(x05 ^ x10, 7);
|
|
991
|
+
x01 = (x01 + x06) | 0;
|
|
992
|
+
x12 = rotl(x12 ^ x01, 16);
|
|
993
|
+
x11 = (x11 + x12) | 0;
|
|
994
|
+
x06 = rotl(x06 ^ x11, 12);
|
|
995
|
+
x01 = (x01 + x06) | 0;
|
|
996
|
+
x12 = rotl(x12 ^ x01, 8);
|
|
997
|
+
x11 = (x11 + x12) | 0;
|
|
998
|
+
x06 = rotl(x06 ^ x11, 7);
|
|
999
|
+
x02 = (x02 + x07) | 0;
|
|
1000
|
+
x13 = rotl(x13 ^ x02, 16);
|
|
1001
|
+
x08 = (x08 + x13) | 0;
|
|
1002
|
+
x07 = rotl(x07 ^ x08, 12);
|
|
1003
|
+
x02 = (x02 + x07) | 0;
|
|
1004
|
+
x13 = rotl(x13 ^ x02, 8);
|
|
1005
|
+
x08 = (x08 + x13) | 0;
|
|
1006
|
+
x07 = rotl(x07 ^ x08, 7);
|
|
1007
|
+
x03 = (x03 + x04) | 0;
|
|
1008
|
+
x14 = rotl(x14 ^ x03, 16);
|
|
1009
|
+
x09 = (x09 + x14) | 0;
|
|
1010
|
+
x04 = rotl(x04 ^ x09, 12);
|
|
1011
|
+
x03 = (x03 + x04) | 0;
|
|
1012
|
+
x14 = rotl(x14 ^ x03, 8);
|
|
1013
|
+
x09 = (x09 + x14) | 0;
|
|
1014
|
+
x04 = rotl(x04 ^ x09, 7);
|
|
1015
|
+
}
|
|
1016
|
+
// Write output
|
|
1017
|
+
let oi = 0;
|
|
1018
|
+
out[oi++] = (y00 + x00) | 0;
|
|
1019
|
+
out[oi++] = (y01 + x01) | 0;
|
|
1020
|
+
out[oi++] = (y02 + x02) | 0;
|
|
1021
|
+
out[oi++] = (y03 + x03) | 0;
|
|
1022
|
+
out[oi++] = (y04 + x04) | 0;
|
|
1023
|
+
out[oi++] = (y05 + x05) | 0;
|
|
1024
|
+
out[oi++] = (y06 + x06) | 0;
|
|
1025
|
+
out[oi++] = (y07 + x07) | 0;
|
|
1026
|
+
out[oi++] = (y08 + x08) | 0;
|
|
1027
|
+
out[oi++] = (y09 + x09) | 0;
|
|
1028
|
+
out[oi++] = (y10 + x10) | 0;
|
|
1029
|
+
out[oi++] = (y11 + x11) | 0;
|
|
1030
|
+
out[oi++] = (y12 + x12) | 0;
|
|
1031
|
+
out[oi++] = (y13 + x13) | 0;
|
|
1032
|
+
out[oi++] = (y14 + x14) | 0;
|
|
1033
|
+
out[oi++] = (y15 + x15) | 0;
|
|
1034
|
+
}
|
|
1035
|
+
/**
|
|
1036
|
+
* ChaCha stream cipher. Conforms to RFC 8439 (IETF, TLS). 12-byte nonce, 4-byte counter.
|
|
1037
|
+
* With smaller nonce, it's not safe to make it random (CSPRNG), due to collision chance.
|
|
1038
|
+
*/
|
|
1039
|
+
const chacha20 = /* @__PURE__ */ createCipher(chachaCore, {
|
|
1040
|
+
counterRight: false,
|
|
1041
|
+
counterLength: 4,
|
|
1042
|
+
allowShortKeys: false,
|
|
1043
|
+
});
|
|
1044
|
+
const ZEROS16 = /* @__PURE__ */ new Uint8Array(16);
|
|
1045
|
+
// Pad to digest size with zeros
|
|
1046
|
+
const updatePadded = (h, msg) => {
|
|
1047
|
+
h.update(msg);
|
|
1048
|
+
const leftover = msg.length % 16;
|
|
1049
|
+
if (leftover)
|
|
1050
|
+
h.update(ZEROS16.subarray(leftover));
|
|
1051
|
+
};
|
|
1052
|
+
const ZEROS32 = /* @__PURE__ */ new Uint8Array(32);
|
|
1053
|
+
function computeTag(fn, key, nonce, ciphertext, AAD) {
|
|
1054
|
+
if (AAD !== undefined)
|
|
1055
|
+
abytes(AAD, undefined, "AAD");
|
|
1056
|
+
const authKey = fn(key, nonce, ZEROS32);
|
|
1057
|
+
const lengths = u64Lengths(ciphertext.length, AAD ? AAD.length : 0, true);
|
|
1058
|
+
// Methods below can be replaced with
|
|
1059
|
+
// return poly1305_computeTag_small(authKey, lengths, ciphertext, AAD)
|
|
1060
|
+
const h = poly1305.create(authKey);
|
|
1061
|
+
if (AAD)
|
|
1062
|
+
updatePadded(h, AAD);
|
|
1063
|
+
updatePadded(h, ciphertext);
|
|
1064
|
+
h.update(lengths);
|
|
1065
|
+
const res = h.digest();
|
|
1066
|
+
clean(authKey, lengths);
|
|
1067
|
+
return res;
|
|
1068
|
+
}
|
|
1069
|
+
/**
|
|
1070
|
+
* AEAD algorithm from RFC 8439.
|
|
1071
|
+
* Salsa20 and chacha (RFC 8439) use poly1305 differently.
|
|
1072
|
+
* We could have composed them, but it's hard because of authKey:
|
|
1073
|
+
* In salsa20, authKey changes position in salsa stream.
|
|
1074
|
+
* In chacha, authKey can't be computed inside computeTag, it modifies the counter.
|
|
1075
|
+
*/
|
|
1076
|
+
const _poly1305_aead = (xorStream) => (key, nonce, AAD) => {
|
|
1077
|
+
const tagLength = 16;
|
|
1078
|
+
return {
|
|
1079
|
+
encrypt(plaintext, output) {
|
|
1080
|
+
const plength = plaintext.length;
|
|
1081
|
+
output = getOutput(plength + tagLength, output, false);
|
|
1082
|
+
output.set(plaintext);
|
|
1083
|
+
const oPlain = output.subarray(0, -tagLength);
|
|
1084
|
+
// Actual encryption
|
|
1085
|
+
xorStream(key, nonce, oPlain, oPlain, 1);
|
|
1086
|
+
const tag = computeTag(xorStream, key, nonce, oPlain, AAD);
|
|
1087
|
+
output.set(tag, plength); // append tag
|
|
1088
|
+
clean(tag);
|
|
1089
|
+
return output;
|
|
1090
|
+
},
|
|
1091
|
+
decrypt(ciphertext, output) {
|
|
1092
|
+
output = getOutput(ciphertext.length - tagLength, output, false);
|
|
1093
|
+
const data = ciphertext.subarray(0, -tagLength);
|
|
1094
|
+
const passedTag = ciphertext.subarray(-tagLength);
|
|
1095
|
+
const tag = computeTag(xorStream, key, nonce, data, AAD);
|
|
1096
|
+
if (!equalBytes(passedTag, tag))
|
|
1097
|
+
throw new Error("invalid tag");
|
|
1098
|
+
output.set(ciphertext.subarray(0, -tagLength));
|
|
1099
|
+
// Actual decryption
|
|
1100
|
+
xorStream(key, nonce, output, output, 1); // start stream with i=1
|
|
1101
|
+
clean(tag);
|
|
1102
|
+
return output;
|
|
1103
|
+
},
|
|
1104
|
+
};
|
|
1105
|
+
};
|
|
1106
|
+
/**
|
|
1107
|
+
* ChaCha20-Poly1305 from RFC 8439.
|
|
1108
|
+
*
|
|
1109
|
+
* Unsafe to use random nonces under the same key, due to collision chance.
|
|
1110
|
+
* Prefer XChaCha instead.
|
|
1111
|
+
*/
|
|
1112
|
+
const chacha20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 12, tagLength: 16 }, _poly1305_aead(chacha20));
|
|
1113
|
+
|
|
1114
|
+
// EXTERNAL MODULE: ./node_modules/@hpke/common/esm/mod.js + 23 modules
|
|
1115
|
+
var mod = __webpack_require__("./node_modules/@hpke/common/esm/mod.js");
|
|
1116
|
+
;// ./node_modules/@hpke/chacha20poly1305/esm/src/chacha20Poly1305.js
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
class Chacha20Poly1305Context {
|
|
1120
|
+
constructor(key) {
|
|
1121
|
+
Object.defineProperty(this, "_key", {
|
|
1122
|
+
enumerable: true,
|
|
1123
|
+
configurable: true,
|
|
1124
|
+
writable: true,
|
|
1125
|
+
value: void 0
|
|
1126
|
+
});
|
|
1127
|
+
this._key = new Uint8Array(key);
|
|
1128
|
+
}
|
|
1129
|
+
async seal(iv, data, aad) {
|
|
1130
|
+
return await this._seal(iv, data, aad);
|
|
1131
|
+
}
|
|
1132
|
+
async open(iv, data, aad) {
|
|
1133
|
+
return await this._open(iv, data, aad);
|
|
1134
|
+
}
|
|
1135
|
+
_seal(iv, data, aad) {
|
|
1136
|
+
return new Promise((resolve) => {
|
|
1137
|
+
const ret = chacha20poly1305(this._key, new Uint8Array(iv), new Uint8Array(aad)).encrypt(new Uint8Array(data));
|
|
1138
|
+
resolve(ret.buffer);
|
|
1139
|
+
});
|
|
1140
|
+
}
|
|
1141
|
+
_open(iv, data, aad) {
|
|
1142
|
+
return new Promise((resolve) => {
|
|
1143
|
+
const ret = chacha20poly1305(this._key, new Uint8Array(iv), new Uint8Array(aad)).decrypt(new Uint8Array(data));
|
|
1144
|
+
resolve(ret.buffer);
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
/**
|
|
1149
|
+
* The ChaCha20Poly1305 for HPKE AEAD implementing {@link AeadInterface}.
|
|
1150
|
+
*
|
|
1151
|
+
* When using `@hpke/core`, the instance of this class can be specified
|
|
1152
|
+
* to the `aead` parameter of {@link CipherSuiteParams} instead of `AeadId.Chacha20Poly1305`
|
|
1153
|
+
* as follows:
|
|
1154
|
+
*
|
|
1155
|
+
* @example
|
|
1156
|
+
*
|
|
1157
|
+
* ```ts
|
|
1158
|
+
* import {
|
|
1159
|
+
* CipherSuite,
|
|
1160
|
+
* DhkemP256HkdfSha256,
|
|
1161
|
+
* HkdfSha256,
|
|
1162
|
+
* } from "@hpke/core";
|
|
1163
|
+
* import {
|
|
1164
|
+
* Chacha20Poly1305,
|
|
1165
|
+
* } from "@hpke/chacha20poly1305";
|
|
1166
|
+
*
|
|
1167
|
+
* const suite = new CipherSuite({
|
|
1168
|
+
* kem: new DhkemP256HkdfSha256(),
|
|
1169
|
+
* kdf: new HkdfSha256(),
|
|
1170
|
+
* aead: new Chacha20Poly1305(),
|
|
1171
|
+
* });
|
|
1172
|
+
* ```
|
|
1173
|
+
*
|
|
1174
|
+
* This class is implemented using
|
|
1175
|
+
* {@link https://github.com/paulmillr/noble-ciphers | @noble/ciphers}.
|
|
1176
|
+
*/
|
|
1177
|
+
class Chacha20Poly1305 {
|
|
1178
|
+
constructor() {
|
|
1179
|
+
/** AeadId.Chacha20Poly1305 (0x0003) */
|
|
1180
|
+
Object.defineProperty(this, "id", {
|
|
1181
|
+
enumerable: true,
|
|
1182
|
+
configurable: true,
|
|
1183
|
+
writable: true,
|
|
1184
|
+
value: mod.AeadId.Chacha20Poly1305
|
|
1185
|
+
});
|
|
1186
|
+
/** 32 */
|
|
1187
|
+
Object.defineProperty(this, "keySize", {
|
|
1188
|
+
enumerable: true,
|
|
1189
|
+
configurable: true,
|
|
1190
|
+
writable: true,
|
|
1191
|
+
value: 32
|
|
1192
|
+
});
|
|
1193
|
+
/** 12 */
|
|
1194
|
+
Object.defineProperty(this, "nonceSize", {
|
|
1195
|
+
enumerable: true,
|
|
1196
|
+
configurable: true,
|
|
1197
|
+
writable: true,
|
|
1198
|
+
value: 12
|
|
1199
|
+
});
|
|
1200
|
+
/** 16 */
|
|
1201
|
+
Object.defineProperty(this, "tagSize", {
|
|
1202
|
+
enumerable: true,
|
|
1203
|
+
configurable: true,
|
|
1204
|
+
writable: true,
|
|
1205
|
+
value: 16
|
|
1206
|
+
});
|
|
1207
|
+
}
|
|
1208
|
+
createEncryptionContext(key) {
|
|
1209
|
+
return new Chacha20Poly1305Context(key);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
;// ./node_modules/@hpke/chacha20poly1305/esm/mod.js
|
|
1214
|
+
|
|
1215
|
+
|
|
1216
|
+
|
|
1217
|
+
/***/ })
|
|
1218
|
+
|
|
1219
|
+
}]);
|
|
1220
|
+
//# sourceMappingURL=defaultVendors-node_modules_hpke_chacha20poly1305_esm_mod_js.shogun-core.js.map
|