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,25 @@
|
|
|
1
|
+
import type { StreamableSignatureSuite } from './types.js';
|
|
2
|
+
export declare class SignStream {
|
|
3
|
+
private readonly suite;
|
|
4
|
+
private readonly sk;
|
|
5
|
+
private readonly ctx;
|
|
6
|
+
private hasher;
|
|
7
|
+
private finalized;
|
|
8
|
+
private disposed;
|
|
9
|
+
constructor(suite: StreamableSignatureSuite, sk: Uint8Array, ctx: Uint8Array);
|
|
10
|
+
/**
|
|
11
|
+
* Build the wire-format preamble for `payloadLength`. Available at
|
|
12
|
+
* any point in the stream lifecycle. See
|
|
13
|
+
* docs/signing.md#attached-envelope.
|
|
14
|
+
*/
|
|
15
|
+
buildPreamble(payloadLength: number): Uint8Array;
|
|
16
|
+
/** Feed a chunk to the running prehash. */
|
|
17
|
+
update(chunk: Uint8Array): void;
|
|
18
|
+
/**
|
|
19
|
+
* Finalize the running prehash and sign. Returns the signature bytes.
|
|
20
|
+
* Caller writes these as the last segment of the output stream.
|
|
21
|
+
*/
|
|
22
|
+
finalize(): Uint8Array;
|
|
23
|
+
/** Wipe lib-owned state. Idempotent. */
|
|
24
|
+
dispose(): void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
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/sign/sign-stream.ts
|
|
23
|
+
//
|
|
24
|
+
// SignStream class, streaming signature production for StreamableSignatureSuite.
|
|
25
|
+
// Sender writes: preamble + payload bytes + sig (from finalize). Wire format
|
|
26
|
+
// is identical to Sign.sign output.
|
|
27
|
+
import { SigningError } from '../errors.js';
|
|
28
|
+
import { wipe } from '../utils.js';
|
|
29
|
+
import { USER_CTX_MAX } from './ctx.js';
|
|
30
|
+
import { createRunningHash } from './hasher.js';
|
|
31
|
+
export class SignStream {
|
|
32
|
+
suite;
|
|
33
|
+
sk;
|
|
34
|
+
ctx;
|
|
35
|
+
hasher;
|
|
36
|
+
finalized = false;
|
|
37
|
+
disposed = false;
|
|
38
|
+
constructor(suite, sk, ctx) {
|
|
39
|
+
this.suite = suite;
|
|
40
|
+
this.sk = sk;
|
|
41
|
+
if (ctx.length > USER_CTX_MAX)
|
|
42
|
+
throw new SigningError('sig-ctx-too-long', `user_ctx length ${ctx.length} > ${USER_CTX_MAX}`);
|
|
43
|
+
// Copy ctx so a later caller-side mutation cannot retroactively
|
|
44
|
+
// change the bytes the preamble emits.
|
|
45
|
+
this.ctx = new Uint8Array(ctx);
|
|
46
|
+
this.hasher = createRunningHash(suite.prehashAlgorithm);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Build the wire-format preamble for `payloadLength`. Available at
|
|
50
|
+
* any point in the stream lifecycle. See
|
|
51
|
+
* docs/signing.md#attached-envelope.
|
|
52
|
+
*/
|
|
53
|
+
buildPreamble(payloadLength) {
|
|
54
|
+
if (!Number.isInteger(payloadLength) || payloadLength < 0)
|
|
55
|
+
throw new SigningError('sig-malformed-input', `payloadLength must be a non-negative integer, got ${payloadLength}`);
|
|
56
|
+
if (payloadLength > 0xFFFFFFFF)
|
|
57
|
+
throw new SigningError('sig-malformed-input', `payloadLength ${payloadLength} > 2^32 - 1 (wire format payload_len is u32)`);
|
|
58
|
+
const out = new Uint8Array(2 + this.ctx.length + 4);
|
|
59
|
+
let pos = 0;
|
|
60
|
+
out[pos++] = this.suite.formatEnum;
|
|
61
|
+
out[pos++] = this.ctx.length;
|
|
62
|
+
out.set(this.ctx, pos);
|
|
63
|
+
pos += this.ctx.length;
|
|
64
|
+
out[pos++] = (payloadLength >>> 24) & 0xFF;
|
|
65
|
+
out[pos++] = (payloadLength >>> 16) & 0xFF;
|
|
66
|
+
out[pos++] = (payloadLength >>> 8) & 0xFF;
|
|
67
|
+
out[pos] = payloadLength & 0xFF;
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
/** Feed a chunk to the running prehash. */
|
|
71
|
+
update(chunk) {
|
|
72
|
+
if (this.disposed)
|
|
73
|
+
throw new SigningError('sig-stream-disposed');
|
|
74
|
+
if (this.finalized)
|
|
75
|
+
throw new SigningError('sig-stream-finalized');
|
|
76
|
+
this.hasher.update(chunk);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Finalize the running prehash and sign. Returns the signature bytes.
|
|
80
|
+
* Caller writes these as the last segment of the output stream.
|
|
81
|
+
*/
|
|
82
|
+
finalize() {
|
|
83
|
+
if (this.disposed)
|
|
84
|
+
throw new SigningError('sig-stream-disposed');
|
|
85
|
+
if (this.finalized)
|
|
86
|
+
throw new SigningError('sig-stream-finalized');
|
|
87
|
+
this.finalized = true;
|
|
88
|
+
const h = this.hasher;
|
|
89
|
+
let digest;
|
|
90
|
+
try {
|
|
91
|
+
digest = h.finalize();
|
|
92
|
+
return this.suite.signPrehashed(this.sk, digest, this.ctx);
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
if (digest !== undefined)
|
|
96
|
+
wipe(digest);
|
|
97
|
+
h.dispose();
|
|
98
|
+
this.hasher = undefined;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** Wipe lib-owned state. Idempotent. */
|
|
102
|
+
dispose() {
|
|
103
|
+
if (this.disposed)
|
|
104
|
+
return;
|
|
105
|
+
this.disposed = true;
|
|
106
|
+
if (this.hasher !== undefined) {
|
|
107
|
+
this.hasher.dispose();
|
|
108
|
+
this.hasher = undefined;
|
|
109
|
+
}
|
|
110
|
+
wipe(this.ctx);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
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/sign/suites/ecdsa-p256.ts
|
|
23
|
+
//
|
|
24
|
+
// EcdsaP256Suite (0x02, FIPS 186-5 §6.4 over SHA-256). Hedged-by-default
|
|
25
|
+
// per draft-irtf-cfrg-det-sigs-with-noise-05.
|
|
26
|
+
//
|
|
27
|
+
// Catalog + sizes: docs/signaturesuite.md. Suite reference: docs/ecdsa-p256.md.
|
|
28
|
+
import { SigningError } from '../../errors.js';
|
|
29
|
+
import { EcdsaP256 } from '../../ecdsa/index.js';
|
|
30
|
+
import { randomBytes, utf8ToBytes, wipe } from '../../utils.js';
|
|
31
|
+
import { CTX_DOMAIN_MAX } from '../ctx.js';
|
|
32
|
+
import { sha256OneShot } from '../hasher.js';
|
|
33
|
+
function EcdsaP256SuiteFactory(formatEnum, formatName, ctxDomain) {
|
|
34
|
+
if (utf8ToBytes(ctxDomain).length > CTX_DOMAIN_MAX)
|
|
35
|
+
throw new Error(`leviathan-crypto: ctxDomain '${ctxDomain}' too long for ${formatName}`);
|
|
36
|
+
const wasmModules = Object.freeze(['p256', 'sha2']);
|
|
37
|
+
const prehashAlgorithm = 'sha-256';
|
|
38
|
+
const prehashSize = 32;
|
|
39
|
+
function rejectCtx(ctx) {
|
|
40
|
+
if (ctx.length > 0)
|
|
41
|
+
throw new SigningError('sig-ctx-unsupported', `${formatName} does not support user context; ECDSA-P256 has `
|
|
42
|
+
+ 'no native ctx parameter in FIPS 186-5 §6.4. Use the '
|
|
43
|
+
+ 'classical+PQ hybrid suites (catalog 0x22 / 0x23) for '
|
|
44
|
+
+ 'context-bound ECDSA-P256 signatures.');
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
formatEnum,
|
|
48
|
+
formatName,
|
|
49
|
+
ctxDomain,
|
|
50
|
+
pkSize: 33,
|
|
51
|
+
skSize: 32,
|
|
52
|
+
sigMaxSize: 64,
|
|
53
|
+
wasmModules,
|
|
54
|
+
prehashAlgorithm,
|
|
55
|
+
prehashSize,
|
|
56
|
+
sign(sk, msg, ctx) {
|
|
57
|
+
rejectCtx(ctx);
|
|
58
|
+
const digest = sha256OneShot(msg);
|
|
59
|
+
const rnd = randomBytes(32);
|
|
60
|
+
const inst = new EcdsaP256();
|
|
61
|
+
try {
|
|
62
|
+
return inst._signInternalPk(sk, digest, rnd);
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
wipe(rnd);
|
|
66
|
+
wipe(digest);
|
|
67
|
+
inst.dispose();
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
verify(pk, msg, sig, ctx) {
|
|
71
|
+
rejectCtx(ctx);
|
|
72
|
+
const digest = sha256OneShot(msg);
|
|
73
|
+
const inst = new EcdsaP256();
|
|
74
|
+
try {
|
|
75
|
+
return inst.verify(pk, digest, sig);
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
inst.dispose();
|
|
79
|
+
wipe(digest);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
keygen() {
|
|
83
|
+
const inst = new EcdsaP256();
|
|
84
|
+
try {
|
|
85
|
+
const kp = inst.keygen();
|
|
86
|
+
return { pk: kp.publicKey, sk: kp.secretKey };
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
inst.dispose();
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
signPrehashed(sk, digest, ctx) {
|
|
93
|
+
rejectCtx(ctx);
|
|
94
|
+
if (digest.length !== prehashSize)
|
|
95
|
+
throw new SigningError('sig-malformed-input', `digest length ${digest.length} != expected ${prehashSize} for ${formatName}`);
|
|
96
|
+
const rnd = randomBytes(32);
|
|
97
|
+
const inst = new EcdsaP256();
|
|
98
|
+
try {
|
|
99
|
+
return inst._signInternalPk(sk, digest, rnd);
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
wipe(rnd);
|
|
103
|
+
inst.dispose();
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
verifyPrehashed(pk, digest, sig, ctx) {
|
|
107
|
+
rejectCtx(ctx);
|
|
108
|
+
if (digest.length !== prehashSize)
|
|
109
|
+
throw new SigningError('sig-malformed-input', `digest length ${digest.length} != expected ${prehashSize} for ${formatName}`);
|
|
110
|
+
const inst = new EcdsaP256();
|
|
111
|
+
try {
|
|
112
|
+
return inst.verify(pk, digest, sig);
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
inst.dispose();
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export const EcdsaP256Suite = EcdsaP256SuiteFactory(0x02, 'ecdsa-p256', 'ecdsa-p256-envelope-v3');
|
|
@@ -0,0 +1,165 @@
|
|
|
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/sign/suites/ed25519.ts
|
|
23
|
+
//
|
|
24
|
+
// Ed25519Suite (0x01, RFC 8032 §5.1.6) and Ed25519PreHashSuite
|
|
25
|
+
// (0x11, Ed25519ph, RFC 8032 §5.1.7).
|
|
26
|
+
//
|
|
27
|
+
// Catalog + sizes: docs/signaturesuite.md. Suite reference: docs/ed25519.md.
|
|
28
|
+
import { utf8ToBytes, wipe } from '../../utils.js';
|
|
29
|
+
import { SigningError } from '../../errors.js';
|
|
30
|
+
import { Ed25519 } from '../../ed25519/index.js';
|
|
31
|
+
import { buildEffectiveCtx, CTX_DOMAIN_MAX, } from '../ctx.js';
|
|
32
|
+
import { sha512OneShot } from '../hasher.js';
|
|
33
|
+
// ── Pure-mode factory ───────────────────────────────────────────────────────
|
|
34
|
+
function Ed25519PureSuite(formatEnum, formatName, ctxDomain) {
|
|
35
|
+
if (utf8ToBytes(ctxDomain).length > CTX_DOMAIN_MAX)
|
|
36
|
+
throw new Error(`leviathan-crypto: ctxDomain '${ctxDomain}' too long for ${formatName}`);
|
|
37
|
+
const wasmModules = Object.freeze(['curve25519']);
|
|
38
|
+
return {
|
|
39
|
+
formatEnum,
|
|
40
|
+
formatName,
|
|
41
|
+
ctxDomain,
|
|
42
|
+
pkSize: 32,
|
|
43
|
+
skSize: 32,
|
|
44
|
+
sigMaxSize: 64,
|
|
45
|
+
wasmModules,
|
|
46
|
+
sign(sk, msg, ctx) {
|
|
47
|
+
if (ctx.length > 0)
|
|
48
|
+
throw new SigningError('sig-ctx-unsupported', `${formatName} (pure Ed25519) does not support user context; `
|
|
49
|
+
+ 'use Ed25519PreHashSuite (formatEnum 0x11) for context-bound signatures');
|
|
50
|
+
const inst = new Ed25519();
|
|
51
|
+
try {
|
|
52
|
+
return inst._signInternalPk(sk, msg);
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
inst.dispose();
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
verify(pk, msg, sig, ctx) {
|
|
59
|
+
if (ctx.length > 0)
|
|
60
|
+
throw new SigningError('sig-ctx-unsupported', `${formatName} (pure Ed25519) does not support user context; `
|
|
61
|
+
+ 'use Ed25519PreHashSuite (formatEnum 0x11) for context-bound signatures');
|
|
62
|
+
const inst = new Ed25519();
|
|
63
|
+
try {
|
|
64
|
+
return inst.verify(pk, msg, sig);
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
inst.dispose();
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
keygen() {
|
|
71
|
+
const inst = new Ed25519();
|
|
72
|
+
try {
|
|
73
|
+
const kp = inst.keygen();
|
|
74
|
+
return { pk: kp.publicKey, sk: kp.secretKey };
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
inst.dispose();
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
// ── Prehash-mode factory ────────────────────────────────────────────────────
|
|
83
|
+
function Ed25519PrehashSuite(formatEnum, formatName, ctxDomain) {
|
|
84
|
+
if (utf8ToBytes(ctxDomain).length > CTX_DOMAIN_MAX)
|
|
85
|
+
throw new Error(`leviathan-crypto: ctxDomain '${ctxDomain}' too long for ${formatName}`);
|
|
86
|
+
const wasmModules = Object.freeze(['curve25519', 'sha2']);
|
|
87
|
+
const prehashAlgorithm = 'sha-512';
|
|
88
|
+
const prehashSize = 64;
|
|
89
|
+
return {
|
|
90
|
+
formatEnum,
|
|
91
|
+
formatName,
|
|
92
|
+
ctxDomain,
|
|
93
|
+
pkSize: 32,
|
|
94
|
+
skSize: 32,
|
|
95
|
+
sigMaxSize: 64,
|
|
96
|
+
wasmModules,
|
|
97
|
+
prehashAlgorithm,
|
|
98
|
+
prehashSize,
|
|
99
|
+
sign(sk, msg, ctx) {
|
|
100
|
+
const effectiveCtx = buildEffectiveCtx(ctxDomain, ctx);
|
|
101
|
+
const digest = sha512OneShot(msg);
|
|
102
|
+
const inst = new Ed25519();
|
|
103
|
+
try {
|
|
104
|
+
return inst._signPrehashedInternalPk(sk, digest, effectiveCtx);
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
inst.dispose();
|
|
108
|
+
wipe(digest);
|
|
109
|
+
wipe(effectiveCtx);
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
verify(pk, msg, sig, ctx) {
|
|
113
|
+
const effectiveCtx = buildEffectiveCtx(ctxDomain, ctx);
|
|
114
|
+
const digest = sha512OneShot(msg);
|
|
115
|
+
const inst = new Ed25519();
|
|
116
|
+
try {
|
|
117
|
+
return inst.verifyPrehashed(pk, digest, effectiveCtx, sig);
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
inst.dispose();
|
|
121
|
+
wipe(digest);
|
|
122
|
+
wipe(effectiveCtx);
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
keygen() {
|
|
126
|
+
const inst = new Ed25519();
|
|
127
|
+
try {
|
|
128
|
+
const kp = inst.keygen();
|
|
129
|
+
return { pk: kp.publicKey, sk: kp.secretKey };
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
inst.dispose();
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
signPrehashed(sk, digest, ctx) {
|
|
136
|
+
if (digest.length !== prehashSize)
|
|
137
|
+
throw new SigningError('sig-malformed-input', `digest length ${digest.length} != expected ${prehashSize} for ${formatName}`);
|
|
138
|
+
const effectiveCtx = buildEffectiveCtx(ctxDomain, ctx);
|
|
139
|
+
const inst = new Ed25519();
|
|
140
|
+
try {
|
|
141
|
+
return inst._signPrehashedInternalPk(sk, digest, effectiveCtx);
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
inst.dispose();
|
|
145
|
+
wipe(effectiveCtx);
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
verifyPrehashed(pk, digest, sig, ctx) {
|
|
149
|
+
if (digest.length !== prehashSize)
|
|
150
|
+
throw new SigningError('sig-malformed-input', `digest length ${digest.length} != expected ${prehashSize} for ${formatName}`);
|
|
151
|
+
const effectiveCtx = buildEffectiveCtx(ctxDomain, ctx);
|
|
152
|
+
const inst = new Ed25519();
|
|
153
|
+
try {
|
|
154
|
+
return inst.verifyPrehashed(pk, digest, effectiveCtx, sig);
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
inst.dispose();
|
|
158
|
+
wipe(effectiveCtx);
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
// ── Exported suite consts ───────────────────────────────────────────────────
|
|
164
|
+
export const Ed25519Suite = Ed25519PureSuite(0x01, 'ed25519', 'ed25519-envelope-v3');
|
|
165
|
+
export const Ed25519PreHashSuite = Ed25519PrehashSuite(0x11, 'ed25519-prehash', 'ed25519-prehash-envelope-v3');
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { StreamableSignatureSuite } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Composite ML-DSA-44 + Ed25519 with SHA-512 prehash.
|
|
4
|
+
* composite-sigs §6, id-MLDSA44-Ed25519-SHA512 (OID 1.3.6.1.5.5.7.6.39).
|
|
5
|
+
*/
|
|
6
|
+
export declare const MlDsa44Ed25519Suite: StreamableSignatureSuite;
|
|
7
|
+
/**
|
|
8
|
+
* Composite ML-DSA-65 + Ed25519 with SHA-512 prehash.
|
|
9
|
+
* composite-sigs §6, id-MLDSA65-Ed25519-SHA512 (OID 1.3.6.1.5.5.7.6.48).
|
|
10
|
+
*/
|
|
11
|
+
export declare const MlDsa65Ed25519Suite: StreamableSignatureSuite;
|
|
12
|
+
/**
|
|
13
|
+
* Composite ML-DSA-44 + ECDSA-P256 with SHA-256 prehash.
|
|
14
|
+
* composite-sigs §6, id-MLDSA44-ECDSA-P256-SHA256 (OID 1.3.6.1.5.5.7.6.40).
|
|
15
|
+
*/
|
|
16
|
+
export declare const MlDsa44EcdsaP256Suite: StreamableSignatureSuite;
|
|
17
|
+
/**
|
|
18
|
+
* Composite ML-DSA-65 + ECDSA-P256 with SHA-512 prehash on the composite
|
|
19
|
+
* layer; the ECDSA half still hashes M' with SHA-256 per composite-sigs §6
|
|
20
|
+
* `ecdsa-with-SHA256` and §10.1 (deployment-fit rationale).
|
|
21
|
+
* composite-sigs §6, id-MLDSA65-ECDSA-P256-SHA512 (OID 1.3.6.1.5.5.7.6.45).
|
|
22
|
+
*/
|
|
23
|
+
export declare const MlDsa65EcdsaP256Suite: StreamableSignatureSuite;
|