leviathan-crypto 2.1.0 → 3.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 +86 -443
- package/README.md +198 -65
- package/dist/aes/aes-cbc.d.ts +40 -0
- package/dist/aes/aes-cbc.js +158 -0
- package/dist/aes/aes-ctr.d.ts +50 -0
- package/dist/aes/aes-ctr.js +141 -0
- package/dist/aes/aes-gcm-siv.d.ts +67 -0
- package/dist/aes/aes-gcm-siv.js +217 -0
- package/dist/aes/aes-gcm.d.ts +61 -0
- package/dist/aes/aes-gcm.js +226 -0
- package/dist/aes/cipher-suite.d.ts +21 -0
- package/dist/aes/cipher-suite.js +179 -0
- package/dist/aes/embedded.d.ts +1 -0
- package/dist/aes/embedded.js +26 -0
- package/dist/aes/generator.d.ts +14 -0
- package/dist/aes/generator.js +103 -0
- package/dist/aes/index.d.ts +58 -0
- package/dist/aes/index.js +125 -0
- package/dist/aes/ops.d.ts +60 -0
- package/dist/aes/ops.js +164 -0
- package/dist/aes/pool-worker.d.ts +1 -0
- package/dist/aes/pool-worker.js +92 -0
- package/dist/aes/types.d.ts +1 -0
- package/dist/aes/types.js +23 -0
- package/dist/aes.wasm +0 -0
- package/dist/blake3/embedded.d.ts +1 -0
- package/dist/blake3/embedded.js +26 -0
- package/dist/blake3/index.d.ts +143 -0
- package/dist/blake3/index.js +620 -0
- package/dist/blake3/types.d.ts +102 -0
- package/dist/blake3/types.js +31 -0
- package/dist/blake3/validate.d.ts +29 -0
- package/dist/blake3/validate.js +80 -0
- package/dist/blake3.wasm +0 -0
- package/dist/chacha20/cipher-suite.js +47 -25
- package/dist/chacha20/generator.d.ts +2 -2
- package/dist/chacha20/generator.js +4 -4
- package/dist/chacha20/index.d.ts +16 -15
- package/dist/chacha20/index.js +52 -46
- package/dist/chacha20/ops.d.ts +7 -7
- package/dist/chacha20/ops.js +34 -34
- package/dist/chacha20/pool-worker.js +5 -3
- package/dist/cte-wasm.d.ts +1 -0
- package/dist/cte-wasm.js +3 -0
- package/dist/curve25519.wasm +0 -0
- package/dist/ecdsa/der.d.ts +23 -0
- package/dist/ecdsa/der.js +192 -0
- package/dist/ecdsa/ecprivatekey-der.d.ts +32 -0
- package/dist/ecdsa/ecprivatekey-der.js +230 -0
- package/dist/ecdsa/embedded.d.ts +1 -0
- package/dist/ecdsa/embedded.js +25 -0
- package/dist/ecdsa/index.d.ts +124 -0
- package/dist/ecdsa/index.js +366 -0
- package/dist/ecdsa/types.d.ts +31 -0
- package/dist/ecdsa/types.js +28 -0
- package/dist/ecdsa/validate.d.ts +18 -0
- package/dist/ecdsa/validate.js +92 -0
- package/dist/ed25519/embedded.d.ts +1 -0
- package/dist/ed25519/embedded.js +31 -0
- package/dist/ed25519/index.d.ts +70 -0
- package/dist/ed25519/index.js +308 -0
- package/dist/ed25519/types.d.ts +27 -0
- package/dist/ed25519/types.js +27 -0
- package/dist/ed25519/validate.d.ts +7 -0
- package/dist/ed25519/validate.js +77 -0
- package/dist/embedded/aes-pool-worker.d.ts +1 -0
- package/dist/embedded/aes-pool-worker.js +5 -0
- package/dist/embedded/aes.d.ts +1 -0
- package/dist/embedded/aes.js +3 -0
- package/dist/embedded/blake3.d.ts +1 -0
- package/dist/embedded/blake3.js +3 -0
- package/dist/embedded/chacha20-pool-worker.d.ts +1 -1
- package/dist/embedded/chacha20-pool-worker.js +2 -2
- package/dist/embedded/chacha20.d.ts +1 -1
- package/dist/embedded/chacha20.js +2 -2
- package/dist/embedded/curve25519.d.ts +1 -0
- package/dist/embedded/curve25519.js +3 -0
- package/dist/embedded/mldsa.d.ts +1 -0
- package/dist/embedded/mldsa.js +3 -0
- package/dist/embedded/mlkem.d.ts +1 -0
- package/dist/embedded/mlkem.js +3 -0
- package/dist/embedded/p256.d.ts +1 -0
- package/dist/embedded/p256.js +3 -0
- package/dist/embedded/serpent-pool-worker.d.ts +1 -1
- package/dist/embedded/serpent-pool-worker.js +2 -2
- package/dist/embedded/serpent.d.ts +1 -1
- package/dist/embedded/serpent.js +2 -2
- package/dist/embedded/sha2.d.ts +1 -1
- package/dist/embedded/sha2.js +2 -2
- package/dist/embedded/sha3.d.ts +1 -1
- package/dist/embedded/sha3.js +2 -2
- package/dist/embedded/slhdsa.d.ts +1 -0
- package/dist/embedded/slhdsa.js +3 -0
- package/dist/errors.d.ts +92 -1
- package/dist/errors.js +111 -1
- package/dist/fortuna.d.ts +5 -5
- package/dist/fortuna.js +37 -64
- package/dist/index.d.ts +38 -9
- package/dist/index.js +63 -19
- package/dist/init.d.ts +1 -1
- package/dist/init.js +11 -25
- package/dist/keccak/embedded.js +1 -1
- package/dist/keccak/index.d.ts +2 -0
- package/dist/keccak/index.js +4 -2
- package/dist/loader.d.ts +1 -24
- package/dist/loader.js +13 -16
- package/dist/merkle/blake3-tree.d.ts +35 -0
- package/dist/merkle/blake3-tree.js +187 -0
- package/dist/merkle/checkpoint.d.ts +58 -0
- package/dist/merkle/checkpoint.js +217 -0
- package/dist/merkle/index.d.ts +19 -0
- package/dist/merkle/index.js +37 -0
- package/dist/merkle/merkle-log.d.ts +130 -0
- package/dist/merkle/merkle-log.js +207 -0
- package/dist/merkle/merkle-verifier.d.ts +126 -0
- package/dist/merkle/merkle-verifier.js +296 -0
- package/dist/merkle/proof.d.ts +70 -0
- package/dist/merkle/proof.js +300 -0
- package/dist/merkle/sha256-tree.d.ts +33 -0
- package/dist/merkle/sha256-tree.js +145 -0
- package/dist/merkle/signed-log.d.ts +156 -0
- package/dist/merkle/signed-log.js +356 -0
- package/dist/merkle/signed-note.d.ts +309 -0
- package/dist/merkle/signed-note.js +648 -0
- package/dist/merkle/sth.d.ts +31 -0
- package/dist/merkle/sth.js +31 -0
- package/dist/merkle/storage.d.ts +40 -0
- package/dist/merkle/storage.js +71 -0
- package/dist/merkle/tree.d.ts +68 -0
- package/dist/merkle/tree.js +94 -0
- package/dist/mldsa/embedded.d.ts +1 -0
- package/dist/{kyber → mldsa}/embedded.js +5 -5
- package/dist/mldsa/expand.d.ts +53 -0
- package/dist/mldsa/expand.js +188 -0
- package/dist/mldsa/format.d.ts +16 -0
- package/dist/mldsa/format.js +68 -0
- package/dist/mldsa/hashvariant.d.ts +32 -0
- package/dist/mldsa/hashvariant.js +248 -0
- package/dist/mldsa/index.d.ts +142 -0
- package/dist/mldsa/index.js +463 -0
- package/dist/mldsa/keygen.d.ts +16 -0
- package/dist/mldsa/keygen.js +232 -0
- package/dist/mldsa/params.d.ts +21 -0
- package/dist/mldsa/params.js +55 -0
- package/dist/mldsa/sha3-helpers.d.ts +30 -0
- package/dist/mldsa/sha3-helpers.js +124 -0
- package/dist/mldsa/sign.d.ts +36 -0
- package/dist/mldsa/sign.js +380 -0
- package/dist/mldsa/types.d.ts +91 -0
- package/dist/mldsa/types.js +25 -0
- package/dist/mldsa/validate.d.ts +55 -0
- package/dist/mldsa/validate.js +125 -0
- package/dist/mldsa/verify.d.ts +29 -0
- package/dist/mldsa/verify.js +269 -0
- package/dist/mldsa.wasm +0 -0
- package/dist/mlkem/embedded.d.ts +1 -0
- package/dist/mlkem/embedded.js +27 -0
- package/dist/mlkem/indcpa.d.ts +49 -0
- package/dist/{kyber → mlkem}/indcpa.js +44 -44
- package/dist/mlkem/index.d.ts +37 -0
- package/dist/{kyber → mlkem}/index.js +24 -34
- package/dist/mlkem/kem.d.ts +21 -0
- package/dist/{kyber → mlkem}/kem.js +44 -64
- package/dist/{kyber → mlkem}/params.d.ts +4 -4
- package/dist/{kyber → mlkem}/params.js +2 -2
- package/dist/mlkem/suite.d.ts +12 -0
- package/dist/{kyber → mlkem}/suite.js +17 -12
- package/dist/{kyber → mlkem}/types.d.ts +3 -3
- package/dist/{kyber → mlkem}/types.js +1 -1
- package/dist/{kyber → mlkem}/validate.d.ts +7 -7
- package/dist/{kyber → mlkem}/validate.js +7 -7
- package/dist/{kyber.wasm → mlkem.wasm} +0 -0
- package/dist/p256.wasm +0 -0
- package/dist/ratchet/index.d.ts +2 -0
- package/dist/ratchet/index.js +1 -0
- package/dist/ratchet/kdf-chain.js +3 -3
- package/dist/ratchet/ratchet-keypair.js +2 -2
- package/dist/ratchet/root-kdf.js +7 -7
- package/dist/ratchet/skipped-key-store.js +4 -4
- package/dist/ratchet/types.d.ts +1 -1
- package/dist/serpent/cipher-suite.js +20 -17
- package/dist/serpent/generator.d.ts +1 -1
- package/dist/serpent/generator.js +2 -2
- package/dist/serpent/index.d.ts +8 -7
- package/dist/serpent/index.js +18 -27
- package/dist/serpent/pool-worker.js +7 -5
- package/dist/serpent/serpent-cbc.d.ts +4 -4
- package/dist/serpent/serpent-cbc.js +11 -8
- package/dist/serpent/shared-ops.d.ts +3 -23
- package/dist/serpent/shared-ops.js +50 -85
- package/dist/serpent.wasm +0 -0
- package/dist/sha2/hkdf.js +5 -5
- package/dist/sha2/index.d.ts +21 -1
- package/dist/sha2/index.js +65 -10
- package/dist/sha2/types.d.ts +41 -2
- package/dist/sha2.wasm +0 -0
- package/dist/sha3/index.d.ts +72 -3
- package/dist/sha3/index.js +240 -14
- package/dist/sha3/kmac.d.ts +121 -0
- package/dist/sha3/kmac.js +800 -0
- package/dist/sha3.wasm +0 -0
- package/dist/shared/pkcs7.d.ts +22 -0
- package/dist/shared/pkcs7.js +84 -0
- package/dist/sign/ctx.d.ts +41 -0
- package/dist/sign/ctx.js +102 -0
- package/dist/sign/envelope.d.ts +45 -0
- package/dist/sign/envelope.js +152 -0
- package/dist/sign/hasher.d.ts +9 -0
- package/dist/sign/hasher.js +132 -0
- package/dist/sign/index.d.ts +11 -0
- package/dist/sign/index.js +34 -0
- package/dist/sign/sign-stream.d.ts +25 -0
- package/dist/sign/sign-stream.js +112 -0
- package/dist/sign/suites/ecdsa-p256.d.ts +2 -0
- package/dist/sign/suites/ecdsa-p256.js +120 -0
- package/dist/sign/suites/ed25519.d.ts +3 -0
- package/dist/sign/suites/ed25519.js +165 -0
- package/dist/sign/suites/hybrid-classical.d.ts +23 -0
- package/dist/sign/suites/hybrid-classical.js +526 -0
- package/dist/sign/suites/hybrid-pq.d.ts +4 -0
- package/dist/sign/suites/hybrid-pq.js +234 -0
- package/dist/sign/suites/mldsa.d.ts +7 -0
- package/dist/sign/suites/mldsa.js +161 -0
- package/dist/sign/suites/slhdsa.d.ts +7 -0
- package/dist/sign/suites/slhdsa.js +176 -0
- package/dist/sign/types.d.ts +106 -0
- package/dist/sign/types.js +28 -0
- package/dist/sign/verify-stream.d.ts +30 -0
- package/dist/sign/verify-stream.js +227 -0
- package/dist/slhdsa/embedded.d.ts +1 -0
- package/dist/slhdsa/embedded.js +26 -0
- package/dist/slhdsa/index.d.ts +149 -0
- package/dist/slhdsa/index.js +493 -0
- package/dist/slhdsa/params.d.ts +26 -0
- package/dist/slhdsa/params.js +70 -0
- package/dist/slhdsa/prehash.d.ts +68 -0
- package/dist/slhdsa/prehash.js +307 -0
- package/dist/slhdsa/sign.d.ts +39 -0
- package/dist/slhdsa/sign.js +116 -0
- package/dist/slhdsa/types.d.ts +129 -0
- package/dist/slhdsa/types.js +27 -0
- package/dist/slhdsa/validate.d.ts +60 -0
- package/dist/slhdsa/validate.js +127 -0
- package/dist/slhdsa/verify.d.ts +32 -0
- package/dist/slhdsa/verify.js +107 -0
- package/dist/slhdsa.wasm +0 -0
- package/dist/stream/header.js +3 -3
- package/dist/stream/index.d.ts +1 -0
- package/dist/stream/index.js +1 -0
- package/dist/stream/open-stream.js +31 -10
- package/dist/stream/seal-stream-pool.d.ts +1 -0
- package/dist/stream/seal-stream-pool.js +63 -26
- package/dist/stream/seal-stream.d.ts +1 -1
- package/dist/stream/seal-stream.js +20 -9
- package/dist/stream/seal.js +6 -6
- package/dist/stream/types.d.ts +3 -1
- package/dist/stream/types.js +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utils.d.ts +3 -3
- package/dist/utils.js +46 -54
- package/dist/wasm-source.d.ts +7 -7
- package/dist/wasm-source.js +1 -1
- package/dist/x25519/embedded.d.ts +1 -0
- package/dist/x25519/embedded.js +31 -0
- package/dist/x25519/index.d.ts +43 -0
- package/dist/x25519/index.js +159 -0
- package/dist/x25519/types.d.ts +25 -0
- package/dist/x25519/types.js +27 -0
- package/dist/x25519/validate.d.ts +2 -0
- package/dist/x25519/validate.js +39 -0
- package/package.json +70 -26
- package/SECURITY.md +0 -163
- package/dist/ct-wasm.d.ts +0 -1
- package/dist/ct-wasm.js +0 -3
- package/dist/docs/aead.md +0 -363
- package/dist/docs/architecture.md +0 -1011
- package/dist/docs/argon2id.md +0 -305
- package/dist/docs/chacha20.md +0 -781
- package/dist/docs/exports.md +0 -277
- package/dist/docs/fortuna.md +0 -530
- package/dist/docs/init.md +0 -301
- package/dist/docs/loader.md +0 -256
- package/dist/docs/serpent.md +0 -617
- package/dist/docs/sha2.md +0 -671
- package/dist/docs/sha3.md +0 -612
- package/dist/docs/types.md +0 -416
- package/dist/docs/utils.md +0 -457
- package/dist/embedded/kyber.d.ts +0 -1
- package/dist/embedded/kyber.js +0 -3
- package/dist/kyber/embedded.d.ts +0 -1
- package/dist/kyber/indcpa.d.ts +0 -49
- package/dist/kyber/index.d.ts +0 -38
- package/dist/kyber/kem.d.ts +0 -21
- package/dist/kyber/suite.d.ts +0 -12
- /package/dist/{ct.wasm → cte.wasm} +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
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/x25519/embedded.ts
|
|
23
|
+
//
|
|
24
|
+
// Exports the gzip+base64 curve25519 WASM blob for use as a WasmSource.
|
|
25
|
+
// Ed25519 and X25519 share the same curve25519 WASM binary; both the
|
|
26
|
+
// `leviathan-crypto/ed25519/embedded` and `leviathan-crypto/x25519/embedded`
|
|
27
|
+
// subpaths re-export the same blob under three names: `curve25519Wasm`
|
|
28
|
+
// (canonical), `ed25519Wasm`, and `x25519Wasm` (aliases that read more
|
|
29
|
+
// naturally in the matching subpath context). All three resolve to the
|
|
30
|
+
// identical underlying string; tree-shaking is unaffected.
|
|
31
|
+
export { WASM_GZ_BASE64 as curve25519Wasm, WASM_GZ_BASE64 as x25519Wasm, } from '../embedded/curve25519.js';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { isInitialized } from '../init.js';
|
|
2
|
+
import type { WasmSource } from '../wasm-source.js';
|
|
3
|
+
import type { X25519KeyPair } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Initialise the curve25519 WASM module under the `x25519` alias.
|
|
6
|
+
* Equivalent to `ed25519Init(source)`; both target the same WASM module
|
|
7
|
+
* and the init layer de-dupes when given identical sources.
|
|
8
|
+
*/
|
|
9
|
+
export declare function x25519Init(source: WasmSource): Promise<void>;
|
|
10
|
+
export type { WasmSource };
|
|
11
|
+
export type { X25519KeyPair, X25519Exports } from './types.js';
|
|
12
|
+
export { isInitialized };
|
|
13
|
+
export declare class X25519 {
|
|
14
|
+
constructor();
|
|
15
|
+
private get mx();
|
|
16
|
+
/**
|
|
17
|
+
* Deterministic X25519 key generation from a 32-byte secret per
|
|
18
|
+
* RFC 7748 §6. Clamping is applied internally on every WASM call;
|
|
19
|
+
* the returned secretKey is a fresh copy of the supplied sk bytes
|
|
20
|
+
* (NOT pre-clamped).
|
|
21
|
+
*/
|
|
22
|
+
keygenDerand(sk: Uint8Array): X25519KeyPair;
|
|
23
|
+
/** Random X25519 key generation, wraps `keygenDerand` with `randomBytes(32)`. */
|
|
24
|
+
keygen(): X25519KeyPair;
|
|
25
|
+
/**
|
|
26
|
+
* X25519 Diffie-Hellman, RFC 7748 §6.
|
|
27
|
+
*
|
|
28
|
+
* Computes the shared u-coordinate from the local secret and the
|
|
29
|
+
* peer's public key. If the resulting shared secret is all-zero
|
|
30
|
+
* (peer public key is a small-order point per RFC 7748 §7), throws
|
|
31
|
+
* `KeyAgreementError` rather than returning the degenerate value.
|
|
32
|
+
* The all-zero scan accumulates via OR across all 32 output bytes
|
|
33
|
+
* before comparing to zero, so the success path is constant-time;
|
|
34
|
+
* the throw branches off only after a known-bad outcome is observed.
|
|
35
|
+
*
|
|
36
|
+
* @param sk 32-byte local secret (NOT pre-clamped, clamped internally)
|
|
37
|
+
* @param peerPk 32-byte peer public key (u-coordinate)
|
|
38
|
+
* @returns 32-byte shared u-coordinate
|
|
39
|
+
* @throws KeyAgreementError on all-zero shared secret
|
|
40
|
+
*/
|
|
41
|
+
dh(sk: Uint8Array, peerPk: Uint8Array): Uint8Array;
|
|
42
|
+
dispose(): void;
|
|
43
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
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/x25519/index.ts
|
|
23
|
+
//
|
|
24
|
+
// X25519 public API. RFC 7748 §5 (algorithm), §6 (keygen + DH), §7
|
|
25
|
+
// (security considerations and the small-order peer-pk rejection that
|
|
26
|
+
// motivates the TS-layer all-zero shared-secret check).
|
|
27
|
+
//
|
|
28
|
+
// Both Ed25519 and X25519 share the curve25519 WASM module;
|
|
29
|
+
// `ed25519Init(source)` and `x25519Init(source)` both target it and the
|
|
30
|
+
// init() layer de-dupes when given identical sources.
|
|
31
|
+
//
|
|
32
|
+
// Per-call lifecycle mirrors the Ed25519 wrapper: stage caller inputs
|
|
33
|
+
// at fixed offsets above the WASM mutable buffer region, call the
|
|
34
|
+
// underlying export, copy outputs to fresh `Uint8Array`s, wipe both
|
|
35
|
+
// the WASM-internal scratch and the TS-side I/O staging region.
|
|
36
|
+
import { getInstance, initModule, isInitialized, _assertNotOwned } from '../init.js';
|
|
37
|
+
import { randomBytes, wipe } from '../utils.js';
|
|
38
|
+
import { KeyAgreementError } from '../errors.js';
|
|
39
|
+
import { validateSecretKey, validatePublicKey } from './validate.js';
|
|
40
|
+
/**
|
|
41
|
+
* Initialise the curve25519 WASM module under the `x25519` alias.
|
|
42
|
+
* Equivalent to `ed25519Init(source)`; both target the same WASM module
|
|
43
|
+
* and the init layer de-dupes when given identical sources.
|
|
44
|
+
*/
|
|
45
|
+
export async function x25519Init(source) {
|
|
46
|
+
return initModule('curve25519', source);
|
|
47
|
+
}
|
|
48
|
+
export { isInitialized };
|
|
49
|
+
// ── I/O staging layout ─────────────────────────────────────────────────────
|
|
50
|
+
//
|
|
51
|
+
// Same base as the ed25519 wrapper, fixed offsets above the WASM mutable
|
|
52
|
+
// buffer region (BUFFER_END = 7836). Two 32-byte input slots plus one
|
|
53
|
+
// 32-byte output slot, no large variable region.
|
|
54
|
+
const IO_BASE = 8192;
|
|
55
|
+
const SK_STAGE = IO_BASE; // 32 bytes
|
|
56
|
+
const PK_STAGE = IO_BASE + 32; // 32 bytes
|
|
57
|
+
const PEER_STAGE = IO_BASE + 64; // 32 bytes
|
|
58
|
+
const SHARED_STAGE = IO_BASE + 96; // 32 bytes
|
|
59
|
+
function ioWipe(mx) {
|
|
60
|
+
// Zero the entire TS-managed staging region. wipeBuffers covers
|
|
61
|
+
// MUTABLE_START..BUFFER_END only; the I/O slots above must be
|
|
62
|
+
// scrubbed at the wrapper layer.
|
|
63
|
+
new Uint8Array(mx.memory.buffer).fill(0, IO_BASE, mx.memory.buffer.byteLength);
|
|
64
|
+
}
|
|
65
|
+
export class X25519 {
|
|
66
|
+
constructor() {
|
|
67
|
+
if (!isInitialized('curve25519'))
|
|
68
|
+
throw new Error('leviathan-crypto: call init({ x25519: ... }) before using X25519');
|
|
69
|
+
}
|
|
70
|
+
get mx() {
|
|
71
|
+
return getInstance('curve25519').exports;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Deterministic X25519 key generation from a 32-byte secret per
|
|
75
|
+
* RFC 7748 §6. Clamping is applied internally on every WASM call;
|
|
76
|
+
* the returned secretKey is a fresh copy of the supplied sk bytes
|
|
77
|
+
* (NOT pre-clamped).
|
|
78
|
+
*/
|
|
79
|
+
keygenDerand(sk) {
|
|
80
|
+
_assertNotOwned('curve25519');
|
|
81
|
+
validateSecretKey(sk);
|
|
82
|
+
const mx = this.mx;
|
|
83
|
+
const mem = new Uint8Array(mx.memory.buffer);
|
|
84
|
+
mem.set(sk, SK_STAGE);
|
|
85
|
+
try {
|
|
86
|
+
mx.x25519Keygen(SK_STAGE, PK_STAGE);
|
|
87
|
+
const publicKey = mem.slice(PK_STAGE, PK_STAGE + 32);
|
|
88
|
+
const secretKey = new Uint8Array(32);
|
|
89
|
+
secretKey.set(sk);
|
|
90
|
+
return { publicKey, secretKey };
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
ioWipe(mx);
|
|
94
|
+
mx.wipeBuffers();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/** Random X25519 key generation, wraps `keygenDerand` with `randomBytes(32)`. */
|
|
98
|
+
keygen() {
|
|
99
|
+
const sk = randomBytes(32);
|
|
100
|
+
try {
|
|
101
|
+
return this.keygenDerand(sk);
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
wipe(sk);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* X25519 Diffie-Hellman, RFC 7748 §6.
|
|
109
|
+
*
|
|
110
|
+
* Computes the shared u-coordinate from the local secret and the
|
|
111
|
+
* peer's public key. If the resulting shared secret is all-zero
|
|
112
|
+
* (peer public key is a small-order point per RFC 7748 §7), throws
|
|
113
|
+
* `KeyAgreementError` rather than returning the degenerate value.
|
|
114
|
+
* The all-zero scan accumulates via OR across all 32 output bytes
|
|
115
|
+
* before comparing to zero, so the success path is constant-time;
|
|
116
|
+
* the throw branches off only after a known-bad outcome is observed.
|
|
117
|
+
*
|
|
118
|
+
* @param sk 32-byte local secret (NOT pre-clamped, clamped internally)
|
|
119
|
+
* @param peerPk 32-byte peer public key (u-coordinate)
|
|
120
|
+
* @returns 32-byte shared u-coordinate
|
|
121
|
+
* @throws KeyAgreementError on all-zero shared secret
|
|
122
|
+
*/
|
|
123
|
+
dh(sk, peerPk) {
|
|
124
|
+
_assertNotOwned('curve25519');
|
|
125
|
+
validateSecretKey(sk);
|
|
126
|
+
validatePublicKey(peerPk);
|
|
127
|
+
const mx = this.mx;
|
|
128
|
+
const mem = new Uint8Array(mx.memory.buffer);
|
|
129
|
+
mem.set(sk, SK_STAGE);
|
|
130
|
+
mem.set(peerPk, PEER_STAGE);
|
|
131
|
+
try {
|
|
132
|
+
mx.x25519DH(SK_STAGE, PEER_STAGE, SHARED_STAGE);
|
|
133
|
+
const shared = mem.slice(SHARED_STAGE, SHARED_STAGE + 32);
|
|
134
|
+
// Constant-time OR-accumulate scan, RFC 7748 §6.1
|
|
135
|
+
// contributory-behaviour requirement. No early exit on the
|
|
136
|
+
// first non-zero byte.
|
|
137
|
+
let acc = 0;
|
|
138
|
+
for (let i = 0; i < 32; i++)
|
|
139
|
+
acc |= shared[i];
|
|
140
|
+
if (acc === 0) {
|
|
141
|
+
wipe(shared);
|
|
142
|
+
throw new KeyAgreementError('leviathan-crypto: X25519 shared secret is all-zero '
|
|
143
|
+
+ '(peer public key is a small-order point)');
|
|
144
|
+
}
|
|
145
|
+
return shared;
|
|
146
|
+
}
|
|
147
|
+
finally {
|
|
148
|
+
ioWipe(mx);
|
|
149
|
+
mx.wipeBuffers();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
dispose() {
|
|
153
|
+
try {
|
|
154
|
+
this.mx.wipeBuffers();
|
|
155
|
+
ioWipe(this.mx);
|
|
156
|
+
}
|
|
157
|
+
catch { /* idempotent */ }
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface X25519KeyPair {
|
|
2
|
+
/** 32-byte public u-coordinate. */
|
|
3
|
+
publicKey: Uint8Array;
|
|
4
|
+
/**
|
|
5
|
+
* 32-byte secret. Per RFC 7748 §5 / §6 this is "any 32 random bytes";
|
|
6
|
+
* clamping is applied internally on every WASM call. The stored
|
|
7
|
+
* secretKey is the unclamped form so that round-tripping through
|
|
8
|
+
* keygen / external storage preserves byte-equality.
|
|
9
|
+
*/
|
|
10
|
+
secretKey: Uint8Array;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The X25519-relevant subset of the curve25519 WASM exports. The
|
|
14
|
+
* curve25519 module is shared between Ed25519 and X25519; this interface
|
|
15
|
+
* deliberately surfaces only the X25519 high-level entry points plus the
|
|
16
|
+
* layout / wipe primitives.
|
|
17
|
+
*/
|
|
18
|
+
export interface X25519Exports {
|
|
19
|
+
memory: WebAssembly.Memory;
|
|
20
|
+
getModuleId: () => number;
|
|
21
|
+
getMemoryPages: () => number;
|
|
22
|
+
x25519Keygen: (skOff: number, pkOff: number) => void;
|
|
23
|
+
x25519DH: (skOff: number, peerPkOff: number, sharedOff: number) => void;
|
|
24
|
+
wipeBuffers: () => void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
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/x25519/types.ts
|
|
23
|
+
//
|
|
24
|
+
// X25519 type surface: the WASM export interface for the curve25519
|
|
25
|
+
// module (X25519-relevant subset) and the public key-pair shape returned
|
|
26
|
+
// by keygen / keygenDerand. RFC 7748 §5 / §6.
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
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/x25519/validate.ts
|
|
23
|
+
//
|
|
24
|
+
// X25519 caller-side input validation. Pure length / type checks. Peer
|
|
25
|
+
// public-key masking happens inside the WASM (feFromBytes masks bit 255
|
|
26
|
+
// per RFC 7748 §5); the all-zero shared-secret rejection happens in the
|
|
27
|
+
// TS X25519.dh method after the WASM returns.
|
|
28
|
+
export function validateSecretKey(sk) {
|
|
29
|
+
if (!(sk instanceof Uint8Array))
|
|
30
|
+
throw new TypeError('leviathan-crypto: x25519 secret key must be a Uint8Array');
|
|
31
|
+
if (sk.length !== 32)
|
|
32
|
+
throw new RangeError(`leviathan-crypto: x25519 secret key must be 32 bytes (got ${sk.length})`);
|
|
33
|
+
}
|
|
34
|
+
export function validatePublicKey(pk) {
|
|
35
|
+
if (!(pk instanceof Uint8Array))
|
|
36
|
+
throw new TypeError('leviathan-crypto: x25519 public key must be a Uint8Array');
|
|
37
|
+
if (pk.length !== 32)
|
|
38
|
+
throw new RangeError(`leviathan-crypto: x25519 public key must be 32 bytes (got ${pk.length})`);
|
|
39
|
+
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leviathan-crypto",
|
|
3
|
-
"version": "
|
|
4
|
-
"author": "xero (https://x-e.ro)",
|
|
3
|
+
"version": "3.0.0",
|
|
5
4
|
"license": "MIT",
|
|
6
|
-
"description": "
|
|
5
|
+
"description": "Paranoid post-quantum WASM cryptography library with bitsliced ciphers (Serpent, XChaCha20, AES), ML-KEM, lattice and hash-based signatures (ML-DSA, SLH-DSA, hybrid composites), hashing (SHA-2, SHA-3, BLAKE3), forward-secret ratchet, and Fortuna CSPRNG. Zero dependencies, tree-shakeable, and side-effect-free.",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/xero/leviathan-crypto.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/xero/leviathan-crypto/issues"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://leviathan.3xi.club",
|
|
14
|
+
"author": "xero (https://x-e.ro)",
|
|
7
15
|
"type": "module",
|
|
8
16
|
"sideEffects": false,
|
|
9
17
|
"exports": {
|
|
@@ -19,24 +27,31 @@
|
|
|
19
27
|
"./sha3/embedded": "./dist/sha3/embedded.js",
|
|
20
28
|
"./keccak": "./dist/keccak/index.js",
|
|
21
29
|
"./keccak/embedded": "./dist/keccak/embedded.js",
|
|
22
|
-
"./
|
|
23
|
-
"./
|
|
24
|
-
"./
|
|
30
|
+
"./mlkem": "./dist/mlkem/index.js",
|
|
31
|
+
"./mlkem/embedded": "./dist/mlkem/embedded.js",
|
|
32
|
+
"./aes": "./dist/aes/index.js",
|
|
33
|
+
"./aes/embedded": "./dist/aes/embedded.js",
|
|
34
|
+
"./blake3": "./dist/blake3/index.js",
|
|
35
|
+
"./blake3/embedded": "./dist/blake3/embedded.js",
|
|
36
|
+
"./ecdsa": "./dist/ecdsa/index.js",
|
|
37
|
+
"./ecdsa/embedded": "./dist/ecdsa/embedded.js",
|
|
38
|
+
"./ed25519": "./dist/ed25519/index.js",
|
|
39
|
+
"./ed25519/embedded": "./dist/ed25519/embedded.js",
|
|
40
|
+
"./mldsa": "./dist/mldsa/index.js",
|
|
41
|
+
"./mldsa/embedded": "./dist/mldsa/embedded.js",
|
|
42
|
+
"./slhdsa": "./dist/slhdsa/index.js",
|
|
43
|
+
"./slhdsa/embedded": "./dist/slhdsa/embedded.js",
|
|
44
|
+
"./x25519": "./dist/x25519/index.js",
|
|
45
|
+
"./x25519/embedded": "./dist/x25519/embedded.js",
|
|
46
|
+
"./ratchet": "./dist/ratchet/index.js",
|
|
47
|
+
"./sign": "./dist/sign/index.js",
|
|
48
|
+
"./merkle": "./dist/merkle/index.js"
|
|
25
49
|
},
|
|
26
50
|
"types": "./dist/index.d.ts",
|
|
27
51
|
"files": [
|
|
28
52
|
"dist",
|
|
29
|
-
"SECURITY.md",
|
|
30
53
|
"CLAUDE.md"
|
|
31
54
|
],
|
|
32
|
-
"repository": {
|
|
33
|
-
"type": "git",
|
|
34
|
-
"url": "git+https://github.com/xero/leviathan-crypto.git"
|
|
35
|
-
},
|
|
36
|
-
"homepage": "https://leviathan.3xi.club",
|
|
37
|
-
"bugs": {
|
|
38
|
-
"url": "https://github.com/xero/leviathan-crypto/issues"
|
|
39
|
-
},
|
|
40
55
|
"keywords": [
|
|
41
56
|
"cryptography",
|
|
42
57
|
"encryption",
|
|
@@ -44,38 +59,67 @@
|
|
|
44
59
|
"typescript",
|
|
45
60
|
"wasm",
|
|
46
61
|
"webassembly",
|
|
62
|
+
"simd",
|
|
63
|
+
"isomorphic",
|
|
47
64
|
"zero-dependency",
|
|
48
65
|
"constant-time",
|
|
66
|
+
"bitsliced",
|
|
49
67
|
"side-channel",
|
|
68
|
+
"post-quantum",
|
|
69
|
+
"pqc",
|
|
70
|
+
"hybrid",
|
|
71
|
+
"aead",
|
|
72
|
+
"kem",
|
|
73
|
+
"key-encapsulation",
|
|
74
|
+
"signing",
|
|
75
|
+
"signature",
|
|
76
|
+
"hashing",
|
|
77
|
+
"cipher",
|
|
50
78
|
"serpent",
|
|
51
79
|
"serpent-256",
|
|
52
|
-
"cipher",
|
|
53
|
-
"aead",
|
|
54
80
|
"chacha20",
|
|
55
81
|
"xchacha20",
|
|
56
82
|
"poly1305",
|
|
57
83
|
"xchacha20-poly1305",
|
|
84
|
+
"aes",
|
|
85
|
+
"aes-256",
|
|
86
|
+
"aes-gcm-siv",
|
|
58
87
|
"kyber",
|
|
59
88
|
"ml-kem",
|
|
60
89
|
"mlkem",
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
90
|
+
"ml-dsa",
|
|
91
|
+
"mldsa",
|
|
92
|
+
"slh-dsa",
|
|
93
|
+
"slhdsa",
|
|
94
|
+
"ed25519",
|
|
95
|
+
"x25519",
|
|
96
|
+
"ecdsa",
|
|
97
|
+
"ecdsa-p256",
|
|
98
|
+
"p256",
|
|
99
|
+
"prime256v1",
|
|
100
|
+
"secp256r1",
|
|
69
101
|
"sha",
|
|
70
102
|
"sha-256",
|
|
71
103
|
"sha-512",
|
|
72
104
|
"sha-3",
|
|
73
105
|
"keccak",
|
|
74
106
|
"shake",
|
|
107
|
+
"cshake",
|
|
108
|
+
"blake3",
|
|
75
109
|
"hmac",
|
|
110
|
+
"kmac",
|
|
76
111
|
"hkdf",
|
|
112
|
+
"argon2",
|
|
113
|
+
"argon2id",
|
|
77
114
|
"fortuna",
|
|
78
115
|
"csprng",
|
|
79
|
-
"entropy"
|
|
116
|
+
"entropy",
|
|
117
|
+
"double-ratchet",
|
|
118
|
+
"ratchet",
|
|
119
|
+
"forward-secrecy",
|
|
120
|
+
"spqr",
|
|
121
|
+
"merkle",
|
|
122
|
+
"merkle-tree",
|
|
123
|
+
"transparency-log"
|
|
80
124
|
]
|
|
81
125
|
}
|