leviathan-crypto 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +265 -0
- package/LICENSE +21 -0
- package/README.md +322 -0
- package/SECURITY.md +174 -0
- package/dist/chacha.wasm +0 -0
- package/dist/chacha20/index.d.ts +49 -0
- package/dist/chacha20/index.js +177 -0
- package/dist/chacha20/ops.d.ts +16 -0
- package/dist/chacha20/ops.js +146 -0
- package/dist/chacha20/pool.d.ts +52 -0
- package/dist/chacha20/pool.js +188 -0
- package/dist/chacha20/pool.worker.d.ts +1 -0
- package/dist/chacha20/pool.worker.js +37 -0
- package/dist/chacha20/types.d.ts +30 -0
- package/dist/chacha20/types.js +1 -0
- package/dist/docs/architecture.md +795 -0
- package/dist/docs/argon2id.md +290 -0
- package/dist/docs/chacha20.md +602 -0
- package/dist/docs/chacha20_pool.md +306 -0
- package/dist/docs/fortuna.md +322 -0
- package/dist/docs/init.md +308 -0
- package/dist/docs/loader.md +206 -0
- package/dist/docs/serpent.md +914 -0
- package/dist/docs/sha2.md +620 -0
- package/dist/docs/sha3.md +509 -0
- package/dist/docs/types.md +198 -0
- package/dist/docs/utils.md +273 -0
- package/dist/docs/wasm.md +193 -0
- package/dist/embedded/chacha.d.ts +1 -0
- package/dist/embedded/chacha.js +2 -0
- package/dist/embedded/serpent.d.ts +1 -0
- package/dist/embedded/serpent.js +2 -0
- package/dist/embedded/sha2.d.ts +1 -0
- package/dist/embedded/sha2.js +2 -0
- package/dist/embedded/sha3.d.ts +1 -0
- package/dist/embedded/sha3.js +2 -0
- package/dist/fortuna.d.ts +72 -0
- package/dist/fortuna.js +445 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +44 -0
- package/dist/init.d.ts +11 -0
- package/dist/init.js +49 -0
- package/dist/loader.d.ts +4 -0
- package/dist/loader.js +30 -0
- package/dist/serpent/index.d.ts +65 -0
- package/dist/serpent/index.js +242 -0
- package/dist/serpent/seal.d.ts +8 -0
- package/dist/serpent/seal.js +70 -0
- package/dist/serpent/stream-encoder.d.ts +20 -0
- package/dist/serpent/stream-encoder.js +167 -0
- package/dist/serpent/stream-pool.d.ts +48 -0
- package/dist/serpent/stream-pool.js +285 -0
- package/dist/serpent/stream-sealer.d.ts +34 -0
- package/dist/serpent/stream-sealer.js +223 -0
- package/dist/serpent/stream.d.ts +28 -0
- package/dist/serpent/stream.js +205 -0
- package/dist/serpent/stream.worker.d.ts +32 -0
- package/dist/serpent/stream.worker.js +117 -0
- package/dist/serpent/types.d.ts +5 -0
- package/dist/serpent/types.js +1 -0
- package/dist/serpent.wasm +0 -0
- package/dist/sha2/hkdf.d.ts +16 -0
- package/dist/sha2/hkdf.js +108 -0
- package/dist/sha2/index.d.ts +40 -0
- package/dist/sha2/index.js +190 -0
- package/dist/sha2/types.d.ts +5 -0
- package/dist/sha2/types.js +1 -0
- package/dist/sha2.wasm +0 -0
- package/dist/sha3/index.d.ts +55 -0
- package/dist/sha3/index.js +246 -0
- package/dist/sha3/types.d.ts +5 -0
- package/dist/sha3/types.js +1 -0
- package/dist/sha3.wasm +0 -0
- package/dist/types.d.ts +24 -0
- package/dist/types.js +26 -0
- package/dist/utils.d.ts +26 -0
- package/dist/utils.js +169 -0
- package/package.json +90 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// ▄▄▄▄▄▄▄▄▄▄
|
|
2
|
+
// ▄████████████████████▄▄ ▒ ▄▀▀ ▒ ▒ █ ▄▀▄ ▀█▀ █ ▒ ▄▀▄ █▀▄
|
|
3
|
+
// ▄██████████████████████ ▀████▄ ▓ ▓▀ ▓ ▓ ▓ ▓▄▓ ▓ ▓▀▓ ▓▄▓ ▓ ▓
|
|
4
|
+
// ▄█████████▀▀▀ ▀███████▄▄███████▌ ▀▄ ▀▄▄ ▀▄▀ ▒ ▒ ▒ ▒ ▒ █ ▒ ▒ ▒ █
|
|
5
|
+
// ▐████████▀ ▄▄▄▄ ▀████████▀██▀█▌
|
|
6
|
+
// ████████ ███▀▀ ████▀ █▀ █▀ Leviathan Crypto Library
|
|
7
|
+
// ███████▌ ▀██▀ ███
|
|
8
|
+
// ███████ ▀███ ▀██ ▀█▄ Repository & Mirror:
|
|
9
|
+
// ▀██████ ▄▄██ ▀▀ ██▄ github.com/xero/leviathan-crypto
|
|
10
|
+
// ▀█████▄ ▄██▄ ▄▀▄▀ unpkg.com/leviathan-crypto
|
|
11
|
+
// ▀████▄ ▄██▄
|
|
12
|
+
// ▐████ ▐███ Author: xero (https://x-e.ro)
|
|
13
|
+
// ▄▄██████████ ▐███ ▄▄ License: MIT
|
|
14
|
+
// ▄██▀▀▀▀▀▀▀▀▀▀ ▄████ ▄██▀
|
|
15
|
+
// ▄▀ ▄▄█████████▄▄ ▀▀▀▀▀ ▄███ This file is provided completely
|
|
16
|
+
// ▄██████▀▀▀▀▀▀██████▄ ▀▄▄▄▄████▀ free, "as is", and without
|
|
17
|
+
// ████▀ ▄▄▄▄▄▄▄ ▀████▄ ▀█████▀ ▄▄▄▄ warranty of any kind. The author
|
|
18
|
+
// █████▄▄█████▀▀▀▀▀▀▄ ▀███▄ ▄████ assumes absolutely no liability
|
|
19
|
+
// ▀██████▀ ▀████▄▄▄████▀ for its {ab,mis,}use.
|
|
20
|
+
// ▀█████▀▀
|
|
21
|
+
//
|
|
22
|
+
// src/ts/sha2/index.ts
|
|
23
|
+
//
|
|
24
|
+
// Public API classes for the SHA-2 WASM module.
|
|
25
|
+
// Uses the init() module cache — call init('sha2') before constructing.
|
|
26
|
+
import { getInstance, initModule } from '../init.js';
|
|
27
|
+
const _embedded = () => import('../embedded/sha2.js').then(m => m.WASM_BASE64);
|
|
28
|
+
export async function sha2Init(mode = 'embedded', opts) {
|
|
29
|
+
return initModule('sha2', _embedded, mode, opts);
|
|
30
|
+
}
|
|
31
|
+
function getExports() {
|
|
32
|
+
return getInstance('sha2').exports;
|
|
33
|
+
}
|
|
34
|
+
export function _sha2Ready() {
|
|
35
|
+
try {
|
|
36
|
+
getInstance('sha2');
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Write msg into input buffer in chunks, calling update for each chunk.
|
|
44
|
+
function feedHash(x, msg, inputOff, chunkSize, updateFn) {
|
|
45
|
+
const mem = new Uint8Array(x.memory.buffer);
|
|
46
|
+
let pos = 0;
|
|
47
|
+
while (pos < msg.length) {
|
|
48
|
+
const n = Math.min(msg.length - pos, chunkSize);
|
|
49
|
+
mem.set(msg.subarray(pos, pos + n), inputOff);
|
|
50
|
+
updateFn(n);
|
|
51
|
+
pos += n;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// ── SHA256 ──────────────────────────────────────────────────────────────────
|
|
55
|
+
export class SHA256 {
|
|
56
|
+
x;
|
|
57
|
+
constructor() {
|
|
58
|
+
this.x = getExports();
|
|
59
|
+
}
|
|
60
|
+
hash(msg) {
|
|
61
|
+
this.x.sha256Init();
|
|
62
|
+
feedHash(this.x, msg, this.x.getSha256InputOffset(), 64, this.x.sha256Update);
|
|
63
|
+
this.x.sha256Final();
|
|
64
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
65
|
+
return mem.slice(this.x.getSha256OutOffset(), this.x.getSha256OutOffset() + 32);
|
|
66
|
+
}
|
|
67
|
+
dispose() {
|
|
68
|
+
this.x.wipeBuffers();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// ── SHA512 ──────────────────────────────────────────────────────────────────
|
|
72
|
+
export class SHA512 {
|
|
73
|
+
x;
|
|
74
|
+
constructor() {
|
|
75
|
+
this.x = getExports();
|
|
76
|
+
}
|
|
77
|
+
hash(msg) {
|
|
78
|
+
this.x.sha512Init();
|
|
79
|
+
feedHash(this.x, msg, this.x.getSha512InputOffset(), 128, this.x.sha512Update);
|
|
80
|
+
this.x.sha512Final();
|
|
81
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
82
|
+
return mem.slice(this.x.getSha512OutOffset(), this.x.getSha512OutOffset() + 64);
|
|
83
|
+
}
|
|
84
|
+
dispose() {
|
|
85
|
+
this.x.wipeBuffers();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// ── SHA384 ──────────────────────────────────────────────────────────────────
|
|
89
|
+
export class SHA384 {
|
|
90
|
+
x;
|
|
91
|
+
constructor() {
|
|
92
|
+
this.x = getExports();
|
|
93
|
+
}
|
|
94
|
+
hash(msg) {
|
|
95
|
+
this.x.sha384Init();
|
|
96
|
+
feedHash(this.x, msg, this.x.getSha512InputOffset(), 128, this.x.sha512Update);
|
|
97
|
+
this.x.sha384Final();
|
|
98
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
99
|
+
return mem.slice(this.x.getSha512OutOffset(), this.x.getSha512OutOffset() + 48);
|
|
100
|
+
}
|
|
101
|
+
dispose() {
|
|
102
|
+
this.x.wipeBuffers();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// ── HMAC_SHA256 ─────────────────────────────────────────────────────────────
|
|
106
|
+
export class HMAC_SHA256 {
|
|
107
|
+
x;
|
|
108
|
+
constructor() {
|
|
109
|
+
this.x = getExports();
|
|
110
|
+
}
|
|
111
|
+
hash(key, msg) {
|
|
112
|
+
let k = key;
|
|
113
|
+
// RFC 2104 §3: keys longer than block size are pre-hashed
|
|
114
|
+
if (k.length > 64) {
|
|
115
|
+
this.x.sha256Init();
|
|
116
|
+
feedHash(this.x, k, this.x.getSha256InputOffset(), 64, this.x.sha256Update);
|
|
117
|
+
this.x.sha256Final();
|
|
118
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
119
|
+
k = mem.slice(this.x.getSha256OutOffset(), this.x.getSha256OutOffset() + 32);
|
|
120
|
+
}
|
|
121
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
122
|
+
mem.set(k, this.x.getSha256InputOffset());
|
|
123
|
+
this.x.hmac256Init(k.length);
|
|
124
|
+
feedHash(this.x, msg, this.x.getSha256InputOffset(), 64, this.x.hmac256Update);
|
|
125
|
+
this.x.hmac256Final();
|
|
126
|
+
const out = new Uint8Array(this.x.memory.buffer);
|
|
127
|
+
return out.slice(this.x.getSha256OutOffset(), this.x.getSha256OutOffset() + 32);
|
|
128
|
+
}
|
|
129
|
+
dispose() {
|
|
130
|
+
this.x.wipeBuffers();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// ── HMAC_SHA512 ─────────────────────────────────────────────────────────────
|
|
134
|
+
export class HMAC_SHA512 {
|
|
135
|
+
x;
|
|
136
|
+
constructor() {
|
|
137
|
+
this.x = getExports();
|
|
138
|
+
}
|
|
139
|
+
hash(key, msg) {
|
|
140
|
+
let k = key;
|
|
141
|
+
// RFC 2104 §3: keys longer than block size (128) are pre-hashed
|
|
142
|
+
if (k.length > 128) {
|
|
143
|
+
this.x.sha512Init();
|
|
144
|
+
feedHash(this.x, k, this.x.getSha512InputOffset(), 128, this.x.sha512Update);
|
|
145
|
+
this.x.sha512Final();
|
|
146
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
147
|
+
k = mem.slice(this.x.getSha512OutOffset(), this.x.getSha512OutOffset() + 64);
|
|
148
|
+
}
|
|
149
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
150
|
+
mem.set(k, this.x.getSha512InputOffset());
|
|
151
|
+
this.x.hmac512Init(k.length);
|
|
152
|
+
feedHash(this.x, msg, this.x.getSha512InputOffset(), 128, this.x.hmac512Update);
|
|
153
|
+
this.x.hmac512Final();
|
|
154
|
+
const out = new Uint8Array(this.x.memory.buffer);
|
|
155
|
+
return out.slice(this.x.getSha512OutOffset(), this.x.getSha512OutOffset() + 64);
|
|
156
|
+
}
|
|
157
|
+
dispose() {
|
|
158
|
+
this.x.wipeBuffers();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// ── HMAC_SHA384 ─────────────────────────────────────────────────────────────
|
|
162
|
+
export class HMAC_SHA384 {
|
|
163
|
+
x;
|
|
164
|
+
constructor() {
|
|
165
|
+
this.x = getExports();
|
|
166
|
+
}
|
|
167
|
+
hash(key, msg) {
|
|
168
|
+
let k = key;
|
|
169
|
+
// RFC 2104 §3: keys longer than block size (128) are pre-hashed with SHA-384
|
|
170
|
+
if (k.length > 128) {
|
|
171
|
+
this.x.sha384Init();
|
|
172
|
+
feedHash(this.x, k, this.x.getSha512InputOffset(), 128, this.x.sha512Update);
|
|
173
|
+
this.x.sha384Final();
|
|
174
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
175
|
+
k = mem.slice(this.x.getSha512OutOffset(), this.x.getSha512OutOffset() + 48);
|
|
176
|
+
}
|
|
177
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
178
|
+
mem.set(k, this.x.getSha512InputOffset());
|
|
179
|
+
this.x.hmac384Init(k.length);
|
|
180
|
+
feedHash(this.x, msg, this.x.getSha512InputOffset(), 128, this.x.hmac384Update);
|
|
181
|
+
this.x.hmac384Final();
|
|
182
|
+
const out = new Uint8Array(this.x.memory.buffer);
|
|
183
|
+
return out.slice(this.x.getSha512OutOffset(), this.x.getSha512OutOffset() + 48);
|
|
184
|
+
}
|
|
185
|
+
dispose() {
|
|
186
|
+
this.x.wipeBuffers();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// ── HKDF ────────────────────────────────────────────────────────────────────
|
|
190
|
+
export { HKDF_SHA256, HKDF_SHA512 } from './hkdf.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/sha2.wasm
ADDED
|
Binary file
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Mode, InitOpts } from '../init.js';
|
|
2
|
+
export declare function sha3Init(mode?: Mode, opts?: InitOpts): Promise<void>;
|
|
3
|
+
export declare function _sha3Ready(): boolean;
|
|
4
|
+
export declare class SHA3_256 {
|
|
5
|
+
private readonly x;
|
|
6
|
+
constructor();
|
|
7
|
+
hash(msg: Uint8Array): Uint8Array;
|
|
8
|
+
dispose(): void;
|
|
9
|
+
}
|
|
10
|
+
export declare class SHA3_512 {
|
|
11
|
+
private readonly x;
|
|
12
|
+
constructor();
|
|
13
|
+
hash(msg: Uint8Array): Uint8Array;
|
|
14
|
+
dispose(): void;
|
|
15
|
+
}
|
|
16
|
+
export declare class SHA3_384 {
|
|
17
|
+
private readonly x;
|
|
18
|
+
constructor();
|
|
19
|
+
hash(msg: Uint8Array): Uint8Array;
|
|
20
|
+
dispose(): void;
|
|
21
|
+
}
|
|
22
|
+
export declare class SHA3_224 {
|
|
23
|
+
private readonly x;
|
|
24
|
+
constructor();
|
|
25
|
+
hash(msg: Uint8Array): Uint8Array;
|
|
26
|
+
dispose(): void;
|
|
27
|
+
}
|
|
28
|
+
/** SHAKE128 XOF — extendable output, multi-squeeze capable. */
|
|
29
|
+
export declare class SHAKE128 {
|
|
30
|
+
private readonly x;
|
|
31
|
+
private readonly _rate;
|
|
32
|
+
private _squeezing;
|
|
33
|
+
private _block;
|
|
34
|
+
private _blockPos;
|
|
35
|
+
constructor();
|
|
36
|
+
reset(): this;
|
|
37
|
+
absorb(msg: Uint8Array): this;
|
|
38
|
+
squeeze(n: number): Uint8Array;
|
|
39
|
+
hash(msg: Uint8Array, outputLength: number): Uint8Array;
|
|
40
|
+
dispose(): void;
|
|
41
|
+
}
|
|
42
|
+
/** SHAKE256 XOF — extendable output, multi-squeeze capable. */
|
|
43
|
+
export declare class SHAKE256 {
|
|
44
|
+
private readonly x;
|
|
45
|
+
private readonly _rate;
|
|
46
|
+
private _squeezing;
|
|
47
|
+
private _block;
|
|
48
|
+
private _blockPos;
|
|
49
|
+
constructor();
|
|
50
|
+
reset(): this;
|
|
51
|
+
absorb(msg: Uint8Array): this;
|
|
52
|
+
squeeze(n: number): Uint8Array;
|
|
53
|
+
hash(msg: Uint8Array, outputLength: number): Uint8Array;
|
|
54
|
+
dispose(): void;
|
|
55
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// ▄▄▄▄▄▄▄▄▄▄
|
|
2
|
+
// ▄████████████████████▄▄ ▒ ▄▀▀ ▒ ▒ █ ▄▀▄ ▀█▀ █ ▒ ▄▀▄ █▀▄
|
|
3
|
+
// ▄██████████████████████ ▀████▄ ▓ ▓▀ ▓ ▓ ▓ ▓▄▓ ▓ ▓▀▓ ▓▄▓ ▓ ▓
|
|
4
|
+
// ▄█████████▀▀▀ ▀███████▄▄███████▌ ▀▄ ▀▄▄ ▀▄▀ ▒ ▒ ▒ ▒ ▒ █ ▒ ▒ ▒ █
|
|
5
|
+
// ▐████████▀ ▄▄▄▄ ▀████████▀██▀█▌
|
|
6
|
+
// ████████ ███▀▀ ████▀ █▀ █▀ Leviathan Crypto Library
|
|
7
|
+
// ███████▌ ▀██▀ ███
|
|
8
|
+
// ███████ ▀███ ▀██ ▀█▄ Repository & Mirror:
|
|
9
|
+
// ▀██████ ▄▄██ ▀▀ ██▄ github.com/xero/leviathan-crypto
|
|
10
|
+
// ▀█████▄ ▄██▄ ▄▀▄▀ unpkg.com/leviathan-crypto
|
|
11
|
+
// ▀████▄ ▄██▄
|
|
12
|
+
// ▐████ ▐███ Author: xero (https://x-e.ro)
|
|
13
|
+
// ▄▄██████████ ▐███ ▄▄ License: MIT
|
|
14
|
+
// ▄██▀▀▀▀▀▀▀▀▀▀ ▄████ ▄██▀
|
|
15
|
+
// ▄▀ ▄▄█████████▄▄ ▀▀▀▀▀ ▄███ This file is provided completely
|
|
16
|
+
// ▄██████▀▀▀▀▀▀██████▄ ▀▄▄▄▄████▀ free, "as is", and without
|
|
17
|
+
// ████▀ ▄▄▄▄▄▄▄ ▀████▄ ▀█████▀ ▄▄▄▄ warranty of any kind. The author
|
|
18
|
+
// █████▄▄█████▀▀▀▀▀▀▄ ▀███▄ ▄████ assumes absolutely no liability
|
|
19
|
+
// ▀██████▀ ▀████▄▄▄████▀ for its {ab,mis,}use.
|
|
20
|
+
// ▀█████▀▀
|
|
21
|
+
//
|
|
22
|
+
// src/ts/sha3/index.ts
|
|
23
|
+
//
|
|
24
|
+
// Public API classes for the SHA-3 WASM module.
|
|
25
|
+
// Uses the init() module cache — call init('sha3') before constructing.
|
|
26
|
+
import { getInstance, initModule } from '../init.js';
|
|
27
|
+
const _embedded = () => import('../embedded/sha3.js').then(m => m.WASM_BASE64);
|
|
28
|
+
export async function sha3Init(mode = 'embedded', opts) {
|
|
29
|
+
return initModule('sha3', _embedded, mode, opts);
|
|
30
|
+
}
|
|
31
|
+
function getExports() {
|
|
32
|
+
return getInstance('sha3').exports;
|
|
33
|
+
}
|
|
34
|
+
export function _sha3Ready() {
|
|
35
|
+
try {
|
|
36
|
+
getInstance('sha3');
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Write msg into INPUT_OFFSET in chunks of 168 bytes (max rate)
|
|
44
|
+
function absorb(x, msg) {
|
|
45
|
+
const mem = new Uint8Array(x.memory.buffer);
|
|
46
|
+
const inputOff = x.getInputOffset();
|
|
47
|
+
let pos = 0;
|
|
48
|
+
while (pos < msg.length) {
|
|
49
|
+
const chunk = Math.min(msg.length - pos, 168);
|
|
50
|
+
mem.set(msg.subarray(pos, pos + chunk), inputOff);
|
|
51
|
+
x.keccakAbsorb(chunk);
|
|
52
|
+
pos += chunk;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// ── SHA3_256 ────────────────────────────────────────────────────────────────
|
|
56
|
+
export class SHA3_256 {
|
|
57
|
+
x;
|
|
58
|
+
constructor() {
|
|
59
|
+
this.x = getExports();
|
|
60
|
+
}
|
|
61
|
+
hash(msg) {
|
|
62
|
+
this.x.sha3_256Init();
|
|
63
|
+
absorb(this.x, msg);
|
|
64
|
+
this.x.sha3_256Final();
|
|
65
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
66
|
+
return mem.slice(this.x.getOutOffset(), this.x.getOutOffset() + 32);
|
|
67
|
+
}
|
|
68
|
+
dispose() {
|
|
69
|
+
this.x.wipeBuffers();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// ── SHA3_512 ────────────────────────────────────────────────────────────────
|
|
73
|
+
export class SHA3_512 {
|
|
74
|
+
x;
|
|
75
|
+
constructor() {
|
|
76
|
+
this.x = getExports();
|
|
77
|
+
}
|
|
78
|
+
hash(msg) {
|
|
79
|
+
this.x.sha3_512Init();
|
|
80
|
+
absorb(this.x, msg);
|
|
81
|
+
this.x.sha3_512Final();
|
|
82
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
83
|
+
return mem.slice(this.x.getOutOffset(), this.x.getOutOffset() + 64);
|
|
84
|
+
}
|
|
85
|
+
dispose() {
|
|
86
|
+
this.x.wipeBuffers();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// ── SHA3_384 ────────────────────────────────────────────────────────────────
|
|
90
|
+
export class SHA3_384 {
|
|
91
|
+
x;
|
|
92
|
+
constructor() {
|
|
93
|
+
this.x = getExports();
|
|
94
|
+
}
|
|
95
|
+
hash(msg) {
|
|
96
|
+
this.x.sha3_384Init();
|
|
97
|
+
absorb(this.x, msg);
|
|
98
|
+
this.x.sha3_384Final();
|
|
99
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
100
|
+
return mem.slice(this.x.getOutOffset(), this.x.getOutOffset() + 48);
|
|
101
|
+
}
|
|
102
|
+
dispose() {
|
|
103
|
+
this.x.wipeBuffers();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// ── SHA3_224 ────────────────────────────────────────────────────────────────
|
|
107
|
+
export class SHA3_224 {
|
|
108
|
+
x;
|
|
109
|
+
constructor() {
|
|
110
|
+
this.x = getExports();
|
|
111
|
+
}
|
|
112
|
+
hash(msg) {
|
|
113
|
+
this.x.sha3_224Init();
|
|
114
|
+
absorb(this.x, msg);
|
|
115
|
+
this.x.sha3_224Final();
|
|
116
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
117
|
+
return mem.slice(this.x.getOutOffset(), this.x.getOutOffset() + 28);
|
|
118
|
+
}
|
|
119
|
+
dispose() {
|
|
120
|
+
this.x.wipeBuffers();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// ── SHAKE128 ────────────────────────────────────────────────────────────────
|
|
124
|
+
/** SHAKE128 XOF — extendable output, multi-squeeze capable. */
|
|
125
|
+
export class SHAKE128 {
|
|
126
|
+
x;
|
|
127
|
+
_rate = 168;
|
|
128
|
+
_squeezing = false;
|
|
129
|
+
_block = new Uint8Array(168);
|
|
130
|
+
_blockPos = 168;
|
|
131
|
+
constructor() {
|
|
132
|
+
this.x = getExports();
|
|
133
|
+
this.x.shake128Init();
|
|
134
|
+
}
|
|
135
|
+
reset() {
|
|
136
|
+
this.x.shake128Init();
|
|
137
|
+
this._squeezing = false;
|
|
138
|
+
this._block.fill(0);
|
|
139
|
+
this._blockPos = this._rate;
|
|
140
|
+
return this;
|
|
141
|
+
}
|
|
142
|
+
absorb(msg) {
|
|
143
|
+
if (this._squeezing)
|
|
144
|
+
throw new Error('SHAKE128: cannot absorb after squeeze — call reset() first');
|
|
145
|
+
absorb(this.x, msg);
|
|
146
|
+
return this;
|
|
147
|
+
}
|
|
148
|
+
squeeze(n) {
|
|
149
|
+
if (n < 1)
|
|
150
|
+
throw new RangeError(`squeeze length must be >= 1 (got ${n})`);
|
|
151
|
+
if (!this._squeezing) {
|
|
152
|
+
this.x.shakePad();
|
|
153
|
+
this._squeezing = true;
|
|
154
|
+
this._blockPos = this._rate;
|
|
155
|
+
}
|
|
156
|
+
const out = new Uint8Array(n);
|
|
157
|
+
let pos = 0;
|
|
158
|
+
while (pos < n) {
|
|
159
|
+
if (this._blockPos >= this._rate) {
|
|
160
|
+
this.x.shakeSqueezeBlock();
|
|
161
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
162
|
+
const off = this.x.getOutOffset();
|
|
163
|
+
this._block.set(mem.subarray(off, off + this._rate));
|
|
164
|
+
this._blockPos = 0;
|
|
165
|
+
}
|
|
166
|
+
const take = Math.min(n - pos, this._rate - this._blockPos);
|
|
167
|
+
out.set(this._block.subarray(this._blockPos, this._blockPos + take), pos);
|
|
168
|
+
this._blockPos += take;
|
|
169
|
+
pos += take;
|
|
170
|
+
}
|
|
171
|
+
return out;
|
|
172
|
+
}
|
|
173
|
+
hash(msg, outputLength) {
|
|
174
|
+
if (outputLength < 1)
|
|
175
|
+
throw new RangeError(`outputLength must be >= 1 (got ${outputLength})`);
|
|
176
|
+
this.reset();
|
|
177
|
+
this.absorb(msg);
|
|
178
|
+
return this.squeeze(outputLength);
|
|
179
|
+
}
|
|
180
|
+
dispose() {
|
|
181
|
+
this._block.fill(0);
|
|
182
|
+
this.x.wipeBuffers();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// ── SHAKE256 ────────────────────────────────────────────────────────────────
|
|
186
|
+
/** SHAKE256 XOF — extendable output, multi-squeeze capable. */
|
|
187
|
+
export class SHAKE256 {
|
|
188
|
+
x;
|
|
189
|
+
_rate = 136;
|
|
190
|
+
_squeezing = false;
|
|
191
|
+
_block = new Uint8Array(136);
|
|
192
|
+
_blockPos = 136;
|
|
193
|
+
constructor() {
|
|
194
|
+
this.x = getExports();
|
|
195
|
+
this.x.shake256Init();
|
|
196
|
+
}
|
|
197
|
+
reset() {
|
|
198
|
+
this.x.shake256Init();
|
|
199
|
+
this._squeezing = false;
|
|
200
|
+
this._block.fill(0);
|
|
201
|
+
this._blockPos = this._rate;
|
|
202
|
+
return this;
|
|
203
|
+
}
|
|
204
|
+
absorb(msg) {
|
|
205
|
+
if (this._squeezing)
|
|
206
|
+
throw new Error('SHAKE256: cannot absorb after squeeze — call reset() first');
|
|
207
|
+
absorb(this.x, msg);
|
|
208
|
+
return this;
|
|
209
|
+
}
|
|
210
|
+
squeeze(n) {
|
|
211
|
+
if (n < 1)
|
|
212
|
+
throw new RangeError(`squeeze length must be >= 1 (got ${n})`);
|
|
213
|
+
if (!this._squeezing) {
|
|
214
|
+
this.x.shakePad();
|
|
215
|
+
this._squeezing = true;
|
|
216
|
+
this._blockPos = this._rate;
|
|
217
|
+
}
|
|
218
|
+
const out = new Uint8Array(n);
|
|
219
|
+
let pos = 0;
|
|
220
|
+
while (pos < n) {
|
|
221
|
+
if (this._blockPos >= this._rate) {
|
|
222
|
+
this.x.shakeSqueezeBlock();
|
|
223
|
+
const mem = new Uint8Array(this.x.memory.buffer);
|
|
224
|
+
const off = this.x.getOutOffset();
|
|
225
|
+
this._block.set(mem.subarray(off, off + this._rate));
|
|
226
|
+
this._blockPos = 0;
|
|
227
|
+
}
|
|
228
|
+
const take = Math.min(n - pos, this._rate - this._blockPos);
|
|
229
|
+
out.set(this._block.subarray(this._blockPos, this._blockPos + take), pos);
|
|
230
|
+
this._blockPos += take;
|
|
231
|
+
pos += take;
|
|
232
|
+
}
|
|
233
|
+
return out;
|
|
234
|
+
}
|
|
235
|
+
hash(msg, outputLength) {
|
|
236
|
+
if (outputLength < 1)
|
|
237
|
+
throw new RangeError(`outputLength must be >= 1 (got ${outputLength})`);
|
|
238
|
+
this.reset();
|
|
239
|
+
this.absorb(msg);
|
|
240
|
+
return this.squeeze(outputLength);
|
|
241
|
+
}
|
|
242
|
+
dispose() {
|
|
243
|
+
this._block.fill(0);
|
|
244
|
+
this.x.wipeBuffers();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/sha3.wasm
ADDED
|
Binary file
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface Hash {
|
|
2
|
+
hash(msg: Uint8Array): Uint8Array;
|
|
3
|
+
dispose(): void;
|
|
4
|
+
}
|
|
5
|
+
export interface KeyedHash {
|
|
6
|
+
hash(key: Uint8Array, msg: Uint8Array): Uint8Array;
|
|
7
|
+
dispose(): void;
|
|
8
|
+
}
|
|
9
|
+
export interface Blockcipher {
|
|
10
|
+
encrypt(block: Uint8Array): Uint8Array;
|
|
11
|
+
decrypt(block: Uint8Array): Uint8Array;
|
|
12
|
+
dispose(): void;
|
|
13
|
+
}
|
|
14
|
+
export interface Streamcipher {
|
|
15
|
+
encrypt(msg: Uint8Array): Uint8Array;
|
|
16
|
+
decrypt(msg: Uint8Array): Uint8Array;
|
|
17
|
+
dispose(): void;
|
|
18
|
+
}
|
|
19
|
+
export interface AEAD {
|
|
20
|
+
encrypt(msg: Uint8Array, aad?: Uint8Array): Uint8Array;
|
|
21
|
+
/** Decrypt and authenticate. Throws `Error` on authentication failure — never returns null. */
|
|
22
|
+
decrypt(ciphertext: Uint8Array, aad?: Uint8Array): Uint8Array;
|
|
23
|
+
dispose(): void;
|
|
24
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// ▄▄▄▄▄▄▄▄▄▄
|
|
2
|
+
// ▄████████████████████▄▄ ▒ ▄▀▀ ▒ ▒ █ ▄▀▄ ▀█▀ █ ▒ ▄▀▄ █▀▄
|
|
3
|
+
// ▄██████████████████████ ▀████▄ ▓ ▓▀ ▓ ▓ ▓ ▓▄▓ ▓ ▓▀▓ ▓▄▓ ▓ ▓
|
|
4
|
+
// ▄█████████▀▀▀ ▀███████▄▄███████▌ ▀▄ ▀▄▄ ▀▄▀ ▒ ▒ ▒ ▒ ▒ █ ▒ ▒ ▒ █
|
|
5
|
+
// ▐████████▀ ▄▄▄▄ ▀████████▀██▀█▌
|
|
6
|
+
// ████████ ███▀▀ ████▀ █▀ █▀ Leviathan Crypto Library
|
|
7
|
+
// ███████▌ ▀██▀ ███
|
|
8
|
+
// ███████ ▀███ ▀██ ▀█▄ Repository & Mirror:
|
|
9
|
+
// ▀██████ ▄▄██ ▀▀ ██▄ github.com/xero/leviathan-crypto
|
|
10
|
+
// ▀█████▄ ▄██▄ ▄▀▄▀ unpkg.com/leviathan-crypto
|
|
11
|
+
// ▀████▄ ▄██▄
|
|
12
|
+
// ▐████ ▐███ Author: xero (https://x-e.ro)
|
|
13
|
+
// ▄▄██████████ ▐███ ▄▄ License: MIT
|
|
14
|
+
// ▄██▀▀▀▀▀▀▀▀▀▀ ▄████ ▄██▀
|
|
15
|
+
// ▄▀ ▄▄█████████▄▄ ▀▀▀▀▀ ▄███ This file is provided completely
|
|
16
|
+
// ▄██████▀▀▀▀▀▀██████▄ ▀▄▄▄▄████▀ free, "as is", and without
|
|
17
|
+
// ████▀ ▄▄▄▄▄▄▄ ▀████▄ ▀█████▀ ▄▄▄▄ warranty of any kind. The author
|
|
18
|
+
// █████▄▄█████▀▀▀▀▀▀▄ ▀███▄ ▄████ assumes absolutely no liability
|
|
19
|
+
// ▀██████▀ ▀████▄▄▄████▀ for its {ab,mis,}use.
|
|
20
|
+
// ▀█████▀▀
|
|
21
|
+
//
|
|
22
|
+
// src/ts/types.ts
|
|
23
|
+
//
|
|
24
|
+
// Primitive interfaces for leviathan-crypto.
|
|
25
|
+
// No init() dependency — available at import time.
|
|
26
|
+
export {};
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Hex string to Uint8Array. Accepts lowercase/uppercase, optional 0x prefix. */
|
|
2
|
+
export declare const hexToBytes: (hex: string) => Uint8Array;
|
|
3
|
+
/** Uint8Array to lowercase hex string. */
|
|
4
|
+
export declare const bytesToHex: (bytes: Uint8Array) => string;
|
|
5
|
+
/** UTF-8 string to Uint8Array. */
|
|
6
|
+
export declare const utf8ToBytes: (str: string) => Uint8Array;
|
|
7
|
+
/** Uint8Array to UTF-8 string. */
|
|
8
|
+
export declare const bytesToUtf8: (bytes: Uint8Array) => string;
|
|
9
|
+
/** Base64 or base64url string to Uint8Array. Returns undefined on invalid input. */
|
|
10
|
+
export declare const base64ToBytes: (b64: string) => Uint8Array | undefined;
|
|
11
|
+
/** Uint8Array to base64 string. Pass url=true for base64url encoding. */
|
|
12
|
+
export declare const bytesToBase64: (bytes: Uint8Array, url?: boolean) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Constant-time byte-array equality.
|
|
15
|
+
* XOR-accumulate pattern — no early return on mismatch.
|
|
16
|
+
* Length check is not constant-time (length is non-secret in all protocols).
|
|
17
|
+
*/
|
|
18
|
+
export declare const constantTimeEqual: (a: Uint8Array, b: Uint8Array) => boolean;
|
|
19
|
+
/** Zero a typed array in place. */
|
|
20
|
+
export declare const wipe: (data: Uint8Array | Uint16Array | Uint32Array) => void;
|
|
21
|
+
/** XOR two equal-length Uint8Arrays, returns new array. */
|
|
22
|
+
export declare const xor: (a: Uint8Array, b: Uint8Array) => Uint8Array;
|
|
23
|
+
/** Concatenate two Uint8Arrays, returns new array. */
|
|
24
|
+
export declare const concat: (a: Uint8Array, b: Uint8Array) => Uint8Array;
|
|
25
|
+
/** Cryptographically secure random bytes via Web Crypto API. */
|
|
26
|
+
export declare const randomBytes: (n: number) => Uint8Array;
|