refactor: 推翻舊架構, 進入 Vite 盛世!
* 所有的 CDN 依賴已全部 npm 化 * Webpack? 一邊去! Vite 太好用啦! * 將 Imports.ts 剔除 * 移除了大量的靜態文件 * 將 index.html 的部分代碼分離 * 修改 deno task * 移除了動態編譯頁面的支持 * ./static 引用全部變更為 npm 包引用
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,3 +4,4 @@ thewhitesilk_config.json
|
||||
thewhitesilk_data/
|
||||
|
||||
deno.lock
|
||||
node_modules/
|
||||
@@ -1,9 +1,9 @@
|
||||
import { CryptoES } from './Imports.ts'
|
||||
import * as CryptoES from 'crypto-es'
|
||||
|
||||
const dataIsEmpty = !localStorage.tws_data || localStorage.tws_data == ''
|
||||
|
||||
const aes = {
|
||||
enc: (m: string, k: string) => CryptoES.AES.encrypt(m, k).toString(CryptoES.Utf8),
|
||||
enc: (m: string, k: string) => CryptoES.AES.encrypt(m, k).toString(CryptoES.HexFormatter),
|
||||
dec: (m: string, k: string) => CryptoES.AES.decrypt(m, k).toString(CryptoES.Utf8),
|
||||
}
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
// @ts-types="./typedef/react@18.3.18.d.ts"
|
||||
import * as React from './static/react-esm-18.3.1.static.js'
|
||||
import * as ReactDOM from './static/react-dom-esm-18.3.1.static.js'
|
||||
import * as CryptoES from './static/crypto-es-3.1.0.static.mjs'
|
||||
|
||||
import type { Dialog } from 'https://unpkg.com/mdui@2.1.4/components/dialog/index.d.ts'
|
||||
import type { TextField } from 'https://unpkg.com/mdui@2.1.4/components/text-field/index.d.ts'
|
||||
import type { Button } from 'https://unpkg.com/mdui@2.1.4/components/button/index.d.ts'
|
||||
import type { NavigationRail } from 'https://unpkg.com/mdui@2.1.4/components/navigation-rail/navigation-rail.d.ts'
|
||||
|
||||
declare global {
|
||||
namespace React {
|
||||
namespace JSX {
|
||||
interface IntrinsicAttributes {
|
||||
id?: string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
React,
|
||||
ReactDOM,
|
||||
CryptoES,
|
||||
|
||||
Dialog as MduiDialog,
|
||||
TextField as MduiTextField,
|
||||
Button as MduiButton,
|
||||
NavigationRail as MduiNavigationRail,
|
||||
}
|
||||
29
client/deno.jsonc
Normal file
29
client/deno.jsonc
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"tasks": {
|
||||
"dev": "deno run -A --node-modules-dir npm:vite",
|
||||
"build": "deno run -A --node-modules-dir npm:vite build",
|
||||
"preview": "deno run -A --node-modules-dir npm:vite preview",
|
||||
"serve": "deno run --allow-net --allow-read jsr:@std/http@1/file-server dist/"
|
||||
},
|
||||
"compilerOptions": {
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "react",
|
||||
"jsxImportSourceTypes": "@types/react"
|
||||
},
|
||||
"imports": {
|
||||
"@deno/vite-plugin": "npm:@deno/vite-plugin@1.0.5",
|
||||
"@types/react": "npm:@types/react@18.3.1",
|
||||
"@types/react-dom": "npm:@types/react-dom@18.3.1",
|
||||
"@vitejs/plugin-react": "npm:@vitejs/plugin-react@4.7.0",
|
||||
"react": "npm:react@18.3.1",
|
||||
"react-dom": "npm:react-dom@18.3.1",
|
||||
"vite": "npm:vite@7.0.6",
|
||||
|
||||
"chalk": "npm:chalk@5.4.1",
|
||||
|
||||
"mdui": "npm:mdui@2.1.4",
|
||||
"split.js": "npm:split.js@1.3.2",
|
||||
"crypto-es": "npm:crypto-es@3.1.0"
|
||||
}
|
||||
}
|
||||
@@ -7,88 +7,12 @@
|
||||
<meta name="renderer" content="webkit" />
|
||||
|
||||
<!-- UI -->
|
||||
<script src="./static/mdui-2.1.4.global.min.js">
|
||||
</script>
|
||||
<link rel="icon" href="icon.ico" />
|
||||
<link rel="stylesheet" href="./static/mdui-2.1.4.css" />
|
||||
<link rel="stylesheet" href="./static/material_icons.css" />
|
||||
|
||||
<script src="./static/jquery-3.7.1.min.js"></script>
|
||||
<script src="./static/splitjs-1.6.5.min.js"></script>
|
||||
|
||||
<title>TheWhiteSilk</title>
|
||||
|
||||
<style>
|
||||
/* 滑条*/
|
||||
.no-scroll-bar::-webkit-scrollbar {
|
||||
width: 0px !important;
|
||||
}
|
||||
|
||||
/* https://blog.csdn.net/qq_39347364/article/details/111996581*/
|
||||
*::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track {
|
||||
width: 6px;
|
||||
background: rgba(#101F1C, 0.1);
|
||||
-webkit-border-radius: 2em;
|
||||
-moz-border-radius: 2em;
|
||||
border-radius: 2em;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background-color: rgba(144, 147, 153, .5);
|
||||
background-clip: padding-box;
|
||||
min-height: 28px;
|
||||
-webkit-border-radius: 2em;
|
||||
-moz-border-radius: 2em;
|
||||
border-radius: 2em;
|
||||
transition: background-color .3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb:hover {
|
||||
background-color: rgba(144, 147, 153, .3);
|
||||
}
|
||||
|
||||
/* 使用系统字体 在部分系统表现很好*/
|
||||
/* 我们至今仍未能知道桌面端浏览器字体的秘密*/
|
||||
*:not(.material-icons, .mdui-icon, mdui-icon, .fa, .google-symbols) {
|
||||
font-family: -apple-system, system-ui, -webkit-system-font !important;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
margin: 0 0 0 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
html {
|
||||
margin: 0 0 0 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 防止小尺寸图片模糊*/
|
||||
* {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
image-rendering: -o-crisp-edges;
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
image-rendering: crisp-edges;
|
||||
-ms-interpolation-mode: nearest-neighbor;
|
||||
}
|
||||
|
||||
.gutter {
|
||||
background-color: rgb(var(--mdui-color-surface-variant));;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50%;
|
||||
}
|
||||
|
||||
.gutter.gutter-horizontal {
|
||||
cursor: col-resize;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="./style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -103,28 +27,7 @@
|
||||
<script nomodule>
|
||||
alert('很抱歉, 此应用无法在较旧的浏览器运行, 请使用基于 Chromium 89+ 的浏览器(内核)使用 :(')
|
||||
</script>
|
||||
<script>
|
||||
new URL(location.href).searchParams.get('debug') == 'true' && window.addEventListener('error', ({ message, filename, lineno, colno, error }) => {
|
||||
const m = $("#ErrorDialog_Message")
|
||||
const d = $("#ErrorDialog").get(0)
|
||||
const s = d.open
|
||||
d.open = true
|
||||
m.html((s ? `${m.html()}<br/><br/>` : '') + `${message} (${filename || 'unknown'}:${lineno}:${colno})`)
|
||||
})
|
||||
</script>
|
||||
<script type="module">
|
||||
import App from './ui/App.tsx'
|
||||
import { React, ReactDOM } from './Imports.ts'
|
||||
ReactDOM.createRoot(document.getElementById('app')).render(React.createElement(App, null))
|
||||
|
||||
let onResize = () => {
|
||||
document.body.style.setProperty('--whitesilk-widget-message-maxwidth', mdui.breakpoint().down('md') ? "80%" : "70%")
|
||||
document.body.style.setProperty('--whitesilk-window-width', window.innerWidth + 'px')
|
||||
document.body.style.setProperty('--whitesilk-window-height', window.innerHeight + 'px')
|
||||
}
|
||||
window.addEventListener('resize', onResize)
|
||||
onResize()
|
||||
</script>
|
||||
<script type="module" src="./index.ts"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
30
client/index.ts
Normal file
30
client/index.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import 'mdui/mdui.css'
|
||||
import 'mdui'
|
||||
import { $ } from "mdui/jq"
|
||||
import { breakpoint, Dialog } from "mdui"
|
||||
|
||||
import * as ReactDOM from 'react-dom'
|
||||
|
||||
// deno-lint-ignore no-window no-window-prefix
|
||||
new URL(location.href).searchParams.get('debug') == 'true' && window.addEventListener('error', ({ message, filename, lineno, colno, error }) => {
|
||||
const m = $("#ErrorDialog_Message")
|
||||
const d = $("#ErrorDialog").get(0) as Dialog
|
||||
const s = d.open
|
||||
d.open = true
|
||||
m.html((s ? `${m.html()}<br/><br/>` : '') + `${message} (${filename || 'unknown'}:${lineno}:${colno})`)
|
||||
})
|
||||
|
||||
import App from './ui/App.tsx'
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('app')).render(React.createElement(App, null))
|
||||
|
||||
const onResize = () => {
|
||||
document.body.style.setProperty('--whitesilk-widget-message-maxwidth', breakpoint().down('md') ? "80%" : "70%")
|
||||
// deno-lint-ignore no-window
|
||||
document.body.style.setProperty('--whitesilk-window-width', window.innerWidth + 'px')
|
||||
// deno-lint-ignore no-window
|
||||
document.body.style.setProperty('--whitesilk-window-height', window.innerHeight + 'px')
|
||||
}
|
||||
// deno-lint-ignore no-window no-window-prefix
|
||||
window.addEventListener('resize', onResize)
|
||||
onResize()
|
||||
@@ -1,35 +0,0 @@
|
||||
import { Base, BufferedBlockAlgorithm, HMAC, Hasher, Hex, Latin1, Utf8, WordArray } from "./crypto-es@3.1.0/core.mjs";
|
||||
import { X64Word, X64WordArray } from "./crypto-es@3.1.0/x64-core.mjs";
|
||||
import { Base64 } from "./crypto-es@3.1.0/enc-base64.mjs";
|
||||
import { HmacMD5, MD5, MD5Algo } from "./crypto-es@3.1.0/md5.mjs";
|
||||
import { EvpKDF, EvpKDFAlgo } from "./crypto-es@3.1.0/evpkdf.mjs";
|
||||
import { BlockCipher, BlockCipherMode, CBC, Cipher, CipherParams, OpenSSLFormatter, OpenSSLKdf, PasswordBasedCipher, Pkcs7, SerializableCipher, StreamCipher } from "./crypto-es@3.1.0/cipher-core.mjs";
|
||||
import { Utf16, Utf16BE, Utf16LE } from "./crypto-es@3.1.0/enc-utf16.mjs";
|
||||
import { Base64url } from "./crypto-es@3.1.0/enc-base64url.mjs";
|
||||
import { HmacSHA1, SHA1, SHA1Algo } from "./crypto-es@3.1.0/sha1.mjs";
|
||||
import { HmacSHA256, SHA256, SHA256Algo } from "./crypto-es@3.1.0/sha256.mjs";
|
||||
import { HmacSHA224, SHA224, SHA224Algo } from "./crypto-es@3.1.0/sha224.mjs";
|
||||
import { HmacSHA512, SHA512, SHA512Algo } from "./crypto-es@3.1.0/sha512.mjs";
|
||||
import { HmacSHA384, SHA384, SHA384Algo } from "./crypto-es@3.1.0/sha384.mjs";
|
||||
import { HmacSHA3, SHA3, SHA3Algo } from "./crypto-es@3.1.0/sha3.mjs";
|
||||
import { HmacRIPEMD160, RIPEMD160, RIPEMD160Algo } from "./crypto-es@3.1.0/ripemd160.mjs";
|
||||
import { PBKDF2, PBKDF2Algo } from "./crypto-es@3.1.0/pbkdf2.mjs";
|
||||
import { AES, AESAlgo } from "./crypto-es@3.1.0/aes.mjs";
|
||||
import { DES, DESAlgo, TripleDES, TripleDESAlgo } from "./crypto-es@3.1.0/tripledes.mjs";
|
||||
import { Rabbit, RabbitAlgo } from "./crypto-es@3.1.0/rabbit.mjs";
|
||||
import { RabbitLegacy, RabbitLegacyAlgo } from "./crypto-es@3.1.0/rabbit-legacy.mjs";
|
||||
import { RC4, RC4Algo, RC4Drop, RC4DropAlgo } from "./crypto-es@3.1.0/rc4.mjs";
|
||||
import { Blowfish, BlowfishAlgo } from "./crypto-es@3.1.0/blowfish.mjs";
|
||||
import { CFB } from "./crypto-es@3.1.0/mode-cfb.mjs";
|
||||
import { CTR } from "./crypto-es@3.1.0/mode-ctr.mjs";
|
||||
import { CTRGladman } from "./crypto-es@3.1.0/mode-ctr-gladman.mjs";
|
||||
import { ECB } from "./crypto-es@3.1.0/mode-ecb.mjs";
|
||||
import { OFB } from "./crypto-es@3.1.0/mode-ofb.mjs";
|
||||
import { AnsiX923 } from "./crypto-es@3.1.0/pad-ansix923.mjs";
|
||||
import { Iso10126 } from "./crypto-es@3.1.0/pad-iso10126.mjs";
|
||||
import { ZeroPadding } from "./crypto-es@3.1.0/pad-zeropadding.mjs";
|
||||
import { Iso97971 } from "./crypto-es@3.1.0/pad-iso97971.mjs";
|
||||
import { NoPadding } from "./crypto-es@3.1.0/pad-nopadding.mjs";
|
||||
import { HexFormatter } from "./crypto-es@3.1.0/format-hex.mjs";
|
||||
|
||||
export { AES, AESAlgo, AnsiX923, Base, Base64, Base64url, BlockCipher, BlockCipherMode, Blowfish, BlowfishAlgo, BufferedBlockAlgorithm, CBC, CFB, CTR, CTRGladman, Cipher, CipherParams, DES, DESAlgo, ECB, EvpKDF, EvpKDFAlgo, HMAC, Hasher, Hex, HexFormatter, HmacMD5, HmacRIPEMD160, HmacSHA1, HmacSHA224, HmacSHA256, HmacSHA3, HmacSHA384, HmacSHA512, Iso10126, Iso97971, Latin1, MD5, MD5Algo, NoPadding, OFB, OpenSSLFormatter, OpenSSLKdf, PBKDF2, PBKDF2Algo, PasswordBasedCipher, Pkcs7, RC4, RC4Algo, RC4Drop, RC4DropAlgo, RIPEMD160, RIPEMD160Algo, Rabbit, RabbitAlgo, RabbitLegacy, RabbitLegacyAlgo, SHA1, SHA1Algo, SHA224, SHA224Algo, SHA256, SHA256Algo, SHA3, SHA384, SHA384Algo, SHA3Algo, SHA512, SHA512Algo, SerializableCipher, StreamCipher, TripleDES, TripleDESAlgo, Utf16, Utf16BE, Utf16LE, Utf8, WordArray, X64Word, X64WordArray, ZeroPadding };
|
||||
@@ -1,134 +0,0 @@
|
||||
import { BlockCipher } from "./cipher-core.mjs";
|
||||
|
||||
//#region src/aes.ts
|
||||
const _SBOX = [];
|
||||
const INV_SBOX = [];
|
||||
const _SUB_MIX_0 = [];
|
||||
const _SUB_MIX_1 = [];
|
||||
const _SUB_MIX_2 = [];
|
||||
const _SUB_MIX_3 = [];
|
||||
const INV_SUB_MIX_0 = [];
|
||||
const INV_SUB_MIX_1 = [];
|
||||
const INV_SUB_MIX_2 = [];
|
||||
const INV_SUB_MIX_3 = [];
|
||||
const RCON = [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
4,
|
||||
8,
|
||||
16,
|
||||
32,
|
||||
64,
|
||||
128,
|
||||
27,
|
||||
54
|
||||
];
|
||||
/**
|
||||
* AES block cipher algorithm.
|
||||
*/
|
||||
var AESAlgo = class extends BlockCipher {
|
||||
/** Number of rounds for this key size */
|
||||
_nRounds;
|
||||
/** Previous key for optimization */
|
||||
_keyPriorReset;
|
||||
/** Key schedule for encryption */
|
||||
_keySchedule;
|
||||
/** Inverse key schedule for decryption */
|
||||
_invKeySchedule;
|
||||
/** Key size in 32-bit words */
|
||||
static keySize = 256 / 32;
|
||||
_doReset() {
|
||||
let t;
|
||||
if (this._nRounds && this._keyPriorReset === this._key) return;
|
||||
this._keyPriorReset = this._key;
|
||||
const key = this._keyPriorReset;
|
||||
const keyWords = key.words;
|
||||
const keySize = key.sigBytes / 4;
|
||||
this._nRounds = keySize + 6;
|
||||
const nRounds = this._nRounds;
|
||||
const ksRows = (nRounds + 1) * 4;
|
||||
this._keySchedule = [];
|
||||
const keySchedule = this._keySchedule;
|
||||
for (let ksRow = 0; ksRow < ksRows; ksRow += 1) if (ksRow < keySize) keySchedule[ksRow] = keyWords[ksRow];
|
||||
else {
|
||||
t = keySchedule[ksRow - 1];
|
||||
if (!(ksRow % keySize)) {
|
||||
t = t << 8 | t >>> 24;
|
||||
t = _SBOX[t >>> 24] << 24 | _SBOX[t >>> 16 & 255] << 16 | _SBOX[t >>> 8 & 255] << 8 | _SBOX[t & 255];
|
||||
t ^= RCON[ksRow / keySize | 0] << 24;
|
||||
} else if (keySize > 6 && ksRow % keySize === 4) t = _SBOX[t >>> 24] << 24 | _SBOX[t >>> 16 & 255] << 16 | _SBOX[t >>> 8 & 255] << 8 | _SBOX[t & 255];
|
||||
keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;
|
||||
}
|
||||
this._invKeySchedule = [];
|
||||
const invKeySchedule = this._invKeySchedule;
|
||||
for (let invKsRow = 0; invKsRow < ksRows; invKsRow += 1) {
|
||||
const ksRow = ksRows - invKsRow;
|
||||
if (invKsRow % 4) t = keySchedule[ksRow];
|
||||
else t = keySchedule[ksRow - 4];
|
||||
if (invKsRow < 4 || ksRow <= 4) invKeySchedule[invKsRow] = t;
|
||||
else invKeySchedule[invKsRow] = INV_SUB_MIX_0[_SBOX[t >>> 24]] ^ INV_SUB_MIX_1[_SBOX[t >>> 16 & 255]] ^ INV_SUB_MIX_2[_SBOX[t >>> 8 & 255]] ^ INV_SUB_MIX_3[_SBOX[t & 255]];
|
||||
}
|
||||
}
|
||||
encryptBlock(M, offset) {
|
||||
this._doCryptBlock(M, offset, this._keySchedule, _SUB_MIX_0, _SUB_MIX_1, _SUB_MIX_2, _SUB_MIX_3, _SBOX);
|
||||
}
|
||||
decryptBlock(M, offset) {
|
||||
const _M = M;
|
||||
let t = _M[offset + 1];
|
||||
_M[offset + 1] = _M[offset + 3];
|
||||
_M[offset + 3] = t;
|
||||
this._doCryptBlock(_M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);
|
||||
t = _M[offset + 1];
|
||||
_M[offset + 1] = _M[offset + 3];
|
||||
_M[offset + 3] = t;
|
||||
}
|
||||
_doCryptBlock(M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {
|
||||
const _M = M;
|
||||
const nRounds = this._nRounds;
|
||||
let s0 = _M[offset] ^ keySchedule[0];
|
||||
let s1 = _M[offset + 1] ^ keySchedule[1];
|
||||
let s2 = _M[offset + 2] ^ keySchedule[2];
|
||||
let s3 = _M[offset + 3] ^ keySchedule[3];
|
||||
let ksRow = 4;
|
||||
for (let round = 1; round < nRounds; round += 1) {
|
||||
const t0$1 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[s1 >>> 16 & 255] ^ SUB_MIX_2[s2 >>> 8 & 255] ^ SUB_MIX_3[s3 & 255] ^ keySchedule[ksRow];
|
||||
ksRow += 1;
|
||||
const t1$1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[s2 >>> 16 & 255] ^ SUB_MIX_2[s3 >>> 8 & 255] ^ SUB_MIX_3[s0 & 255] ^ keySchedule[ksRow];
|
||||
ksRow += 1;
|
||||
const t2$1 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[s3 >>> 16 & 255] ^ SUB_MIX_2[s0 >>> 8 & 255] ^ SUB_MIX_3[s1 & 255] ^ keySchedule[ksRow];
|
||||
ksRow += 1;
|
||||
const t3$1 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[s0 >>> 16 & 255] ^ SUB_MIX_2[s1 >>> 8 & 255] ^ SUB_MIX_3[s2 & 255] ^ keySchedule[ksRow];
|
||||
ksRow += 1;
|
||||
s0 = t0$1;
|
||||
s1 = t1$1;
|
||||
s2 = t2$1;
|
||||
s3 = t3$1;
|
||||
}
|
||||
const t0 = (SBOX[s0 >>> 24] << 24 | SBOX[s1 >>> 16 & 255] << 16 | SBOX[s2 >>> 8 & 255] << 8 | SBOX[s3 & 255]) ^ keySchedule[ksRow];
|
||||
ksRow += 1;
|
||||
const t1 = (SBOX[s1 >>> 24] << 24 | SBOX[s2 >>> 16 & 255] << 16 | SBOX[s3 >>> 8 & 255] << 8 | SBOX[s0 & 255]) ^ keySchedule[ksRow];
|
||||
ksRow += 1;
|
||||
const t2 = (SBOX[s2 >>> 24] << 24 | SBOX[s3 >>> 16 & 255] << 16 | SBOX[s0 >>> 8 & 255] << 8 | SBOX[s1 & 255]) ^ keySchedule[ksRow];
|
||||
ksRow += 1;
|
||||
const t3 = (SBOX[s3 >>> 24] << 24 | SBOX[s0 >>> 16 & 255] << 16 | SBOX[s1 >>> 8 & 255] << 8 | SBOX[s2 & 255]) ^ keySchedule[ksRow];
|
||||
ksRow += 1;
|
||||
_M[offset] = t0;
|
||||
_M[offset + 1] = t1;
|
||||
_M[offset + 2] = t2;
|
||||
_M[offset + 3] = t3;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut functions to the cipher's object interface.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var ciphertext = AES.encrypt(message, key, cfg);
|
||||
* var plaintext = AES.decrypt(ciphertext, key, cfg);
|
||||
*/
|
||||
const AES = BlockCipher._createHelper(AESAlgo);
|
||||
|
||||
//#endregion
|
||||
export { AES, AESAlgo };
|
||||
//# sourceMappingURL=aes.mjs.map
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,636 +0,0 @@
|
||||
import { Base, BufferedBlockAlgorithm, Hex, WordArray } from "./core.mjs";
|
||||
import { Base64 } from "./enc-base64.mjs";
|
||||
import { EvpKDFAlgo } from "./evpkdf.mjs";
|
||||
|
||||
//#region src/cipher-core.ts
|
||||
/**
|
||||
* Abstract base cipher template.
|
||||
* Provides the foundation for all encryption and decryption algorithms.
|
||||
*
|
||||
* @property keySize - This cipher's key size in words (default: 4 = 128 bits)
|
||||
* @property ivSize - This cipher's IV size in words (default: 4 = 128 bits)
|
||||
* @property _ENC_XFORM_MODE - A constant representing encryption mode
|
||||
* @property _DEC_XFORM_MODE - A constant representing decryption mode
|
||||
*/
|
||||
var Cipher = class Cipher extends BufferedBlockAlgorithm {
|
||||
/** Encryption mode constant */
|
||||
static _ENC_XFORM_MODE = 1;
|
||||
/** Decryption mode constant */
|
||||
static _DEC_XFORM_MODE = 2;
|
||||
/** Default key size in words (128 bits) */
|
||||
static keySize = 128 / 32;
|
||||
/** Default IV size in words (128 bits) */
|
||||
static ivSize = 128 / 32;
|
||||
/** Configuration options */
|
||||
cfg;
|
||||
/** Transform mode (encryption or decryption) */
|
||||
_xformMode;
|
||||
/** The key */
|
||||
_key;
|
||||
/** Block size in words */
|
||||
blockSize = 128 / 32;
|
||||
/**
|
||||
* Initializes a newly created cipher.
|
||||
*
|
||||
* @param xformMode - Either the encryption or decryption transformation mode constant
|
||||
* @param key - The key
|
||||
* @param cfg - Configuration options to use for this operation
|
||||
* @example
|
||||
* ```javascript
|
||||
* const cipher = new AESAlgo(
|
||||
* Cipher._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray }
|
||||
* );
|
||||
* ```
|
||||
*/
|
||||
constructor(xformMode, key, cfg) {
|
||||
super();
|
||||
this.cfg = Object.assign({}, cfg);
|
||||
this._xformMode = xformMode;
|
||||
this._key = key;
|
||||
}
|
||||
/**
|
||||
* Creates this cipher in encryption mode.
|
||||
*
|
||||
* @param key - The key
|
||||
* @param cfg - Configuration options to use for this operation
|
||||
* @returns A cipher instance
|
||||
* @static
|
||||
* @example
|
||||
* ```javascript
|
||||
* const cipher = AESAlgo.createEncryptor(keyWordArray, { iv: ivWordArray });
|
||||
* ```
|
||||
*/
|
||||
static createEncryptor(key, cfg) {
|
||||
return this.create(Cipher._ENC_XFORM_MODE, key, cfg);
|
||||
}
|
||||
/**
|
||||
* Creates this cipher in decryption mode.
|
||||
*
|
||||
* @param key - The key
|
||||
* @param cfg - Configuration options to use for this operation
|
||||
* @returns A cipher instance
|
||||
* @static
|
||||
* @example
|
||||
* ```javascript
|
||||
* const cipher = AESAlgo.createDecryptor(keyWordArray, { iv: ivWordArray });
|
||||
* ```
|
||||
*/
|
||||
static createDecryptor(key, cfg) {
|
||||
return this.create(Cipher._DEC_XFORM_MODE, key, cfg);
|
||||
}
|
||||
static create(...args) {
|
||||
if (args.length >= 2 && typeof args[0] === "number") {
|
||||
const [xformMode, key, cfg] = args;
|
||||
const instance = new this(xformMode, key, cfg);
|
||||
instance.reset();
|
||||
return instance;
|
||||
} else return new this(...args);
|
||||
}
|
||||
/**
|
||||
* Creates shortcut functions to a cipher's object interface.
|
||||
*
|
||||
* @param SubCipher - The cipher to create a helper for
|
||||
* @returns An object with encrypt and decrypt shortcut functions
|
||||
* @static
|
||||
* @example
|
||||
* ```javascript
|
||||
* const AES = Cipher._createHelper(AESAlgo);
|
||||
* ```
|
||||
*/
|
||||
static _createHelper(SubCipher) {
|
||||
const selectCipherStrategy = (key) => {
|
||||
if (typeof key === "string") return PasswordBasedCipher;
|
||||
return SerializableCipher;
|
||||
};
|
||||
return {
|
||||
encrypt(message, key, cfg) {
|
||||
return selectCipherStrategy(key).encrypt(SubCipher, message, key, cfg);
|
||||
},
|
||||
decrypt(ciphertext, key, cfg) {
|
||||
return selectCipherStrategy(key).decrypt(SubCipher, ciphertext, key, cfg);
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Resets this cipher to its initial state.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* cipher.reset();
|
||||
* ```
|
||||
*/
|
||||
reset() {
|
||||
super.reset();
|
||||
this._doReset();
|
||||
}
|
||||
/**
|
||||
* Adds data to be encrypted or decrypted.
|
||||
*
|
||||
* @param dataUpdate - The data to encrypt or decrypt
|
||||
* @returns The data after processing
|
||||
* @example
|
||||
* ```javascript
|
||||
* const encrypted = cipher.process('data');
|
||||
* const encrypted = cipher.process(wordArray);
|
||||
* ```
|
||||
*/
|
||||
process(dataUpdate) {
|
||||
this._append(dataUpdate);
|
||||
return this._process();
|
||||
}
|
||||
/**
|
||||
* Finalizes the encryption or decryption process.
|
||||
* Note that the finalize operation is effectively a destructive, read-once operation.
|
||||
*
|
||||
* @param dataUpdate - The final data to encrypt or decrypt
|
||||
* @returns The data after final processing
|
||||
* @example
|
||||
* ```javascript
|
||||
* const encrypted = cipher.finalize();
|
||||
* const encrypted = cipher.finalize('data');
|
||||
* const encrypted = cipher.finalize(wordArray);
|
||||
* ```
|
||||
*/
|
||||
finalize(dataUpdate) {
|
||||
if (dataUpdate) this._append(dataUpdate);
|
||||
const finalProcessedData = this._doFinalize();
|
||||
return finalProcessedData;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Abstract base stream cipher template.
|
||||
* Stream ciphers process data one unit at a time rather than in blocks.
|
||||
*
|
||||
* @property blockSize - The number of 32-bit words this cipher operates on (default: 1 = 32 bits)
|
||||
*/
|
||||
var StreamCipher = class extends Cipher {
|
||||
blockSize = 1;
|
||||
constructor(xformMode, key, cfg) {
|
||||
super(xformMode, key, cfg);
|
||||
this.blockSize = 1;
|
||||
}
|
||||
_doFinalize() {
|
||||
const finalProcessedBlocks = this._process(true);
|
||||
return finalProcessedBlocks;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Abstract base block cipher mode template.
|
||||
* Defines how multiple blocks are processed together.
|
||||
*/
|
||||
var BlockCipherMode = class extends Base {
|
||||
/** The cipher instance */
|
||||
_cipher;
|
||||
/** The initialization vector */
|
||||
_iv;
|
||||
/** The previous block (for chaining modes) */
|
||||
_prevBlock;
|
||||
/**
|
||||
* Initializes a newly created mode.
|
||||
*
|
||||
* @param cipher - A block cipher instance
|
||||
* @param iv - The IV words
|
||||
* @example
|
||||
* ```javascript
|
||||
* const mode = new CBCMode(cipher, iv.words);
|
||||
* ```
|
||||
*/
|
||||
constructor(cipher, iv) {
|
||||
super();
|
||||
this._cipher = cipher;
|
||||
this._iv = iv;
|
||||
}
|
||||
/**
|
||||
* Creates this mode for encryption.
|
||||
*
|
||||
* @param cipher - A block cipher instance
|
||||
* @param iv - The IV words
|
||||
* @returns The mode instance
|
||||
* @static
|
||||
* @example
|
||||
* ```javascript
|
||||
* const mode = CBC.createEncryptor(cipher, iv.words);
|
||||
* ```
|
||||
*/
|
||||
static createEncryptor(cipher, iv) {
|
||||
return this.Encryptor.create(cipher, iv);
|
||||
}
|
||||
/**
|
||||
* Creates this mode for decryption.
|
||||
*
|
||||
* @param cipher - A block cipher instance
|
||||
* @param iv - The IV words
|
||||
* @returns The mode instance
|
||||
* @static
|
||||
* @example
|
||||
* ```javascript
|
||||
* const mode = CBC.createDecryptor(cipher, iv.words);
|
||||
* ```
|
||||
*/
|
||||
static createDecryptor(cipher, iv) {
|
||||
return this.Decryptor.create(cipher, iv);
|
||||
}
|
||||
/**
|
||||
* Process a block of data
|
||||
* Must be implemented by concrete modes
|
||||
*/
|
||||
processBlock(_words, _offset) {}
|
||||
};
|
||||
/**
|
||||
* XOR blocks for cipher block chaining
|
||||
* @private
|
||||
*/
|
||||
function xorBlock(words, offset, blockSize) {
|
||||
const _words = words;
|
||||
let block;
|
||||
const iv = this._iv;
|
||||
if (iv) {
|
||||
block = iv;
|
||||
this._iv = void 0;
|
||||
} else block = this._prevBlock;
|
||||
if (block) for (let i = 0; i < blockSize; i += 1) _words[offset + i] ^= block[i];
|
||||
}
|
||||
/**
|
||||
* CBC Encryptor
|
||||
*/
|
||||
var CBCEncryptor = class extends BlockCipherMode {
|
||||
/**
|
||||
* Processes the data block at offset.
|
||||
*
|
||||
* @param words - The data words to operate on
|
||||
* @param offset - The offset where the block starts
|
||||
* @example
|
||||
* ```javascript
|
||||
* mode.processBlock(data.words, offset);
|
||||
* ```
|
||||
*/
|
||||
processBlock(words, offset) {
|
||||
const cipher = this._cipher;
|
||||
const blockSize = cipher.blockSize;
|
||||
xorBlock.call(this, words, offset, blockSize);
|
||||
cipher.encryptBlock(words, offset);
|
||||
this._prevBlock = words.slice(offset, offset + blockSize);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* CBC Decryptor
|
||||
*/
|
||||
var CBCDecryptor = class extends BlockCipherMode {
|
||||
/**
|
||||
* Processes the data block at offset.
|
||||
*
|
||||
* @param words - The data words to operate on
|
||||
* @param offset - The offset where the block starts
|
||||
* @example
|
||||
* ```javascript
|
||||
* mode.processBlock(data.words, offset);
|
||||
* ```
|
||||
*/
|
||||
processBlock(words, offset) {
|
||||
const cipher = this._cipher;
|
||||
const blockSize = cipher.blockSize;
|
||||
const thisBlock = words.slice(offset, offset + blockSize);
|
||||
cipher.decryptBlock(words, offset);
|
||||
xorBlock.call(this, words, offset, blockSize);
|
||||
this._prevBlock = thisBlock;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Cipher Block Chaining mode.
|
||||
* Each block is XORed with the previous ciphertext block before encryption.
|
||||
*/
|
||||
var CBC = class extends BlockCipherMode {
|
||||
/** CBC Encryptor */
|
||||
static Encryptor = CBCEncryptor;
|
||||
/** CBC Decryptor */
|
||||
static Decryptor = CBCDecryptor;
|
||||
};
|
||||
/**
|
||||
* PKCS #5/7 padding strategy.
|
||||
* Pads data with bytes all of the same value as the count of padding bytes.
|
||||
*/
|
||||
const Pkcs7 = {
|
||||
pad(data, blockSize) {
|
||||
const blockSizeBytes = blockSize * 4;
|
||||
const nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
|
||||
const paddingWord = nPaddingBytes << 24 | nPaddingBytes << 16 | nPaddingBytes << 8 | nPaddingBytes;
|
||||
const paddingWords = [];
|
||||
for (let i = 0; i < nPaddingBytes; i += 4) paddingWords.push(paddingWord);
|
||||
const padding = WordArray.create(paddingWords, nPaddingBytes);
|
||||
data.concat(padding);
|
||||
},
|
||||
unpad(data) {
|
||||
const nPaddingBytes = data.words[data.sigBytes - 1 >>> 2] & 255;
|
||||
data.sigBytes -= nPaddingBytes;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Abstract base block cipher template.
|
||||
* Block ciphers process data in fixed-size blocks.
|
||||
*
|
||||
* @property blockSize - The number of 32-bit words this cipher operates on (default: 4 = 128 bits)
|
||||
*/
|
||||
var BlockCipher = class extends Cipher {
|
||||
/** Block mode instance */
|
||||
_mode;
|
||||
/**
|
||||
* Initializes a newly created block cipher.
|
||||
*
|
||||
* @param xformMode - Transform mode
|
||||
* @param key - The key
|
||||
* @param cfg - Configuration options
|
||||
*/
|
||||
constructor(xformMode, key, cfg) {
|
||||
super(xformMode, key, Object.assign({
|
||||
mode: CBC,
|
||||
padding: Pkcs7
|
||||
}, cfg));
|
||||
this.blockSize = 128 / 32;
|
||||
}
|
||||
reset() {
|
||||
super.reset();
|
||||
const { cfg } = this;
|
||||
const { iv, mode } = cfg;
|
||||
let modeCreator;
|
||||
if (this._xformMode === this.constructor._ENC_XFORM_MODE) modeCreator = mode?.createEncryptor;
|
||||
else {
|
||||
modeCreator = mode?.createDecryptor;
|
||||
this._minBufferSize = 1;
|
||||
}
|
||||
if (modeCreator && mode) {
|
||||
this._mode = modeCreator.call(mode, this, iv?.words);
|
||||
this._mode.__creator = modeCreator;
|
||||
}
|
||||
}
|
||||
_doProcessBlock(words, offset) {
|
||||
this._mode?.processBlock(words, offset);
|
||||
}
|
||||
_doFinalize() {
|
||||
let finalProcessedBlocks;
|
||||
const { padding } = this.cfg;
|
||||
if (this._xformMode === this.constructor._ENC_XFORM_MODE) {
|
||||
if (padding) padding.pad(this._data, this.blockSize);
|
||||
finalProcessedBlocks = this._process(true);
|
||||
} else {
|
||||
finalProcessedBlocks = this._process(true);
|
||||
if (padding) padding.unpad(finalProcessedBlocks);
|
||||
}
|
||||
return finalProcessedBlocks;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* A collection of cipher parameters.
|
||||
* Encapsulates all the parameters used in a cipher operation.
|
||||
*
|
||||
* @property ciphertext - The raw ciphertext
|
||||
* @property key - The key to this ciphertext
|
||||
* @property iv - The IV used in the ciphering operation
|
||||
* @property salt - The salt used with a key derivation function
|
||||
* @property algorithm - The cipher algorithm
|
||||
* @property mode - The block mode used in the ciphering operation
|
||||
* @property padding - The padding scheme used in the ciphering operation
|
||||
* @property blockSize - The block size of the cipher
|
||||
* @property formatter - The default formatting strategy
|
||||
*/
|
||||
var CipherParams = class CipherParams extends Base {
|
||||
ciphertext;
|
||||
key;
|
||||
iv;
|
||||
salt;
|
||||
algorithm;
|
||||
mode;
|
||||
padding;
|
||||
blockSize;
|
||||
formatter;
|
||||
/**
|
||||
* Initializes a newly created cipher params object.
|
||||
*
|
||||
* @param cipherParams - An object with any of the possible cipher parameters
|
||||
* @example
|
||||
* ```javascript
|
||||
* const cipherParams = new CipherParams({
|
||||
* ciphertext: ciphertextWordArray,
|
||||
* key: keyWordArray,
|
||||
* iv: ivWordArray,
|
||||
* salt: saltWordArray,
|
||||
* algorithm: AESAlgo,
|
||||
* mode: CBC,
|
||||
* padding: Pkcs7,
|
||||
* blockSize: 4,
|
||||
* formatter: OpenSSLFormatter
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
constructor(cipherParams) {
|
||||
super();
|
||||
if (cipherParams) this.mixIn(cipherParams);
|
||||
if (!this.formatter) this.formatter = OpenSSLFormatter;
|
||||
}
|
||||
static create(...args) {
|
||||
const [cipherParams] = args;
|
||||
return new CipherParams(cipherParams);
|
||||
}
|
||||
/**
|
||||
* Converts this cipher params object to a string.
|
||||
*
|
||||
* @param formatter - The formatting strategy to use
|
||||
* @returns The stringified cipher params
|
||||
* @throws Error if neither the formatter nor the default formatter is set
|
||||
* @example
|
||||
* ```javascript
|
||||
* const string = cipherParams.toString();
|
||||
* const string = cipherParams.toString(OpenSSLFormatter);
|
||||
* ```
|
||||
*/
|
||||
toString(formatter) {
|
||||
const fmt = formatter || this.formatter;
|
||||
if (!fmt) throw new Error("cipher params formatter required");
|
||||
return fmt.stringify(this);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* OpenSSL formatting strategy.
|
||||
* Formats cipher params in OpenSSL-compatible format.
|
||||
*/
|
||||
const OpenSSLFormatter = {
|
||||
stringify(cipherParams) {
|
||||
let wordArray;
|
||||
const { ciphertext, salt } = cipherParams;
|
||||
if (salt && ciphertext) wordArray = WordArray.create([1398893684, 1701076831]).concat(salt).concat(ciphertext);
|
||||
else if (ciphertext) wordArray = ciphertext;
|
||||
else wordArray = new WordArray();
|
||||
return wordArray.toString(Base64);
|
||||
},
|
||||
parse(openSSLStr) {
|
||||
let salt;
|
||||
const ciphertext = Base64.parse(openSSLStr);
|
||||
const ciphertextWords = ciphertext.words;
|
||||
if (ciphertextWords[0] === 1398893684 && ciphertextWords[1] === 1701076831) {
|
||||
salt = WordArray.create(ciphertextWords.slice(2, 4));
|
||||
ciphertextWords.splice(0, 4);
|
||||
ciphertext.sigBytes -= 16;
|
||||
}
|
||||
return CipherParams.create({
|
||||
ciphertext,
|
||||
salt
|
||||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* A cipher wrapper that returns ciphertext as a serializable cipher params object.
|
||||
* Handles the serialization and deserialization of cipher operations.
|
||||
*/
|
||||
var SerializableCipher = class extends Base {
|
||||
/** Configuration options */
|
||||
static cfg = { format: OpenSSLFormatter };
|
||||
/**
|
||||
* Encrypts a message.
|
||||
*
|
||||
* @param cipher - The cipher algorithm to use
|
||||
* @param message - The message to encrypt
|
||||
* @param key - The key
|
||||
* @param cfg - Configuration options to use for this operation
|
||||
* @returns A cipher params object
|
||||
* @static
|
||||
* @example
|
||||
* ```javascript
|
||||
* const ciphertextParams = SerializableCipher.encrypt(AESAlgo, message, key);
|
||||
* const ciphertextParams = SerializableCipher.encrypt(AESAlgo, message, key, { iv: iv });
|
||||
* ```
|
||||
*/
|
||||
static encrypt(cipher, message, key, cfg) {
|
||||
const _cfg = Object.assign({}, this.cfg, cfg);
|
||||
const encryptor = cipher.createEncryptor(key, _cfg);
|
||||
const ciphertext = encryptor.finalize(message);
|
||||
const cipherCfg = encryptor.cfg;
|
||||
return CipherParams.create({
|
||||
ciphertext,
|
||||
key,
|
||||
iv: cipherCfg.iv,
|
||||
algorithm: cipher,
|
||||
mode: cipherCfg.mode,
|
||||
padding: cipherCfg.padding,
|
||||
blockSize: encryptor.blockSize,
|
||||
formatter: _cfg.format || OpenSSLFormatter
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Decrypts serialized ciphertext.
|
||||
*
|
||||
* @param cipher - The cipher algorithm to use
|
||||
* @param ciphertext - The ciphertext to decrypt
|
||||
* @param key - The key
|
||||
* @param cfg - Configuration options to use for this operation
|
||||
* @returns The plaintext
|
||||
* @static
|
||||
* @example
|
||||
* ```javascript
|
||||
* const plaintext = SerializableCipher.decrypt(AESAlgo, formattedCiphertext, key, { iv: iv });
|
||||
* const plaintext = SerializableCipher.decrypt(AESAlgo, ciphertextParams, key, { iv: iv });
|
||||
* ```
|
||||
*/
|
||||
static decrypt(cipher, ciphertext, key, cfg) {
|
||||
const _cfg = Object.assign({}, this.cfg, cfg);
|
||||
const _ciphertext = this._parse(ciphertext, _cfg.format);
|
||||
const plaintext = cipher.createDecryptor(key, _cfg).finalize(_ciphertext.ciphertext);
|
||||
return plaintext;
|
||||
}
|
||||
/**
|
||||
* Converts serialized ciphertext to CipherParams.
|
||||
*
|
||||
* @param ciphertext - The ciphertext
|
||||
* @param format - The formatting strategy to use to parse serialized ciphertext
|
||||
* @returns The unserialized ciphertext
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
static _parse(ciphertext, format) {
|
||||
if (typeof ciphertext === "string") {
|
||||
if (!format) throw new Error("Format required to parse string");
|
||||
return format.parse(ciphertext, this);
|
||||
}
|
||||
if (ciphertext instanceof CipherParams) return ciphertext;
|
||||
return new CipherParams(ciphertext);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* OpenSSL key derivation function.
|
||||
* Derives a key and IV from a password using the OpenSSL method.
|
||||
*/
|
||||
const OpenSSLKdf = { execute(password, keySize, ivSize, salt, hasher) {
|
||||
let _salt;
|
||||
if (!salt) _salt = WordArray.random(64 / 8);
|
||||
else if (typeof salt === "string") _salt = Hex.parse(salt);
|
||||
else _salt = salt;
|
||||
let key;
|
||||
if (!hasher) key = EvpKDFAlgo.create({ keySize: keySize + ivSize }).compute(password, _salt);
|
||||
else key = EvpKDFAlgo.create({
|
||||
keySize: keySize + ivSize,
|
||||
hasher
|
||||
}).compute(password, _salt);
|
||||
const iv = WordArray.create(key.words.slice(keySize), ivSize * 4);
|
||||
key.sigBytes = keySize * 4;
|
||||
return CipherParams.create({
|
||||
key,
|
||||
iv,
|
||||
salt: _salt
|
||||
});
|
||||
} };
|
||||
/**
|
||||
* A serializable cipher wrapper that derives the key from a password.
|
||||
* Returns ciphertext as a serializable cipher params object.
|
||||
*/
|
||||
var PasswordBasedCipher = class extends SerializableCipher {
|
||||
/** Configuration options */
|
||||
static cfg = Object.assign({}, SerializableCipher.cfg, { kdf: OpenSSLKdf });
|
||||
/**
|
||||
* Encrypts a message using a password.
|
||||
*
|
||||
* @param cipher - The cipher algorithm to use
|
||||
* @param message - The message to encrypt
|
||||
* @param password - The password
|
||||
* @param cfg - Configuration options to use for this operation
|
||||
* @returns A cipher params object
|
||||
* @static
|
||||
* @example
|
||||
* ```javascript
|
||||
* const ciphertextParams = PasswordBasedCipher.encrypt(AESAlgo, message, 'password');
|
||||
* ```
|
||||
*/
|
||||
static encrypt(cipher, message, password, cfg) {
|
||||
const _cfg = Object.assign({}, this.cfg, cfg);
|
||||
if (!_cfg.kdf) throw new Error("KDF required for password-based encryption");
|
||||
const derivedParams = _cfg.kdf.execute(password, cipher.keySize || cipher.keySize, cipher.ivSize || cipher.ivSize, _cfg.salt, _cfg.hasher);
|
||||
_cfg.iv = derivedParams.iv;
|
||||
const ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, _cfg);
|
||||
ciphertext.salt = derivedParams.salt;
|
||||
return ciphertext;
|
||||
}
|
||||
/**
|
||||
* Decrypts serialized ciphertext using a password.
|
||||
*
|
||||
* @param cipher - The cipher algorithm to use
|
||||
* @param ciphertext - The ciphertext to decrypt
|
||||
* @param password - The password
|
||||
* @param cfg - Configuration options to use for this operation
|
||||
* @returns The plaintext
|
||||
* @static
|
||||
* @example
|
||||
* ```javascript
|
||||
* const plaintext = PasswordBasedCipher.decrypt(AESAlgo, formattedCiphertext, 'password');
|
||||
* ```
|
||||
*/
|
||||
static decrypt(cipher, ciphertext, password, cfg) {
|
||||
const _cfg = Object.assign({}, this.cfg, cfg);
|
||||
const _ciphertext = this._parse(ciphertext, _cfg.format);
|
||||
if (!_cfg.kdf) throw new Error("KDF required for password-based decryption");
|
||||
const derivedParams = _cfg.kdf.execute(password, cipher.keySize || cipher.keySize, cipher.ivSize || cipher.ivSize, _ciphertext.salt, _cfg.hasher);
|
||||
_cfg.iv = derivedParams.iv;
|
||||
const plaintext = SerializableCipher.decrypt.call(this, cipher, _ciphertext, derivedParams.key, _cfg);
|
||||
return plaintext;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { BlockCipher, BlockCipherMode, CBC, Cipher, CipherParams, OpenSSLFormatter, OpenSSLKdf, PasswordBasedCipher, Pkcs7, SerializableCipher, StreamCipher };
|
||||
//# sourceMappingURL=cipher-core.mjs.map
|
||||
@@ -1,584 +0,0 @@
|
||||
//#region src/core.ts
|
||||
const crypto = (typeof globalThis !== "undefined" ? globalThis : void 0)?.crypto || (typeof global !== "undefined" ? global : void 0)?.crypto || (typeof window !== "undefined" ? window : void 0)?.crypto || (typeof self !== "undefined" ? self : void 0)?.crypto || (typeof frames !== "undefined" ? frames : void 0)?.[0]?.crypto;
|
||||
/**
|
||||
* Random word array generator function
|
||||
*/
|
||||
let randomWordArray;
|
||||
if (crypto) randomWordArray = (nBytes) => {
|
||||
const words = [];
|
||||
for (let i = 0; i < nBytes; i += 4) words.push(crypto.getRandomValues(new Uint32Array(1))[0]);
|
||||
return new WordArray(words, nBytes);
|
||||
};
|
||||
else randomWordArray = (nBytes) => {
|
||||
const words = [];
|
||||
const r = (m_w) => {
|
||||
let _m_w = m_w;
|
||||
let _m_z = 987654321;
|
||||
const mask = 4294967295;
|
||||
return () => {
|
||||
_m_z = 36969 * (_m_z & 65535) + (_m_z >> 16) & mask;
|
||||
_m_w = 18e3 * (_m_w & 65535) + (_m_w >> 16) & mask;
|
||||
let result = (_m_z << 16) + _m_w & mask;
|
||||
result /= 4294967296;
|
||||
result += .5;
|
||||
return result * (Math.random() > .5 ? 1 : -1);
|
||||
};
|
||||
};
|
||||
let rcache;
|
||||
for (let i = 0; i < nBytes; i += 4) {
|
||||
const _r = r((rcache || Math.random()) * 4294967296);
|
||||
rcache = _r() * 987654071;
|
||||
words.push(_r() * 4294967296 | 0);
|
||||
}
|
||||
return new WordArray(words, nBytes);
|
||||
};
|
||||
/**
|
||||
* Base class for inheritance.
|
||||
* Provides basic object-oriented programming utilities.
|
||||
*/
|
||||
var Base = class {
|
||||
/**
|
||||
* Creates a new instance of this class with the provided arguments.
|
||||
* This is a factory method that provides an alternative to using 'new'.
|
||||
*
|
||||
* @param args - Arguments to pass to the constructor
|
||||
* @returns A new instance of this class
|
||||
* @static
|
||||
* @example
|
||||
* ```javascript
|
||||
* const instance = MyType.create(arg1, arg2);
|
||||
* ```
|
||||
*/
|
||||
static create(...args) {
|
||||
return new this(...args);
|
||||
}
|
||||
/**
|
||||
* Copies properties from the provided object into this instance.
|
||||
* Performs a shallow merge of properties.
|
||||
*
|
||||
* @param properties - The properties to mix in
|
||||
* @returns This instance for method chaining
|
||||
* @example
|
||||
* ```javascript
|
||||
* instance.mixIn({ field: 'value', another: 123 });
|
||||
* ```
|
||||
*/
|
||||
mixIn(properties) {
|
||||
return Object.assign(this, properties);
|
||||
}
|
||||
/**
|
||||
* Creates a deep copy of this object.
|
||||
*
|
||||
* @returns A clone of this instance
|
||||
* @example
|
||||
* ```javascript
|
||||
* const clone = instance.clone();
|
||||
* ```
|
||||
*/
|
||||
clone() {
|
||||
const clone = new this.constructor();
|
||||
Object.assign(clone, this);
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* An array of 32-bit words.
|
||||
* This is the core data structure used throughout the library for representing binary data.
|
||||
*
|
||||
* @property words - The array of 32-bit words
|
||||
* @property sigBytes - The number of significant bytes in this word array
|
||||
*/
|
||||
var WordArray = class extends Base {
|
||||
/** The array of 32-bit words */
|
||||
words;
|
||||
/** The number of significant bytes in this word array */
|
||||
sigBytes;
|
||||
/**
|
||||
* Initializes a newly created word array.
|
||||
* Can accept various input formats including regular arrays, typed arrays, and ArrayBuffers.
|
||||
*
|
||||
* @param words - An array of 32-bit words, typed array, or ArrayBuffer
|
||||
* @param sigBytes - The number of significant bytes in the words (defaults to words.length * 4)
|
||||
* @example
|
||||
* ```javascript
|
||||
* const wordArray = new WordArray();
|
||||
* const wordArray = new WordArray([0x00010203, 0x04050607]);
|
||||
* const wordArray = new WordArray([0x00010203, 0x04050607], 6);
|
||||
* const wordArray = new WordArray(new Uint8Array([1, 2, 3, 4]));
|
||||
* ```
|
||||
*/
|
||||
constructor(words = [], sigBytes) {
|
||||
super();
|
||||
if (words instanceof ArrayBuffer) {
|
||||
const typedArray = new Uint8Array(words);
|
||||
this._initFromUint8Array(typedArray);
|
||||
return;
|
||||
}
|
||||
if (ArrayBuffer.isView(words)) {
|
||||
let uint8Array;
|
||||
if (words instanceof Uint8Array) uint8Array = words;
|
||||
else uint8Array = new Uint8Array(words.buffer, words.byteOffset, words.byteLength);
|
||||
this._initFromUint8Array(uint8Array);
|
||||
return;
|
||||
}
|
||||
this.words = words;
|
||||
this.sigBytes = sigBytes !== void 0 ? sigBytes : this.words.length * 4;
|
||||
}
|
||||
/**
|
||||
* Initialize from Uint8Array
|
||||
* @private
|
||||
*/
|
||||
_initFromUint8Array(typedArray) {
|
||||
const typedArrayByteLength = typedArray.byteLength;
|
||||
const words = [];
|
||||
for (let i = 0; i < typedArrayByteLength; i += 1) words[i >>> 2] |= typedArray[i] << 24 - i % 4 * 8;
|
||||
this.words = words;
|
||||
this.sigBytes = typedArrayByteLength;
|
||||
}
|
||||
/**
|
||||
* Creates a word array filled with cryptographically strong random bytes.
|
||||
* Uses Web Crypto API if available, falls back to Math.random() if not.
|
||||
*
|
||||
* @param nBytes - The number of random bytes to generate
|
||||
* @returns The random word array
|
||||
* @static
|
||||
* @example
|
||||
* ```javascript
|
||||
* const randomBytes = WordArray.random(16); // Generate 16 random bytes
|
||||
* ```
|
||||
*/
|
||||
static random = randomWordArray;
|
||||
/**
|
||||
* Converts this word array to a string using the specified encoding.
|
||||
*
|
||||
* @param encoder - The encoding strategy to use (defaults to Hex)
|
||||
* @returns The stringified word array
|
||||
* @example
|
||||
* ```javascript
|
||||
* const hexString = wordArray.toString();
|
||||
* const base64String = wordArray.toString(Base64);
|
||||
* const utf8String = wordArray.toString(Utf8);
|
||||
* ```
|
||||
*/
|
||||
toString(encoder = Hex) {
|
||||
return encoder.stringify(this);
|
||||
}
|
||||
/**
|
||||
* Concatenates a word array to this word array.
|
||||
* Modifies this word array in place.
|
||||
*
|
||||
* @param wordArray - The word array to append
|
||||
* @returns This word array for method chaining
|
||||
* @example
|
||||
* ```javascript
|
||||
* wordArray1.concat(wordArray2);
|
||||
* const combined = wordArray1.concat(wordArray2).concat(wordArray3);
|
||||
* ```
|
||||
*/
|
||||
concat(wordArray) {
|
||||
const thisWords = this.words;
|
||||
const thatWords = wordArray.words;
|
||||
const thisSigBytes = this.sigBytes;
|
||||
const thatSigBytes = wordArray.sigBytes;
|
||||
this.clamp();
|
||||
if (thisSigBytes % 4) for (let i = 0; i < thatSigBytes; i += 1) {
|
||||
const thatByte = thatWords[i >>> 2] >>> 24 - i % 4 * 8 & 255;
|
||||
thisWords[thisSigBytes + i >>> 2] |= thatByte << 24 - (thisSigBytes + i) % 4 * 8;
|
||||
}
|
||||
else for (let i = 0; i < thatSigBytes; i += 4) thisWords[thisSigBytes + i >>> 2] = thatWords[i >>> 2];
|
||||
this.sigBytes += thatSigBytes;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Removes insignificant bits from the end of the word array.
|
||||
* This ensures the word array only contains the exact number of significant bytes.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* wordArray.clamp();
|
||||
* ```
|
||||
*/
|
||||
clamp() {
|
||||
const { words, sigBytes } = this;
|
||||
words[sigBytes >>> 2] &= 4294967295 << 32 - sigBytes % 4 * 8;
|
||||
words.length = Math.ceil(sigBytes / 4);
|
||||
}
|
||||
/**
|
||||
* Creates a copy of this word array.
|
||||
*
|
||||
* @returns The cloned word array
|
||||
* @example
|
||||
* ```javascript
|
||||
* const clone = wordArray.clone();
|
||||
* ```
|
||||
*/
|
||||
clone() {
|
||||
const clone = super.clone();
|
||||
clone.words = this.words.slice(0);
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Hex encoding strategy.
|
||||
* Converts between word arrays and hexadecimal strings.
|
||||
*/
|
||||
const Hex = {
|
||||
stringify(wordArray) {
|
||||
const { words, sigBytes } = wordArray;
|
||||
const hexChars = [];
|
||||
for (let i = 0; i < sigBytes; i += 1) {
|
||||
const bite = words[i >>> 2] >>> 24 - i % 4 * 8 & 255;
|
||||
hexChars.push((bite >>> 4).toString(16));
|
||||
hexChars.push((bite & 15).toString(16));
|
||||
}
|
||||
return hexChars.join("");
|
||||
},
|
||||
parse(hexStr) {
|
||||
const hexStrLength = hexStr.length;
|
||||
const words = [];
|
||||
for (let i = 0; i < hexStrLength; i += 2) words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << 24 - i % 8 * 4;
|
||||
return new WordArray(words, hexStrLength / 2);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Latin1 encoding strategy.
|
||||
* Converts between word arrays and Latin-1 (ISO-8859-1) strings.
|
||||
*/
|
||||
const Latin1 = {
|
||||
stringify(wordArray) {
|
||||
const { words, sigBytes } = wordArray;
|
||||
const latin1Chars = [];
|
||||
for (let i = 0; i < sigBytes; i += 1) {
|
||||
const bite = words[i >>> 2] >>> 24 - i % 4 * 8 & 255;
|
||||
latin1Chars.push(String.fromCharCode(bite));
|
||||
}
|
||||
return latin1Chars.join("");
|
||||
},
|
||||
parse(latin1Str) {
|
||||
const latin1StrLength = latin1Str.length;
|
||||
const words = [];
|
||||
for (let i = 0; i < latin1StrLength; i += 1) words[i >>> 2] |= (latin1Str.charCodeAt(i) & 255) << 24 - i % 4 * 8;
|
||||
return new WordArray(words, latin1StrLength);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* UTF-8 encoding strategy.
|
||||
* Converts between word arrays and UTF-8 strings.
|
||||
*/
|
||||
const Utf8 = {
|
||||
stringify(wordArray) {
|
||||
try {
|
||||
return decodeURIComponent(escape(Latin1.stringify(wordArray)));
|
||||
} catch (e) {
|
||||
throw new Error("Malformed UTF-8 data");
|
||||
}
|
||||
},
|
||||
parse(utf8Str) {
|
||||
return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Abstract buffered block algorithm template.
|
||||
* Provides a base implementation for algorithms that process data in fixed-size blocks.
|
||||
*
|
||||
* @property _minBufferSize - The number of blocks that should be kept unprocessed in the buffer
|
||||
*/
|
||||
var BufferedBlockAlgorithm = class extends Base {
|
||||
/** The number of blocks that should be kept unprocessed in the buffer */
|
||||
_minBufferSize = 0;
|
||||
/** The data buffer */
|
||||
_data;
|
||||
/** The number of bytes in the data buffer */
|
||||
_nDataBytes;
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
/**
|
||||
* Resets this block algorithm's data buffer to its initial state.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* bufferedBlockAlgorithm.reset();
|
||||
* ```
|
||||
*/
|
||||
reset() {
|
||||
this._data = new WordArray();
|
||||
this._nDataBytes = 0;
|
||||
}
|
||||
/**
|
||||
* Adds new data to this block algorithm's buffer.
|
||||
*
|
||||
* @param data - The data to append (strings are converted to WordArray using UTF-8)
|
||||
* @example
|
||||
* ```javascript
|
||||
* bufferedBlockAlgorithm._append('data');
|
||||
* bufferedBlockAlgorithm._append(wordArray);
|
||||
* ```
|
||||
*/
|
||||
_append(data) {
|
||||
let m_data;
|
||||
if (typeof data === "string") m_data = Utf8.parse(data);
|
||||
else m_data = data;
|
||||
this._data.concat(m_data);
|
||||
this._nDataBytes += m_data.sigBytes;
|
||||
}
|
||||
/**
|
||||
* Processes available data blocks.
|
||||
* This method invokes _doProcessBlock(dataWords, offset), which must be implemented by a concrete subtype.
|
||||
*
|
||||
* @param doFlush - Whether all blocks and partial blocks should be processed
|
||||
* @returns The processed data
|
||||
* @example
|
||||
* ```javascript
|
||||
* const processedData = bufferedBlockAlgorithm._process();
|
||||
* const processedData = bufferedBlockAlgorithm._process(true); // Flush
|
||||
* ```
|
||||
*/
|
||||
_process(doFlush) {
|
||||
let processedWords;
|
||||
const data = this._data;
|
||||
const dataWords = data.words;
|
||||
const dataSigBytes = data.sigBytes;
|
||||
const blockSizeBytes = this.blockSize * 4;
|
||||
let nBlocksReady = dataSigBytes / blockSizeBytes;
|
||||
if (doFlush) nBlocksReady = Math.ceil(nBlocksReady);
|
||||
else nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
|
||||
const nWordsReady = nBlocksReady * this.blockSize;
|
||||
const nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
|
||||
if (nWordsReady) {
|
||||
for (let offset = 0; offset < nWordsReady; offset += this.blockSize) this._doProcessBlock(dataWords, offset);
|
||||
processedWords = dataWords.splice(0, nWordsReady);
|
||||
data.sigBytes -= nBytesReady;
|
||||
}
|
||||
return new WordArray(processedWords || [], nBytesReady);
|
||||
}
|
||||
/**
|
||||
* Creates a copy of this object.
|
||||
*
|
||||
* @returns The clone
|
||||
* @example
|
||||
* ```javascript
|
||||
* const clone = bufferedBlockAlgorithm.clone();
|
||||
* ```
|
||||
*/
|
||||
clone() {
|
||||
const clone = super.clone();
|
||||
clone._data = this._data.clone();
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Abstract hasher template.
|
||||
* Base class for all hash algorithm implementations.
|
||||
*
|
||||
* @property blockSize - The number of 32-bit words this hasher operates on (default: 16 = 512 bits)
|
||||
*/
|
||||
var Hasher = class extends BufferedBlockAlgorithm {
|
||||
/** The number of 32-bit words this hasher operates on */
|
||||
blockSize = 512 / 32;
|
||||
/** Configuration options */
|
||||
cfg;
|
||||
/** The hash result */
|
||||
_hash;
|
||||
/**
|
||||
* Initializes a newly created hasher.
|
||||
*
|
||||
* @param cfg - Configuration options
|
||||
*/
|
||||
constructor(cfg) {
|
||||
super();
|
||||
this.cfg = Object.assign({}, cfg);
|
||||
this.reset();
|
||||
}
|
||||
/**
|
||||
* Creates a shortcut function to a hasher's object interface.
|
||||
*
|
||||
* @param SubHasher - The hasher class to create a helper for
|
||||
* @returns The shortcut function
|
||||
* @static
|
||||
* @example
|
||||
* ```javascript
|
||||
* const SHA256 = Hasher._createHelper(SHA256Algo);
|
||||
* ```
|
||||
*/
|
||||
static _createHelper(SubHasher) {
|
||||
return (message, cfg) => {
|
||||
return new SubHasher(cfg).finalize(message);
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Creates a shortcut function to the HMAC's object interface.
|
||||
*
|
||||
* @param SubHasher - The hasher class to use in this HMAC helper
|
||||
* @returns The shortcut function
|
||||
* @static
|
||||
* @example
|
||||
* ```javascript
|
||||
* const HmacSHA256 = Hasher._createHmacHelper(SHA256Algo);
|
||||
* ```
|
||||
*/
|
||||
static _createHmacHelper(SubHasher) {
|
||||
return (message, key) => {
|
||||
return new HMAC(SubHasher, key).finalize(message);
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Resets this hasher to its initial state.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* hasher.reset();
|
||||
* ```
|
||||
*/
|
||||
reset() {
|
||||
super.reset();
|
||||
this._doReset();
|
||||
}
|
||||
/**
|
||||
* Updates this hasher with a message.
|
||||
*
|
||||
* @param messageUpdate - The message to append
|
||||
* @returns This hasher instance for method chaining
|
||||
* @example
|
||||
* ```javascript
|
||||
* hasher.update('message');
|
||||
* hasher.update(wordArray);
|
||||
* ```
|
||||
*/
|
||||
update(messageUpdate) {
|
||||
this._append(messageUpdate);
|
||||
this._process();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Finalizes the hash computation.
|
||||
* Note that the finalize operation is effectively a destructive, read-once operation.
|
||||
*
|
||||
* @param messageUpdate - An optional final message update
|
||||
* @returns The computed hash
|
||||
* @example
|
||||
* ```javascript
|
||||
* const hash = hasher.finalize();
|
||||
* const hash = hasher.finalize('message');
|
||||
* const hash = hasher.finalize(wordArray);
|
||||
* ```
|
||||
*/
|
||||
finalize(messageUpdate) {
|
||||
if (messageUpdate) this._append(messageUpdate);
|
||||
const hash = this._doFinalize();
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Base class for 32-bit hash algorithms.
|
||||
* Hash algorithms that operate on 32-bit words should extend this class.
|
||||
*/
|
||||
var Hasher32 = class extends Hasher {};
|
||||
/**
|
||||
* Base class for 64-bit hash algorithms.
|
||||
* Hash algorithms that operate on 64-bit words should extend this class.
|
||||
*/
|
||||
var Hasher64 = class extends Hasher {};
|
||||
/**
|
||||
* HMAC (Hash-based Message Authentication Code) algorithm.
|
||||
* Provides message authentication using a cryptographic hash function and a secret key.
|
||||
*/
|
||||
var HMAC = class HMAC extends Base {
|
||||
/** The inner hasher instance */
|
||||
_hasher;
|
||||
/** The outer key */
|
||||
_oKey;
|
||||
/** The inner key */
|
||||
_iKey;
|
||||
/**
|
||||
* Initializes a newly created HMAC.
|
||||
*
|
||||
* @param SubHasher - The hash algorithm class to use
|
||||
* @param key - The secret key
|
||||
* @example
|
||||
* ```javascript
|
||||
* const hmac = new HMAC(SHA256Algo, 'secret key');
|
||||
* ```
|
||||
*/
|
||||
constructor(SubHasher, key) {
|
||||
super();
|
||||
const hasher = new SubHasher();
|
||||
this._hasher = hasher;
|
||||
let _key;
|
||||
if (typeof key === "string") _key = Utf8.parse(key);
|
||||
else _key = key;
|
||||
const hasherBlockSize = hasher.blockSize;
|
||||
const hasherBlockSizeBytes = hasherBlockSize * 4;
|
||||
if (_key.sigBytes > hasherBlockSizeBytes) _key = hasher.finalize(_key);
|
||||
_key.clamp();
|
||||
const oKey = _key.clone();
|
||||
this._oKey = oKey;
|
||||
const iKey = _key.clone();
|
||||
this._iKey = iKey;
|
||||
const oKeyWords = oKey.words;
|
||||
const iKeyWords = iKey.words;
|
||||
for (let i = 0; i < hasherBlockSize; i += 1) {
|
||||
oKeyWords[i] ^= 1549556828;
|
||||
iKeyWords[i] ^= 909522486;
|
||||
}
|
||||
oKey.sigBytes = hasherBlockSizeBytes;
|
||||
iKey.sigBytes = hasherBlockSizeBytes;
|
||||
this.reset();
|
||||
}
|
||||
static create(...args) {
|
||||
const [SubHasher, key] = args;
|
||||
return new HMAC(SubHasher, key);
|
||||
}
|
||||
/**
|
||||
* Resets this HMAC to its initial state.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* hmac.reset();
|
||||
* ```
|
||||
*/
|
||||
reset() {
|
||||
const hasher = this._hasher;
|
||||
hasher.reset();
|
||||
hasher.update(this._iKey);
|
||||
}
|
||||
/**
|
||||
* Updates this HMAC with a message.
|
||||
*
|
||||
* @param messageUpdate - The message to append
|
||||
* @returns This HMAC instance for method chaining
|
||||
* @example
|
||||
* ```javascript
|
||||
* hmac.update('message');
|
||||
* hmac.update(wordArray);
|
||||
* ```
|
||||
*/
|
||||
update(messageUpdate) {
|
||||
this._hasher.update(messageUpdate);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Finalizes the HMAC computation.
|
||||
* Note that the finalize operation is effectively a destructive, read-once operation.
|
||||
*
|
||||
* @param messageUpdate - An optional final message update
|
||||
* @returns The computed HMAC
|
||||
* @example
|
||||
* ```javascript
|
||||
* const hmacValue = hmac.finalize();
|
||||
* const hmacValue = hmac.finalize('message');
|
||||
* const hmacValue = hmac.finalize(wordArray);
|
||||
* ```
|
||||
*/
|
||||
finalize(messageUpdate) {
|
||||
const hasher = this._hasher;
|
||||
const innerHash = hasher.finalize(messageUpdate);
|
||||
hasher.reset();
|
||||
const hmac = hasher.finalize(this._oKey.clone().concat(innerHash));
|
||||
return hmac;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { Base, BufferedBlockAlgorithm, HMAC, Hasher, Hasher32, Hasher64, Hex, Latin1, Utf8, WordArray };
|
||||
//# sourceMappingURL=core.mjs.map
|
||||
@@ -1,104 +0,0 @@
|
||||
import { WordArray } from "./core.mjs";
|
||||
|
||||
//#region src/enc-base64.ts
|
||||
/**
|
||||
* Parses a Base64 string to a WordArray.
|
||||
* Helper function for Base64 decoding.
|
||||
*
|
||||
* @param base64Str - The Base64 string to parse
|
||||
* @param base64StrLength - The length of the Base64 string
|
||||
* @param reverseMap - The reverse character map for decoding
|
||||
* @returns The decoded WordArray
|
||||
*/
|
||||
const parseLoop = (base64Str, base64StrLength, reverseMap) => {
|
||||
const words = [];
|
||||
let nBytes = 0;
|
||||
for (let i = 0; i < base64StrLength; i += 1) if (i % 4) {
|
||||
const bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << i % 4 * 2;
|
||||
const bits2 = reverseMap[base64Str.charCodeAt(i)] >>> 6 - i % 4 * 2;
|
||||
const bitsCombined = bits1 | bits2;
|
||||
words[nBytes >>> 2] |= bitsCombined << 24 - nBytes % 4 * 8;
|
||||
nBytes += 1;
|
||||
}
|
||||
return WordArray.create(words, nBytes);
|
||||
};
|
||||
/**
|
||||
* Base64 encoding strategy implementation.
|
||||
* @private
|
||||
*/
|
||||
var Base64Impl = class {
|
||||
/** The Base64 character map */
|
||||
_map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
/** The reverse character map for decoding */
|
||||
_reverseMap;
|
||||
/**
|
||||
* Converts a word array to a Base64 string.
|
||||
*
|
||||
* @param wordArray - The word array to convert
|
||||
* @returns The Base64 string representation
|
||||
* @example
|
||||
* ```javascript
|
||||
* const base64String = Base64.stringify(wordArray);
|
||||
* ```
|
||||
*/
|
||||
stringify(wordArray) {
|
||||
const { words, sigBytes } = wordArray;
|
||||
const map = this._map;
|
||||
wordArray.clamp();
|
||||
const base64Chars = [];
|
||||
for (let i = 0; i < sigBytes; i += 3) {
|
||||
const byte1 = words[i >>> 2] >>> 24 - i % 4 * 8 & 255;
|
||||
const byte2 = words[i + 1 >>> 2] >>> 24 - (i + 1) % 4 * 8 & 255;
|
||||
const byte3 = words[i + 2 >>> 2] >>> 24 - (i + 2) % 4 * 8 & 255;
|
||||
const triplet = byte1 << 16 | byte2 << 8 | byte3;
|
||||
for (let j = 0; j < 4 && i + j * .75 < sigBytes; j += 1) base64Chars.push(map.charAt(triplet >>> 6 * (3 - j) & 63));
|
||||
}
|
||||
const paddingChar = map.charAt(64);
|
||||
if (paddingChar) while (base64Chars.length % 4) base64Chars.push(paddingChar);
|
||||
return base64Chars.join("");
|
||||
}
|
||||
/**
|
||||
* Converts a Base64 string to a word array.
|
||||
*
|
||||
* @param base64Str - The Base64 string to parse
|
||||
* @returns The word array representation
|
||||
* @example
|
||||
* ```javascript
|
||||
* const wordArray = Base64.parse(base64String);
|
||||
* ```
|
||||
*/
|
||||
parse(base64Str) {
|
||||
let base64StrLength = base64Str.length;
|
||||
const map = this._map;
|
||||
let reverseMap = this._reverseMap;
|
||||
if (!reverseMap) {
|
||||
this._reverseMap = [];
|
||||
reverseMap = this._reverseMap;
|
||||
for (let j = 0; j < map.length; j += 1) reverseMap[map.charCodeAt(j)] = j;
|
||||
}
|
||||
const paddingChar = map.charAt(64);
|
||||
if (paddingChar) {
|
||||
const paddingIndex = base64Str.indexOf(paddingChar);
|
||||
if (paddingIndex !== -1) base64StrLength = paddingIndex;
|
||||
}
|
||||
return parseLoop(base64Str, base64StrLength, reverseMap);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Base64 encoding strategy.
|
||||
* Converts between WordArrays and Base64 strings.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* // Encoding
|
||||
* const base64String = Base64.stringify(wordArray);
|
||||
*
|
||||
* // Decoding
|
||||
* const wordArray = Base64.parse(base64String);
|
||||
* ```
|
||||
*/
|
||||
const Base64 = new Base64Impl();
|
||||
|
||||
//#endregion
|
||||
export { Base64, parseLoop };
|
||||
//# sourceMappingURL=enc-base64.mjs.map
|
||||
@@ -1,102 +0,0 @@
|
||||
import { parseLoop } from "./enc-base64.mjs";
|
||||
|
||||
//#region src/enc-base64url.ts
|
||||
/**
|
||||
* Base64url encoding strategy implementation.
|
||||
* @private
|
||||
*/
|
||||
var Base64urlImpl = class {
|
||||
/** Standard Base64 character map */
|
||||
_map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
/** URL-safe Base64 character map (no padding) */
|
||||
_safeMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
||||
/** Reverse character map for decoding */
|
||||
_reverseMap;
|
||||
/**
|
||||
* Converts a word array to a Base64url string.
|
||||
*
|
||||
* @param wordArray - The word array to convert
|
||||
* @param urlSafe - Whether to use URL-safe encoding (default: true)
|
||||
* @returns The Base64url string representation
|
||||
* @example
|
||||
* ```javascript
|
||||
* // URL-safe encoding (default)
|
||||
* const base64urlString = Base64url.stringify(wordArray);
|
||||
*
|
||||
* // Standard Base64 encoding
|
||||
* const base64String = Base64url.stringify(wordArray, false);
|
||||
* ```
|
||||
*/
|
||||
stringify(wordArray, urlSafe = true) {
|
||||
const { words, sigBytes } = wordArray;
|
||||
const map = urlSafe ? this._safeMap : this._map;
|
||||
wordArray.clamp();
|
||||
const base64Chars = [];
|
||||
for (let i = 0; i < sigBytes; i += 3) {
|
||||
const byte1 = words[i >>> 2] >>> 24 - i % 4 * 8 & 255;
|
||||
const byte2 = words[i + 1 >>> 2] >>> 24 - (i + 1) % 4 * 8 & 255;
|
||||
const byte3 = words[i + 2 >>> 2] >>> 24 - (i + 2) % 4 * 8 & 255;
|
||||
const triplet = byte1 << 16 | byte2 << 8 | byte3;
|
||||
for (let j = 0; j < 4 && i + j * .75 < sigBytes; j += 1) base64Chars.push(map.charAt(triplet >>> 6 * (3 - j) & 63));
|
||||
}
|
||||
const paddingChar = map.charAt(64);
|
||||
if (paddingChar) while (base64Chars.length % 4) base64Chars.push(paddingChar);
|
||||
return base64Chars.join("");
|
||||
}
|
||||
/**
|
||||
* Converts a Base64url string to a word array.
|
||||
*
|
||||
* @param base64Str - The Base64url string to parse
|
||||
* @param urlSafe - Whether to use URL-safe decoding (default: true)
|
||||
* @returns The word array representation
|
||||
* @example
|
||||
* ```javascript
|
||||
* // URL-safe decoding (default)
|
||||
* const wordArray = Base64url.parse(base64urlString);
|
||||
*
|
||||
* // Standard Base64 decoding
|
||||
* const wordArray = Base64url.parse(base64String, false);
|
||||
* ```
|
||||
*/
|
||||
parse(base64Str, urlSafe = true) {
|
||||
let base64StrLength = base64Str.length;
|
||||
const map = urlSafe ? this._safeMap : this._map;
|
||||
let reverseMap = this._reverseMap;
|
||||
if (!reverseMap) {
|
||||
this._reverseMap = [];
|
||||
reverseMap = this._reverseMap;
|
||||
for (let j = 0; j < map.length; j += 1) reverseMap[map.charCodeAt(j)] = j;
|
||||
}
|
||||
const paddingChar = map.charAt(64);
|
||||
if (paddingChar) {
|
||||
const paddingIndex = base64Str.indexOf(paddingChar);
|
||||
if (paddingIndex !== -1) base64StrLength = paddingIndex;
|
||||
}
|
||||
return parseLoop(base64Str, base64StrLength, reverseMap);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Base64url encoding strategy.
|
||||
* Provides URL-safe Base64 encoding/decoding that can be used in URLs without escaping.
|
||||
*
|
||||
* The URL-safe variant:
|
||||
* - Uses '-' instead of '+'
|
||||
* - Uses '_' instead of '/'
|
||||
* - Omits padding '=' characters
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* // URL-safe encoding (default)
|
||||
* const urlSafeString = Base64url.stringify(wordArray);
|
||||
* const wordArray = Base64url.parse(urlSafeString);
|
||||
*
|
||||
* // Standard Base64 encoding
|
||||
* const base64String = Base64url.stringify(wordArray, false);
|
||||
* const wordArray = Base64url.parse(base64String, false);
|
||||
* ```
|
||||
*/
|
||||
const Base64url = new Base64urlImpl();
|
||||
|
||||
//#endregion
|
||||
export { Base64url };
|
||||
//# sourceMappingURL=enc-base64url.mjs.map
|
||||
@@ -1,57 +0,0 @@
|
||||
import { WordArray } from "./core.mjs";
|
||||
|
||||
//#region src/enc-utf16.ts
|
||||
/**
|
||||
* Swaps endian of a word
|
||||
* @param word - The word to swap
|
||||
* @returns The word with swapped endian
|
||||
*/
|
||||
const swapEndian = (word) => word << 8 & 4278255360 | word >>> 8 & 16711935;
|
||||
/**
|
||||
* UTF-16 BE encoding strategy.
|
||||
*/
|
||||
const Utf16BE = {
|
||||
stringify(wordArray) {
|
||||
const { words, sigBytes } = wordArray;
|
||||
const utf16Chars = [];
|
||||
for (let i = 0; i < sigBytes; i += 2) {
|
||||
const codePoint = words[i >>> 2] >>> 16 - i % 4 * 8 & 65535;
|
||||
utf16Chars.push(String.fromCharCode(codePoint));
|
||||
}
|
||||
return utf16Chars.join("");
|
||||
},
|
||||
parse(utf16Str) {
|
||||
const utf16StrLength = utf16Str.length;
|
||||
const words = [];
|
||||
for (let i = 0; i < utf16StrLength; i += 1) words[i >>> 1] |= utf16Str.charCodeAt(i) << 16 - i % 2 * 16;
|
||||
return WordArray.create(words, utf16StrLength * 2);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* UTF-16 encoding strategy (defaults to UTF-16 BE).
|
||||
*/
|
||||
const Utf16 = Utf16BE;
|
||||
/**
|
||||
* UTF-16 LE encoding strategy.
|
||||
*/
|
||||
const Utf16LE = {
|
||||
stringify(wordArray) {
|
||||
const { words, sigBytes } = wordArray;
|
||||
const utf16Chars = [];
|
||||
for (let i = 0; i < sigBytes; i += 2) {
|
||||
const codePoint = swapEndian(words[i >>> 2] >>> 16 - i % 4 * 8 & 65535);
|
||||
utf16Chars.push(String.fromCharCode(codePoint));
|
||||
}
|
||||
return utf16Chars.join("");
|
||||
},
|
||||
parse(utf16Str) {
|
||||
const utf16StrLength = utf16Str.length;
|
||||
const words = [];
|
||||
for (let i = 0; i < utf16StrLength; i += 1) words[i >>> 1] |= swapEndian(utf16Str.charCodeAt(i) << 16 - i % 2 * 16);
|
||||
return WordArray.create(words, utf16StrLength * 2);
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { Utf16, Utf16BE, Utf16LE };
|
||||
//# sourceMappingURL=enc-utf16.mjs.map
|
||||
@@ -1,91 +0,0 @@
|
||||
import { Base, WordArray } from "./core.mjs";
|
||||
import { MD5Algo } from "./md5.mjs";
|
||||
|
||||
//#region src/evpkdf.ts
|
||||
/**
|
||||
* This key derivation function is meant to conform with EVP_BytesToKey.
|
||||
* www.openssl.org/docs/crypto/EVP_BytesToKey.html
|
||||
*/
|
||||
var EvpKDFAlgo = class extends Base {
|
||||
cfg;
|
||||
/**
|
||||
* Initializes a newly created key derivation function.
|
||||
*
|
||||
* @param {Object} cfg (Optional) The configuration options to use for the derivation.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const kdf = new EvpKDFAlgo();
|
||||
* const kdf = new EvpKDFAlgo({ keySize: 8 });
|
||||
* const kdf = new EvpKDFAlgo({ keySize: 8, iterations: 1000 });
|
||||
*/
|
||||
constructor(cfg) {
|
||||
super();
|
||||
/**
|
||||
* Configuration options.
|
||||
*
|
||||
* @property {number} keySize The key size in words to generate. Default: 4 (128 bits)
|
||||
* @property {Hasher} hasher The hash algorithm to use. Default: MD5
|
||||
* @property {number} iterations The number of iterations to perform. Default: 1
|
||||
*/
|
||||
this.cfg = Object.assign({}, {
|
||||
keySize: 128 / 32,
|
||||
hasher: MD5Algo,
|
||||
iterations: 1
|
||||
}, cfg);
|
||||
}
|
||||
/**
|
||||
* Derives a key from a password.
|
||||
*
|
||||
* @param {WordArray|string} password The password.
|
||||
* @param {WordArray|string} salt A salt.
|
||||
*
|
||||
* @return {WordArray} The derived key.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const key = kdf.compute(password, salt);
|
||||
*/
|
||||
compute(password, salt) {
|
||||
let block;
|
||||
const { cfg } = this;
|
||||
const hasher = new cfg.hasher();
|
||||
const derivedKey = WordArray.create();
|
||||
const derivedKeyWords = derivedKey.words;
|
||||
const { keySize, iterations } = cfg;
|
||||
while (derivedKeyWords.length < keySize) {
|
||||
if (block) hasher.update(block);
|
||||
block = hasher.update(password).finalize(salt);
|
||||
hasher.reset();
|
||||
for (let i = 1; i < iterations; i += 1) {
|
||||
block = hasher.finalize(block);
|
||||
hasher.reset();
|
||||
}
|
||||
derivedKey.concat(block);
|
||||
}
|
||||
derivedKey.sigBytes = keySize * 4;
|
||||
return derivedKey;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Derives a key from a password.
|
||||
*
|
||||
* @param {WordArray|string} password The password.
|
||||
* @param {WordArray|string} salt A salt.
|
||||
* @param {Object} cfg (Optional) The configuration options to use for this computation.
|
||||
*
|
||||
* @return {WordArray} The derived key.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var key = EvpKDF(password, salt);
|
||||
* var key = EvpKDF(password, salt, { keySize: 8 });
|
||||
* var key = EvpKDF(password, salt, { keySize: 8, iterations: 1000 });
|
||||
*/
|
||||
const EvpKDF = (password, salt, cfg) => new EvpKDFAlgo(cfg).compute(password, salt);
|
||||
|
||||
//#endregion
|
||||
export { EvpKDF, EvpKDFAlgo };
|
||||
//# sourceMappingURL=evpkdf.mjs.map
|
||||
@@ -1,22 +0,0 @@
|
||||
import { Hex } from "./core.mjs";
|
||||
import { CipherParams } from "./cipher-core.mjs";
|
||||
|
||||
//#region src/format-hex.ts
|
||||
/**
|
||||
* Hex formatter for cipher params.
|
||||
* Converts cipher params to/from hexadecimal strings.
|
||||
*/
|
||||
const HexFormatter = {
|
||||
stringify(cipherParams) {
|
||||
if (!cipherParams.ciphertext) throw new Error("Ciphertext is required");
|
||||
return cipherParams.ciphertext.toString(Hex);
|
||||
},
|
||||
parse(input) {
|
||||
const ciphertext = Hex.parse(input);
|
||||
return CipherParams.create({ ciphertext });
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { HexFormatter };
|
||||
//# sourceMappingURL=format-hex.mjs.map
|
||||
@@ -1,201 +0,0 @@
|
||||
import { Hasher, Hasher32, WordArray } from "./core.mjs";
|
||||
|
||||
//#region src/md5.ts
|
||||
const T = /* @__PURE__ */ (() => {
|
||||
const a = [];
|
||||
for (let i = 0; i < 64; i += 1) a[i] = Math.abs(Math.sin(i + 1)) * 4294967296 | 0;
|
||||
return a;
|
||||
})();
|
||||
/**
|
||||
* MD5 round function F
|
||||
*/
|
||||
const FF = (a, b, c, d, x, s, t) => {
|
||||
const n = a + (b & c | ~b & d) + x + t;
|
||||
return (n << s | n >>> 32 - s) + b;
|
||||
};
|
||||
/**
|
||||
* MD5 round function G
|
||||
*/
|
||||
const GG = (a, b, c, d, x, s, t) => {
|
||||
const n = a + (b & d | c & ~d) + x + t;
|
||||
return (n << s | n >>> 32 - s) + b;
|
||||
};
|
||||
/**
|
||||
* MD5 round function H
|
||||
*/
|
||||
const HH = (a, b, c, d, x, s, t) => {
|
||||
const n = a + (b ^ c ^ d) + x + t;
|
||||
return (n << s | n >>> 32 - s) + b;
|
||||
};
|
||||
/**
|
||||
* MD5 round function I
|
||||
*/
|
||||
const II = (a, b, c, d, x, s, t) => {
|
||||
const n = a + (c ^ (b | ~d)) + x + t;
|
||||
return (n << s | n >>> 32 - s) + b;
|
||||
};
|
||||
/**
|
||||
* MD5 hash algorithm.
|
||||
*/
|
||||
var MD5Algo = class extends Hasher32 {
|
||||
_doReset() {
|
||||
this._hash = new WordArray([
|
||||
1732584193,
|
||||
4023233417,
|
||||
2562383102,
|
||||
271733878
|
||||
]);
|
||||
}
|
||||
_doProcessBlock(M, offset) {
|
||||
const _M = M;
|
||||
for (let i = 0; i < 16; i += 1) {
|
||||
const offset_i = offset + i;
|
||||
const M_offset_i = M[offset_i];
|
||||
_M[offset_i] = (M_offset_i << 8 | M_offset_i >>> 24) & 16711935 | (M_offset_i << 24 | M_offset_i >>> 8) & 4278255360;
|
||||
}
|
||||
const H = this._hash.words;
|
||||
const M_offset_0 = _M[offset + 0];
|
||||
const M_offset_1 = _M[offset + 1];
|
||||
const M_offset_2 = _M[offset + 2];
|
||||
const M_offset_3 = _M[offset + 3];
|
||||
const M_offset_4 = _M[offset + 4];
|
||||
const M_offset_5 = _M[offset + 5];
|
||||
const M_offset_6 = _M[offset + 6];
|
||||
const M_offset_7 = _M[offset + 7];
|
||||
const M_offset_8 = _M[offset + 8];
|
||||
const M_offset_9 = _M[offset + 9];
|
||||
const M_offset_10 = _M[offset + 10];
|
||||
const M_offset_11 = _M[offset + 11];
|
||||
const M_offset_12 = _M[offset + 12];
|
||||
const M_offset_13 = _M[offset + 13];
|
||||
const M_offset_14 = _M[offset + 14];
|
||||
const M_offset_15 = _M[offset + 15];
|
||||
let a = H[0];
|
||||
let b = H[1];
|
||||
let c = H[2];
|
||||
let d = H[3];
|
||||
a = FF(a, b, c, d, M_offset_0, 7, T[0]);
|
||||
d = FF(d, a, b, c, M_offset_1, 12, T[1]);
|
||||
c = FF(c, d, a, b, M_offset_2, 17, T[2]);
|
||||
b = FF(b, c, d, a, M_offset_3, 22, T[3]);
|
||||
a = FF(a, b, c, d, M_offset_4, 7, T[4]);
|
||||
d = FF(d, a, b, c, M_offset_5, 12, T[5]);
|
||||
c = FF(c, d, a, b, M_offset_6, 17, T[6]);
|
||||
b = FF(b, c, d, a, M_offset_7, 22, T[7]);
|
||||
a = FF(a, b, c, d, M_offset_8, 7, T[8]);
|
||||
d = FF(d, a, b, c, M_offset_9, 12, T[9]);
|
||||
c = FF(c, d, a, b, M_offset_10, 17, T[10]);
|
||||
b = FF(b, c, d, a, M_offset_11, 22, T[11]);
|
||||
a = FF(a, b, c, d, M_offset_12, 7, T[12]);
|
||||
d = FF(d, a, b, c, M_offset_13, 12, T[13]);
|
||||
c = FF(c, d, a, b, M_offset_14, 17, T[14]);
|
||||
b = FF(b, c, d, a, M_offset_15, 22, T[15]);
|
||||
a = GG(a, b, c, d, M_offset_1, 5, T[16]);
|
||||
d = GG(d, a, b, c, M_offset_6, 9, T[17]);
|
||||
c = GG(c, d, a, b, M_offset_11, 14, T[18]);
|
||||
b = GG(b, c, d, a, M_offset_0, 20, T[19]);
|
||||
a = GG(a, b, c, d, M_offset_5, 5, T[20]);
|
||||
d = GG(d, a, b, c, M_offset_10, 9, T[21]);
|
||||
c = GG(c, d, a, b, M_offset_15, 14, T[22]);
|
||||
b = GG(b, c, d, a, M_offset_4, 20, T[23]);
|
||||
a = GG(a, b, c, d, M_offset_9, 5, T[24]);
|
||||
d = GG(d, a, b, c, M_offset_14, 9, T[25]);
|
||||
c = GG(c, d, a, b, M_offset_3, 14, T[26]);
|
||||
b = GG(b, c, d, a, M_offset_8, 20, T[27]);
|
||||
a = GG(a, b, c, d, M_offset_13, 5, T[28]);
|
||||
d = GG(d, a, b, c, M_offset_2, 9, T[29]);
|
||||
c = GG(c, d, a, b, M_offset_7, 14, T[30]);
|
||||
b = GG(b, c, d, a, M_offset_12, 20, T[31]);
|
||||
a = HH(a, b, c, d, M_offset_5, 4, T[32]);
|
||||
d = HH(d, a, b, c, M_offset_8, 11, T[33]);
|
||||
c = HH(c, d, a, b, M_offset_11, 16, T[34]);
|
||||
b = HH(b, c, d, a, M_offset_14, 23, T[35]);
|
||||
a = HH(a, b, c, d, M_offset_1, 4, T[36]);
|
||||
d = HH(d, a, b, c, M_offset_4, 11, T[37]);
|
||||
c = HH(c, d, a, b, M_offset_7, 16, T[38]);
|
||||
b = HH(b, c, d, a, M_offset_10, 23, T[39]);
|
||||
a = HH(a, b, c, d, M_offset_13, 4, T[40]);
|
||||
d = HH(d, a, b, c, M_offset_0, 11, T[41]);
|
||||
c = HH(c, d, a, b, M_offset_3, 16, T[42]);
|
||||
b = HH(b, c, d, a, M_offset_6, 23, T[43]);
|
||||
a = HH(a, b, c, d, M_offset_9, 4, T[44]);
|
||||
d = HH(d, a, b, c, M_offset_12, 11, T[45]);
|
||||
c = HH(c, d, a, b, M_offset_15, 16, T[46]);
|
||||
b = HH(b, c, d, a, M_offset_2, 23, T[47]);
|
||||
a = II(a, b, c, d, M_offset_0, 6, T[48]);
|
||||
d = II(d, a, b, c, M_offset_7, 10, T[49]);
|
||||
c = II(c, d, a, b, M_offset_14, 15, T[50]);
|
||||
b = II(b, c, d, a, M_offset_5, 21, T[51]);
|
||||
a = II(a, b, c, d, M_offset_12, 6, T[52]);
|
||||
d = II(d, a, b, c, M_offset_3, 10, T[53]);
|
||||
c = II(c, d, a, b, M_offset_10, 15, T[54]);
|
||||
b = II(b, c, d, a, M_offset_1, 21, T[55]);
|
||||
a = II(a, b, c, d, M_offset_8, 6, T[56]);
|
||||
d = II(d, a, b, c, M_offset_15, 10, T[57]);
|
||||
c = II(c, d, a, b, M_offset_6, 15, T[58]);
|
||||
b = II(b, c, d, a, M_offset_13, 21, T[59]);
|
||||
a = II(a, b, c, d, M_offset_4, 6, T[60]);
|
||||
d = II(d, a, b, c, M_offset_11, 10, T[61]);
|
||||
c = II(c, d, a, b, M_offset_2, 15, T[62]);
|
||||
b = II(b, c, d, a, M_offset_9, 21, T[63]);
|
||||
H[0] = H[0] + a | 0;
|
||||
H[1] = H[1] + b | 0;
|
||||
H[2] = H[2] + c | 0;
|
||||
H[3] = H[3] + d | 0;
|
||||
}
|
||||
_doFinalize() {
|
||||
const data = this._data;
|
||||
const dataWords = data.words;
|
||||
const nBitsTotal = this._nDataBytes * 8;
|
||||
const nBitsLeft = data.sigBytes * 8;
|
||||
dataWords[nBitsLeft >>> 5] |= 128 << 24 - nBitsLeft % 32;
|
||||
const nBitsTotalH = Math.floor(nBitsTotal / 4294967296);
|
||||
const nBitsTotalL = nBitsTotal;
|
||||
dataWords[(nBitsLeft + 64 >>> 9 << 4) + 15] = (nBitsTotalH << 8 | nBitsTotalH >>> 24) & 16711935 | (nBitsTotalH << 24 | nBitsTotalH >>> 8) & 4278255360;
|
||||
dataWords[(nBitsLeft + 64 >>> 9 << 4) + 14] = (nBitsTotalL << 8 | nBitsTotalL >>> 24) & 16711935 | (nBitsTotalL << 24 | nBitsTotalL >>> 8) & 4278255360;
|
||||
data.sigBytes = (dataWords.length + 1) * 4;
|
||||
this._process();
|
||||
const hash = this._hash;
|
||||
const H = hash.words;
|
||||
for (let i = 0; i < 4; i += 1) {
|
||||
const H_i = H[i];
|
||||
H[i] = (H_i << 8 | H_i >>> 24) & 16711935 | (H_i << 24 | H_i >>> 8) & 4278255360;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
clone() {
|
||||
const clone = super.clone.call(this);
|
||||
clone._hash = this._hash.clone();
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut function to the hasher's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @returns The hash.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hash = MD5('message');
|
||||
* const hash = MD5(wordArray);
|
||||
* ```
|
||||
*/
|
||||
const MD5 = Hasher._createHelper(MD5Algo);
|
||||
/**
|
||||
* Shortcut function to the HMAC's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @param key - The secret key.
|
||||
* @returns The HMAC.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hmac = HmacMD5(message, key);
|
||||
* ```
|
||||
*/
|
||||
const HmacMD5 = Hasher._createHmacHelper(MD5Algo);
|
||||
|
||||
//#endregion
|
||||
export { HmacMD5, MD5, MD5Algo };
|
||||
//# sourceMappingURL=md5.mjs.map
|
||||
@@ -1,48 +0,0 @@
|
||||
import { BlockCipherMode } from "./cipher-core.mjs";
|
||||
|
||||
//#region src/mode-cfb.ts
|
||||
function generateKeystreamAndEncrypt(words, offset, blockSize, cipher) {
|
||||
const _words = words;
|
||||
let keystream;
|
||||
const iv = this._iv;
|
||||
if (iv) {
|
||||
keystream = iv.slice(0);
|
||||
this._iv = void 0;
|
||||
} else keystream = this._prevBlock;
|
||||
cipher.encryptBlock(keystream, 0);
|
||||
for (let i = 0; i < blockSize; i += 1) _words[offset + i] ^= keystream[i];
|
||||
}
|
||||
/**
|
||||
* CFB Encryptor
|
||||
*/
|
||||
var CFBEncryptor = class extends BlockCipherMode {
|
||||
processBlock(words, offset) {
|
||||
const cipher = this._cipher;
|
||||
const blockSize = cipher.blockSize;
|
||||
generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);
|
||||
this._prevBlock = words.slice(offset, offset + blockSize);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* CFB Decryptor
|
||||
*/
|
||||
var CFBDecryptor = class extends BlockCipherMode {
|
||||
processBlock(words, offset) {
|
||||
const cipher = this._cipher;
|
||||
const blockSize = cipher.blockSize;
|
||||
const thisBlock = words.slice(offset, offset + blockSize);
|
||||
generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);
|
||||
this._prevBlock = thisBlock;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Cipher Feedback block mode.
|
||||
*/
|
||||
var CFB = class extends BlockCipherMode {
|
||||
static Encryptor = CFBEncryptor;
|
||||
static Decryptor = CFBDecryptor;
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { CFB };
|
||||
//# sourceMappingURL=mode-cfb.mjs.map
|
||||
@@ -1,68 +0,0 @@
|
||||
import { BlockCipherMode } from "./cipher-core.mjs";
|
||||
|
||||
//#region src/mode-ctr-gladman.ts
|
||||
const incWord = (word) => {
|
||||
let _word = word;
|
||||
if ((word >> 24 & 255) === 255) {
|
||||
let b1 = word >> 16 & 255;
|
||||
let b2 = word >> 8 & 255;
|
||||
let b3 = word & 255;
|
||||
if (b1 === 255) {
|
||||
b1 = 0;
|
||||
if (b2 === 255) {
|
||||
b2 = 0;
|
||||
if (b3 === 255) b3 = 0;
|
||||
else b3 += 1;
|
||||
} else b2 += 1;
|
||||
} else b1 += 1;
|
||||
_word = 0;
|
||||
_word += b1 << 16;
|
||||
_word += b2 << 8;
|
||||
_word += b3;
|
||||
} else _word += 1 << 24;
|
||||
return _word;
|
||||
};
|
||||
const incCounter = (counter) => {
|
||||
const _counter = counter;
|
||||
_counter[0] = incWord(_counter[0]);
|
||||
if (_counter[0] === 0) _counter[1] = incWord(_counter[1]);
|
||||
return _counter;
|
||||
};
|
||||
/**
|
||||
* CTRGladman Encryptor/Decryptor (same operation)
|
||||
*/
|
||||
var CTRGladmanMode = class extends BlockCipherMode {
|
||||
/** Counter for CTR Gladman mode */
|
||||
_counter;
|
||||
processBlock(words, offset) {
|
||||
const _words = words;
|
||||
const cipher = this._cipher;
|
||||
const blockSize = cipher.blockSize;
|
||||
const iv = this._iv;
|
||||
let counter = this._counter;
|
||||
if (iv) {
|
||||
this._counter = iv.slice(0);
|
||||
counter = this._counter;
|
||||
this._iv = void 0;
|
||||
}
|
||||
incCounter(counter);
|
||||
const keystream = counter.slice(0);
|
||||
cipher.encryptBlock(keystream, 0);
|
||||
for (let i = 0; i < blockSize; i += 1) _words[offset + i] ^= keystream[i];
|
||||
}
|
||||
};
|
||||
/** @preserve
|
||||
* Counter block mode compatible with Dr Brian Gladman fileenc.c
|
||||
* derived from CTR mode
|
||||
* Jan Hruby jhruby.web@gmail.com
|
||||
*/
|
||||
var CTRGladman = class extends BlockCipherMode {
|
||||
/** Counter for CTR Gladman mode */
|
||||
_counter;
|
||||
static Encryptor = CTRGladmanMode;
|
||||
static Decryptor = CTRGladmanMode;
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { CTRGladman };
|
||||
//# sourceMappingURL=mode-ctr-gladman.mjs.map
|
||||
@@ -1,39 +0,0 @@
|
||||
import { BlockCipherMode } from "./cipher-core.mjs";
|
||||
|
||||
//#region src/mode-ctr.ts
|
||||
/**
|
||||
* CTR Encryptor/Decryptor (same operation)
|
||||
*/
|
||||
var CTRMode = class extends BlockCipherMode {
|
||||
/** Counter for CTR mode */
|
||||
_counter;
|
||||
processBlock(words, offset) {
|
||||
const _words = words;
|
||||
const cipher = this._cipher;
|
||||
const blockSize = cipher.blockSize;
|
||||
const iv = this._iv;
|
||||
let counter = this._counter;
|
||||
if (iv) {
|
||||
this._counter = iv.slice(0);
|
||||
counter = this._counter;
|
||||
this._iv = void 0;
|
||||
}
|
||||
const keystream = counter.slice(0);
|
||||
cipher.encryptBlock(keystream, 0);
|
||||
counter[blockSize - 1] = counter[blockSize - 1] + 1 | 0;
|
||||
for (let i = 0; i < blockSize; i += 1) _words[offset + i] ^= keystream[i];
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Counter block mode.
|
||||
*/
|
||||
var CTR = class extends BlockCipherMode {
|
||||
/** Counter for CTR mode */
|
||||
_counter;
|
||||
static Encryptor = CTRMode;
|
||||
static Decryptor = CTRMode;
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { CTR };
|
||||
//# sourceMappingURL=mode-ctr.mjs.map
|
||||
@@ -1,30 +0,0 @@
|
||||
import { BlockCipherMode } from "./cipher-core.mjs";
|
||||
|
||||
//#region src/mode-ecb.ts
|
||||
/**
|
||||
* ECB Encryptor
|
||||
*/
|
||||
var ECBEncryptor = class extends BlockCipherMode {
|
||||
processBlock(words, offset) {
|
||||
this._cipher.encryptBlock(words, offset);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* ECB Decryptor
|
||||
*/
|
||||
var ECBDecryptor = class extends BlockCipherMode {
|
||||
processBlock(words, offset) {
|
||||
this._cipher.decryptBlock(words, offset);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Electronic Codebook block mode.
|
||||
*/
|
||||
var ECB = class extends BlockCipherMode {
|
||||
static Encryptor = ECBEncryptor;
|
||||
static Decryptor = ECBDecryptor;
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { ECB };
|
||||
//# sourceMappingURL=mode-ecb.mjs.map
|
||||
@@ -1,40 +0,0 @@
|
||||
import { BlockCipherMode } from "./cipher-core.mjs";
|
||||
|
||||
//#region src/mode-ofb.ts
|
||||
/**
|
||||
* OFB Encryptor/Decryptor (same operation)
|
||||
*/
|
||||
var OFBMode = class extends BlockCipherMode {
|
||||
/** Keystream for OFB mode */
|
||||
_keystream;
|
||||
processBlock(words, offset) {
|
||||
const _words = words;
|
||||
const cipher = this._cipher;
|
||||
const blockSize = cipher.blockSize;
|
||||
const iv = this._iv;
|
||||
let keystream = this._keystream;
|
||||
if (iv) {
|
||||
this._keystream = iv.slice(0);
|
||||
keystream = this._keystream;
|
||||
this._iv = void 0;
|
||||
} else if (!keystream) {
|
||||
this._keystream = new Array(blockSize).fill(0);
|
||||
keystream = this._keystream;
|
||||
}
|
||||
cipher.encryptBlock(keystream, 0);
|
||||
for (let i = 0; i < blockSize; i += 1) _words[offset + i] ^= keystream[i];
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Output Feedback block mode.
|
||||
*/
|
||||
var OFB = class extends BlockCipherMode {
|
||||
/** Keystream for OFB mode */
|
||||
_keystream;
|
||||
static Encryptor = OFBMode;
|
||||
static Decryptor = OFBMode;
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { OFB };
|
||||
//# sourceMappingURL=mode-ofb.mjs.map
|
||||
@@ -1,25 +0,0 @@
|
||||
//#region src/pad-ansix923.ts
|
||||
/**
|
||||
* ANSI X.923 padding strategy.
|
||||
*/
|
||||
const AnsiX923 = {
|
||||
pad(data, blockSize) {
|
||||
const _data = data;
|
||||
const dataSigBytes = _data.sigBytes;
|
||||
const blockSizeBytes = blockSize * 4;
|
||||
const nPaddingBytes = blockSizeBytes - dataSigBytes % blockSizeBytes;
|
||||
const lastBytePos = dataSigBytes + nPaddingBytes - 1;
|
||||
_data.clamp();
|
||||
_data.words[lastBytePos >>> 2] |= nPaddingBytes << 24 - lastBytePos % 4 * 8;
|
||||
_data.sigBytes += nPaddingBytes;
|
||||
},
|
||||
unpad(data) {
|
||||
const _data = data;
|
||||
const nPaddingBytes = _data.words[_data.sigBytes - 1 >>> 2] & 255;
|
||||
_data.sigBytes -= nPaddingBytes;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { AnsiX923 };
|
||||
//# sourceMappingURL=pad-ansix923.mjs.map
|
||||
@@ -1,22 +0,0 @@
|
||||
import { WordArray } from "./core.mjs";
|
||||
|
||||
//#region src/pad-iso10126.ts
|
||||
/**
|
||||
* ISO 10126 padding strategy.
|
||||
*/
|
||||
const Iso10126 = {
|
||||
pad(data, blockSize) {
|
||||
const blockSizeBytes = blockSize * 4;
|
||||
const nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
|
||||
data.concat(WordArray.random(nPaddingBytes - 1)).concat(WordArray.create([nPaddingBytes << 24], 1));
|
||||
},
|
||||
unpad(data) {
|
||||
const _data = data;
|
||||
const nPaddingBytes = _data.words[_data.sigBytes - 1 >>> 2] & 255;
|
||||
_data.sigBytes -= nPaddingBytes;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { Iso10126 };
|
||||
//# sourceMappingURL=pad-iso10126.mjs.map
|
||||
@@ -1,22 +0,0 @@
|
||||
import { WordArray } from "./core.mjs";
|
||||
import { ZeroPadding } from "./pad-zeropadding.mjs";
|
||||
|
||||
//#region src/pad-iso97971.ts
|
||||
/**
|
||||
* ISO/IEC 9797-1 Padding Method 2.
|
||||
*/
|
||||
const Iso97971 = {
|
||||
pad(data, blockSize) {
|
||||
data.concat(WordArray.create([2147483648], 1));
|
||||
ZeroPadding.pad(data, blockSize);
|
||||
},
|
||||
unpad(data) {
|
||||
const _data = data;
|
||||
ZeroPadding.unpad(_data);
|
||||
_data.sigBytes -= 1;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { Iso97971 };
|
||||
//# sourceMappingURL=pad-iso97971.mjs.map
|
||||
@@ -1,12 +0,0 @@
|
||||
//#region src/pad-nopadding.ts
|
||||
/**
|
||||
* A noop padding strategy.
|
||||
*/
|
||||
const NoPadding = {
|
||||
pad(_data, _blockSize) {},
|
||||
unpad(_data) {}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { NoPadding };
|
||||
//# sourceMappingURL=pad-nopadding.mjs.map
|
||||
@@ -1,24 +0,0 @@
|
||||
//#region src/pad-zeropadding.ts
|
||||
/**
|
||||
* Zero padding strategy.
|
||||
*/
|
||||
const ZeroPadding = {
|
||||
pad(data, blockSize) {
|
||||
const _data = data;
|
||||
const blockSizeBytes = blockSize * 4;
|
||||
_data.clamp();
|
||||
_data.sigBytes += blockSizeBytes - (data.sigBytes % blockSizeBytes || blockSizeBytes);
|
||||
},
|
||||
unpad(data) {
|
||||
const _data = data;
|
||||
const dataWords = _data.words;
|
||||
for (let i = _data.sigBytes - 1; i >= 0; i -= 1) if (dataWords[i >>> 2] >>> 24 - i % 4 * 8 & 255) {
|
||||
_data.sigBytes = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { ZeroPadding };
|
||||
//# sourceMappingURL=pad-zeropadding.mjs.map
|
||||
@@ -1,99 +0,0 @@
|
||||
import { Base, HMAC, WordArray } from "./core.mjs";
|
||||
import { SHA256Algo } from "./sha256.mjs";
|
||||
|
||||
//#region src/pbkdf2.ts
|
||||
/**
|
||||
* Password-Based Key Derivation Function 2 algorithm.
|
||||
*/
|
||||
var PBKDF2Algo = class extends Base {
|
||||
cfg;
|
||||
/**
|
||||
* Initializes a newly created key derivation function.
|
||||
*
|
||||
* @param {Object} cfg (Optional) The configuration options to use for the derivation.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const kdf = new PBKDF2Algo();
|
||||
* const kdf = new PBKDF2Algo({ keySize: 8 });
|
||||
* const kdf = new PBKDF2Algo({ keySize: 8, iterations: 1000 });
|
||||
*/
|
||||
constructor(cfg) {
|
||||
super();
|
||||
/**
|
||||
* Configuration options.
|
||||
*
|
||||
* The default `hasher` and `interations` is different from CryptoJs to enhance security:
|
||||
* https://github.com/entronad/crypto-es/security/advisories/GHSA-mpj8-q39x-wq5h
|
||||
*
|
||||
* @property {number} keySize The key size in words to generate. Default: 4 (128 bits)
|
||||
* @property {Hasher} hasher The hasher to use. Default: SHA256
|
||||
* @property {number} iterations The number of iterations to perform. Default: 250000
|
||||
*/
|
||||
this.cfg = Object.assign({}, {
|
||||
keySize: 128 / 32,
|
||||
hasher: SHA256Algo,
|
||||
iterations: 25e4
|
||||
}, cfg);
|
||||
}
|
||||
/**
|
||||
* Computes the Password-Based Key Derivation Function 2.
|
||||
*
|
||||
* @param {WordArray|string} password The password.
|
||||
* @param {WordArray|string} salt A salt.
|
||||
*
|
||||
* @return {WordArray} The derived key.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const key = kdf.compute(password, salt);
|
||||
*/
|
||||
compute(password, salt) {
|
||||
const { cfg } = this;
|
||||
const hmac = HMAC.create(cfg.hasher, password);
|
||||
const derivedKey = WordArray.create();
|
||||
const blockIndex = WordArray.create([1]);
|
||||
const derivedKeyWords = derivedKey.words;
|
||||
const blockIndexWords = blockIndex.words;
|
||||
const { keySize, iterations } = cfg;
|
||||
while (derivedKeyWords.length < keySize) {
|
||||
const block = hmac.update(salt).finalize(blockIndex);
|
||||
hmac.reset();
|
||||
const blockWords = block.words;
|
||||
const blockWordsLength = blockWords.length;
|
||||
let intermediate = block;
|
||||
for (let i = 1; i < iterations; i += 1) {
|
||||
intermediate = hmac.finalize(intermediate);
|
||||
hmac.reset();
|
||||
const intermediateWords = intermediate.words;
|
||||
for (let j = 0; j < blockWordsLength; j += 1) blockWords[j] ^= intermediateWords[j];
|
||||
}
|
||||
derivedKey.concat(block);
|
||||
blockIndexWords[0] += 1;
|
||||
}
|
||||
derivedKey.sigBytes = keySize * 4;
|
||||
return derivedKey;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Computes the Password-Based Key Derivation Function 2.
|
||||
*
|
||||
* @param {WordArray|string} password The password.
|
||||
* @param {WordArray|string} salt A salt.
|
||||
* @param {Object} cfg (Optional) The configuration options to use for this computation.
|
||||
*
|
||||
* @return {WordArray} The derived key.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var key = PBKDF2(password, salt);
|
||||
* var key = PBKDF2(password, salt, { keySize: 8 });
|
||||
* var key = PBKDF2(password, salt, { keySize: 8, iterations: 1000 });
|
||||
*/
|
||||
const PBKDF2 = (password, salt, cfg) => new PBKDF2Algo(cfg).compute(password, salt);
|
||||
|
||||
//#endregion
|
||||
export { PBKDF2, PBKDF2Algo };
|
||||
//# sourceMappingURL=pbkdf2.mjs.map
|
||||
@@ -1,126 +0,0 @@
|
||||
import { StreamCipher } from "./cipher-core.mjs";
|
||||
|
||||
//#region src/rabbit-legacy.ts
|
||||
const S = [];
|
||||
const C_ = [];
|
||||
const G = [];
|
||||
function nextState() {
|
||||
const X = this._X;
|
||||
const C = this._C;
|
||||
for (let i = 0; i < 8; i += 1) C_[i] = C[i];
|
||||
C[0] = C[0] + 1295307597 + this._b | 0;
|
||||
C[1] = C[1] + 3545052371 + (C[0] >>> 0 < C_[0] >>> 0 ? 1 : 0) | 0;
|
||||
C[2] = C[2] + 886263092 + (C[1] >>> 0 < C_[1] >>> 0 ? 1 : 0) | 0;
|
||||
C[3] = C[3] + 1295307597 + (C[2] >>> 0 < C_[2] >>> 0 ? 1 : 0) | 0;
|
||||
C[4] = C[4] + 3545052371 + (C[3] >>> 0 < C_[3] >>> 0 ? 1 : 0) | 0;
|
||||
C[5] = C[5] + 886263092 + (C[4] >>> 0 < C_[4] >>> 0 ? 1 : 0) | 0;
|
||||
C[6] = C[6] + 1295307597 + (C[5] >>> 0 < C_[5] >>> 0 ? 1 : 0) | 0;
|
||||
C[7] = C[7] + 3545052371 + (C[6] >>> 0 < C_[6] >>> 0 ? 1 : 0) | 0;
|
||||
this._b = C[7] >>> 0 < C_[7] >>> 0 ? 1 : 0;
|
||||
for (let i = 0; i < 8; i += 1) {
|
||||
const gx = X[i] + C[i];
|
||||
const ga = gx & 65535;
|
||||
const gb = gx >>> 16;
|
||||
const gh = ((ga * ga >>> 17) + ga * gb >>> 15) + gb * gb;
|
||||
const gl = ((gx & 4294901760) * gx | 0) + ((gx & 65535) * gx | 0);
|
||||
G[i] = gh ^ gl;
|
||||
}
|
||||
X[0] = G[0] + (G[7] << 16 | G[7] >>> 16) + (G[6] << 16 | G[6] >>> 16) | 0;
|
||||
X[1] = G[1] + (G[0] << 8 | G[0] >>> 24) + G[7] | 0;
|
||||
X[2] = G[2] + (G[1] << 16 | G[1] >>> 16) + (G[0] << 16 | G[0] >>> 16) | 0;
|
||||
X[3] = G[3] + (G[2] << 8 | G[2] >>> 24) + G[1] | 0;
|
||||
X[4] = G[4] + (G[3] << 16 | G[3] >>> 16) + (G[2] << 16 | G[2] >>> 16) | 0;
|
||||
X[5] = G[5] + (G[4] << 8 | G[4] >>> 24) + G[3] | 0;
|
||||
X[6] = G[6] + (G[5] << 16 | G[5] >>> 16) + (G[4] << 16 | G[4] >>> 16) | 0;
|
||||
X[7] = G[7] + (G[6] << 8 | G[6] >>> 24) + G[5] | 0;
|
||||
}
|
||||
/**
|
||||
* Rabbit stream cipher algorithm.
|
||||
*
|
||||
* This is a legacy version that neglected to convert the key to little-endian.
|
||||
* This error doesn't affect the cipher's security,
|
||||
* but it does affect its compatibility with other implementations.
|
||||
*/
|
||||
var RabbitLegacyAlgo = class extends StreamCipher {
|
||||
_X;
|
||||
_C;
|
||||
_b;
|
||||
static ivSize = 64 / 32;
|
||||
constructor(xformMode, key, cfg) {
|
||||
super(xformMode, key, cfg);
|
||||
this.blockSize = 128 / 32;
|
||||
}
|
||||
_doReset() {
|
||||
const K = this._key.words;
|
||||
const { iv } = this.cfg;
|
||||
this._X = [
|
||||
K[0],
|
||||
K[3] << 16 | K[2] >>> 16,
|
||||
K[1],
|
||||
K[0] << 16 | K[3] >>> 16,
|
||||
K[2],
|
||||
K[1] << 16 | K[0] >>> 16,
|
||||
K[3],
|
||||
K[2] << 16 | K[1] >>> 16
|
||||
];
|
||||
const X = this._X;
|
||||
this._C = [
|
||||
K[2] << 16 | K[2] >>> 16,
|
||||
K[0] & 4294901760 | K[1] & 65535,
|
||||
K[3] << 16 | K[3] >>> 16,
|
||||
K[1] & 4294901760 | K[2] & 65535,
|
||||
K[0] << 16 | K[0] >>> 16,
|
||||
K[2] & 4294901760 | K[3] & 65535,
|
||||
K[1] << 16 | K[1] >>> 16,
|
||||
K[3] & 4294901760 | K[0] & 65535
|
||||
];
|
||||
const C = this._C;
|
||||
this._b = 0;
|
||||
for (let i = 0; i < 4; i += 1) nextState.call(this);
|
||||
for (let i = 0; i < 8; i += 1) C[i] ^= X[i + 4 & 7];
|
||||
if (iv) {
|
||||
const IV = iv.words;
|
||||
const IV_0 = IV[0];
|
||||
const IV_1 = IV[1];
|
||||
const i0 = (IV_0 << 8 | IV_0 >>> 24) & 16711935 | (IV_0 << 24 | IV_0 >>> 8) & 4278255360;
|
||||
const i2 = (IV_1 << 8 | IV_1 >>> 24) & 16711935 | (IV_1 << 24 | IV_1 >>> 8) & 4278255360;
|
||||
const i1 = i0 >>> 16 | i2 & 4294901760;
|
||||
const i3 = i2 << 16 | i0 & 65535;
|
||||
C[0] ^= i0;
|
||||
C[1] ^= i1;
|
||||
C[2] ^= i2;
|
||||
C[3] ^= i3;
|
||||
C[4] ^= i0;
|
||||
C[5] ^= i1;
|
||||
C[6] ^= i2;
|
||||
C[7] ^= i3;
|
||||
for (let i = 0; i < 4; i += 1) nextState.call(this);
|
||||
}
|
||||
}
|
||||
_doProcessBlock(M, offset) {
|
||||
const _M = M;
|
||||
const X = this._X;
|
||||
nextState.call(this);
|
||||
S[0] = X[0] ^ X[5] >>> 16 ^ X[3] << 16;
|
||||
S[1] = X[2] ^ X[7] >>> 16 ^ X[5] << 16;
|
||||
S[2] = X[4] ^ X[1] >>> 16 ^ X[7] << 16;
|
||||
S[3] = X[6] ^ X[3] >>> 16 ^ X[1] << 16;
|
||||
for (let i = 0; i < 4; i += 1) {
|
||||
S[i] = (S[i] << 8 | S[i] >>> 24) & 16711935 | (S[i] << 24 | S[i] >>> 8) & 4278255360;
|
||||
_M[offset + i] ^= S[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut functions to the cipher's object interface.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var ciphertext = RabbitLegacy.encrypt(message, key, cfg);
|
||||
* var plaintext = RabbitLegacy.decrypt(ciphertext, key, cfg);
|
||||
*/
|
||||
const RabbitLegacy = StreamCipher._createHelper(RabbitLegacyAlgo);
|
||||
|
||||
//#endregion
|
||||
export { RabbitLegacy, RabbitLegacyAlgo };
|
||||
//# sourceMappingURL=rabbit-legacy.mjs.map
|
||||
@@ -1,123 +0,0 @@
|
||||
import { StreamCipher } from "./cipher-core.mjs";
|
||||
|
||||
//#region src/rabbit.ts
|
||||
const S = [];
|
||||
const C_ = [];
|
||||
const G = [];
|
||||
function nextState() {
|
||||
const X = this._X;
|
||||
const C = this._C;
|
||||
for (let i = 0; i < 8; i += 1) C_[i] = C[i];
|
||||
C[0] = C[0] + 1295307597 + this._b | 0;
|
||||
C[1] = C[1] + 3545052371 + (C[0] >>> 0 < C_[0] >>> 0 ? 1 : 0) | 0;
|
||||
C[2] = C[2] + 886263092 + (C[1] >>> 0 < C_[1] >>> 0 ? 1 : 0) | 0;
|
||||
C[3] = C[3] + 1295307597 + (C[2] >>> 0 < C_[2] >>> 0 ? 1 : 0) | 0;
|
||||
C[4] = C[4] + 3545052371 + (C[3] >>> 0 < C_[3] >>> 0 ? 1 : 0) | 0;
|
||||
C[5] = C[5] + 886263092 + (C[4] >>> 0 < C_[4] >>> 0 ? 1 : 0) | 0;
|
||||
C[6] = C[6] + 1295307597 + (C[5] >>> 0 < C_[5] >>> 0 ? 1 : 0) | 0;
|
||||
C[7] = C[7] + 3545052371 + (C[6] >>> 0 < C_[6] >>> 0 ? 1 : 0) | 0;
|
||||
this._b = C[7] >>> 0 < C_[7] >>> 0 ? 1 : 0;
|
||||
for (let i = 0; i < 8; i += 1) {
|
||||
const gx = X[i] + C[i];
|
||||
const ga = gx & 65535;
|
||||
const gb = gx >>> 16;
|
||||
const gh = ((ga * ga >>> 17) + ga * gb >>> 15) + gb * gb;
|
||||
const gl = ((gx & 4294901760) * gx | 0) + ((gx & 65535) * gx | 0);
|
||||
G[i] = gh ^ gl;
|
||||
}
|
||||
X[0] = G[0] + (G[7] << 16 | G[7] >>> 16) + (G[6] << 16 | G[6] >>> 16) | 0;
|
||||
X[1] = G[1] + (G[0] << 8 | G[0] >>> 24) + G[7] | 0;
|
||||
X[2] = G[2] + (G[1] << 16 | G[1] >>> 16) + (G[0] << 16 | G[0] >>> 16) | 0;
|
||||
X[3] = G[3] + (G[2] << 8 | G[2] >>> 24) + G[1] | 0;
|
||||
X[4] = G[4] + (G[3] << 16 | G[3] >>> 16) + (G[2] << 16 | G[2] >>> 16) | 0;
|
||||
X[5] = G[5] + (G[4] << 8 | G[4] >>> 24) + G[3] | 0;
|
||||
X[6] = G[6] + (G[5] << 16 | G[5] >>> 16) + (G[4] << 16 | G[4] >>> 16) | 0;
|
||||
X[7] = G[7] + (G[6] << 8 | G[6] >>> 24) + G[5] | 0;
|
||||
}
|
||||
/**
|
||||
* Rabbit stream cipher algorithm
|
||||
*/
|
||||
var RabbitAlgo = class extends StreamCipher {
|
||||
_X;
|
||||
_C;
|
||||
_b;
|
||||
static ivSize = 64 / 32;
|
||||
constructor(xformMode, key, cfg) {
|
||||
super(xformMode, key, cfg);
|
||||
this.blockSize = 128 / 32;
|
||||
}
|
||||
_doReset() {
|
||||
const K = this._key.words;
|
||||
const { iv } = this.cfg;
|
||||
for (let i = 0; i < 4; i += 1) K[i] = (K[i] << 8 | K[i] >>> 24) & 16711935 | (K[i] << 24 | K[i] >>> 8) & 4278255360;
|
||||
this._X = [
|
||||
K[0],
|
||||
K[3] << 16 | K[2] >>> 16,
|
||||
K[1],
|
||||
K[0] << 16 | K[3] >>> 16,
|
||||
K[2],
|
||||
K[1] << 16 | K[0] >>> 16,
|
||||
K[3],
|
||||
K[2] << 16 | K[1] >>> 16
|
||||
];
|
||||
const X = this._X;
|
||||
this._C = [
|
||||
K[2] << 16 | K[2] >>> 16,
|
||||
K[0] & 4294901760 | K[1] & 65535,
|
||||
K[3] << 16 | K[3] >>> 16,
|
||||
K[1] & 4294901760 | K[2] & 65535,
|
||||
K[0] << 16 | K[0] >>> 16,
|
||||
K[2] & 4294901760 | K[3] & 65535,
|
||||
K[1] << 16 | K[1] >>> 16,
|
||||
K[3] & 4294901760 | K[0] & 65535
|
||||
];
|
||||
const C = this._C;
|
||||
this._b = 0;
|
||||
for (let i = 0; i < 4; i += 1) nextState.call(this);
|
||||
for (let i = 0; i < 8; i += 1) C[i] ^= X[i + 4 & 7];
|
||||
if (iv) {
|
||||
const IV = iv.words;
|
||||
const IV_0 = IV[0];
|
||||
const IV_1 = IV[1];
|
||||
const i0 = (IV_0 << 8 | IV_0 >>> 24) & 16711935 | (IV_0 << 24 | IV_0 >>> 8) & 4278255360;
|
||||
const i2 = (IV_1 << 8 | IV_1 >>> 24) & 16711935 | (IV_1 << 24 | IV_1 >>> 8) & 4278255360;
|
||||
const i1 = i0 >>> 16 | i2 & 4294901760;
|
||||
const i3 = i2 << 16 | i0 & 65535;
|
||||
C[0] ^= i0;
|
||||
C[1] ^= i1;
|
||||
C[2] ^= i2;
|
||||
C[3] ^= i3;
|
||||
C[4] ^= i0;
|
||||
C[5] ^= i1;
|
||||
C[6] ^= i2;
|
||||
C[7] ^= i3;
|
||||
for (let i = 0; i < 4; i += 1) nextState.call(this);
|
||||
}
|
||||
}
|
||||
_doProcessBlock(M, offset) {
|
||||
const _M = M;
|
||||
const X = this._X;
|
||||
nextState.call(this);
|
||||
S[0] = X[0] ^ X[5] >>> 16 ^ X[3] << 16;
|
||||
S[1] = X[2] ^ X[7] >>> 16 ^ X[5] << 16;
|
||||
S[2] = X[4] ^ X[1] >>> 16 ^ X[7] << 16;
|
||||
S[3] = X[6] ^ X[3] >>> 16 ^ X[1] << 16;
|
||||
for (let i = 0; i < 4; i += 1) {
|
||||
S[i] = (S[i] << 8 | S[i] >>> 24) & 16711935 | (S[i] << 24 | S[i] >>> 8) & 4278255360;
|
||||
_M[offset + i] ^= S[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut functions to the cipher's object interface.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var ciphertext = Rabbit.encrypt(message, key, cfg);
|
||||
* var plaintext = Rabbit.decrypt(ciphertext, key, cfg);
|
||||
*/
|
||||
const Rabbit = StreamCipher._createHelper(RabbitAlgo);
|
||||
|
||||
//#endregion
|
||||
export { Rabbit, RabbitAlgo };
|
||||
//# sourceMappingURL=rabbit.mjs.map
|
||||
@@ -1,93 +0,0 @@
|
||||
import { StreamCipher } from "./cipher-core.mjs";
|
||||
|
||||
//#region src/rc4.ts
|
||||
/**
|
||||
* RC4 stream cipher algorithm.
|
||||
*/
|
||||
var RC4Algo = class extends StreamCipher {
|
||||
static keySize = 256 / 32;
|
||||
static ivSize = 0;
|
||||
_S;
|
||||
_i;
|
||||
_j;
|
||||
generateKeystreamWord() {
|
||||
const S = this._S;
|
||||
let i = this._i;
|
||||
let j = this._j;
|
||||
let keystreamWord = 0;
|
||||
for (let n = 0; n < 4; n += 1) {
|
||||
i = (i + 1) % 256;
|
||||
j = (j + S[i]) % 256;
|
||||
const t = S[i];
|
||||
S[i] = S[j];
|
||||
S[j] = t;
|
||||
keystreamWord |= S[(S[i] + S[j]) % 256] << 24 - n * 8;
|
||||
}
|
||||
this._i = i;
|
||||
this._j = j;
|
||||
return keystreamWord;
|
||||
}
|
||||
_doReset() {
|
||||
const key = this._key;
|
||||
const keyWords = key.words;
|
||||
const keySigBytes = key.sigBytes;
|
||||
this._S = [];
|
||||
const S = this._S;
|
||||
for (let i = 0; i < 256; i += 1) S[i] = i;
|
||||
for (let i = 0, j = 0; i < 256; i += 1) {
|
||||
const keyByteIndex = i % keySigBytes;
|
||||
const keyByte = keyWords[keyByteIndex >>> 2] >>> 24 - keyByteIndex % 4 * 8 & 255;
|
||||
j = (j + S[i] + keyByte) % 256;
|
||||
const t = S[i];
|
||||
S[i] = S[j];
|
||||
S[j] = t;
|
||||
}
|
||||
this._j = 0;
|
||||
this._i = this._j;
|
||||
}
|
||||
_doProcessBlock(M, offset) {
|
||||
const _M = M;
|
||||
_M[offset] ^= this.generateKeystreamWord();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut functions to the cipher's object interface.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var ciphertext = RC4.encrypt(message, key, cfg);
|
||||
* var plaintext = RC4.decrypt(ciphertext, key, cfg);
|
||||
*/
|
||||
const RC4 = StreamCipher._createHelper(RC4Algo);
|
||||
/**
|
||||
* Modified RC4 stream cipher algorithm.
|
||||
*/
|
||||
var RC4DropAlgo = class extends RC4Algo {
|
||||
constructor(xformMode, key, cfg) {
|
||||
super(xformMode, key, cfg);
|
||||
/**
|
||||
* Configuration options.
|
||||
*
|
||||
* @property {number} drop The number of keystream words to drop. Default 192
|
||||
*/
|
||||
if (this.cfg.drop === void 0) this.cfg.drop = 192;
|
||||
}
|
||||
_doReset() {
|
||||
super._doReset();
|
||||
const dropCount = this.cfg.drop || 192;
|
||||
for (let i = dropCount; i > 0; i -= 1) this.generateKeystreamWord();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut functions to the cipher's object interface.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var ciphertext = RC4Drop.encrypt(message, key, cfg);
|
||||
* var plaintext = RC4Drop.decrypt(ciphertext, key, cfg);
|
||||
*/
|
||||
const RC4Drop = StreamCipher._createHelper(RC4DropAlgo);
|
||||
|
||||
//#endregion
|
||||
export { RC4, RC4Algo, RC4Drop, RC4DropAlgo };
|
||||
//# sourceMappingURL=rc4.mjs.map
|
||||
@@ -1,497 +0,0 @@
|
||||
import { Hasher, Hasher32, WordArray } from "./core.mjs";
|
||||
|
||||
//#region src/ripemd160.ts
|
||||
const _zl = WordArray.create([
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
7,
|
||||
4,
|
||||
13,
|
||||
1,
|
||||
10,
|
||||
6,
|
||||
15,
|
||||
3,
|
||||
12,
|
||||
0,
|
||||
9,
|
||||
5,
|
||||
2,
|
||||
14,
|
||||
11,
|
||||
8,
|
||||
3,
|
||||
10,
|
||||
14,
|
||||
4,
|
||||
9,
|
||||
15,
|
||||
8,
|
||||
1,
|
||||
2,
|
||||
7,
|
||||
0,
|
||||
6,
|
||||
13,
|
||||
11,
|
||||
5,
|
||||
12,
|
||||
1,
|
||||
9,
|
||||
11,
|
||||
10,
|
||||
0,
|
||||
8,
|
||||
12,
|
||||
4,
|
||||
13,
|
||||
3,
|
||||
7,
|
||||
15,
|
||||
14,
|
||||
5,
|
||||
6,
|
||||
2,
|
||||
4,
|
||||
0,
|
||||
5,
|
||||
9,
|
||||
7,
|
||||
12,
|
||||
2,
|
||||
10,
|
||||
14,
|
||||
1,
|
||||
3,
|
||||
8,
|
||||
11,
|
||||
6,
|
||||
15,
|
||||
13
|
||||
]);
|
||||
const _zr = WordArray.create([
|
||||
5,
|
||||
14,
|
||||
7,
|
||||
0,
|
||||
9,
|
||||
2,
|
||||
11,
|
||||
4,
|
||||
13,
|
||||
6,
|
||||
15,
|
||||
8,
|
||||
1,
|
||||
10,
|
||||
3,
|
||||
12,
|
||||
6,
|
||||
11,
|
||||
3,
|
||||
7,
|
||||
0,
|
||||
13,
|
||||
5,
|
||||
10,
|
||||
14,
|
||||
15,
|
||||
8,
|
||||
12,
|
||||
4,
|
||||
9,
|
||||
1,
|
||||
2,
|
||||
15,
|
||||
5,
|
||||
1,
|
||||
3,
|
||||
7,
|
||||
14,
|
||||
6,
|
||||
9,
|
||||
11,
|
||||
8,
|
||||
12,
|
||||
2,
|
||||
10,
|
||||
0,
|
||||
4,
|
||||
13,
|
||||
8,
|
||||
6,
|
||||
4,
|
||||
1,
|
||||
3,
|
||||
11,
|
||||
15,
|
||||
0,
|
||||
5,
|
||||
12,
|
||||
2,
|
||||
13,
|
||||
9,
|
||||
7,
|
||||
10,
|
||||
14,
|
||||
12,
|
||||
15,
|
||||
10,
|
||||
4,
|
||||
1,
|
||||
5,
|
||||
8,
|
||||
7,
|
||||
6,
|
||||
2,
|
||||
13,
|
||||
14,
|
||||
0,
|
||||
3,
|
||||
9,
|
||||
11
|
||||
]);
|
||||
const _sl = WordArray.create([
|
||||
11,
|
||||
14,
|
||||
15,
|
||||
12,
|
||||
5,
|
||||
8,
|
||||
7,
|
||||
9,
|
||||
11,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
6,
|
||||
7,
|
||||
9,
|
||||
8,
|
||||
7,
|
||||
6,
|
||||
8,
|
||||
13,
|
||||
11,
|
||||
9,
|
||||
7,
|
||||
15,
|
||||
7,
|
||||
12,
|
||||
15,
|
||||
9,
|
||||
11,
|
||||
7,
|
||||
13,
|
||||
12,
|
||||
11,
|
||||
13,
|
||||
6,
|
||||
7,
|
||||
14,
|
||||
9,
|
||||
13,
|
||||
15,
|
||||
14,
|
||||
8,
|
||||
13,
|
||||
6,
|
||||
5,
|
||||
12,
|
||||
7,
|
||||
5,
|
||||
11,
|
||||
12,
|
||||
14,
|
||||
15,
|
||||
14,
|
||||
15,
|
||||
9,
|
||||
8,
|
||||
9,
|
||||
14,
|
||||
5,
|
||||
6,
|
||||
8,
|
||||
6,
|
||||
5,
|
||||
12,
|
||||
9,
|
||||
15,
|
||||
5,
|
||||
11,
|
||||
6,
|
||||
8,
|
||||
13,
|
||||
12,
|
||||
5,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
11,
|
||||
8,
|
||||
5,
|
||||
6
|
||||
]);
|
||||
const _sr = WordArray.create([
|
||||
8,
|
||||
9,
|
||||
9,
|
||||
11,
|
||||
13,
|
||||
15,
|
||||
15,
|
||||
5,
|
||||
7,
|
||||
7,
|
||||
8,
|
||||
11,
|
||||
14,
|
||||
14,
|
||||
12,
|
||||
6,
|
||||
9,
|
||||
13,
|
||||
15,
|
||||
7,
|
||||
12,
|
||||
8,
|
||||
9,
|
||||
11,
|
||||
7,
|
||||
7,
|
||||
12,
|
||||
7,
|
||||
6,
|
||||
15,
|
||||
13,
|
||||
11,
|
||||
9,
|
||||
7,
|
||||
15,
|
||||
11,
|
||||
8,
|
||||
6,
|
||||
6,
|
||||
14,
|
||||
12,
|
||||
13,
|
||||
5,
|
||||
14,
|
||||
13,
|
||||
13,
|
||||
7,
|
||||
5,
|
||||
15,
|
||||
5,
|
||||
8,
|
||||
11,
|
||||
14,
|
||||
14,
|
||||
6,
|
||||
14,
|
||||
6,
|
||||
9,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
5,
|
||||
15,
|
||||
8,
|
||||
8,
|
||||
5,
|
||||
12,
|
||||
9,
|
||||
12,
|
||||
5,
|
||||
14,
|
||||
6,
|
||||
8,
|
||||
13,
|
||||
6,
|
||||
5,
|
||||
15,
|
||||
13,
|
||||
11,
|
||||
11
|
||||
]);
|
||||
const _hl = WordArray.create([
|
||||
0,
|
||||
1518500249,
|
||||
1859775393,
|
||||
2400959708,
|
||||
2840853838
|
||||
]);
|
||||
const _hr = WordArray.create([
|
||||
1352829926,
|
||||
1548603684,
|
||||
1836072691,
|
||||
2053994217,
|
||||
0
|
||||
]);
|
||||
/**
|
||||
* RIPEMD160 round function 1
|
||||
*/
|
||||
const f1 = (x, y, z) => x ^ y ^ z;
|
||||
/**
|
||||
* RIPEMD160 round function 2
|
||||
*/
|
||||
const f2 = (x, y, z) => x & y | ~x & z;
|
||||
/**
|
||||
* RIPEMD160 round function 3
|
||||
*/
|
||||
const f3 = (x, y, z) => (x | ~y) ^ z;
|
||||
/**
|
||||
* RIPEMD160 round function 4
|
||||
*/
|
||||
const f4 = (x, y, z) => x & z | y & ~z;
|
||||
/**
|
||||
* RIPEMD160 round function 5
|
||||
*/
|
||||
const f5 = (x, y, z) => x ^ (y | ~z);
|
||||
/**
|
||||
* Rotate left helper
|
||||
*/
|
||||
const rotl = (x, n) => x << n | x >>> 32 - n;
|
||||
/**
|
||||
* RIPEMD160 hash algorithm.
|
||||
*/
|
||||
var RIPEMD160Algo = class extends Hasher32 {
|
||||
_doReset() {
|
||||
this._hash = WordArray.create([
|
||||
1732584193,
|
||||
4023233417,
|
||||
2562383102,
|
||||
271733878,
|
||||
3285377520
|
||||
]);
|
||||
}
|
||||
_doProcessBlock(M, offset) {
|
||||
const _M = M;
|
||||
for (let i = 0; i < 16; i += 1) {
|
||||
const offset_i = offset + i;
|
||||
const M_offset_i = _M[offset_i];
|
||||
_M[offset_i] = (M_offset_i << 8 | M_offset_i >>> 24) & 16711935 | (M_offset_i << 24 | M_offset_i >>> 8) & 4278255360;
|
||||
}
|
||||
const H = this._hash.words;
|
||||
const hl = _hl.words;
|
||||
const hr = _hr.words;
|
||||
const zl = _zl.words;
|
||||
const zr = _zr.words;
|
||||
const sl = _sl.words;
|
||||
const sr = _sr.words;
|
||||
let al = H[0];
|
||||
let bl = H[1];
|
||||
let cl = H[2];
|
||||
let dl = H[3];
|
||||
let el = H[4];
|
||||
let ar = H[0];
|
||||
let br = H[1];
|
||||
let cr = H[2];
|
||||
let dr = H[3];
|
||||
let er = H[4];
|
||||
let t;
|
||||
for (let i = 0; i < 80; i += 1) {
|
||||
t = al + _M[offset + zl[i]] | 0;
|
||||
if (i < 16) t += f1(bl, cl, dl) + hl[0];
|
||||
else if (i < 32) t += f2(bl, cl, dl) + hl[1];
|
||||
else if (i < 48) t += f3(bl, cl, dl) + hl[2];
|
||||
else if (i < 64) t += f4(bl, cl, dl) + hl[3];
|
||||
else t += f5(bl, cl, dl) + hl[4];
|
||||
t |= 0;
|
||||
t = rotl(t, sl[i]);
|
||||
t = t + el | 0;
|
||||
al = el;
|
||||
el = dl;
|
||||
dl = rotl(cl, 10);
|
||||
cl = bl;
|
||||
bl = t;
|
||||
t = ar + _M[offset + zr[i]] | 0;
|
||||
if (i < 16) t += f5(br, cr, dr) + hr[0];
|
||||
else if (i < 32) t += f4(br, cr, dr) + hr[1];
|
||||
else if (i < 48) t += f3(br, cr, dr) + hr[2];
|
||||
else if (i < 64) t += f2(br, cr, dr) + hr[3];
|
||||
else t += f1(br, cr, dr) + hr[4];
|
||||
t |= 0;
|
||||
t = rotl(t, sr[i]);
|
||||
t = t + er | 0;
|
||||
ar = er;
|
||||
er = dr;
|
||||
dr = rotl(cr, 10);
|
||||
cr = br;
|
||||
br = t;
|
||||
}
|
||||
t = H[1] + cl + dr | 0;
|
||||
H[1] = H[2] + dl + er | 0;
|
||||
H[2] = H[3] + el + ar | 0;
|
||||
H[3] = H[4] + al + br | 0;
|
||||
H[4] = H[0] + bl + cr | 0;
|
||||
H[0] = t;
|
||||
}
|
||||
_doFinalize() {
|
||||
const data = this._data;
|
||||
const dataWords = data.words;
|
||||
const nBitsTotal = this._nDataBytes * 8;
|
||||
const nBitsLeft = data.sigBytes * 8;
|
||||
dataWords[nBitsLeft >>> 5] |= 128 << 24 - nBitsLeft % 32;
|
||||
dataWords[(nBitsLeft + 64 >>> 9 << 4) + 14] = (nBitsTotal << 8 | nBitsTotal >>> 24) & 16711935 | (nBitsTotal << 24 | nBitsTotal >>> 8) & 4278255360;
|
||||
data.sigBytes = (dataWords.length + 1) * 4;
|
||||
this._process();
|
||||
const hash = this._hash;
|
||||
const H = hash.words;
|
||||
for (let i = 0; i < 5; i += 1) {
|
||||
const H_i = H[i];
|
||||
H[i] = (H_i << 8 | H_i >>> 24) & 16711935 | (H_i << 24 | H_i >>> 8) & 4278255360;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
clone() {
|
||||
const clone = super.clone.call(this);
|
||||
clone._hash = this._hash.clone();
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut function to the hasher's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @returns The hash.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hash = RIPEMD160('message');
|
||||
* const hash = RIPEMD160(wordArray);
|
||||
* ```
|
||||
*/
|
||||
const RIPEMD160 = Hasher._createHelper(RIPEMD160Algo);
|
||||
/**
|
||||
* Shortcut function to the HMAC's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @param key - The secret key.
|
||||
* @returns The HMAC.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hmac = HmacRIPEMD160(message, key);
|
||||
* ```
|
||||
*/
|
||||
const HmacRIPEMD160 = Hasher._createHmacHelper(RIPEMD160Algo);
|
||||
|
||||
//#endregion
|
||||
export { HmacRIPEMD160, RIPEMD160, RIPEMD160Algo };
|
||||
//# sourceMappingURL=ripemd160.mjs.map
|
||||
@@ -1,95 +0,0 @@
|
||||
import { Hasher, Hasher32, WordArray } from "./core.mjs";
|
||||
|
||||
//#region src/sha1.ts
|
||||
const W = [];
|
||||
/**
|
||||
* SHA-1 hash algorithm.
|
||||
*/
|
||||
var SHA1Algo = class extends Hasher32 {
|
||||
_doReset() {
|
||||
this._hash = new WordArray([
|
||||
1732584193,
|
||||
4023233417,
|
||||
2562383102,
|
||||
271733878,
|
||||
3285377520
|
||||
]);
|
||||
}
|
||||
_doProcessBlock(M, offset) {
|
||||
const H = this._hash.words;
|
||||
let a = H[0];
|
||||
let b = H[1];
|
||||
let c = H[2];
|
||||
let d = H[3];
|
||||
let e = H[4];
|
||||
for (let i = 0; i < 80; i += 1) {
|
||||
if (i < 16) W[i] = M[offset + i] | 0;
|
||||
else {
|
||||
const n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
|
||||
W[i] = n << 1 | n >>> 31;
|
||||
}
|
||||
let t = (a << 5 | a >>> 27) + e + W[i];
|
||||
if (i < 20) t += (b & c | ~b & d) + 1518500249;
|
||||
else if (i < 40) t += (b ^ c ^ d) + 1859775393;
|
||||
else if (i < 60) t += (b & c | b & d | c & d) - 1894007588;
|
||||
else t += (b ^ c ^ d) - 899497514;
|
||||
e = d;
|
||||
d = c;
|
||||
c = b << 30 | b >>> 2;
|
||||
b = a;
|
||||
a = t;
|
||||
}
|
||||
H[0] = H[0] + a | 0;
|
||||
H[1] = H[1] + b | 0;
|
||||
H[2] = H[2] + c | 0;
|
||||
H[3] = H[3] + d | 0;
|
||||
H[4] = H[4] + e | 0;
|
||||
}
|
||||
_doFinalize() {
|
||||
const data = this._data;
|
||||
const dataWords = data.words;
|
||||
const nBitsTotal = this._nDataBytes * 8;
|
||||
const nBitsLeft = data.sigBytes * 8;
|
||||
dataWords[nBitsLeft >>> 5] |= 128 << 24 - nBitsLeft % 32;
|
||||
dataWords[(nBitsLeft + 64 >>> 9 << 4) + 14] = Math.floor(nBitsTotal / 4294967296);
|
||||
dataWords[(nBitsLeft + 64 >>> 9 << 4) + 15] = nBitsTotal;
|
||||
data.sigBytes = dataWords.length * 4;
|
||||
this._process();
|
||||
return this._hash;
|
||||
}
|
||||
clone() {
|
||||
const clone = super.clone.call(this);
|
||||
clone._hash = this._hash.clone();
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut function to the hasher's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @returns The hash.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hash = SHA1('message');
|
||||
* const hash = SHA1(wordArray);
|
||||
* ```
|
||||
*/
|
||||
const SHA1 = Hasher._createHelper(SHA1Algo);
|
||||
/**
|
||||
* Shortcut function to the HMAC's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @param key - The secret key.
|
||||
* @returns The HMAC.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hmac = HmacSHA1(message, key);
|
||||
* ```
|
||||
*/
|
||||
const HmacSHA1 = Hasher._createHmacHelper(SHA1Algo);
|
||||
|
||||
//#endregion
|
||||
export { HmacSHA1, SHA1, SHA1Algo };
|
||||
//# sourceMappingURL=sha1.mjs.map
|
||||
@@ -1,60 +0,0 @@
|
||||
import { WordArray } from "./core.mjs";
|
||||
import { SHA256Algo } from "./sha256.mjs";
|
||||
|
||||
//#region src/sha224.ts
|
||||
/**
|
||||
* SHA-224 hash algorithm.
|
||||
*/
|
||||
var SHA224Algo = class extends SHA256Algo {
|
||||
_doReset() {
|
||||
this._hash = new WordArray([
|
||||
3238371032,
|
||||
914150663,
|
||||
812702999,
|
||||
4144912697,
|
||||
4290775857,
|
||||
1750603025,
|
||||
1694076839,
|
||||
3204075428
|
||||
]);
|
||||
}
|
||||
_doFinalize() {
|
||||
const hash = super._doFinalize.call(this);
|
||||
hash.sigBytes -= 4;
|
||||
return hash;
|
||||
}
|
||||
clone() {
|
||||
const clone = super.clone.call(this);
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut function to the hasher's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @returns The hash.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hash = SHA224('message');
|
||||
* const hash = SHA224(wordArray);
|
||||
* ```
|
||||
*/
|
||||
const SHA224 = SHA256Algo._createHelper(SHA224Algo);
|
||||
/**
|
||||
* Shortcut function to the HMAC's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @param key - The secret key.
|
||||
* @returns The HMAC.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hmac = HmacSHA224(message, key);
|
||||
* ```
|
||||
*/
|
||||
const HmacSHA224 = SHA256Algo._createHmacHelper(SHA224Algo);
|
||||
|
||||
//#endregion
|
||||
export { HmacSHA224, SHA224, SHA224Algo };
|
||||
//# sourceMappingURL=sha224.mjs.map
|
||||
@@ -1,126 +0,0 @@
|
||||
import { Hasher, Hasher32, WordArray } from "./core.mjs";
|
||||
|
||||
//#region src/sha256.ts
|
||||
const { H, K } = /* @__PURE__ */ (() => {
|
||||
const _H = [];
|
||||
const _K = [];
|
||||
const isPrime = (n$1) => {
|
||||
const sqrtN = Math.sqrt(n$1);
|
||||
for (let factor = 2; factor <= sqrtN; factor += 1) if (!(n$1 % factor)) return false;
|
||||
return true;
|
||||
};
|
||||
const getFractionalBits = (n$1) => (n$1 - (n$1 | 0)) * 4294967296 | 0;
|
||||
let n = 2;
|
||||
let nPrime = 0;
|
||||
while (nPrime < 64) {
|
||||
if (isPrime(n)) {
|
||||
if (nPrime < 8) _H[nPrime] = getFractionalBits(n ** (1 / 2));
|
||||
_K[nPrime] = getFractionalBits(n ** (1 / 3));
|
||||
nPrime += 1;
|
||||
}
|
||||
n += 1;
|
||||
}
|
||||
return {
|
||||
H: _H,
|
||||
K: _K
|
||||
};
|
||||
})();
|
||||
const W = [];
|
||||
/**
|
||||
* SHA-256 hash algorithm.
|
||||
*/
|
||||
var SHA256Algo = class extends Hasher32 {
|
||||
_doReset() {
|
||||
this._hash = new WordArray(H.slice(0));
|
||||
}
|
||||
_doProcessBlock(M, offset) {
|
||||
const _H = this._hash.words;
|
||||
let a = _H[0];
|
||||
let b = _H[1];
|
||||
let c = _H[2];
|
||||
let d = _H[3];
|
||||
let e = _H[4];
|
||||
let f = _H[5];
|
||||
let g = _H[6];
|
||||
let h = _H[7];
|
||||
for (let i = 0; i < 64; i += 1) {
|
||||
if (i < 16) W[i] = M[offset + i] | 0;
|
||||
else {
|
||||
const gamma0x = W[i - 15];
|
||||
const gamma0 = (gamma0x << 25 | gamma0x >>> 7) ^ (gamma0x << 14 | gamma0x >>> 18) ^ gamma0x >>> 3;
|
||||
const gamma1x = W[i - 2];
|
||||
const gamma1 = (gamma1x << 15 | gamma1x >>> 17) ^ (gamma1x << 13 | gamma1x >>> 19) ^ gamma1x >>> 10;
|
||||
W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];
|
||||
}
|
||||
const ch = e & f ^ ~e & g;
|
||||
const maj = a & b ^ a & c ^ b & c;
|
||||
const sigma0 = (a << 30 | a >>> 2) ^ (a << 19 | a >>> 13) ^ (a << 10 | a >>> 22);
|
||||
const sigma1 = (e << 26 | e >>> 6) ^ (e << 21 | e >>> 11) ^ (e << 7 | e >>> 25);
|
||||
const t1 = h + sigma1 + ch + K[i] + W[i];
|
||||
const t2 = sigma0 + maj;
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1 | 0;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2 | 0;
|
||||
}
|
||||
_H[0] = _H[0] + a | 0;
|
||||
_H[1] = _H[1] + b | 0;
|
||||
_H[2] = _H[2] + c | 0;
|
||||
_H[3] = _H[3] + d | 0;
|
||||
_H[4] = _H[4] + e | 0;
|
||||
_H[5] = _H[5] + f | 0;
|
||||
_H[6] = _H[6] + g | 0;
|
||||
_H[7] = _H[7] + h | 0;
|
||||
}
|
||||
_doFinalize() {
|
||||
const data = this._data;
|
||||
const dataWords = data.words;
|
||||
const nBitsTotal = this._nDataBytes * 8;
|
||||
const nBitsLeft = data.sigBytes * 8;
|
||||
dataWords[nBitsLeft >>> 5] |= 128 << 24 - nBitsLeft % 32;
|
||||
dataWords[(nBitsLeft + 64 >>> 9 << 4) + 14] = Math.floor(nBitsTotal / 4294967296);
|
||||
dataWords[(nBitsLeft + 64 >>> 9 << 4) + 15] = nBitsTotal;
|
||||
data.sigBytes = dataWords.length * 4;
|
||||
this._process();
|
||||
return this._hash;
|
||||
}
|
||||
clone() {
|
||||
const clone = super.clone.call(this);
|
||||
clone._hash = this._hash.clone();
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut function to the hasher's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @returns The hash.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hash = SHA256('message');
|
||||
* const hash = SHA256(wordArray);
|
||||
* ```
|
||||
*/
|
||||
const SHA256 = Hasher._createHelper(SHA256Algo);
|
||||
/**
|
||||
* Shortcut function to the HMAC's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @param key - The secret key.
|
||||
* @returns The HMAC.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hmac = HmacSHA256(message, key);
|
||||
* ```
|
||||
*/
|
||||
const HmacSHA256 = Hasher._createHmacHelper(SHA256Algo);
|
||||
|
||||
//#endregion
|
||||
export { HmacSHA256, SHA256, SHA256Algo };
|
||||
//# sourceMappingURL=sha256.mjs.map
|
||||
@@ -1,170 +0,0 @@
|
||||
import { Hasher, Hasher32, WordArray } from "./core.mjs";
|
||||
import { X64Word } from "./x64-core.mjs";
|
||||
|
||||
//#region src/sha3.ts
|
||||
const RHO_OFFSETS = [];
|
||||
const PI_INDEXES = [];
|
||||
const ROUND_CONSTANTS = [];
|
||||
const T = /* @__PURE__ */ (() => {
|
||||
const a = [];
|
||||
for (let i = 0; i < 25; i += 1) a[i] = X64Word.create();
|
||||
return a;
|
||||
})();
|
||||
/**
|
||||
* SHA-3 hash algorithm.
|
||||
*/
|
||||
var SHA3Algo = class extends Hasher32 {
|
||||
_state = [];
|
||||
/**
|
||||
* Initializes a newly created hasher.
|
||||
*
|
||||
* @param cfg - Configuration options.
|
||||
* @property {number} outputLength - The desired number of bits in the output hash.
|
||||
* Only values permitted are: 224, 256, 384, 512.
|
||||
* Default: 512
|
||||
*/
|
||||
constructor(cfg) {
|
||||
super(Object.assign({ outputLength: 512 }, cfg));
|
||||
}
|
||||
_doReset() {
|
||||
this._state = [];
|
||||
for (let i = 0; i < 25; i += 1) this._state[i] = new X64Word();
|
||||
this.blockSize = (1600 - 2 * this.cfg.outputLength) / 32;
|
||||
}
|
||||
_doProcessBlock(M, offset) {
|
||||
if (this._state.length === 0) this._doReset();
|
||||
const state = this._state;
|
||||
const nBlockSizeLanes = this.blockSize / 2;
|
||||
for (let i = 0; i < nBlockSizeLanes; i += 1) {
|
||||
let M2i = M[offset + 2 * i];
|
||||
let M2i1 = M[offset + 2 * i + 1];
|
||||
M2i = (M2i << 8 | M2i >>> 24) & 16711935 | (M2i << 24 | M2i >>> 8) & 4278255360;
|
||||
M2i1 = (M2i1 << 8 | M2i1 >>> 24) & 16711935 | (M2i1 << 24 | M2i1 >>> 8) & 4278255360;
|
||||
const lane = state[i];
|
||||
lane.high ^= M2i1;
|
||||
lane.low ^= M2i;
|
||||
}
|
||||
for (let round = 0; round < 24; round += 1) {
|
||||
for (let x = 0; x < 5; x += 1) {
|
||||
let tMsw = 0;
|
||||
let tLsw = 0;
|
||||
for (let y = 0; y < 5; y += 1) {
|
||||
const lane$1 = state[x + 5 * y];
|
||||
tMsw ^= lane$1.high;
|
||||
tLsw ^= lane$1.low;
|
||||
}
|
||||
const Tx = T[x];
|
||||
Tx.high = tMsw;
|
||||
Tx.low = tLsw;
|
||||
}
|
||||
for (let x = 0; x < 5; x += 1) {
|
||||
const Tx4 = T[(x + 4) % 5];
|
||||
const Tx1 = T[(x + 1) % 5];
|
||||
const Tx1Msw = Tx1.high;
|
||||
const Tx1Lsw = Tx1.low;
|
||||
const tMsw = Tx4.high ^ (Tx1Msw << 1 | Tx1Lsw >>> 31);
|
||||
const tLsw = Tx4.low ^ (Tx1Lsw << 1 | Tx1Msw >>> 31);
|
||||
for (let y = 0; y < 5; y += 1) {
|
||||
const lane$1 = state[x + 5 * y];
|
||||
lane$1.high ^= tMsw;
|
||||
lane$1.low ^= tLsw;
|
||||
}
|
||||
}
|
||||
for (let laneIndex = 1; laneIndex < 25; laneIndex += 1) {
|
||||
let tMsw;
|
||||
let tLsw;
|
||||
const lane$1 = state[laneIndex];
|
||||
const laneMsw = lane$1.high;
|
||||
const laneLsw = lane$1.low;
|
||||
const rhoOffset = RHO_OFFSETS[laneIndex];
|
||||
if (rhoOffset < 32) {
|
||||
tMsw = laneMsw << rhoOffset | laneLsw >>> 32 - rhoOffset;
|
||||
tLsw = laneLsw << rhoOffset | laneMsw >>> 32 - rhoOffset;
|
||||
} else {
|
||||
tMsw = laneLsw << rhoOffset - 32 | laneMsw >>> 64 - rhoOffset;
|
||||
tLsw = laneMsw << rhoOffset - 32 | laneLsw >>> 64 - rhoOffset;
|
||||
}
|
||||
const TPiLane = T[PI_INDEXES[laneIndex]];
|
||||
TPiLane.high = tMsw;
|
||||
TPiLane.low = tLsw;
|
||||
}
|
||||
const T0 = T[0];
|
||||
const state0 = state[0];
|
||||
T0.high = state0.high;
|
||||
T0.low = state0.low;
|
||||
for (let x = 0; x < 5; x += 1) for (let y = 0; y < 5; y += 1) {
|
||||
const laneIndex = x + 5 * y;
|
||||
const lane$1 = state[laneIndex];
|
||||
const TLane = T[laneIndex];
|
||||
const Tx1Lane = T[(x + 1) % 5 + 5 * y];
|
||||
const Tx2Lane = T[(x + 2) % 5 + 5 * y];
|
||||
lane$1.high = TLane.high ^ ~Tx1Lane.high & Tx2Lane.high;
|
||||
lane$1.low = TLane.low ^ ~Tx1Lane.low & Tx2Lane.low;
|
||||
}
|
||||
const lane = state[0];
|
||||
const roundConstant = ROUND_CONSTANTS[round];
|
||||
lane.high ^= roundConstant.high;
|
||||
lane.low ^= roundConstant.low;
|
||||
}
|
||||
}
|
||||
_doFinalize() {
|
||||
const data = this._data;
|
||||
const dataWords = data.words;
|
||||
const nBitsLeft = data.sigBytes * 8;
|
||||
const blockSizeBits = this.blockSize * 32;
|
||||
dataWords[nBitsLeft >>> 5] |= 1 << 24 - nBitsLeft % 32;
|
||||
dataWords[(Math.ceil((nBitsLeft + 1) / blockSizeBits) * blockSizeBits >>> 5) - 1] |= 128;
|
||||
data.sigBytes = dataWords.length * 4;
|
||||
this._process();
|
||||
const state = this._state;
|
||||
const outputLengthBytes = this.cfg.outputLength / 8;
|
||||
const outputLengthLanes = outputLengthBytes / 8;
|
||||
const hashWords = [];
|
||||
for (let i = 0; i < outputLengthLanes; i += 1) {
|
||||
const lane = state[i];
|
||||
let laneMsw = lane.high;
|
||||
let laneLsw = lane.low;
|
||||
laneMsw = (laneMsw << 8 | laneMsw >>> 24) & 16711935 | (laneMsw << 24 | laneMsw >>> 8) & 4278255360;
|
||||
laneLsw = (laneLsw << 8 | laneLsw >>> 24) & 16711935 | (laneLsw << 24 | laneLsw >>> 8) & 4278255360;
|
||||
hashWords.push(laneLsw);
|
||||
hashWords.push(laneMsw);
|
||||
}
|
||||
return new WordArray(hashWords, outputLengthBytes);
|
||||
}
|
||||
clone() {
|
||||
const clone = super.clone.call(this);
|
||||
clone._state = [];
|
||||
for (let i = 0; i < this._state.length; i += 1) clone._state[i] = this._state[i].clone();
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut function to the hasher's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @returns The hash.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hash = SHA3('message');
|
||||
* const hash = SHA3(wordArray);
|
||||
* ```
|
||||
*/
|
||||
const SHA3 = Hasher._createHelper(SHA3Algo);
|
||||
/**
|
||||
* Shortcut function to the HMAC's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @param key - The secret key.
|
||||
* @returns The HMAC.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hmac = HmacSHA3(message, key);
|
||||
* ```
|
||||
*/
|
||||
const HmacSHA3 = Hasher._createHmacHelper(SHA3Algo);
|
||||
|
||||
//#endregion
|
||||
export { HmacSHA3, SHA3, SHA3Algo };
|
||||
//# sourceMappingURL=sha3.mjs.map
|
||||
@@ -1,60 +0,0 @@
|
||||
import { X64Word, X64WordArray } from "./x64-core.mjs";
|
||||
import { SHA512Algo } from "./sha512.mjs";
|
||||
|
||||
//#region src/sha384.ts
|
||||
/**
|
||||
* SHA-384 hash algorithm.
|
||||
*/
|
||||
var SHA384Algo = class extends SHA512Algo {
|
||||
_doReset() {
|
||||
this._hash = new X64WordArray([
|
||||
new X64Word(3418070365, 3238371032),
|
||||
new X64Word(1654270250, 914150663),
|
||||
new X64Word(2438529370, 812702999),
|
||||
new X64Word(355462360, 4144912697),
|
||||
new X64Word(1731405415, 4290775857),
|
||||
new X64Word(2394180231, 1750603025),
|
||||
new X64Word(3675008525, 1694076839),
|
||||
new X64Word(1203062813, 3204075428)
|
||||
]);
|
||||
}
|
||||
_doFinalize() {
|
||||
const hash = super._doFinalize.call(this);
|
||||
hash.sigBytes -= 16;
|
||||
return hash;
|
||||
}
|
||||
clone() {
|
||||
const clone = super.clone.call(this);
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut function to the hasher's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @returns The hash.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hash = SHA384('message');
|
||||
* const hash = SHA384(wordArray);
|
||||
* ```
|
||||
*/
|
||||
const SHA384 = SHA512Algo._createHelper(SHA384Algo);
|
||||
/**
|
||||
* Shortcut function to the HMAC's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @param key - The secret key.
|
||||
* @returns The HMAC.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hmac = HmacSHA384(message, key);
|
||||
* ```
|
||||
*/
|
||||
const HmacSHA384 = SHA512Algo._createHmacHelper(SHA384Algo);
|
||||
|
||||
//#endregion
|
||||
export { HmacSHA384, SHA384, SHA384Algo };
|
||||
//# sourceMappingURL=sha384.mjs.map
|
||||
@@ -1,300 +0,0 @@
|
||||
import { Hasher, Hasher64 } from "./core.mjs";
|
||||
import { X64Word, X64WordArray } from "./x64-core.mjs";
|
||||
|
||||
//#region src/sha512.ts
|
||||
const K = [
|
||||
new X64Word(1116352408, 3609767458),
|
||||
new X64Word(1899447441, 602891725),
|
||||
new X64Word(3049323471, 3964484399),
|
||||
new X64Word(3921009573, 2173295548),
|
||||
new X64Word(961987163, 4081628472),
|
||||
new X64Word(1508970993, 3053834265),
|
||||
new X64Word(2453635748, 2937671579),
|
||||
new X64Word(2870763221, 3664609560),
|
||||
new X64Word(3624381080, 2734883394),
|
||||
new X64Word(310598401, 1164996542),
|
||||
new X64Word(607225278, 1323610764),
|
||||
new X64Word(1426881987, 3590304994),
|
||||
new X64Word(1925078388, 4068182383),
|
||||
new X64Word(2162078206, 991336113),
|
||||
new X64Word(2614888103, 633803317),
|
||||
new X64Word(3248222580, 3479774868),
|
||||
new X64Word(3835390401, 2666613458),
|
||||
new X64Word(4022224774, 944711139),
|
||||
new X64Word(264347078, 2341262773),
|
||||
new X64Word(604807628, 2007800933),
|
||||
new X64Word(770255983, 1495990901),
|
||||
new X64Word(1249150122, 1856431235),
|
||||
new X64Word(1555081692, 3175218132),
|
||||
new X64Word(1996064986, 2198950837),
|
||||
new X64Word(2554220882, 3999719339),
|
||||
new X64Word(2821834349, 766784016),
|
||||
new X64Word(2952996808, 2566594879),
|
||||
new X64Word(3210313671, 3203337956),
|
||||
new X64Word(3336571891, 1034457026),
|
||||
new X64Word(3584528711, 2466948901),
|
||||
new X64Word(113926993, 3758326383),
|
||||
new X64Word(338241895, 168717936),
|
||||
new X64Word(666307205, 1188179964),
|
||||
new X64Word(773529912, 1546045734),
|
||||
new X64Word(1294757372, 1522805485),
|
||||
new X64Word(1396182291, 2643833823),
|
||||
new X64Word(1695183700, 2343527390),
|
||||
new X64Word(1986661051, 1014477480),
|
||||
new X64Word(2177026350, 1206759142),
|
||||
new X64Word(2456956037, 344077627),
|
||||
new X64Word(2730485921, 1290863460),
|
||||
new X64Word(2820302411, 3158454273),
|
||||
new X64Word(3259730800, 3505952657),
|
||||
new X64Word(3345764771, 106217008),
|
||||
new X64Word(3516065817, 3606008344),
|
||||
new X64Word(3600352804, 1432725776),
|
||||
new X64Word(4094571909, 1467031594),
|
||||
new X64Word(275423344, 851169720),
|
||||
new X64Word(430227734, 3100823752),
|
||||
new X64Word(506948616, 1363258195),
|
||||
new X64Word(659060556, 3750685593),
|
||||
new X64Word(883997877, 3785050280),
|
||||
new X64Word(958139571, 3318307427),
|
||||
new X64Word(1322822218, 3812723403),
|
||||
new X64Word(1537002063, 2003034995),
|
||||
new X64Word(1747873779, 3602036899),
|
||||
new X64Word(1955562222, 1575990012),
|
||||
new X64Word(2024104815, 1125592928),
|
||||
new X64Word(2227730452, 2716904306),
|
||||
new X64Word(2361852424, 442776044),
|
||||
new X64Word(2428436474, 593698344),
|
||||
new X64Word(2756734187, 3733110249),
|
||||
new X64Word(3204031479, 2999351573),
|
||||
new X64Word(3329325298, 3815920427),
|
||||
new X64Word(3391569614, 3928383900),
|
||||
new X64Word(3515267271, 566280711),
|
||||
new X64Word(3940187606, 3454069534),
|
||||
new X64Word(4118630271, 4000239992),
|
||||
new X64Word(116418474, 1914138554),
|
||||
new X64Word(174292421, 2731055270),
|
||||
new X64Word(289380356, 3203993006),
|
||||
new X64Word(460393269, 320620315),
|
||||
new X64Word(685471733, 587496836),
|
||||
new X64Word(852142971, 1086792851),
|
||||
new X64Word(1017036298, 365543100),
|
||||
new X64Word(1126000580, 2618297676),
|
||||
new X64Word(1288033470, 3409855158),
|
||||
new X64Word(1501505948, 4234509866),
|
||||
new X64Word(1607167915, 987167468),
|
||||
new X64Word(1816402316, 1246189591)
|
||||
];
|
||||
const W = /* @__PURE__ */ (() => {
|
||||
const a = [];
|
||||
for (let i = 0; i < 80; i += 1) a[i] = new X64Word();
|
||||
return a;
|
||||
})();
|
||||
/**
|
||||
* SHA-512 hash algorithm.
|
||||
*/
|
||||
var SHA512Algo = class extends Hasher64 {
|
||||
constructor(cfg) {
|
||||
super(cfg);
|
||||
this.blockSize = 1024 / 32;
|
||||
}
|
||||
_doReset() {
|
||||
this._hash = new X64WordArray([
|
||||
new X64Word(1779033703, 4089235720),
|
||||
new X64Word(3144134277, 2227873595),
|
||||
new X64Word(1013904242, 4271175723),
|
||||
new X64Word(2773480762, 1595750129),
|
||||
new X64Word(1359893119, 2917565137),
|
||||
new X64Word(2600822924, 725511199),
|
||||
new X64Word(528734635, 4215389547),
|
||||
new X64Word(1541459225, 327033209)
|
||||
]);
|
||||
}
|
||||
_doProcessBlock(M, offset) {
|
||||
const H = this._hash.words;
|
||||
const H0 = H[0];
|
||||
const H1 = H[1];
|
||||
const H2 = H[2];
|
||||
const H3 = H[3];
|
||||
const H4 = H[4];
|
||||
const H5 = H[5];
|
||||
const H6 = H[6];
|
||||
const H7 = H[7];
|
||||
const H0h = H0.high;
|
||||
let H0l = H0.low;
|
||||
const H1h = H1.high;
|
||||
let H1l = H1.low;
|
||||
const H2h = H2.high;
|
||||
let H2l = H2.low;
|
||||
const H3h = H3.high;
|
||||
let H3l = H3.low;
|
||||
const H4h = H4.high;
|
||||
let H4l = H4.low;
|
||||
const H5h = H5.high;
|
||||
let H5l = H5.low;
|
||||
const H6h = H6.high;
|
||||
let H6l = H6.low;
|
||||
const H7h = H7.high;
|
||||
let H7l = H7.low;
|
||||
let ah = H0h;
|
||||
let al = H0l;
|
||||
let bh = H1h;
|
||||
let bl = H1l;
|
||||
let ch = H2h;
|
||||
let cl = H2l;
|
||||
let dh = H3h;
|
||||
let dl = H3l;
|
||||
let eh = H4h;
|
||||
let el = H4l;
|
||||
let fh = H5h;
|
||||
let fl = H5l;
|
||||
let gh = H6h;
|
||||
let gl = H6l;
|
||||
let hh = H7h;
|
||||
let hl = H7l;
|
||||
for (let i = 0; i < 80; i += 1) {
|
||||
let Wil;
|
||||
let Wih;
|
||||
const Wi = W[i];
|
||||
if (i < 16) {
|
||||
Wi.high = M[offset + i * 2] | 0;
|
||||
Wih = Wi.high;
|
||||
Wi.low = M[offset + i * 2 + 1] | 0;
|
||||
Wil = Wi.low;
|
||||
} else {
|
||||
const gamma0x = W[i - 15];
|
||||
const gamma0xh = gamma0x.high;
|
||||
const gamma0xl = gamma0x.low;
|
||||
const gamma0h = (gamma0xh >>> 1 | gamma0xl << 31) ^ (gamma0xh >>> 8 | gamma0xl << 24) ^ gamma0xh >>> 7;
|
||||
const gamma0l = (gamma0xl >>> 1 | gamma0xh << 31) ^ (gamma0xl >>> 8 | gamma0xh << 24) ^ (gamma0xl >>> 7 | gamma0xh << 25);
|
||||
const gamma1x = W[i - 2];
|
||||
const gamma1xh = gamma1x.high;
|
||||
const gamma1xl = gamma1x.low;
|
||||
const gamma1h = (gamma1xh >>> 19 | gamma1xl << 13) ^ (gamma1xh << 3 | gamma1xl >>> 29) ^ gamma1xh >>> 6;
|
||||
const gamma1l = (gamma1xl >>> 19 | gamma1xh << 13) ^ (gamma1xl << 3 | gamma1xh >>> 29) ^ (gamma1xl >>> 6 | gamma1xh << 26);
|
||||
const Wi7 = W[i - 7];
|
||||
const Wi7h = Wi7.high;
|
||||
const Wi7l = Wi7.low;
|
||||
const Wi16 = W[i - 16];
|
||||
const Wi16h = Wi16.high;
|
||||
const Wi16l = Wi16.low;
|
||||
Wil = gamma0l + Wi7l;
|
||||
Wih = gamma0h + Wi7h + (Wil >>> 0 < gamma0l >>> 0 ? 1 : 0);
|
||||
Wil += gamma1l;
|
||||
Wih = Wih + gamma1h + (Wil >>> 0 < gamma1l >>> 0 ? 1 : 0);
|
||||
Wil += Wi16l;
|
||||
Wih = Wih + Wi16h + (Wil >>> 0 < Wi16l >>> 0 ? 1 : 0);
|
||||
Wi.high = Wih;
|
||||
Wi.low = Wil;
|
||||
}
|
||||
const chh = eh & fh ^ ~eh & gh;
|
||||
const chl = el & fl ^ ~el & gl;
|
||||
const majh = ah & bh ^ ah & ch ^ bh & ch;
|
||||
const majl = al & bl ^ al & cl ^ bl & cl;
|
||||
const sigma0h = (ah >>> 28 | al << 4) ^ (ah << 30 | al >>> 2) ^ (ah << 25 | al >>> 7);
|
||||
const sigma0l = (al >>> 28 | ah << 4) ^ (al << 30 | ah >>> 2) ^ (al << 25 | ah >>> 7);
|
||||
const sigma1h = (eh >>> 14 | el << 18) ^ (eh >>> 18 | el << 14) ^ (eh << 23 | el >>> 9);
|
||||
const sigma1l = (el >>> 14 | eh << 18) ^ (el >>> 18 | eh << 14) ^ (el << 23 | eh >>> 9);
|
||||
const Ki = K[i];
|
||||
const Kih = Ki.high;
|
||||
const Kil = Ki.low;
|
||||
let t1l = hl + sigma1l;
|
||||
let t1h = hh + sigma1h + (t1l >>> 0 < hl >>> 0 ? 1 : 0);
|
||||
t1l += chl;
|
||||
t1h = t1h + chh + (t1l >>> 0 < chl >>> 0 ? 1 : 0);
|
||||
t1l += Kil;
|
||||
t1h = t1h + Kih + (t1l >>> 0 < Kil >>> 0 ? 1 : 0);
|
||||
t1l += Wil;
|
||||
t1h = t1h + Wih + (t1l >>> 0 < Wil >>> 0 ? 1 : 0);
|
||||
const t2l = sigma0l + majl;
|
||||
const t2h = sigma0h + majh + (t2l >>> 0 < sigma0l >>> 0 ? 1 : 0);
|
||||
hh = gh;
|
||||
hl = gl;
|
||||
gh = fh;
|
||||
gl = fl;
|
||||
fh = eh;
|
||||
fl = el;
|
||||
el = dl + t1l | 0;
|
||||
eh = dh + t1h + (el >>> 0 < dl >>> 0 ? 1 : 0) | 0;
|
||||
dh = ch;
|
||||
dl = cl;
|
||||
ch = bh;
|
||||
cl = bl;
|
||||
bh = ah;
|
||||
bl = al;
|
||||
al = t1l + t2l | 0;
|
||||
ah = t1h + t2h + (al >>> 0 < t1l >>> 0 ? 1 : 0) | 0;
|
||||
}
|
||||
H0.low = H0l + al;
|
||||
H0l = H0.low;
|
||||
H0.high = H0h + ah + (H0l >>> 0 < al >>> 0 ? 1 : 0);
|
||||
H1.low = H1l + bl;
|
||||
H1l = H1.low;
|
||||
H1.high = H1h + bh + (H1l >>> 0 < bl >>> 0 ? 1 : 0);
|
||||
H2.low = H2l + cl;
|
||||
H2l = H2.low;
|
||||
H2.high = H2h + ch + (H2l >>> 0 < cl >>> 0 ? 1 : 0);
|
||||
H3.low = H3l + dl;
|
||||
H3l = H3.low;
|
||||
H3.high = H3h + dh + (H3l >>> 0 < dl >>> 0 ? 1 : 0);
|
||||
H4.low = H4l + el;
|
||||
H4l = H4.low;
|
||||
H4.high = H4h + eh + (H4l >>> 0 < el >>> 0 ? 1 : 0);
|
||||
H5.low = H5l + fl;
|
||||
H5l = H5.low;
|
||||
H5.high = H5h + fh + (H5l >>> 0 < fl >>> 0 ? 1 : 0);
|
||||
H6.low = H6l + gl;
|
||||
H6l = H6.low;
|
||||
H6.high = H6h + gh + (H6l >>> 0 < gl >>> 0 ? 1 : 0);
|
||||
H7.low = H7l + hl;
|
||||
H7l = H7.low;
|
||||
H7.high = H7h + hh + (H7l >>> 0 < hl >>> 0 ? 1 : 0);
|
||||
}
|
||||
_doFinalize() {
|
||||
const data = this._data;
|
||||
const dataWords = data.words;
|
||||
const nBitsTotal = this._nDataBytes * 8;
|
||||
const nBitsLeft = data.sigBytes * 8;
|
||||
dataWords[nBitsLeft >>> 5] |= 128 << 24 - nBitsLeft % 32;
|
||||
dataWords[(nBitsLeft + 128 >>> 10 << 5) + 30] = Math.floor(nBitsTotal / 4294967296);
|
||||
dataWords[(nBitsLeft + 128 >>> 10 << 5) + 31] = nBitsTotal;
|
||||
data.sigBytes = dataWords.length * 4;
|
||||
this._process();
|
||||
const hash = this._hash.toX32();
|
||||
return hash;
|
||||
}
|
||||
clone() {
|
||||
const clone = super.clone.call(this);
|
||||
clone._hash = this._hash.clone();
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut function to the hasher's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @returns The hash.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hash = SHA512('message');
|
||||
* const hash = SHA512(wordArray);
|
||||
* ```
|
||||
*/
|
||||
const SHA512 = Hasher._createHelper(SHA512Algo);
|
||||
/**
|
||||
* Shortcut function to the HMAC's object interface.
|
||||
*
|
||||
* @param message - The message to hash.
|
||||
* @param key - The secret key.
|
||||
* @returns The HMAC.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const hmac = HmacSHA512(message, key);
|
||||
* ```
|
||||
*/
|
||||
const HmacSHA512 = Hasher._createHmacHelper(SHA512Algo);
|
||||
|
||||
//#endregion
|
||||
export { HmacSHA512, SHA512, SHA512Algo };
|
||||
//# sourceMappingURL=sha512.mjs.map
|
||||
@@ -1,822 +0,0 @@
|
||||
import { WordArray } from "./core.mjs";
|
||||
import { BlockCipher } from "./cipher-core.mjs";
|
||||
|
||||
//#region src/tripledes.ts
|
||||
const PC1 = [
|
||||
57,
|
||||
49,
|
||||
41,
|
||||
33,
|
||||
25,
|
||||
17,
|
||||
9,
|
||||
1,
|
||||
58,
|
||||
50,
|
||||
42,
|
||||
34,
|
||||
26,
|
||||
18,
|
||||
10,
|
||||
2,
|
||||
59,
|
||||
51,
|
||||
43,
|
||||
35,
|
||||
27,
|
||||
19,
|
||||
11,
|
||||
3,
|
||||
60,
|
||||
52,
|
||||
44,
|
||||
36,
|
||||
63,
|
||||
55,
|
||||
47,
|
||||
39,
|
||||
31,
|
||||
23,
|
||||
15,
|
||||
7,
|
||||
62,
|
||||
54,
|
||||
46,
|
||||
38,
|
||||
30,
|
||||
22,
|
||||
14,
|
||||
6,
|
||||
61,
|
||||
53,
|
||||
45,
|
||||
37,
|
||||
29,
|
||||
21,
|
||||
13,
|
||||
5,
|
||||
28,
|
||||
20,
|
||||
12,
|
||||
4
|
||||
];
|
||||
const PC2 = [
|
||||
14,
|
||||
17,
|
||||
11,
|
||||
24,
|
||||
1,
|
||||
5,
|
||||
3,
|
||||
28,
|
||||
15,
|
||||
6,
|
||||
21,
|
||||
10,
|
||||
23,
|
||||
19,
|
||||
12,
|
||||
4,
|
||||
26,
|
||||
8,
|
||||
16,
|
||||
7,
|
||||
27,
|
||||
20,
|
||||
13,
|
||||
2,
|
||||
41,
|
||||
52,
|
||||
31,
|
||||
37,
|
||||
47,
|
||||
55,
|
||||
30,
|
||||
40,
|
||||
51,
|
||||
45,
|
||||
33,
|
||||
48,
|
||||
44,
|
||||
49,
|
||||
39,
|
||||
56,
|
||||
34,
|
||||
53,
|
||||
46,
|
||||
42,
|
||||
50,
|
||||
36,
|
||||
29,
|
||||
32
|
||||
];
|
||||
const BIT_SHIFTS = [
|
||||
1,
|
||||
2,
|
||||
4,
|
||||
6,
|
||||
8,
|
||||
10,
|
||||
12,
|
||||
14,
|
||||
15,
|
||||
17,
|
||||
19,
|
||||
21,
|
||||
23,
|
||||
25,
|
||||
27,
|
||||
28
|
||||
];
|
||||
const SBOX_P = [
|
||||
{
|
||||
0: 8421888,
|
||||
268435456: 32768,
|
||||
536870912: 8421378,
|
||||
805306368: 2,
|
||||
1073741824: 512,
|
||||
1342177280: 8421890,
|
||||
1610612736: 8389122,
|
||||
1879048192: 8388608,
|
||||
2147483648: 514,
|
||||
2415919104: 8389120,
|
||||
2684354560: 33280,
|
||||
2952790016: 8421376,
|
||||
3221225472: 32770,
|
||||
3489660928: 8388610,
|
||||
3758096384: 0,
|
||||
4026531840: 33282,
|
||||
134217728: 0,
|
||||
402653184: 8421890,
|
||||
671088640: 33282,
|
||||
939524096: 32768,
|
||||
1207959552: 8421888,
|
||||
1476395008: 512,
|
||||
1744830464: 8421378,
|
||||
2013265920: 2,
|
||||
2281701376: 8389120,
|
||||
2550136832: 33280,
|
||||
2818572288: 8421376,
|
||||
3087007744: 8389122,
|
||||
3355443200: 8388610,
|
||||
3623878656: 32770,
|
||||
3892314112: 514,
|
||||
4160749568: 8388608,
|
||||
1: 32768,
|
||||
268435457: 2,
|
||||
536870913: 8421888,
|
||||
805306369: 8388608,
|
||||
1073741825: 8421378,
|
||||
1342177281: 33280,
|
||||
1610612737: 512,
|
||||
1879048193: 8389122,
|
||||
2147483649: 8421890,
|
||||
2415919105: 8421376,
|
||||
2684354561: 8388610,
|
||||
2952790017: 33282,
|
||||
3221225473: 514,
|
||||
3489660929: 8389120,
|
||||
3758096385: 32770,
|
||||
4026531841: 0,
|
||||
134217729: 8421890,
|
||||
402653185: 8421376,
|
||||
671088641: 8388608,
|
||||
939524097: 512,
|
||||
1207959553: 32768,
|
||||
1476395009: 8388610,
|
||||
1744830465: 2,
|
||||
2013265921: 33282,
|
||||
2281701377: 32770,
|
||||
2550136833: 8389122,
|
||||
2818572289: 514,
|
||||
3087007745: 8421888,
|
||||
3355443201: 8389120,
|
||||
3623878657: 0,
|
||||
3892314113: 33280,
|
||||
4160749569: 8421378
|
||||
},
|
||||
{
|
||||
0: 1074282512,
|
||||
16777216: 16384,
|
||||
33554432: 524288,
|
||||
50331648: 1074266128,
|
||||
67108864: 1073741840,
|
||||
83886080: 1074282496,
|
||||
100663296: 1073758208,
|
||||
117440512: 16,
|
||||
134217728: 540672,
|
||||
150994944: 1073758224,
|
||||
167772160: 1073741824,
|
||||
184549376: 540688,
|
||||
201326592: 524304,
|
||||
218103808: 0,
|
||||
234881024: 16400,
|
||||
251658240: 1074266112,
|
||||
8388608: 1073758208,
|
||||
25165824: 540688,
|
||||
41943040: 16,
|
||||
58720256: 1073758224,
|
||||
75497472: 1074282512,
|
||||
92274688: 1073741824,
|
||||
109051904: 524288,
|
||||
125829120: 1074266128,
|
||||
142606336: 524304,
|
||||
159383552: 0,
|
||||
176160768: 16384,
|
||||
192937984: 1074266112,
|
||||
209715200: 1073741840,
|
||||
226492416: 540672,
|
||||
243269632: 1074282496,
|
||||
260046848: 16400,
|
||||
268435456: 0,
|
||||
285212672: 1074266128,
|
||||
301989888: 1073758224,
|
||||
318767104: 1074282496,
|
||||
335544320: 1074266112,
|
||||
352321536: 16,
|
||||
369098752: 540688,
|
||||
385875968: 16384,
|
||||
402653184: 16400,
|
||||
419430400: 524288,
|
||||
436207616: 524304,
|
||||
452984832: 1073741840,
|
||||
469762048: 540672,
|
||||
486539264: 1073758208,
|
||||
503316480: 1073741824,
|
||||
520093696: 1074282512,
|
||||
276824064: 540688,
|
||||
293601280: 524288,
|
||||
310378496: 1074266112,
|
||||
327155712: 16384,
|
||||
343932928: 1073758208,
|
||||
360710144: 1074282512,
|
||||
377487360: 16,
|
||||
394264576: 1073741824,
|
||||
411041792: 1074282496,
|
||||
427819008: 1073741840,
|
||||
444596224: 1073758224,
|
||||
461373440: 524304,
|
||||
478150656: 0,
|
||||
494927872: 16400,
|
||||
511705088: 1074266128,
|
||||
528482304: 540672
|
||||
},
|
||||
{
|
||||
0: 260,
|
||||
1048576: 0,
|
||||
2097152: 67109120,
|
||||
3145728: 65796,
|
||||
4194304: 65540,
|
||||
5242880: 67108868,
|
||||
6291456: 67174660,
|
||||
7340032: 67174400,
|
||||
8388608: 67108864,
|
||||
9437184: 67174656,
|
||||
10485760: 65792,
|
||||
11534336: 67174404,
|
||||
12582912: 67109124,
|
||||
13631488: 65536,
|
||||
14680064: 4,
|
||||
15728640: 256,
|
||||
524288: 67174656,
|
||||
1572864: 67174404,
|
||||
2621440: 0,
|
||||
3670016: 67109120,
|
||||
4718592: 67108868,
|
||||
5767168: 65536,
|
||||
6815744: 65540,
|
||||
7864320: 260,
|
||||
8912896: 4,
|
||||
9961472: 256,
|
||||
11010048: 67174400,
|
||||
12058624: 65796,
|
||||
13107200: 65792,
|
||||
14155776: 67109124,
|
||||
15204352: 67174660,
|
||||
16252928: 67108864,
|
||||
16777216: 67174656,
|
||||
17825792: 65540,
|
||||
18874368: 65536,
|
||||
19922944: 67109120,
|
||||
20971520: 256,
|
||||
22020096: 67174660,
|
||||
23068672: 67108868,
|
||||
24117248: 0,
|
||||
25165824: 67109124,
|
||||
26214400: 67108864,
|
||||
27262976: 4,
|
||||
28311552: 65792,
|
||||
29360128: 67174400,
|
||||
30408704: 260,
|
||||
31457280: 65796,
|
||||
32505856: 67174404,
|
||||
17301504: 67108864,
|
||||
18350080: 260,
|
||||
19398656: 67174656,
|
||||
20447232: 0,
|
||||
21495808: 65540,
|
||||
22544384: 67109120,
|
||||
23592960: 256,
|
||||
24641536: 67174404,
|
||||
25690112: 65536,
|
||||
26738688: 67174660,
|
||||
27787264: 65796,
|
||||
28835840: 67108868,
|
||||
29884416: 67109124,
|
||||
30932992: 67174400,
|
||||
31981568: 4,
|
||||
33030144: 65792
|
||||
},
|
||||
{
|
||||
0: 2151682048,
|
||||
65536: 2147487808,
|
||||
131072: 4198464,
|
||||
196608: 2151677952,
|
||||
262144: 0,
|
||||
327680: 4198400,
|
||||
393216: 2147483712,
|
||||
458752: 4194368,
|
||||
524288: 2147483648,
|
||||
589824: 4194304,
|
||||
655360: 64,
|
||||
720896: 2147487744,
|
||||
786432: 2151678016,
|
||||
851968: 4160,
|
||||
917504: 4096,
|
||||
983040: 2151682112,
|
||||
32768: 2147487808,
|
||||
98304: 64,
|
||||
163840: 2151678016,
|
||||
229376: 2147487744,
|
||||
294912: 4198400,
|
||||
360448: 2151682112,
|
||||
425984: 0,
|
||||
491520: 2151677952,
|
||||
557056: 4096,
|
||||
622592: 2151682048,
|
||||
688128: 4194304,
|
||||
753664: 4160,
|
||||
819200: 2147483648,
|
||||
884736: 4194368,
|
||||
950272: 4198464,
|
||||
1015808: 2147483712,
|
||||
1048576: 4194368,
|
||||
1114112: 4198400,
|
||||
1179648: 2147483712,
|
||||
1245184: 0,
|
||||
1310720: 4160,
|
||||
1376256: 2151678016,
|
||||
1441792: 2151682048,
|
||||
1507328: 2147487808,
|
||||
1572864: 2151682112,
|
||||
1638400: 2147483648,
|
||||
1703936: 2151677952,
|
||||
1769472: 4198464,
|
||||
1835008: 2147487744,
|
||||
1900544: 4194304,
|
||||
1966080: 64,
|
||||
2031616: 4096,
|
||||
1081344: 2151677952,
|
||||
1146880: 2151682112,
|
||||
1212416: 0,
|
||||
1277952: 4198400,
|
||||
1343488: 4194368,
|
||||
1409024: 2147483648,
|
||||
1474560: 2147487808,
|
||||
1540096: 64,
|
||||
1605632: 2147483712,
|
||||
1671168: 4096,
|
||||
1736704: 2147487744,
|
||||
1802240: 2151678016,
|
||||
1867776: 4160,
|
||||
1933312: 2151682048,
|
||||
1998848: 4194304,
|
||||
2064384: 4198464
|
||||
},
|
||||
{
|
||||
0: 128,
|
||||
4096: 17039360,
|
||||
8192: 262144,
|
||||
12288: 536870912,
|
||||
16384: 537133184,
|
||||
20480: 16777344,
|
||||
24576: 553648256,
|
||||
28672: 262272,
|
||||
32768: 16777216,
|
||||
36864: 537133056,
|
||||
40960: 536871040,
|
||||
45056: 553910400,
|
||||
49152: 553910272,
|
||||
53248: 0,
|
||||
57344: 17039488,
|
||||
61440: 553648128,
|
||||
2048: 17039488,
|
||||
6144: 553648256,
|
||||
10240: 128,
|
||||
14336: 17039360,
|
||||
18432: 262144,
|
||||
22528: 537133184,
|
||||
26624: 553910272,
|
||||
30720: 536870912,
|
||||
34816: 537133056,
|
||||
38912: 0,
|
||||
43008: 553910400,
|
||||
47104: 16777344,
|
||||
51200: 536871040,
|
||||
55296: 553648128,
|
||||
59392: 16777216,
|
||||
63488: 262272,
|
||||
65536: 262144,
|
||||
69632: 128,
|
||||
73728: 536870912,
|
||||
77824: 553648256,
|
||||
81920: 16777344,
|
||||
86016: 553910272,
|
||||
90112: 537133184,
|
||||
94208: 16777216,
|
||||
98304: 553910400,
|
||||
102400: 553648128,
|
||||
106496: 17039360,
|
||||
110592: 537133056,
|
||||
114688: 262272,
|
||||
118784: 536871040,
|
||||
122880: 0,
|
||||
126976: 17039488,
|
||||
67584: 553648256,
|
||||
71680: 16777216,
|
||||
75776: 17039360,
|
||||
79872: 537133184,
|
||||
83968: 536870912,
|
||||
88064: 17039488,
|
||||
92160: 128,
|
||||
96256: 553910272,
|
||||
100352: 262272,
|
||||
104448: 553910400,
|
||||
108544: 0,
|
||||
112640: 553648128,
|
||||
116736: 16777344,
|
||||
120832: 262144,
|
||||
124928: 537133056,
|
||||
129024: 536871040
|
||||
},
|
||||
{
|
||||
0: 268435464,
|
||||
256: 8192,
|
||||
512: 270532608,
|
||||
768: 270540808,
|
||||
1024: 268443648,
|
||||
1280: 2097152,
|
||||
1536: 2097160,
|
||||
1792: 268435456,
|
||||
2048: 0,
|
||||
2304: 268443656,
|
||||
2560: 2105344,
|
||||
2816: 8,
|
||||
3072: 270532616,
|
||||
3328: 2105352,
|
||||
3584: 8200,
|
||||
3840: 270540800,
|
||||
128: 270532608,
|
||||
384: 270540808,
|
||||
640: 8,
|
||||
896: 2097152,
|
||||
1152: 2105352,
|
||||
1408: 268435464,
|
||||
1664: 268443648,
|
||||
1920: 8200,
|
||||
2176: 2097160,
|
||||
2432: 8192,
|
||||
2688: 268443656,
|
||||
2944: 270532616,
|
||||
3200: 0,
|
||||
3456: 270540800,
|
||||
3712: 2105344,
|
||||
3968: 268435456,
|
||||
4096: 268443648,
|
||||
4352: 270532616,
|
||||
4608: 270540808,
|
||||
4864: 8200,
|
||||
5120: 2097152,
|
||||
5376: 268435456,
|
||||
5632: 268435464,
|
||||
5888: 2105344,
|
||||
6144: 2105352,
|
||||
6400: 0,
|
||||
6656: 8,
|
||||
6912: 270532608,
|
||||
7168: 8192,
|
||||
7424: 268443656,
|
||||
7680: 270540800,
|
||||
7936: 2097160,
|
||||
4224: 8,
|
||||
4480: 2105344,
|
||||
4736: 2097152,
|
||||
4992: 268435464,
|
||||
5248: 268443648,
|
||||
5504: 8200,
|
||||
5760: 270540808,
|
||||
6016: 270532608,
|
||||
6272: 270540800,
|
||||
6528: 270532616,
|
||||
6784: 8192,
|
||||
7040: 2105352,
|
||||
7296: 2097160,
|
||||
7552: 0,
|
||||
7808: 268435456,
|
||||
8064: 268443656
|
||||
},
|
||||
{
|
||||
0: 1048576,
|
||||
16: 33555457,
|
||||
32: 1024,
|
||||
48: 1049601,
|
||||
64: 34604033,
|
||||
80: 0,
|
||||
96: 1,
|
||||
112: 34603009,
|
||||
128: 33555456,
|
||||
144: 1048577,
|
||||
160: 33554433,
|
||||
176: 34604032,
|
||||
192: 34603008,
|
||||
208: 1025,
|
||||
224: 1049600,
|
||||
240: 33554432,
|
||||
8: 34603009,
|
||||
24: 0,
|
||||
40: 33555457,
|
||||
56: 34604032,
|
||||
72: 1048576,
|
||||
88: 33554433,
|
||||
104: 33554432,
|
||||
120: 1025,
|
||||
136: 1049601,
|
||||
152: 33555456,
|
||||
168: 34603008,
|
||||
184: 1048577,
|
||||
200: 1024,
|
||||
216: 34604033,
|
||||
232: 1,
|
||||
248: 1049600,
|
||||
256: 33554432,
|
||||
272: 1048576,
|
||||
288: 33555457,
|
||||
304: 34603009,
|
||||
320: 1048577,
|
||||
336: 33555456,
|
||||
352: 34604032,
|
||||
368: 1049601,
|
||||
384: 1025,
|
||||
400: 34604033,
|
||||
416: 1049600,
|
||||
432: 1,
|
||||
448: 0,
|
||||
464: 34603008,
|
||||
480: 33554433,
|
||||
496: 1024,
|
||||
264: 1049600,
|
||||
280: 33555457,
|
||||
296: 34603009,
|
||||
312: 1,
|
||||
328: 33554432,
|
||||
344: 1048576,
|
||||
360: 1025,
|
||||
376: 34604032,
|
||||
392: 33554433,
|
||||
408: 34603008,
|
||||
424: 0,
|
||||
440: 34604033,
|
||||
456: 1049601,
|
||||
472: 1024,
|
||||
488: 33555456,
|
||||
504: 1048577
|
||||
},
|
||||
{
|
||||
0: 134219808,
|
||||
1: 131072,
|
||||
2: 134217728,
|
||||
3: 32,
|
||||
4: 131104,
|
||||
5: 134350880,
|
||||
6: 134350848,
|
||||
7: 2048,
|
||||
8: 134348800,
|
||||
9: 134219776,
|
||||
10: 133120,
|
||||
11: 134348832,
|
||||
12: 2080,
|
||||
13: 0,
|
||||
14: 134217760,
|
||||
15: 133152,
|
||||
2147483648: 2048,
|
||||
2147483649: 134350880,
|
||||
2147483650: 134219808,
|
||||
2147483651: 134217728,
|
||||
2147483652: 134348800,
|
||||
2147483653: 133120,
|
||||
2147483654: 133152,
|
||||
2147483655: 32,
|
||||
2147483656: 134217760,
|
||||
2147483657: 2080,
|
||||
2147483658: 131104,
|
||||
2147483659: 134350848,
|
||||
2147483660: 0,
|
||||
2147483661: 134348832,
|
||||
2147483662: 134219776,
|
||||
2147483663: 131072,
|
||||
16: 133152,
|
||||
17: 134350848,
|
||||
18: 32,
|
||||
19: 2048,
|
||||
20: 134219776,
|
||||
21: 134217760,
|
||||
22: 134348832,
|
||||
23: 131072,
|
||||
24: 0,
|
||||
25: 131104,
|
||||
26: 134348800,
|
||||
27: 134219808,
|
||||
28: 134350880,
|
||||
29: 133120,
|
||||
30: 2080,
|
||||
31: 134217728,
|
||||
2147483664: 131072,
|
||||
2147483665: 2048,
|
||||
2147483666: 134348832,
|
||||
2147483667: 133152,
|
||||
2147483668: 32,
|
||||
2147483669: 134348800,
|
||||
2147483670: 134217728,
|
||||
2147483671: 134219808,
|
||||
2147483672: 134350880,
|
||||
2147483673: 134217760,
|
||||
2147483674: 134219776,
|
||||
2147483675: 0,
|
||||
2147483676: 133120,
|
||||
2147483677: 2080,
|
||||
2147483678: 131104,
|
||||
2147483679: 134350848
|
||||
}
|
||||
];
|
||||
const SBOX_MASK = [
|
||||
4160749569,
|
||||
528482304,
|
||||
33030144,
|
||||
2064384,
|
||||
129024,
|
||||
8064,
|
||||
504,
|
||||
2147483679
|
||||
];
|
||||
function exchangeLR(offset, mask) {
|
||||
if (this._lBlock === void 0 || this._rBlock === void 0) throw new Error("Block values not initialized");
|
||||
const t = (this._lBlock >>> offset ^ this._rBlock) & mask;
|
||||
this._rBlock ^= t;
|
||||
this._lBlock ^= t << offset;
|
||||
}
|
||||
function exchangeRL(offset, mask) {
|
||||
if (this._lBlock === void 0 || this._rBlock === void 0) throw new Error("Block values not initialized");
|
||||
const t = (this._rBlock >>> offset ^ this._lBlock) & mask;
|
||||
this._lBlock ^= t;
|
||||
this._rBlock ^= t << offset;
|
||||
}
|
||||
/**
|
||||
* DES block cipher algorithm.
|
||||
*/
|
||||
var DESAlgo = class extends BlockCipher {
|
||||
/** Key size in 32-bit words */
|
||||
static keySize = 64 / 32;
|
||||
/** IV size in 32-bit words */
|
||||
static ivSize = 64 / 32;
|
||||
/** Subkeys for encryption */
|
||||
_subKeys;
|
||||
/** Inverse subkeys for decryption */
|
||||
_invSubKeys;
|
||||
/** Left block for processing */
|
||||
_lBlock;
|
||||
/** Right block for processing */
|
||||
_rBlock;
|
||||
constructor(xformMode, key, cfg) {
|
||||
super(xformMode, key, cfg);
|
||||
this.blockSize = 64 / 32;
|
||||
}
|
||||
_doReset() {
|
||||
const key = this._key;
|
||||
const keyWords = key.words;
|
||||
const keyBits = [];
|
||||
for (let i = 0; i < 56; i += 1) {
|
||||
const keyBitPos = PC1[i] - 1;
|
||||
keyBits[i] = keyWords[keyBitPos >>> 5] >>> 31 - keyBitPos % 32 & 1;
|
||||
}
|
||||
this._subKeys = [];
|
||||
const subKeys = this._subKeys;
|
||||
for (let nSubKey = 0; nSubKey < 16; nSubKey += 1) {
|
||||
subKeys[nSubKey] = [];
|
||||
const subKey = subKeys[nSubKey];
|
||||
const bitShift = BIT_SHIFTS[nSubKey];
|
||||
for (let i = 0; i < 24; i += 1) {
|
||||
subKey[i / 6 | 0] |= keyBits[(PC2[i] - 1 + bitShift) % 28] << 31 - i % 6;
|
||||
subKey[4 + (i / 6 | 0)] |= keyBits[28 + (PC2[i + 24] - 1 + bitShift) % 28] << 31 - i % 6;
|
||||
}
|
||||
subKey[0] = subKey[0] << 1 | subKey[0] >>> 31;
|
||||
for (let i = 1; i < 7; i += 1) subKey[i] >>>= (i - 1) * 4 + 3;
|
||||
subKey[7] = subKey[7] << 5 | subKey[7] >>> 27;
|
||||
}
|
||||
this._invSubKeys = [];
|
||||
const invSubKeys = this._invSubKeys;
|
||||
for (let i = 0; i < 16; i += 1) invSubKeys[i] = subKeys[15 - i];
|
||||
}
|
||||
encryptBlock(M, offset) {
|
||||
this._doCryptBlock(M, offset, this._subKeys);
|
||||
}
|
||||
decryptBlock(M, offset) {
|
||||
this._doCryptBlock(M, offset, this._invSubKeys);
|
||||
}
|
||||
_doCryptBlock(M, offset, subKeys) {
|
||||
const _M = M;
|
||||
this._lBlock = M[offset];
|
||||
this._rBlock = M[offset + 1];
|
||||
exchangeLR.call(this, 4, 252645135);
|
||||
exchangeLR.call(this, 16, 65535);
|
||||
exchangeRL.call(this, 2, 858993459);
|
||||
exchangeRL.call(this, 8, 16711935);
|
||||
exchangeLR.call(this, 1, 1431655765);
|
||||
for (let round = 0; round < 16; round += 1) {
|
||||
const subKey = subKeys[round];
|
||||
const lBlock = this._lBlock;
|
||||
const rBlock = this._rBlock;
|
||||
let f = 0;
|
||||
for (let i = 0; i < 8; i += 1) f |= SBOX_P[i][((rBlock ^ subKey[i]) & SBOX_MASK[i]) >>> 0];
|
||||
this._lBlock = rBlock;
|
||||
this._rBlock = lBlock ^ f;
|
||||
}
|
||||
const t = this._lBlock;
|
||||
this._lBlock = this._rBlock;
|
||||
this._rBlock = t;
|
||||
exchangeLR.call(this, 1, 1431655765);
|
||||
exchangeRL.call(this, 8, 16711935);
|
||||
exchangeRL.call(this, 2, 858993459);
|
||||
exchangeLR.call(this, 16, 65535);
|
||||
exchangeLR.call(this, 4, 252645135);
|
||||
_M[offset] = this._lBlock;
|
||||
_M[offset + 1] = this._rBlock;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut functions to the cipher's object interface.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var ciphertext = DES.encrypt(message, key, cfg);
|
||||
* var plaintext = DES.decrypt(ciphertext, key, cfg);
|
||||
*/
|
||||
const DES = BlockCipher._createHelper(DESAlgo);
|
||||
/**
|
||||
* Triple-DES block cipher algorithm.
|
||||
*/
|
||||
var TripleDESAlgo = class extends BlockCipher {
|
||||
/** Key size in 32-bit words */
|
||||
static keySize = 192 / 32;
|
||||
/** IV size in 32-bit words */
|
||||
static ivSize = 64 / 32;
|
||||
/** First DES instance */
|
||||
_des1;
|
||||
/** Second DES instance */
|
||||
_des2;
|
||||
/** Third DES instance */
|
||||
_des3;
|
||||
_doReset() {
|
||||
const key = this._key;
|
||||
const keyWords = key.words;
|
||||
if (keyWords.length !== 2 && keyWords.length !== 4 && keyWords.length < 6) throw new Error("Invalid key length - 3DES requires the key length to be 64, 128, 192 or >192.");
|
||||
const key1 = keyWords.slice(0, 2);
|
||||
const key2 = keyWords.length < 4 ? keyWords.slice(0, 2) : keyWords.slice(2, 4);
|
||||
const key3 = keyWords.length < 6 ? keyWords.slice(0, 2) : keyWords.slice(4, 6);
|
||||
this._des1 = DESAlgo.createEncryptor(WordArray.create(key1));
|
||||
this._des2 = DESAlgo.createEncryptor(WordArray.create(key2));
|
||||
this._des3 = DESAlgo.createEncryptor(WordArray.create(key3));
|
||||
}
|
||||
encryptBlock(M, offset) {
|
||||
this._des1.encryptBlock(M, offset);
|
||||
this._des2.decryptBlock(M, offset);
|
||||
this._des3.encryptBlock(M, offset);
|
||||
}
|
||||
decryptBlock(M, offset) {
|
||||
this._des3.decryptBlock(M, offset);
|
||||
this._des2.encryptBlock(M, offset);
|
||||
this._des1.decryptBlock(M, offset);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Shortcut functions to the cipher's object interface.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var ciphertext = TripleDES.encrypt(message, key, cfg);
|
||||
* var plaintext = TripleDES.decrypt(ciphertext, key, cfg);
|
||||
*/
|
||||
const TripleDES = BlockCipher._createHelper(TripleDESAlgo);
|
||||
|
||||
//#endregion
|
||||
export { DES, DESAlgo, TripleDES, TripleDESAlgo };
|
||||
//# sourceMappingURL=tripledes.mjs.map
|
||||
@@ -1,132 +0,0 @@
|
||||
import { Base, WordArray } from "./core.mjs";
|
||||
|
||||
//#region src/x64-core.ts
|
||||
/**
|
||||
* A 64-bit word representation.
|
||||
* Stores a 64-bit value as two 32-bit words due to JavaScript's number limitations.
|
||||
*
|
||||
* @property high - The high 32 bits
|
||||
* @property low - The low 32 bits
|
||||
*/
|
||||
var X64Word = class extends Base {
|
||||
/** The high 32 bits of the 64-bit word */
|
||||
high;
|
||||
/** The low 32 bits of the 64-bit word */
|
||||
low;
|
||||
/**
|
||||
* Initializes a newly created 64-bit word.
|
||||
*
|
||||
* @param high - The high 32 bits (default: 0)
|
||||
* @param low - The low 32 bits (default: 0)
|
||||
* @example
|
||||
* ```javascript
|
||||
* const x64Word = new X64Word(0x00010203, 0x04050607);
|
||||
* const x64Word = X64Word.create(0x00010203, 0x04050607);
|
||||
* ```
|
||||
*/
|
||||
constructor(high = 0, low = 0) {
|
||||
super();
|
||||
this.high = high;
|
||||
this.low = low;
|
||||
}
|
||||
/**
|
||||
* Creates a copy of this word.
|
||||
*
|
||||
* @returns The cloned 64-bit word
|
||||
* @example
|
||||
* ```javascript
|
||||
* const clone = x64Word.clone();
|
||||
* ```
|
||||
*/
|
||||
clone() {
|
||||
const clone = super.clone();
|
||||
clone.high = this.high;
|
||||
clone.low = this.low;
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* An array of 64-bit words.
|
||||
* This is used for algorithms that operate on 64-bit words, such as SHA-512.
|
||||
*
|
||||
* @property words - The array of X64Word objects
|
||||
* @property sigBytes - The number of significant bytes in this word array
|
||||
*/
|
||||
var X64WordArray = class X64WordArray extends Base {
|
||||
/** The array of X64Word objects */
|
||||
words;
|
||||
/** The number of significant bytes in this word array */
|
||||
sigBytes;
|
||||
/**
|
||||
* Initializes a newly created 64-bit word array.
|
||||
*
|
||||
* @param words - An array of X64Word objects
|
||||
* @param sigBytes - The number of significant bytes in the words (defaults to words.length * 8)
|
||||
* @example
|
||||
* ```javascript
|
||||
* const wordArray = new X64WordArray();
|
||||
*
|
||||
* const wordArray = new X64WordArray([
|
||||
* new X64Word(0x00010203, 0x04050607),
|
||||
* new X64Word(0x18191a1b, 0x1c1d1e1f)
|
||||
* ]);
|
||||
*
|
||||
* const wordArray = new X64WordArray([
|
||||
* new X64Word(0x00010203, 0x04050607),
|
||||
* new X64Word(0x18191a1b, 0x1c1d1e1f)
|
||||
* ], 10);
|
||||
* ```
|
||||
*/
|
||||
constructor(words = [], sigBytes = words.length * 8) {
|
||||
super();
|
||||
this.words = words;
|
||||
this.sigBytes = sigBytes;
|
||||
}
|
||||
static create(...args) {
|
||||
const [words, sigBytes] = args;
|
||||
return new X64WordArray(words, sigBytes);
|
||||
}
|
||||
/**
|
||||
* Converts this 64-bit word array to a 32-bit word array.
|
||||
* Each 64-bit word is split into two 32-bit words (high and low).
|
||||
*
|
||||
* @returns This word array's data as a 32-bit word array
|
||||
* @example
|
||||
* ```javascript
|
||||
* const x32WordArray = x64WordArray.toX32();
|
||||
* ```
|
||||
*/
|
||||
toX32() {
|
||||
const x64Words = this.words;
|
||||
const x64WordsLength = x64Words.length;
|
||||
const x32Words = [];
|
||||
for (let i = 0; i < x64WordsLength; i += 1) {
|
||||
const x64Word = x64Words[i];
|
||||
x32Words.push(x64Word.high);
|
||||
x32Words.push(x64Word.low);
|
||||
}
|
||||
return WordArray.create(x32Words, this.sigBytes);
|
||||
}
|
||||
/**
|
||||
* Creates a deep copy of this word array.
|
||||
* Clones both the array and each X64Word object within it.
|
||||
*
|
||||
* @returns The cloned X64WordArray
|
||||
* @example
|
||||
* ```javascript
|
||||
* const clone = x64WordArray.clone();
|
||||
* ```
|
||||
*/
|
||||
clone() {
|
||||
const clone = super.clone();
|
||||
clone.words = this.words.slice(0);
|
||||
const { words } = clone;
|
||||
const wordsLength = words.length;
|
||||
for (let i = 0; i < wordsLength; i += 1) words[i] = words[i].clone();
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
|
||||
//#endregion
|
||||
export { X64Word, X64WordArray };
|
||||
//# sourceMappingURL=x64-core.mjs.map
|
||||
2
client/static/jquery-3.7.1.min.js
vendored
2
client/static/jquery-3.7.1.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
22
client/static/mdui-2.1.4.global.min.js
vendored
22
client/static/mdui-2.1.4.global.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,5 +0,0 @@
|
||||
/* esm.sh - react-dom@18.3.1 */
|
||||
import "./react@18.3.1/react.mjs";
|
||||
import "./scheduler@0.23.2/scheduler.mjs";
|
||||
export * from "./react-dom@18.3.1/react-dom.mjs";
|
||||
export { default } from "./react-dom@18.3.1/react-dom.mjs";
|
||||
File diff suppressed because one or more lines are too long
@@ -1,3 +0,0 @@
|
||||
/* esm.sh - react@18.3.1 */
|
||||
export * from "./react@18.3.1/react.mjs";
|
||||
export { default } from "./react@18.3.1/react.mjs";
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
client/static/splitjs-1.6.5.min.js
vendored
3
client/static/splitjs-1.6.5.min.js
vendored
File diff suppressed because one or more lines are too long
69
client/style.css
Normal file
69
client/style.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* 滑条*/
|
||||
.no-scroll-bar::-webkit-scrollbar {
|
||||
width: 0px !important;
|
||||
}
|
||||
|
||||
/* https://blog.csdn.net/qq_39347364/article/details/111996581*/
|
||||
*::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track {
|
||||
width: 6px;
|
||||
background: rgba(#101f1c, 0.1);
|
||||
-webkit-border-radius: 2em;
|
||||
-moz-border-radius: 2em;
|
||||
border-radius: 2em;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background-color: rgba(144, 147, 153, 0.5);
|
||||
background-clip: padding-box;
|
||||
min-height: 28px;
|
||||
-webkit-border-radius: 2em;
|
||||
-moz-border-radius: 2em;
|
||||
border-radius: 2em;
|
||||
transition: background-color 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb:hover {
|
||||
background-color: rgba(144, 147, 153, 0.3);
|
||||
}
|
||||
|
||||
/* 使用系统字体 在部分系统表现很好*/
|
||||
/* 我们至今仍未能知道桌面端浏览器字体的秘密*/
|
||||
*:not(.material-icons, .mdui-icon, mdui-icon, .fa, .google-symbols) {
|
||||
font-family: -apple-system, system-ui, -webkit-system-font !important;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
margin: 0 0 0 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
html {
|
||||
margin: 0 0 0 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 防止小尺寸图片模糊*/
|
||||
* {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
image-rendering: -o-crisp-edges;
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
image-rendering: crisp-edges;
|
||||
-ms-interpolation-mode: nearest-neighbor;
|
||||
}
|
||||
|
||||
.gutter {
|
||||
background-color: rgb(var(--mdui-color-surface-variant));
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50%;
|
||||
}
|
||||
|
||||
.gutter.gutter-horizontal {
|
||||
cursor: col-resize;
|
||||
}
|
||||
21297
client/typedef/csstype@3.1.3.d.ts
vendored
21297
client/typedef/csstype@3.1.3.d.ts
vendored
File diff suppressed because it is too large
Load Diff
3350
client/typedef/mdui-jsx.d.ts
vendored
3350
client/typedef/mdui-jsx.d.ts
vendored
File diff suppressed because it is too large
Load Diff
131
client/typedef/prop-types@15.7.15.d.ts
vendored
131
client/typedef/prop-types@15.7.15.d.ts
vendored
@@ -1,131 +0,0 @@
|
||||
// eslint-disable-next-line @definitelytyped/export-just-namespace
|
||||
export = PropTypes;
|
||||
|
||||
declare namespace PropTypes {
|
||||
type ReactComponentLike =
|
||||
| string
|
||||
| ((props: any) => any)
|
||||
| (new(props: any, context: any) => any);
|
||||
|
||||
interface ReactElementLike {
|
||||
type: ReactComponentLike;
|
||||
props: unknown;
|
||||
key: string | null;
|
||||
}
|
||||
|
||||
interface ReactNodeArray extends Iterable<ReactNodeLike> {}
|
||||
|
||||
/**
|
||||
* @internal Use `Awaited<ReactNodeLike>` instead
|
||||
*/
|
||||
// Helper type to enable `Awaited<ReactNodeLike>`.
|
||||
// Must be a copy of the non-thenables of `ReactNodeLike`.
|
||||
type AwaitedReactNodeLike =
|
||||
| ReactElementLike
|
||||
| string
|
||||
| number
|
||||
| bigint
|
||||
| ReactNodeArray
|
||||
| boolean
|
||||
| null
|
||||
| undefined;
|
||||
|
||||
type ReactNodeLike =
|
||||
| ReactElementLike
|
||||
| ReactNodeArray
|
||||
| string
|
||||
| number
|
||||
| bigint
|
||||
| boolean
|
||||
| null
|
||||
| undefined
|
||||
| Promise<AwaitedReactNodeLike>;
|
||||
|
||||
const nominalTypeHack: unique symbol;
|
||||
|
||||
type IsOptional<T> = undefined extends T ? true : false;
|
||||
|
||||
type RequiredKeys<V> = {
|
||||
[K in keyof V]-?: Exclude<V[K], undefined> extends Validator<infer T> ? IsOptional<T> extends true ? never : K
|
||||
: never;
|
||||
}[keyof V];
|
||||
type OptionalKeys<V> = Exclude<keyof V, RequiredKeys<V>>;
|
||||
type InferPropsInner<V> = { [K in keyof V]-?: InferType<V[K]> };
|
||||
|
||||
interface Validator<T> {
|
||||
(
|
||||
props: { [key: string]: any },
|
||||
propName: string,
|
||||
componentName: string,
|
||||
location: string,
|
||||
propFullName: string,
|
||||
): Error | null;
|
||||
[nominalTypeHack]?: {
|
||||
type: T;
|
||||
} | undefined;
|
||||
}
|
||||
|
||||
interface Requireable<T> extends Validator<T | undefined | null> {
|
||||
isRequired: Validator<NonNullable<T>>;
|
||||
}
|
||||
|
||||
type ValidationMap<T> = { [K in keyof T]?: Validator<T[K]> };
|
||||
|
||||
/**
|
||||
* Like {@link ValidationMap} but treats `undefined`, `null` and optional properties the same.
|
||||
* This type is only added as a migration path in React 19 where this type was removed from React.
|
||||
* Runtime and compile time types would mismatch since you could see `undefined` at runtime when your types don't expect this type.
|
||||
*/
|
||||
type WeakValidationMap<T> = {
|
||||
[K in keyof T]?: null extends T[K] ? Validator<T[K] | null | undefined>
|
||||
: undefined extends T[K] ? Validator<T[K] | null | undefined>
|
||||
: Validator<T[K]>;
|
||||
};
|
||||
|
||||
type InferType<V> = V extends Validator<infer T> ? T : any;
|
||||
type InferProps<V> =
|
||||
& InferPropsInner<Pick<V, RequiredKeys<V>>>
|
||||
& Partial<InferPropsInner<Pick<V, OptionalKeys<V>>>>;
|
||||
|
||||
const any: Requireable<any>;
|
||||
const array: Requireable<any[]>;
|
||||
const bool: Requireable<boolean>;
|
||||
const func: Requireable<(...args: any[]) => any>;
|
||||
const number: Requireable<number>;
|
||||
const object: Requireable<object>;
|
||||
const string: Requireable<string>;
|
||||
const node: Requireable<ReactNodeLike>;
|
||||
const element: Requireable<ReactElementLike>;
|
||||
const symbol: Requireable<symbol>;
|
||||
const elementType: Requireable<ReactComponentLike>;
|
||||
function instanceOf<T>(expectedClass: new(...args: any[]) => T): Requireable<T>;
|
||||
function oneOf<T>(types: readonly T[]): Requireable<T>;
|
||||
function oneOfType<T extends Validator<any>>(types: T[]): Requireable<NonNullable<InferType<T>>>;
|
||||
function arrayOf<T>(type: Validator<T>): Requireable<T[]>;
|
||||
function objectOf<T>(type: Validator<T>): Requireable<{ [K in keyof any]: T }>;
|
||||
function shape<P extends ValidationMap<any>>(type: P): Requireable<InferProps<P>>;
|
||||
function exact<P extends ValidationMap<any>>(type: P): Requireable<Required<InferProps<P>>>;
|
||||
|
||||
/**
|
||||
* Assert that the values match with the type specs.
|
||||
* Error messages are memorized and will only be shown once.
|
||||
*
|
||||
* @param typeSpecs Map of name to a ReactPropType
|
||||
* @param values Runtime values that need to be type-checked
|
||||
* @param location e.g. "prop", "context", "child context"
|
||||
* @param componentName Name of the component for error messages
|
||||
* @param getStack Returns the component stack
|
||||
*/
|
||||
function checkPropTypes(
|
||||
typeSpecs: any,
|
||||
values: any,
|
||||
location: string,
|
||||
componentName: string,
|
||||
getStack?: () => any,
|
||||
): void;
|
||||
|
||||
/**
|
||||
* Only available if NODE_ENV=production
|
||||
*/
|
||||
function resetWarningCache(): void;
|
||||
}
|
||||
161
client/typedef/react@18.3.18-global.d.ts
vendored
161
client/typedef/react@18.3.18-global.d.ts
vendored
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
React projects that don't include the DOM library need these interfaces to compile.
|
||||
React Native applications use React, but there is no DOM available. The JavaScript runtime
|
||||
is ES6/ES2015 only. These definitions allow such projects to compile with only `--lib ES6`.
|
||||
|
||||
Warning: all of these interfaces are empty. If you want type definitions for various properties
|
||||
(such as HTMLInputElement.prototype.value), you need to add `--lib DOM` (via command line or tsconfig.json).
|
||||
*/
|
||||
|
||||
interface Event {}
|
||||
interface AnimationEvent extends Event {}
|
||||
interface ClipboardEvent extends Event {}
|
||||
interface CompositionEvent extends Event {}
|
||||
interface DragEvent extends Event {}
|
||||
interface FocusEvent extends Event {}
|
||||
interface InputEvent extends Event {}
|
||||
interface KeyboardEvent extends Event {}
|
||||
interface MouseEvent extends Event {}
|
||||
interface TouchEvent extends Event {}
|
||||
interface PointerEvent extends Event {}
|
||||
interface ToggleEvent extends Event {}
|
||||
interface TransitionEvent extends Event {}
|
||||
interface UIEvent extends Event {}
|
||||
interface WheelEvent extends Event {}
|
||||
|
||||
interface EventTarget {}
|
||||
interface Document {}
|
||||
interface DataTransfer {}
|
||||
interface StyleMedia {}
|
||||
|
||||
interface Element {}
|
||||
interface DocumentFragment {}
|
||||
|
||||
interface HTMLElement extends Element {}
|
||||
interface HTMLAnchorElement extends HTMLElement {}
|
||||
interface HTMLAreaElement extends HTMLElement {}
|
||||
interface HTMLAudioElement extends HTMLElement {}
|
||||
interface HTMLBaseElement extends HTMLElement {}
|
||||
interface HTMLBodyElement extends HTMLElement {}
|
||||
interface HTMLBRElement extends HTMLElement {}
|
||||
interface HTMLButtonElement extends HTMLElement {}
|
||||
interface HTMLCanvasElement extends HTMLElement {}
|
||||
interface HTMLDataElement extends HTMLElement {}
|
||||
interface HTMLDataListElement extends HTMLElement {}
|
||||
interface HTMLDetailsElement extends HTMLElement {}
|
||||
interface HTMLDialogElement extends HTMLElement {}
|
||||
interface HTMLDivElement extends HTMLElement {}
|
||||
interface HTMLDListElement extends HTMLElement {}
|
||||
interface HTMLEmbedElement extends HTMLElement {}
|
||||
interface HTMLFieldSetElement extends HTMLElement {}
|
||||
interface HTMLFormElement extends HTMLElement {}
|
||||
interface HTMLHeadingElement extends HTMLElement {}
|
||||
interface HTMLHeadElement extends HTMLElement {}
|
||||
interface HTMLHRElement extends HTMLElement {}
|
||||
interface HTMLHtmlElement extends HTMLElement {}
|
||||
interface HTMLIFrameElement extends HTMLElement {}
|
||||
interface HTMLImageElement extends HTMLElement {}
|
||||
interface HTMLInputElement extends HTMLElement {}
|
||||
interface HTMLModElement extends HTMLElement {}
|
||||
interface HTMLLabelElement extends HTMLElement {}
|
||||
interface HTMLLegendElement extends HTMLElement {}
|
||||
interface HTMLLIElement extends HTMLElement {}
|
||||
interface HTMLLinkElement extends HTMLElement {}
|
||||
interface HTMLMapElement extends HTMLElement {}
|
||||
interface HTMLMetaElement extends HTMLElement {}
|
||||
interface HTMLMeterElement extends HTMLElement {}
|
||||
interface HTMLObjectElement extends HTMLElement {}
|
||||
interface HTMLOListElement extends HTMLElement {}
|
||||
interface HTMLOptGroupElement extends HTMLElement {}
|
||||
interface HTMLOptionElement extends HTMLElement {}
|
||||
interface HTMLOutputElement extends HTMLElement {}
|
||||
interface HTMLParagraphElement extends HTMLElement {}
|
||||
interface HTMLParamElement extends HTMLElement {}
|
||||
interface HTMLPreElement extends HTMLElement {}
|
||||
interface HTMLProgressElement extends HTMLElement {}
|
||||
interface HTMLQuoteElement extends HTMLElement {}
|
||||
interface HTMLSlotElement extends HTMLElement {}
|
||||
interface HTMLScriptElement extends HTMLElement {}
|
||||
interface HTMLSelectElement extends HTMLElement {}
|
||||
interface HTMLSourceElement extends HTMLElement {}
|
||||
interface HTMLSpanElement extends HTMLElement {}
|
||||
interface HTMLStyleElement extends HTMLElement {}
|
||||
interface HTMLTableElement extends HTMLElement {}
|
||||
interface HTMLTableColElement extends HTMLElement {}
|
||||
interface HTMLTableDataCellElement extends HTMLElement {}
|
||||
interface HTMLTableHeaderCellElement extends HTMLElement {}
|
||||
interface HTMLTableRowElement extends HTMLElement {}
|
||||
interface HTMLTableSectionElement extends HTMLElement {}
|
||||
interface HTMLTemplateElement extends HTMLElement {}
|
||||
interface HTMLTextAreaElement extends HTMLElement {}
|
||||
interface HTMLTimeElement extends HTMLElement {}
|
||||
interface HTMLTitleElement extends HTMLElement {}
|
||||
interface HTMLTrackElement extends HTMLElement {}
|
||||
interface HTMLUListElement extends HTMLElement {}
|
||||
interface HTMLVideoElement extends HTMLElement {}
|
||||
interface HTMLWebViewElement extends HTMLElement {}
|
||||
|
||||
interface SVGElement extends Element {}
|
||||
interface SVGSVGElement extends SVGElement {}
|
||||
interface SVGCircleElement extends SVGElement {}
|
||||
interface SVGClipPathElement extends SVGElement {}
|
||||
interface SVGDefsElement extends SVGElement {}
|
||||
interface SVGDescElement extends SVGElement {}
|
||||
interface SVGEllipseElement extends SVGElement {}
|
||||
interface SVGFEBlendElement extends SVGElement {}
|
||||
interface SVGFEColorMatrixElement extends SVGElement {}
|
||||
interface SVGFEComponentTransferElement extends SVGElement {}
|
||||
interface SVGFECompositeElement extends SVGElement {}
|
||||
interface SVGFEConvolveMatrixElement extends SVGElement {}
|
||||
interface SVGFEDiffuseLightingElement extends SVGElement {}
|
||||
interface SVGFEDisplacementMapElement extends SVGElement {}
|
||||
interface SVGFEDistantLightElement extends SVGElement {}
|
||||
interface SVGFEDropShadowElement extends SVGElement {}
|
||||
interface SVGFEFloodElement extends SVGElement {}
|
||||
interface SVGFEFuncAElement extends SVGElement {}
|
||||
interface SVGFEFuncBElement extends SVGElement {}
|
||||
interface SVGFEFuncGElement extends SVGElement {}
|
||||
interface SVGFEFuncRElement extends SVGElement {}
|
||||
interface SVGFEGaussianBlurElement extends SVGElement {}
|
||||
interface SVGFEImageElement extends SVGElement {}
|
||||
interface SVGFEMergeElement extends SVGElement {}
|
||||
interface SVGFEMergeNodeElement extends SVGElement {}
|
||||
interface SVGFEMorphologyElement extends SVGElement {}
|
||||
interface SVGFEOffsetElement extends SVGElement {}
|
||||
interface SVGFEPointLightElement extends SVGElement {}
|
||||
interface SVGFESpecularLightingElement extends SVGElement {}
|
||||
interface SVGFESpotLightElement extends SVGElement {}
|
||||
interface SVGFETileElement extends SVGElement {}
|
||||
interface SVGFETurbulenceElement extends SVGElement {}
|
||||
interface SVGFilterElement extends SVGElement {}
|
||||
interface SVGForeignObjectElement extends SVGElement {}
|
||||
interface SVGGElement extends SVGElement {}
|
||||
interface SVGImageElement extends SVGElement {}
|
||||
interface SVGLineElement extends SVGElement {}
|
||||
interface SVGLinearGradientElement extends SVGElement {}
|
||||
interface SVGMarkerElement extends SVGElement {}
|
||||
interface SVGMaskElement extends SVGElement {}
|
||||
interface SVGMetadataElement extends SVGElement {}
|
||||
interface SVGPathElement extends SVGElement {}
|
||||
interface SVGPatternElement extends SVGElement {}
|
||||
interface SVGPolygonElement extends SVGElement {}
|
||||
interface SVGPolylineElement extends SVGElement {}
|
||||
interface SVGRadialGradientElement extends SVGElement {}
|
||||
interface SVGRectElement extends SVGElement {}
|
||||
interface SVGSetElement extends SVGElement {}
|
||||
interface SVGStopElement extends SVGElement {}
|
||||
interface SVGSwitchElement extends SVGElement {}
|
||||
interface SVGSymbolElement extends SVGElement {}
|
||||
interface SVGTextElement extends SVGElement {}
|
||||
interface SVGTextPathElement extends SVGElement {}
|
||||
interface SVGTSpanElement extends SVGElement {}
|
||||
interface SVGUseElement extends SVGElement {}
|
||||
interface SVGViewElement extends SVGElement {}
|
||||
|
||||
interface FormData {}
|
||||
interface Text {}
|
||||
interface TouchList {}
|
||||
interface WebGLRenderingContext {}
|
||||
interface WebGL2RenderingContext {}
|
||||
|
||||
interface TrustedHTML {}
|
||||
4586
client/typedef/react@18.3.18.d.ts
vendored
4586
client/typedef/react@18.3.18.d.ts
vendored
File diff suppressed because it is too large
Load Diff
@@ -4,29 +4,24 @@ import ChatFragment from "./chat/ChatFragment.jsx"
|
||||
import LoginDialog from "./dialog/LoginDialog.tsx"
|
||||
import ContactsListItem from "./main/ContactsListItem.jsx"
|
||||
import RecentsListItem from "./main/RecentsListItem.jsx"
|
||||
import snackbar from "./snackbar.js"
|
||||
import useEventListener from './useEventListener.js'
|
||||
|
||||
import { MduiDialog, React, MduiNavigationRail, MduiTextField, MduiButton } from '../Imports.ts'
|
||||
import User from "../api/client_data/User.ts"
|
||||
import RecentChat from "../api/client_data/RecentChat.ts"
|
||||
|
||||
import '../typedef/mdui-jsx.d.ts'
|
||||
import * as React from 'react'
|
||||
import * as CryptoES from 'crypto-es'
|
||||
import { Button, Dialog, NavigationRail, snackbar, TextField } from "mdui"
|
||||
import Split from 'split.js'
|
||||
import 'mdui/jsx.zh-cn.d.ts'
|
||||
|
||||
declare function Split(r: unknown, s: unknown): {
|
||||
setSizes?: undefined;
|
||||
getSizes?: undefined;
|
||||
collapse?: undefined;
|
||||
destroy?: undefined;
|
||||
parent?: undefined;
|
||||
pairs?: undefined;
|
||||
} | {
|
||||
setSizes: (e: unknown) => void;
|
||||
getSizes: () => unknown;
|
||||
collapse: (e: unknown) => void;
|
||||
destroy: (e: unknown, t: unknown) => void;
|
||||
parent: unknown;
|
||||
pairs: unknown[];
|
||||
declare global {
|
||||
namespace React {
|
||||
namespace JSX {
|
||||
interface IntrinsicAttributes {
|
||||
id?: string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
@@ -62,14 +57,28 @@ export default function App() {
|
||||
|
||||
const navigationRailRef = React.useRef(null)
|
||||
useEventListener(navigationRailRef, 'change', (event) => {
|
||||
setNavigationItemSelected((event.target as HTMLElement as MduiNavigationRail).value as string)
|
||||
setNavigationItemSelected((event.target as HTMLElement as NavigationRail).value as string)
|
||||
})
|
||||
|
||||
const loginDialogRef: React.MutableRefObject<MduiDialog | null> = React.useRef(null)
|
||||
const inputAccountRef: React.MutableRefObject<MduiTextField | null> = React.useRef(null)
|
||||
const inputPasswordRef: React.MutableRefObject<MduiTextField | null> = React.useRef(null)
|
||||
const registerButtonRef: React.MutableRefObject<MduiButton | null> = React.useRef(null)
|
||||
const loginButtonRef: React.MutableRefObject<MduiButton | null> = React.useRef(null)
|
||||
const loginDialogRef: React.MutableRefObject<Dialog | null> = React.useRef(null)
|
||||
const inputAccountRef: React.MutableRefObject<TextField | null> = React.useRef(null)
|
||||
const inputPasswordRef: React.MutableRefObject<TextField | null> = React.useRef(null)
|
||||
const registerButtonRef: React.MutableRefObject<Button | null> = React.useRef(null)
|
||||
const loginButtonRef: React.MutableRefObject<Button | null> = React.useRef(null)
|
||||
|
||||
useEventListener(loginButtonRef, 'click', async () => {
|
||||
const account = inputAccountRef.current!.value
|
||||
const password = inputPasswordRef.current!.value
|
||||
|
||||
const re = await Client.invoke("User.login", {
|
||||
account: account,
|
||||
password: CryptoES.SHA256(password),
|
||||
})
|
||||
if (re.code != 200)
|
||||
snackbar({
|
||||
message: "登錄失敗: " + re.msg
|
||||
})
|
||||
})
|
||||
|
||||
React.useEffect(() => {
|
||||
;(async () => {
|
||||
@@ -86,7 +95,9 @@ export default function App() {
|
||||
if (re.code == 401)
|
||||
loginDialogRef.current!.open = true
|
||||
else if (re.code != 200)
|
||||
snackbar("驗證失敗: " + re.msg)
|
||||
snackbar({
|
||||
message: "驗證失敗: " + re.msg
|
||||
})
|
||||
})()
|
||||
}, [])
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { React } from '../Imports.ts'
|
||||
|
||||
export default function Avatar({ src, text, icon = 'person', ...props } = {}) {
|
||||
return (
|
||||
src ? <mdui-avatar {...props}>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Message from "./Message.jsx"
|
||||
import MessageContainer from "./MessageContainer.jsx"
|
||||
|
||||
import { React } from '../../Imports.ts'
|
||||
import * as React from 'react'
|
||||
|
||||
export default function ChatFragment({ ...props } = {}) {
|
||||
return (
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import Avatar from "../Avatar.jsx"
|
||||
|
||||
import { React } from '../../Imports.ts'
|
||||
|
||||
/**
|
||||
* 一条消息
|
||||
* @param { Object } param
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { React } from '../../Imports.ts'
|
||||
|
||||
/**
|
||||
* 消息容器
|
||||
* @returns { React.JSX.Element }
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { React } from '../../Imports.ts'
|
||||
|
||||
/**
|
||||
* 一条系统提示消息
|
||||
* @returns { React.JSX.Element }
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { React, MduiDialog, MduiTextField, MduiButton } from '../../Imports.ts'
|
||||
import * as React from 'react'
|
||||
import { Button, Dialog, TextField } from "mdui";
|
||||
|
||||
interface Refs {
|
||||
inputAccountRef: React.MutableRefObject<MduiTextField | null>
|
||||
inputPasswordRef: React.MutableRefObject<MduiTextField | null>
|
||||
registerButtonRef: React.MutableRefObject<MduiButton | null>
|
||||
loginButtonRef: React.MutableRefObject<MduiButton | null>
|
||||
loginDialogRef: React.MutableRefObject<MduiDialog | null>
|
||||
inputAccountRef: React.MutableRefObject<TextField | null>
|
||||
inputPasswordRef: React.MutableRefObject<TextField | null>
|
||||
registerButtonRef: React.MutableRefObject<Button | null>
|
||||
loginButtonRef: React.MutableRefObject<Button | null>
|
||||
loginDialogRef: React.MutableRefObject<Dialog | null>
|
||||
}
|
||||
|
||||
export default function LoginDialog({
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import Avatar from "../Avatar.jsx"
|
||||
|
||||
import { React } from '../../Imports.ts'
|
||||
|
||||
export default function ContactsListItem({ nickName, avatar }) {
|
||||
return (
|
||||
<mdui-list-item rounded style={{
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import Avatar from "../Avatar.jsx"
|
||||
|
||||
import { React } from '../../Imports.ts'
|
||||
|
||||
export default function RecentsListItem({ nickName, avatar, content }) {
|
||||
return (
|
||||
<mdui-list-item rounded style={{
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export default function snackbar(text) {
|
||||
$("#public_snackbar").text(text).get(0).open()
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* @param { Event } event
|
||||
*/
|
||||
|
||||
import { React } from "../Imports.ts"
|
||||
import * as React from 'react'
|
||||
|
||||
/**
|
||||
* 绑定事件
|
||||
|
||||
15
client/vite.config.ts
Normal file
15
client/vite.config.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import path from 'node:path'
|
||||
import { defineConfig } from 'vite'
|
||||
import deno from '@deno/vite-plugin'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
import config from '../server/config.ts'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [deno(), react()],
|
||||
build: {
|
||||
sourcemap: "inline",
|
||||
outDir: "." + config.data_path + '/page_compiled',
|
||||
},
|
||||
})
|
||||
12
deno.jsonc
12
deno.jsonc
@@ -1,18 +1,12 @@
|
||||
{
|
||||
"tasks": {
|
||||
"main": "deno run --allow-read --allow-write --allow-env --allow-net --allow-sys ./server/main.ts",
|
||||
"debug": "deno run --watch --allow-read --allow-write --allow-env --allow-net --allow-sys ./server/main.ts",
|
||||
"test": "deno run --allow-read --allow-write --allow-env --allow-net ./server/main_test.ts"
|
||||
"server": "deno task build && deno run --allow-read --allow-write --allow-env --allow-net --allow-sys ./server/main.ts",
|
||||
"build": "cd ./client && deno task build"
|
||||
},
|
||||
"imports": {
|
||||
"chalk": "npm:chalk@5.4.1",
|
||||
"file-type": "npm:file-type@21.0.0",
|
||||
"express": "npm:express@5.1.0",
|
||||
"socket.io": "npm:socket.io@4.8.1",
|
||||
|
||||
"@babel/core": "npm:@babel/core@^7.26.10",
|
||||
"@babel/preset-env": "npm:@babel/preset-env@7.26.9",
|
||||
"@babel/preset-react": "npm:@babel/preset-react@7.26.3",
|
||||
"@babel/preset-typescript": "npm:@babel/preset-typescript@7.27.1"
|
||||
"socket.io": "npm:socket.io@4.8.1"
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ export default abstract class BaseApi {
|
||||
this.onInit()
|
||||
}
|
||||
abstract onInit(): void
|
||||
checkArgsMissing(args: { [key: string]: unknown }, names: []) {
|
||||
checkArgsMissing(args: { [key: string]: unknown }, names: string[]) {
|
||||
for (const k of names)
|
||||
if (!(k in args))
|
||||
return true
|
||||
|
||||
@@ -11,5 +11,16 @@ export default class UserApi extends BaseApi {
|
||||
code: 401,
|
||||
}
|
||||
})
|
||||
this.registerEvent("User.login", (args) => {
|
||||
if (this.checkArgsMissing(args, ['account', 'password'])) return {
|
||||
msg: "",
|
||||
code: 400,
|
||||
}
|
||||
|
||||
return {
|
||||
msg: "",
|
||||
code: 501,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,263 +0,0 @@
|
||||
/*
|
||||
* Simple File Access Library
|
||||
* Author - @MoonLeeeaf <https://github.com/MoonLeeeaf>
|
||||
*/
|
||||
|
||||
import fs from 'node:fs'
|
||||
|
||||
/**
|
||||
* 简单文件类
|
||||
*/
|
||||
export default class io {
|
||||
/**
|
||||
* 构建函数
|
||||
* @param { String } path
|
||||
* @param { String } mode
|
||||
*/
|
||||
constructor(path, mode) {
|
||||
this.path = path
|
||||
this.r = mode.includes('r')
|
||||
this.w = mode.includes('w')
|
||||
}
|
||||
/**
|
||||
* 构建函数
|
||||
* @param { String } path
|
||||
* @param { String } mode
|
||||
*/
|
||||
static open(path, mode) {
|
||||
if (!mode || mode == '')
|
||||
throw new Error('当前文件对象未设置属性!')
|
||||
return new io(path, mode)
|
||||
}
|
||||
/**
|
||||
* 检测文件或目录是否存在
|
||||
* @param { String } path
|
||||
* @returns { Boolean }
|
||||
*/
|
||||
static exists(path) {
|
||||
return fs.existsSync(path)
|
||||
}
|
||||
/**
|
||||
* 枚举目录下所有文件
|
||||
* @param { String } 扫描路径
|
||||
* @param { Object } extra 额外参数
|
||||
* @param { Function<String> } [extra.filter] 过滤器<文件路径>
|
||||
* @param { Boolean } [extra.recursive] 是否搜索文件夹内的文件
|
||||
* @param { Boolean } [extra.fullPath] 是否返回完整文件路径
|
||||
* @returns { String[] } 文件路径列表
|
||||
*/
|
||||
static listFiles(path, { filter, recursive = false, fullPath = true } = {}) {
|
||||
let a = fs.readdirSync(path, { recursive: recursive })
|
||||
a.forEach(function (v, index, arrayThis) {
|
||||
arrayThis[index] = `${path}//${v}`
|
||||
})
|
||||
|
||||
a = a.filter(function (v) {
|
||||
if (!fs.lstatSync(v).isFile()) return false
|
||||
|
||||
if (filter) return filter(v)
|
||||
return true
|
||||
})
|
||||
if (!fullPath)
|
||||
a.forEach(function (v, index, arrayThis) {
|
||||
arrayThis[index] = v.substring(v.lastIndexOf('/') + 1)
|
||||
})
|
||||
return a
|
||||
}
|
||||
/**
|
||||
* 枚举目录下所有文件夹
|
||||
* @param { String } 扫描路径
|
||||
* @param { Object } extra 额外参数
|
||||
* @param { Function<String> } [extra.filter] 过滤器<文件夹路径>
|
||||
* @param { Boolean } [extra.recursive] 是否搜索文件夹内的文件夹
|
||||
* @param { Boolean } [extra.fullPath] 是否返回完整文件路径
|
||||
* @returns { String[] } 文件夹路径列表
|
||||
*/
|
||||
static listFolders(path, { filter, recursive = false, fullPath = true } = {}) {
|
||||
let a = fs.readdirSync(path, { recursive: recursive })
|
||||
a.forEach(function (v, index, arrayThis) {
|
||||
arrayThis[index] = `${path}//${v}`
|
||||
})
|
||||
|
||||
a = a.filter(function (v) {
|
||||
if (!fs.lstatSync(v).isDirectory()) return false
|
||||
|
||||
if (filter) return filter(v)
|
||||
return true
|
||||
})
|
||||
if (!fullPath)
|
||||
a.forEach(function (v, index, arrayThis) {
|
||||
arrayThis[index] = v.substring(v.lastIndexOf('/') + 1)
|
||||
})
|
||||
return a
|
||||
}
|
||||
/**
|
||||
* 获取文件(夹)的全名
|
||||
* @param { String } path
|
||||
* @returns { String } name
|
||||
*/
|
||||
static getName(path) {
|
||||
let r = /\\|\//
|
||||
let s = path.search(r)
|
||||
while (s != -1) {
|
||||
path = path.substring(s + 1)
|
||||
s = path.search(r)
|
||||
}
|
||||
return path
|
||||
}
|
||||
/**
|
||||
* 获取文件(夹)的父文件夹路径
|
||||
* @param { String } path
|
||||
* @returns { String } parentPath
|
||||
*/
|
||||
static getParent(path) {
|
||||
return path.substring(0, path.lastIndexOf(this.getName(path)) - 1)
|
||||
}
|
||||
/**
|
||||
* 复制某文件夹的全部内容, 自动创建文件夹
|
||||
* @param { String } from
|
||||
* @param { String } to
|
||||
*/
|
||||
static copyDir(from, to) {
|
||||
this.mkdirs(to)
|
||||
this.listFiles(from).forEach(function (v) {
|
||||
io.open(v, 'r').pipe(io.open(`${to}//${io.getName(v)}`, 'w')).close()
|
||||
})
|
||||
this.listFolders(from).forEach(function (v) {
|
||||
io.copyDir(v, `${to}//${io.getName(v)}`)
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 删除文件
|
||||
* @param { String } path
|
||||
*/
|
||||
static remove(f) {
|
||||
fs.rmSync(f, { recursive: true })
|
||||
}
|
||||
/**
|
||||
* 移动文件
|
||||
* @param { String }} path
|
||||
* @param { String } newPath
|
||||
*/
|
||||
static move(path, newPath) {
|
||||
fs.renameSync(path, newPath)
|
||||
}
|
||||
/**
|
||||
* 创建文件夹, 有则忽略
|
||||
* @param { String } path
|
||||
* @returns { String } path
|
||||
*/
|
||||
static mkdirs(path) {
|
||||
if (!this.exists(path))
|
||||
fs.mkdirSync(path, { recursive: true })
|
||||
return path
|
||||
}
|
||||
/**
|
||||
* 将文件内容写入到另一个文件
|
||||
* @param { io } file
|
||||
* @returns { io } this
|
||||
*/
|
||||
pipe(file) {
|
||||
file.writeAll(this.readAll())
|
||||
file.close()
|
||||
return this
|
||||
}
|
||||
/**
|
||||
* 检查文件是否存在, 若无则写入, 有则忽略
|
||||
* @param { Buffer | String } 写入数据
|
||||
* @returns { io } 对象自身
|
||||
*/
|
||||
checkExistsOrWrite(data) {
|
||||
if (!io.exists(this.path))
|
||||
this.writeAll(data)
|
||||
return this
|
||||
}
|
||||
/**
|
||||
* 检查文件是否存在, 若无则写入 JSON 数据, 有则忽略
|
||||
* @param { Object } 写入数据
|
||||
* @returns { io } 对象自身
|
||||
*/
|
||||
checkExistsOrWriteJson(data) {
|
||||
if (!io.exists(this.path))
|
||||
this.writeAllJson(data)
|
||||
return this
|
||||
}
|
||||
/**
|
||||
* 读取一个文件
|
||||
* @returns { Buffer } 文件数据字节
|
||||
*/
|
||||
readAll() {
|
||||
if (this.r)
|
||||
return fs.readFileSync(this.path)
|
||||
throw new Error('当前文件对象未设置可读')
|
||||
}
|
||||
/**
|
||||
* 读取一个文件并关闭
|
||||
* @returns { Buffer } 文件数据
|
||||
*/
|
||||
readAllAndClose() {
|
||||
let r
|
||||
if (this.r)
|
||||
r = this.readAll()
|
||||
else
|
||||
throw new Error('当前文件对象未设置可读!')
|
||||
this.close()
|
||||
return r
|
||||
}
|
||||
/**
|
||||
* 写入一个文件
|
||||
* @param { Buffer | String } 写入数据
|
||||
* @returns { io } 对象自身
|
||||
*/
|
||||
writeAll(data) {
|
||||
if (this.w)
|
||||
fs.writeFileSync(this.path, data)
|
||||
else
|
||||
throw new Error('当前文件对象未设置可写!')
|
||||
return this
|
||||
}
|
||||
/**
|
||||
* 写入一个JSON文件
|
||||
* @param { Object } 写入数据
|
||||
* @returns { io } 对象自身
|
||||
*/
|
||||
writeAllJson(data) {
|
||||
if (!data instanceof Object)
|
||||
throw new Error('你只能输入一个 JSON 对象!')
|
||||
if (this.w)
|
||||
this.writeAll(JSON.stringify(data))
|
||||
else
|
||||
throw new Error('当前文件对象未设置可写!')
|
||||
return this
|
||||
}
|
||||
/**
|
||||
* 读取一个JSON文件
|
||||
* @returns { Object } 文件数据
|
||||
*/
|
||||
readAllJson() {
|
||||
if (this.r)
|
||||
return JSON.parse(this.readAll().toString())
|
||||
throw new Error('当前文件对象未设置可读!')
|
||||
}
|
||||
/**
|
||||
* 读取一个JSON文件并关闭
|
||||
* @returns { Object } 文件数据
|
||||
*/
|
||||
readAllJsonAndClose() {
|
||||
let r
|
||||
if (this.r)
|
||||
r = JSON.parse(this.readAll().toString())
|
||||
else
|
||||
throw new Error('当前文件对象未设置可读!')
|
||||
this.close()
|
||||
return r
|
||||
}
|
||||
/**
|
||||
* 回收文件对象
|
||||
*/
|
||||
close() {
|
||||
delete this.path
|
||||
delete this.r
|
||||
delete this.w
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
// @ts-types="npm:@types/babel__core"
|
||||
import babel from '@babel/core'
|
||||
import fs from 'node:fs/promises'
|
||||
import io from './io.js'
|
||||
|
||||
async function compileJs(path: string) {
|
||||
const result = await babel.transformFileAsync(path, {
|
||||
presets: [
|
||||
[
|
||||
"@babel/preset-env", {
|
||||
modules: false,
|
||||
},
|
||||
],
|
||||
"@babel/preset-react",
|
||||
[
|
||||
"@babel/preset-typescript", {
|
||||
allowDeclareFields: true,
|
||||
},
|
||||
],
|
||||
],
|
||||
targets: {
|
||||
chrome: "53",
|
||||
android: "40",
|
||||
},
|
||||
sourceMaps: true,
|
||||
})
|
||||
await fs.writeFile(path, result!.code + '\n' + `//@ sourceMappingURL=${io.getName(path)}.map`)
|
||||
await fs.writeFile(path + '.map', JSON.stringify(result!.map))
|
||||
console.log(`编译: ${path}`)
|
||||
}
|
||||
|
||||
export default async function(source: string, output: string) {
|
||||
const t = Date.now()
|
||||
io.remove(output)
|
||||
io.copyDir(source, output)
|
||||
for (const v of io.listFiles(output, {
|
||||
recursive: true,
|
||||
fullPath: true,
|
||||
}))
|
||||
if (/\.(t|j)sx?$/.test(v) && !/\.(min|static)\.(t|j)sx?$/.test(v))
|
||||
if (/\.d\.ts$/.test(v))
|
||||
await fs.writeFile(v, '')
|
||||
else
|
||||
await compileJs(v)
|
||||
return (Date.now() - t) / 1000
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
import fs from 'node:fs/promises'
|
||||
import chalk from 'chalk'
|
||||
import { cwd } from "node:process"
|
||||
|
||||
const isCompilingClient = /client(\\|\/)?$/.test(cwd())
|
||||
const prefix = isCompilingClient ? '.' : ''
|
||||
|
||||
const default_data_path = "./thewhitesilk_data"
|
||||
let config = {
|
||||
@@ -28,12 +32,12 @@ let config = {
|
||||
}
|
||||
|
||||
try {
|
||||
config = JSON.parse(await fs.readFile('thewhitesilk_config.json', 'utf-8'))
|
||||
config = JSON.parse(await fs.readFile(prefix + './thewhitesilk_config.json', 'utf-8'))
|
||||
} catch (_e) {
|
||||
console.log(chalk.yellow("配置文件貌似不存在, 正在创建..."))
|
||||
await fs.writeFile('thewhitesilk_config.json', JSON.stringify(config))
|
||||
await fs.writeFile(prefix + './thewhitesilk_config.json', JSON.stringify(config))
|
||||
}
|
||||
|
||||
await fs.mkdir(config.data_path, { recursive: true })
|
||||
await fs.mkdir(prefix + config.data_path, { recursive: true })
|
||||
|
||||
export default config
|
||||
|
||||
@@ -8,7 +8,6 @@ import http from 'node:http'
|
||||
import https from 'node:https'
|
||||
import readline from 'node:readline'
|
||||
import process from "node:process"
|
||||
import transform from './compiler/transform.ts'
|
||||
import chalk from "chalk"
|
||||
|
||||
const app = express()
|
||||
@@ -34,18 +33,13 @@ ApiManager.initEvents()
|
||||
ApiManager.initAllApis()
|
||||
|
||||
httpServer.listen(config.server.listen)
|
||||
console.log(chalk.green("API & Web 服務已經開始運作"))
|
||||
|
||||
console.log(chalk.green("Web 頁面已編譯完成, 用時 " + await transform('./client', config.data_path + '/page_compiled') + "s"))
|
||||
|
||||
console.log(chalk.yellow("===== TheWhiteSilk Server ====="))
|
||||
console.log(chalk.yellow("b - 重新編譯 Web 頁面"))
|
||||
console.log(chalk.green("API & Web 服務已經開始運作"))
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
})
|
||||
rl.on('line', async (text) => {
|
||||
if (text == "b")
|
||||
console.log(chalk.green("Web 頁面已編譯完成, 用時 " + await transform('./client', config.data_path + '/page_compiled') + "s"))
|
||||
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user