@omnituum/pqc-shared 0.3.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/crypto/index.cjs +39 -71
- package/dist/crypto/index.d.cts +48 -45
- package/dist/crypto/index.d.ts +48 -45
- package/dist/crypto/index.js +33 -72
- package/dist/crypto/safe/index.cjs +556 -0
- package/dist/crypto/safe/index.d.cts +341 -0
- package/dist/crypto/safe/index.d.ts +341 -0
- package/dist/crypto/safe/index.js +524 -0
- package/dist/fs/index.cjs +6 -34
- package/dist/fs/index.js +6 -34
- package/dist/index.cjs +39 -71
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +33 -72
- package/dist/{integrity-Dx9jukMH.d.cts → integrity-BenoFsmP.d.cts} +1 -1
- package/dist/{integrity-CCYjrap3.d.ts → integrity-D9J98Bty.d.ts} +1 -1
- package/dist/{types-61c7Q9ri.d.ts → types-CRka8PC7.d.cts} +54 -2
- package/dist/{types-Ch0y-n7K.d.cts → types-CRka8PC7.d.ts} +54 -2
- package/dist/utils/index.d.cts +2 -3
- package/dist/utils/index.d.ts +2 -3
- package/dist/vault/index.cjs +13 -41
- package/dist/vault/index.d.cts +2 -3
- package/dist/vault/index.d.ts +2 -3
- package/dist/vault/index.js +13 -41
- package/package.json +13 -5
- package/src/crypto/dilithium.ts +8 -4
- package/src/crypto/hybrid.ts +13 -29
- package/src/crypto/index.ts +9 -1
- package/src/crypto/kyber.ts +80 -118
- package/src/crypto/safe/adapters.ts +306 -0
- package/src/crypto/safe/dilithium.ts +74 -0
- package/src/crypto/safe/index.ts +97 -0
- package/src/crypto/safe/kyber.ts +47 -0
- package/src/crypto/safe/manifests.ts +192 -0
- package/src/crypto/safe/secretbox.ts +24 -0
- package/src/crypto/safe/types.ts +88 -0
- package/src/crypto/safe/x25519.ts +31 -0
- package/src/index.ts +12 -4
- package/src/version.ts +9 -4
- package/dist/version-BygzPVGs.d.cts +0 -55
- package/dist/version-BygzPVGs.d.ts +0 -55
package/dist/crypto/index.cjs
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
var sha2_js = require('@noble/hashes/sha2.js');
|
|
4
4
|
var hmac_js = require('@noble/hashes/hmac.js');
|
|
5
5
|
var nacl = require('tweetnacl');
|
|
6
|
+
var mlKem_js = require('@noble/post-quantum/ml-kem.js');
|
|
7
|
+
var envelopeRegistry = require('@omnituum/envelope-registry');
|
|
6
8
|
var blake3_js = require('@noble/hashes/blake3.js');
|
|
7
9
|
var chacha_js = require('@noble/ciphers/chacha.js');
|
|
8
10
|
var hkdf_js = require('@noble/hashes/hkdf.js');
|
|
@@ -198,78 +200,42 @@ function x25519SharedSecret(ourSecretKey, theirPublicKey) {
|
|
|
198
200
|
function deriveKeyFromShared(shared, salt, info) {
|
|
199
201
|
return hkdfSha256(shared, { salt: u8(salt), info: u8(info), length: 32 });
|
|
200
202
|
}
|
|
201
|
-
var
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
kyberModule = k.kyber ?? k;
|
|
208
|
-
return kyberModule;
|
|
209
|
-
} catch (e) {
|
|
210
|
-
console.warn("[Kyber] Failed to load kyber-crystals:", e);
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
203
|
+
var KYBER_SUITE = "ML-KEM-1024-FIPS203";
|
|
204
|
+
var KYBER_PUBLIC_KEY_SIZE = 1568;
|
|
205
|
+
var KYBER_SECRET_KEY_SIZE = 3168;
|
|
206
|
+
var KYBER_CIPHERTEXT_SIZE = 1568;
|
|
207
|
+
var KYBER_SHARED_SECRET_SIZE = 32;
|
|
208
|
+
var KYBER_SEED_SIZE = 64;
|
|
214
209
|
async function isKyberAvailable() {
|
|
215
|
-
|
|
216
|
-
return mod !== null;
|
|
210
|
+
return true;
|
|
217
211
|
}
|
|
218
212
|
async function generateKyberKeypair() {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
230
|
-
const kp = await fn.call(mod);
|
|
231
|
-
const pub = kp?.publicKey ?? kp?.public ?? kp?.pk;
|
|
232
|
-
const priv = kp?.privateKey ?? kp?.secretKey ?? kp?.secret ?? kp?.sk;
|
|
233
|
-
if (!pub || !priv) {
|
|
234
|
-
console.warn("[Kyber] Invalid keypair result");
|
|
235
|
-
return null;
|
|
236
|
-
}
|
|
237
|
-
return {
|
|
238
|
-
publicB64: b64(new Uint8Array(pub)),
|
|
239
|
-
secretB64: b64(new Uint8Array(priv))
|
|
240
|
-
};
|
|
241
|
-
} catch (e) {
|
|
242
|
-
console.warn("[Kyber] Key generation failed:", e);
|
|
243
|
-
return null;
|
|
213
|
+
const seed = randN(64);
|
|
214
|
+
const kp = mlKem_js.ml_kem1024.keygen(seed);
|
|
215
|
+
return {
|
|
216
|
+
publicB64: b64(kp.publicKey),
|
|
217
|
+
secretB64: b64(kp.secretKey)
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function generateKyberKeypairFromSeed(seed) {
|
|
221
|
+
if (seed.length !== 64) {
|
|
222
|
+
throw new Error("Kyber seed must be 64 bytes");
|
|
244
223
|
}
|
|
224
|
+
const kp = mlKem_js.ml_kem1024.keygen(seed);
|
|
225
|
+
return { publicKey: kp.publicKey, secretKey: kp.secretKey };
|
|
245
226
|
}
|
|
246
227
|
async function kyberEncapsulate(pubKeyB64) {
|
|
247
|
-
const kyber = await loadKyber();
|
|
248
|
-
if (!kyber?.encrypt) {
|
|
249
|
-
throw new Error("Kyber encrypt not available");
|
|
250
|
-
}
|
|
251
228
|
const pk = ub64(pubKeyB64);
|
|
252
|
-
const
|
|
253
|
-
const ctRaw = r?.ciphertext ?? r?.cyphertext ?? r?.ct ?? r?.bytes?.ciphertext ?? r?.bytes?.cyphertext ?? r?.bytes?.ct ?? (Array.isArray(r) ? r[0] : void 0);
|
|
254
|
-
const ssRaw = r?.key ?? r?.sharedSecret ?? r?.secret ?? r?.bytes?.key ?? r?.bytes?.sharedSecret ?? (Array.isArray(r) ? r[1] : void 0);
|
|
255
|
-
if (!ctRaw || !ssRaw) {
|
|
256
|
-
throw new Error("Kyber encapsulate failed: missing ciphertext or shared secret");
|
|
257
|
-
}
|
|
229
|
+
const enc = mlKem_js.ml_kem1024.encapsulate(pk);
|
|
258
230
|
return {
|
|
259
|
-
ciphertext:
|
|
260
|
-
sharedSecret:
|
|
231
|
+
ciphertext: enc.cipherText,
|
|
232
|
+
sharedSecret: enc.sharedSecret
|
|
261
233
|
};
|
|
262
234
|
}
|
|
263
235
|
async function kyberDecapsulate(kemCiphertextB64, secretKeyB64) {
|
|
264
|
-
const kyber = await loadKyber();
|
|
265
|
-
if (!kyber?.decrypt && !kyber?.decapsulate) {
|
|
266
|
-
throw new Error("Kyber decrypt/decapsulate not available");
|
|
267
|
-
}
|
|
268
236
|
const ct = ub64(kemCiphertextB64);
|
|
269
237
|
const sk = ub64(secretKeyB64);
|
|
270
|
-
|
|
271
|
-
const key = r && (r.key ?? r.sharedSecret) ? r.key ?? r.sharedSecret : r;
|
|
272
|
-
return new Uint8Array(key);
|
|
238
|
+
return mlKem_js.ml_kem1024.decapsulate(ct, sk);
|
|
273
239
|
}
|
|
274
240
|
function kyberWrapKey(sharedSecret, msgKey32) {
|
|
275
241
|
if (msgKey32.length !== 32) {
|
|
@@ -278,10 +244,7 @@ function kyberWrapKey(sharedSecret, msgKey32) {
|
|
|
278
244
|
const kek = sha256(sharedSecret);
|
|
279
245
|
const nonce = globalThis.crypto.getRandomValues(new Uint8Array(24));
|
|
280
246
|
const wrapped = nacl__default.default.secretbox(msgKey32, nonce, kek);
|
|
281
|
-
return {
|
|
282
|
-
nonce: b64(nonce),
|
|
283
|
-
wrapped: b64(wrapped)
|
|
284
|
-
};
|
|
247
|
+
return { nonce: b64(nonce), wrapped: b64(wrapped) };
|
|
285
248
|
}
|
|
286
249
|
function kyberUnwrapKey(sharedSecret, nonceB64, wrappedB64) {
|
|
287
250
|
const kek = sha256(sharedSecret);
|
|
@@ -344,7 +307,7 @@ async function dilithiumSign(message, secretKeyB64) {
|
|
|
344
307
|
}
|
|
345
308
|
const sk = fromB64(secretKeyB64);
|
|
346
309
|
const msg = typeof message === "string" ? new TextEncoder().encode(message) : message;
|
|
347
|
-
const signature = mod.sign(
|
|
310
|
+
const signature = mod.sign(msg, sk);
|
|
348
311
|
return {
|
|
349
312
|
signature: toB64(signature),
|
|
350
313
|
algorithm: "ML-DSA-65"
|
|
@@ -355,7 +318,7 @@ async function dilithiumSignRaw(message, secretKey) {
|
|
|
355
318
|
if (!mod) {
|
|
356
319
|
throw new Error("Dilithium library not available");
|
|
357
320
|
}
|
|
358
|
-
return mod.sign(
|
|
321
|
+
return mod.sign(message, secretKey);
|
|
359
322
|
}
|
|
360
323
|
async function dilithiumVerify(message, signatureB64, publicKeyB64) {
|
|
361
324
|
const mod = await loadDilithium();
|
|
@@ -366,7 +329,7 @@ async function dilithiumVerify(message, signatureB64, publicKeyB64) {
|
|
|
366
329
|
const sig = fromB64(signatureB64);
|
|
367
330
|
const msg = typeof message === "string" ? new TextEncoder().encode(message) : message;
|
|
368
331
|
try {
|
|
369
|
-
return mod.verify(
|
|
332
|
+
return mod.verify(sig, msg, pk);
|
|
370
333
|
} catch {
|
|
371
334
|
return false;
|
|
372
335
|
}
|
|
@@ -377,7 +340,7 @@ async function dilithiumVerifyRaw(message, signature, publicKey) {
|
|
|
377
340
|
throw new Error("Dilithium library not available");
|
|
378
341
|
}
|
|
379
342
|
try {
|
|
380
|
-
return mod.verify(
|
|
343
|
+
return mod.verify(signature, message, publicKey);
|
|
381
344
|
} catch {
|
|
382
345
|
return false;
|
|
383
346
|
}
|
|
@@ -386,10 +349,8 @@ var DILITHIUM_PUBLIC_KEY_SIZE = 1952;
|
|
|
386
349
|
var DILITHIUM_SECRET_KEY_SIZE = 4032;
|
|
387
350
|
var DILITHIUM_SIGNATURE_SIZE = 3309;
|
|
388
351
|
var DILITHIUM_ALGORITHM = "ML-DSA-65";
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
var ENVELOPE_VERSION = "omnituum.hybrid.v1";
|
|
392
|
-
var ENVELOPE_VERSION_LEGACY = "pqc-demo.hybrid.v1";
|
|
352
|
+
var ENVELOPE_VERSION = envelopeRegistry.OMNI_VERSIONS.HYBRID_V1;
|
|
353
|
+
var ENVELOPE_VERSION_LEGACY = envelopeRegistry.DEPRECATED_VERSIONS.PQC_DEMO_HYBRID_V1;
|
|
393
354
|
var ENVELOPE_SUITE = "x25519+kyber768";
|
|
394
355
|
var ENVELOPE_AEAD = "xsalsa20poly1305";
|
|
395
356
|
var SUPPORTED_ENVELOPE_VERSIONS = [
|
|
@@ -733,6 +694,12 @@ exports.HKDF_SHA256_MAX_OUTPUT = HKDF_SHA256_MAX_OUTPUT;
|
|
|
733
694
|
exports.HKDF_SHA256_OUTPUT_SIZE = HKDF_SHA256_OUTPUT_SIZE;
|
|
734
695
|
exports.HKDF_SHA512_MAX_OUTPUT = HKDF_SHA512_MAX_OUTPUT;
|
|
735
696
|
exports.HKDF_SHA512_OUTPUT_SIZE = HKDF_SHA512_OUTPUT_SIZE;
|
|
697
|
+
exports.KYBER_CIPHERTEXT_SIZE = KYBER_CIPHERTEXT_SIZE;
|
|
698
|
+
exports.KYBER_PUBLIC_KEY_SIZE = KYBER_PUBLIC_KEY_SIZE;
|
|
699
|
+
exports.KYBER_SECRET_KEY_SIZE = KYBER_SECRET_KEY_SIZE;
|
|
700
|
+
exports.KYBER_SEED_SIZE = KYBER_SEED_SIZE;
|
|
701
|
+
exports.KYBER_SHARED_SECRET_SIZE = KYBER_SHARED_SECRET_SIZE;
|
|
702
|
+
exports.KYBER_SUITE = KYBER_SUITE;
|
|
736
703
|
exports.POLY1305_TAG_SIZE = POLY1305_TAG_SIZE;
|
|
737
704
|
exports.SECRETBOX_KEY_SIZE = SECRETBOX_KEY_SIZE;
|
|
738
705
|
exports.SECRETBOX_NONCE_SIZE = SECRETBOX_NONCE_SIZE;
|
|
@@ -763,6 +730,7 @@ exports.generateDilithiumKeypair = generateDilithiumKeypair;
|
|
|
763
730
|
exports.generateDilithiumKeypairFromSeed = generateDilithiumKeypairFromSeed;
|
|
764
731
|
exports.generateHybridIdentity = generateHybridIdentity;
|
|
765
732
|
exports.generateKyberKeypair = generateKyberKeypair;
|
|
733
|
+
exports.generateKyberKeypairFromSeed = generateKyberKeypairFromSeed;
|
|
766
734
|
exports.generateX25519Keypair = generateX25519Keypair;
|
|
767
735
|
exports.generateX25519KeypairFromSeed = generateX25519KeypairFromSeed;
|
|
768
736
|
exports.getPublicKeys = getPublicKeys;
|
package/dist/crypto/index.d.cts
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OmniHybridV1 } from '@omnituum/envelope-registry';
|
|
2
2
|
import * as _noble_ciphers_utils_js from '@noble/ciphers/utils.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Omnituum PQC Shared
|
|
5
|
+
* Omnituum PQC Shared — Kyber (ML-KEM-1024, FIPS 203)
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Backend: @noble/post-quantum `ml_kem1024`. NIST FIPS 203 (final, 2024).
|
|
8
|
+
*
|
|
9
|
+
* Wire-format note: previous releases (<= 0.3.x) of this package were backed by
|
|
10
|
+
* `kyber-crystals`, which implements an earlier draft of Kyber and is NOT
|
|
11
|
+
* interoperable with FIPS 203 — see `tests/interop/historical/` and
|
|
12
|
+
* `package-docs/GAPS_AND_TASKS.md` (PQC-02 result). 0.4.0 is an intentional
|
|
13
|
+
* clean break: legacy draft-Kyber material cannot be read by this version.
|
|
14
|
+
*
|
|
15
|
+
* Sizes (ML-KEM-1024):
|
|
16
|
+
* publicKey 1568 bytes
|
|
17
|
+
* secretKey 3168 bytes
|
|
18
|
+
* ciphertext 1568 bytes
|
|
19
|
+
* sharedSecret 32 bytes
|
|
20
|
+
*
|
|
21
|
+
* Suite tag for new material: "ML-KEM-1024-FIPS203".
|
|
9
22
|
*/
|
|
10
23
|
interface KyberKeypair {
|
|
11
24
|
publicKey: Uint8Array;
|
|
@@ -19,29 +32,44 @@ interface KyberEncapsulation {
|
|
|
19
32
|
ciphertext: Uint8Array;
|
|
20
33
|
sharedSecret: Uint8Array;
|
|
21
34
|
}
|
|
35
|
+
/** Canonical suite identifier for new material produced by this package. */
|
|
36
|
+
declare const KYBER_SUITE: "ML-KEM-1024-FIPS203";
|
|
37
|
+
type KyberSuite = typeof KYBER_SUITE;
|
|
38
|
+
/** ML-KEM-1024 public key size (bytes). */
|
|
39
|
+
declare const KYBER_PUBLIC_KEY_SIZE = 1568;
|
|
40
|
+
/** ML-KEM-1024 secret key size (bytes). */
|
|
41
|
+
declare const KYBER_SECRET_KEY_SIZE = 3168;
|
|
42
|
+
/** ML-KEM-1024 ciphertext size (bytes). */
|
|
43
|
+
declare const KYBER_CIPHERTEXT_SIZE = 1568;
|
|
44
|
+
/** ML-KEM-1024 shared-secret size (bytes). */
|
|
45
|
+
declare const KYBER_SHARED_SECRET_SIZE = 32;
|
|
46
|
+
/** Seed size accepted by `generateKyberKeypairFromSeed` (bytes). */
|
|
47
|
+
declare const KYBER_SEED_SIZE = 64;
|
|
48
|
+
/**
|
|
49
|
+
* @deprecated Always returns true. Retained for API stability across the
|
|
50
|
+
* 0.3.x → 0.4.x cut. The noble backend is statically imported and always
|
|
51
|
+
* present; there is no runtime feature-detection path.
|
|
52
|
+
*/
|
|
22
53
|
declare function isKyberAvailable(): Promise<boolean>;
|
|
23
54
|
/**
|
|
24
|
-
* Generate a
|
|
55
|
+
* Generate a fresh ML-KEM-1024 keypair using a cryptographically random seed.
|
|
25
56
|
*/
|
|
26
57
|
declare function generateKyberKeypair(): Promise<KyberKeypairB64 | null>;
|
|
27
58
|
/**
|
|
28
|
-
*
|
|
59
|
+
* Derive a deterministic ML-KEM-1024 keypair from a 64-byte seed.
|
|
60
|
+
* Same seed → byte-identical keypair, across runtimes (Node, browser).
|
|
61
|
+
*
|
|
62
|
+
* The seed is passed verbatim to the FIPS 203 keygen. Callers that need
|
|
63
|
+
* domain separation between Kyber and other key types must apply it
|
|
64
|
+
* upstream (e.g. via SHA-256 with a domain tag) before calling.
|
|
29
65
|
*/
|
|
66
|
+
declare function generateKyberKeypairFromSeed(seed: Uint8Array): KyberKeypair;
|
|
30
67
|
declare function kyberEncapsulate(pubKeyB64: string): Promise<KyberEncapsulation>;
|
|
31
|
-
/**
|
|
32
|
-
* Decapsulate a shared secret using Kyber ML-KEM-768.
|
|
33
|
-
*/
|
|
34
68
|
declare function kyberDecapsulate(kemCiphertextB64: string, secretKeyB64: string): Promise<Uint8Array>;
|
|
35
|
-
/**
|
|
36
|
-
* Wrap a message key using Kyber shared secret.
|
|
37
|
-
*/
|
|
38
69
|
declare function kyberWrapKey(sharedSecret: Uint8Array, msgKey32: Uint8Array): {
|
|
39
70
|
nonce: string;
|
|
40
71
|
wrapped: string;
|
|
41
72
|
};
|
|
42
|
-
/**
|
|
43
|
-
* Unwrap a message key using Kyber shared secret.
|
|
44
|
-
*/
|
|
45
73
|
declare function kyberUnwrapKey(sharedSecret: Uint8Array, nonceB64: string, wrappedB64: string): Uint8Array | null;
|
|
46
74
|
|
|
47
75
|
/**
|
|
@@ -87,38 +115,13 @@ interface HybridSecretKeys {
|
|
|
87
115
|
/** Kyber secret key (base64) */
|
|
88
116
|
kyberSecB64: string;
|
|
89
117
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
/** Algorithm suite */
|
|
94
|
-
suite: typeof ENVELOPE_SUITE;
|
|
95
|
-
/** AEAD algorithm */
|
|
96
|
-
aead: typeof ENVELOPE_AEAD;
|
|
97
|
-
/** X25519 ephemeral public key (hex) */
|
|
98
|
-
x25519Epk: string;
|
|
99
|
-
/** X25519 wrapped content key */
|
|
100
|
-
x25519Wrap: {
|
|
101
|
-
nonce: string;
|
|
102
|
-
wrapped: string;
|
|
103
|
-
};
|
|
104
|
-
/** Kyber KEM ciphertext (base64) */
|
|
105
|
-
kyberKemCt: string;
|
|
106
|
-
/** Kyber wrapped content key */
|
|
107
|
-
kyberWrap: {
|
|
108
|
-
nonce: string;
|
|
109
|
-
wrapped: string;
|
|
110
|
-
};
|
|
111
|
-
/** Content encryption nonce (base64) */
|
|
112
|
-
contentNonce: string;
|
|
113
|
-
/** Encrypted content (base64) */
|
|
114
|
-
ciphertext: string;
|
|
115
|
-
/** Metadata */
|
|
116
|
-
meta: {
|
|
117
|
-
createdAt: string;
|
|
118
|
+
|
|
119
|
+
type HybridEnvelope = Omit<OmniHybridV1, 'meta'> & {
|
|
120
|
+
meta: OmniHybridV1['meta'] & {
|
|
118
121
|
senderName?: string;
|
|
119
122
|
senderId?: string;
|
|
120
123
|
};
|
|
121
|
-
}
|
|
124
|
+
};
|
|
122
125
|
/**
|
|
123
126
|
* Generate a new hybrid identity with both X25519 and Kyber keys.
|
|
124
127
|
*/
|
|
@@ -638,4 +641,4 @@ declare const BOX_KEY_SIZE: number;
|
|
|
638
641
|
/** NaCl box nonce size (24 bytes) */
|
|
639
642
|
declare const BOX_NONCE_SIZE: number;
|
|
640
643
|
|
|
641
|
-
export { BLAKE3_BLOCK_SIZE, BLAKE3_KEY_LENGTH, BLAKE3_OUTPUT_LENGTH, BOX_KEY_SIZE, BOX_NONCE_SIZE, type Blake3Options, type BoxPayload, CHACHA20_KEY_SIZE, CHACHA20_NONCE_SIZE, type ChaChaPayload, type ClassicalWrap, DILITHIUM_ALGORITHM, DILITHIUM_PUBLIC_KEY_SIZE, DILITHIUM_SECRET_KEY_SIZE, DILITHIUM_SIGNATURE_SIZE, type DilithiumKeypair, type DilithiumKeypairB64, type DilithiumSignature, HKDF_SHA256_MAX_OUTPUT, HKDF_SHA256_OUTPUT_SIZE, HKDF_SHA512_MAX_OUTPUT, HKDF_SHA512_OUTPUT_SIZE, type HkdfHash, type HkdfOptions, type HybridEnvelope, type HybridIdentity, type HybridPublicKeys, type HybridSecretKeys, type KyberEncapsulation, type KyberKeypair, type KyberKeypairB64, POLY1305_TAG_SIZE, SECRETBOX_KEY_SIZE, SECRETBOX_NONCE_SIZE, SECRETBOX_OVERHEAD, type SecretboxPayload, type X25519Keypair, type X25519KeypairHex, XCHACHA20_NONCE_SIZE, assertLen, b64, blake3, blake3DeriveKey, blake3Hex, blake3Mac, boxDecrypt, boxEncrypt, boxUnwrapWithX25519, boxWrapWithX25519, chaCha20Poly1305Decrypt, chaCha20Poly1305Encrypt, createChaCha20Poly1305, createXChaCha20Poly1305, deriveKeyFromShared, dilithiumSign, dilithiumSignRaw, dilithiumVerify, dilithiumVerifyRaw, fromB64, fromHex, generateDilithiumKeypair, generateDilithiumKeypairFromSeed, generateHybridIdentity, generateKyberKeypair, generateX25519Keypair, generateX25519KeypairFromSeed, getPublicKeys, getSecretKeys, hkdfDerive, hkdfExpand, hkdfExtract, hkdfSha256, hkdfSplitForNoise, hkdfTripleSplitForNoise, hybridDecrypt, hybridDecryptToString, hybridEncrypt, isDilithiumAvailable, isKyberAvailable, kyberDecapsulate, kyberEncapsulate, kyberUnwrapKey, kyberWrapKey, rand12, rand24, rand32, randN, rotateHybridIdentity, secretboxDecrypt, secretboxDecryptString, secretboxEncrypt, secretboxEncryptString, secretboxOpenRaw, secretboxRaw, sha256, sha256String, textDecoder, textEncoder, toB64, toHex, u8, ub64, x25519SharedSecret, xChaCha20Poly1305Decrypt, xChaCha20Poly1305Encrypt };
|
|
644
|
+
export { BLAKE3_BLOCK_SIZE, BLAKE3_KEY_LENGTH, BLAKE3_OUTPUT_LENGTH, BOX_KEY_SIZE, BOX_NONCE_SIZE, type Blake3Options, type BoxPayload, CHACHA20_KEY_SIZE, CHACHA20_NONCE_SIZE, type ChaChaPayload, type ClassicalWrap, DILITHIUM_ALGORITHM, DILITHIUM_PUBLIC_KEY_SIZE, DILITHIUM_SECRET_KEY_SIZE, DILITHIUM_SIGNATURE_SIZE, type DilithiumKeypair, type DilithiumKeypairB64, type DilithiumSignature, HKDF_SHA256_MAX_OUTPUT, HKDF_SHA256_OUTPUT_SIZE, HKDF_SHA512_MAX_OUTPUT, HKDF_SHA512_OUTPUT_SIZE, type HkdfHash, type HkdfOptions, type HybridEnvelope, type HybridIdentity, type HybridPublicKeys, type HybridSecretKeys, KYBER_CIPHERTEXT_SIZE, KYBER_PUBLIC_KEY_SIZE, KYBER_SECRET_KEY_SIZE, KYBER_SEED_SIZE, KYBER_SHARED_SECRET_SIZE, KYBER_SUITE, type KyberEncapsulation, type KyberKeypair, type KyberKeypairB64, type KyberSuite, POLY1305_TAG_SIZE, SECRETBOX_KEY_SIZE, SECRETBOX_NONCE_SIZE, SECRETBOX_OVERHEAD, type SecretboxPayload, type X25519Keypair, type X25519KeypairHex, XCHACHA20_NONCE_SIZE, assertLen, b64, blake3, blake3DeriveKey, blake3Hex, blake3Mac, boxDecrypt, boxEncrypt, boxUnwrapWithX25519, boxWrapWithX25519, chaCha20Poly1305Decrypt, chaCha20Poly1305Encrypt, createChaCha20Poly1305, createXChaCha20Poly1305, deriveKeyFromShared, dilithiumSign, dilithiumSignRaw, dilithiumVerify, dilithiumVerifyRaw, fromB64, fromHex, generateDilithiumKeypair, generateDilithiumKeypairFromSeed, generateHybridIdentity, generateKyberKeypair, generateKyberKeypairFromSeed, generateX25519Keypair, generateX25519KeypairFromSeed, getPublicKeys, getSecretKeys, hkdfDerive, hkdfExpand, hkdfExtract, hkdfSha256, hkdfSplitForNoise, hkdfTripleSplitForNoise, hybridDecrypt, hybridDecryptToString, hybridEncrypt, isDilithiumAvailable, isKyberAvailable, kyberDecapsulate, kyberEncapsulate, kyberUnwrapKey, kyberWrapKey, rand12, rand24, rand32, randN, rotateHybridIdentity, secretboxDecrypt, secretboxDecryptString, secretboxEncrypt, secretboxEncryptString, secretboxOpenRaw, secretboxRaw, sha256, sha256String, textDecoder, textEncoder, toB64, toHex, u8, ub64, x25519SharedSecret, xChaCha20Poly1305Decrypt, xChaCha20Poly1305Encrypt };
|
package/dist/crypto/index.d.ts
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OmniHybridV1 } from '@omnituum/envelope-registry';
|
|
2
2
|
import * as _noble_ciphers_utils_js from '@noble/ciphers/utils.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Omnituum PQC Shared
|
|
5
|
+
* Omnituum PQC Shared — Kyber (ML-KEM-1024, FIPS 203)
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Backend: @noble/post-quantum `ml_kem1024`. NIST FIPS 203 (final, 2024).
|
|
8
|
+
*
|
|
9
|
+
* Wire-format note: previous releases (<= 0.3.x) of this package were backed by
|
|
10
|
+
* `kyber-crystals`, which implements an earlier draft of Kyber and is NOT
|
|
11
|
+
* interoperable with FIPS 203 — see `tests/interop/historical/` and
|
|
12
|
+
* `package-docs/GAPS_AND_TASKS.md` (PQC-02 result). 0.4.0 is an intentional
|
|
13
|
+
* clean break: legacy draft-Kyber material cannot be read by this version.
|
|
14
|
+
*
|
|
15
|
+
* Sizes (ML-KEM-1024):
|
|
16
|
+
* publicKey 1568 bytes
|
|
17
|
+
* secretKey 3168 bytes
|
|
18
|
+
* ciphertext 1568 bytes
|
|
19
|
+
* sharedSecret 32 bytes
|
|
20
|
+
*
|
|
21
|
+
* Suite tag for new material: "ML-KEM-1024-FIPS203".
|
|
9
22
|
*/
|
|
10
23
|
interface KyberKeypair {
|
|
11
24
|
publicKey: Uint8Array;
|
|
@@ -19,29 +32,44 @@ interface KyberEncapsulation {
|
|
|
19
32
|
ciphertext: Uint8Array;
|
|
20
33
|
sharedSecret: Uint8Array;
|
|
21
34
|
}
|
|
35
|
+
/** Canonical suite identifier for new material produced by this package. */
|
|
36
|
+
declare const KYBER_SUITE: "ML-KEM-1024-FIPS203";
|
|
37
|
+
type KyberSuite = typeof KYBER_SUITE;
|
|
38
|
+
/** ML-KEM-1024 public key size (bytes). */
|
|
39
|
+
declare const KYBER_PUBLIC_KEY_SIZE = 1568;
|
|
40
|
+
/** ML-KEM-1024 secret key size (bytes). */
|
|
41
|
+
declare const KYBER_SECRET_KEY_SIZE = 3168;
|
|
42
|
+
/** ML-KEM-1024 ciphertext size (bytes). */
|
|
43
|
+
declare const KYBER_CIPHERTEXT_SIZE = 1568;
|
|
44
|
+
/** ML-KEM-1024 shared-secret size (bytes). */
|
|
45
|
+
declare const KYBER_SHARED_SECRET_SIZE = 32;
|
|
46
|
+
/** Seed size accepted by `generateKyberKeypairFromSeed` (bytes). */
|
|
47
|
+
declare const KYBER_SEED_SIZE = 64;
|
|
48
|
+
/**
|
|
49
|
+
* @deprecated Always returns true. Retained for API stability across the
|
|
50
|
+
* 0.3.x → 0.4.x cut. The noble backend is statically imported and always
|
|
51
|
+
* present; there is no runtime feature-detection path.
|
|
52
|
+
*/
|
|
22
53
|
declare function isKyberAvailable(): Promise<boolean>;
|
|
23
54
|
/**
|
|
24
|
-
* Generate a
|
|
55
|
+
* Generate a fresh ML-KEM-1024 keypair using a cryptographically random seed.
|
|
25
56
|
*/
|
|
26
57
|
declare function generateKyberKeypair(): Promise<KyberKeypairB64 | null>;
|
|
27
58
|
/**
|
|
28
|
-
*
|
|
59
|
+
* Derive a deterministic ML-KEM-1024 keypair from a 64-byte seed.
|
|
60
|
+
* Same seed → byte-identical keypair, across runtimes (Node, browser).
|
|
61
|
+
*
|
|
62
|
+
* The seed is passed verbatim to the FIPS 203 keygen. Callers that need
|
|
63
|
+
* domain separation between Kyber and other key types must apply it
|
|
64
|
+
* upstream (e.g. via SHA-256 with a domain tag) before calling.
|
|
29
65
|
*/
|
|
66
|
+
declare function generateKyberKeypairFromSeed(seed: Uint8Array): KyberKeypair;
|
|
30
67
|
declare function kyberEncapsulate(pubKeyB64: string): Promise<KyberEncapsulation>;
|
|
31
|
-
/**
|
|
32
|
-
* Decapsulate a shared secret using Kyber ML-KEM-768.
|
|
33
|
-
*/
|
|
34
68
|
declare function kyberDecapsulate(kemCiphertextB64: string, secretKeyB64: string): Promise<Uint8Array>;
|
|
35
|
-
/**
|
|
36
|
-
* Wrap a message key using Kyber shared secret.
|
|
37
|
-
*/
|
|
38
69
|
declare function kyberWrapKey(sharedSecret: Uint8Array, msgKey32: Uint8Array): {
|
|
39
70
|
nonce: string;
|
|
40
71
|
wrapped: string;
|
|
41
72
|
};
|
|
42
|
-
/**
|
|
43
|
-
* Unwrap a message key using Kyber shared secret.
|
|
44
|
-
*/
|
|
45
73
|
declare function kyberUnwrapKey(sharedSecret: Uint8Array, nonceB64: string, wrappedB64: string): Uint8Array | null;
|
|
46
74
|
|
|
47
75
|
/**
|
|
@@ -87,38 +115,13 @@ interface HybridSecretKeys {
|
|
|
87
115
|
/** Kyber secret key (base64) */
|
|
88
116
|
kyberSecB64: string;
|
|
89
117
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
/** Algorithm suite */
|
|
94
|
-
suite: typeof ENVELOPE_SUITE;
|
|
95
|
-
/** AEAD algorithm */
|
|
96
|
-
aead: typeof ENVELOPE_AEAD;
|
|
97
|
-
/** X25519 ephemeral public key (hex) */
|
|
98
|
-
x25519Epk: string;
|
|
99
|
-
/** X25519 wrapped content key */
|
|
100
|
-
x25519Wrap: {
|
|
101
|
-
nonce: string;
|
|
102
|
-
wrapped: string;
|
|
103
|
-
};
|
|
104
|
-
/** Kyber KEM ciphertext (base64) */
|
|
105
|
-
kyberKemCt: string;
|
|
106
|
-
/** Kyber wrapped content key */
|
|
107
|
-
kyberWrap: {
|
|
108
|
-
nonce: string;
|
|
109
|
-
wrapped: string;
|
|
110
|
-
};
|
|
111
|
-
/** Content encryption nonce (base64) */
|
|
112
|
-
contentNonce: string;
|
|
113
|
-
/** Encrypted content (base64) */
|
|
114
|
-
ciphertext: string;
|
|
115
|
-
/** Metadata */
|
|
116
|
-
meta: {
|
|
117
|
-
createdAt: string;
|
|
118
|
+
|
|
119
|
+
type HybridEnvelope = Omit<OmniHybridV1, 'meta'> & {
|
|
120
|
+
meta: OmniHybridV1['meta'] & {
|
|
118
121
|
senderName?: string;
|
|
119
122
|
senderId?: string;
|
|
120
123
|
};
|
|
121
|
-
}
|
|
124
|
+
};
|
|
122
125
|
/**
|
|
123
126
|
* Generate a new hybrid identity with both X25519 and Kyber keys.
|
|
124
127
|
*/
|
|
@@ -638,4 +641,4 @@ declare const BOX_KEY_SIZE: number;
|
|
|
638
641
|
/** NaCl box nonce size (24 bytes) */
|
|
639
642
|
declare const BOX_NONCE_SIZE: number;
|
|
640
643
|
|
|
641
|
-
export { BLAKE3_BLOCK_SIZE, BLAKE3_KEY_LENGTH, BLAKE3_OUTPUT_LENGTH, BOX_KEY_SIZE, BOX_NONCE_SIZE, type Blake3Options, type BoxPayload, CHACHA20_KEY_SIZE, CHACHA20_NONCE_SIZE, type ChaChaPayload, type ClassicalWrap, DILITHIUM_ALGORITHM, DILITHIUM_PUBLIC_KEY_SIZE, DILITHIUM_SECRET_KEY_SIZE, DILITHIUM_SIGNATURE_SIZE, type DilithiumKeypair, type DilithiumKeypairB64, type DilithiumSignature, HKDF_SHA256_MAX_OUTPUT, HKDF_SHA256_OUTPUT_SIZE, HKDF_SHA512_MAX_OUTPUT, HKDF_SHA512_OUTPUT_SIZE, type HkdfHash, type HkdfOptions, type HybridEnvelope, type HybridIdentity, type HybridPublicKeys, type HybridSecretKeys, type KyberEncapsulation, type KyberKeypair, type KyberKeypairB64, POLY1305_TAG_SIZE, SECRETBOX_KEY_SIZE, SECRETBOX_NONCE_SIZE, SECRETBOX_OVERHEAD, type SecretboxPayload, type X25519Keypair, type X25519KeypairHex, XCHACHA20_NONCE_SIZE, assertLen, b64, blake3, blake3DeriveKey, blake3Hex, blake3Mac, boxDecrypt, boxEncrypt, boxUnwrapWithX25519, boxWrapWithX25519, chaCha20Poly1305Decrypt, chaCha20Poly1305Encrypt, createChaCha20Poly1305, createXChaCha20Poly1305, deriveKeyFromShared, dilithiumSign, dilithiumSignRaw, dilithiumVerify, dilithiumVerifyRaw, fromB64, fromHex, generateDilithiumKeypair, generateDilithiumKeypairFromSeed, generateHybridIdentity, generateKyberKeypair, generateX25519Keypair, generateX25519KeypairFromSeed, getPublicKeys, getSecretKeys, hkdfDerive, hkdfExpand, hkdfExtract, hkdfSha256, hkdfSplitForNoise, hkdfTripleSplitForNoise, hybridDecrypt, hybridDecryptToString, hybridEncrypt, isDilithiumAvailable, isKyberAvailable, kyberDecapsulate, kyberEncapsulate, kyberUnwrapKey, kyberWrapKey, rand12, rand24, rand32, randN, rotateHybridIdentity, secretboxDecrypt, secretboxDecryptString, secretboxEncrypt, secretboxEncryptString, secretboxOpenRaw, secretboxRaw, sha256, sha256String, textDecoder, textEncoder, toB64, toHex, u8, ub64, x25519SharedSecret, xChaCha20Poly1305Decrypt, xChaCha20Poly1305Encrypt };
|
|
644
|
+
export { BLAKE3_BLOCK_SIZE, BLAKE3_KEY_LENGTH, BLAKE3_OUTPUT_LENGTH, BOX_KEY_SIZE, BOX_NONCE_SIZE, type Blake3Options, type BoxPayload, CHACHA20_KEY_SIZE, CHACHA20_NONCE_SIZE, type ChaChaPayload, type ClassicalWrap, DILITHIUM_ALGORITHM, DILITHIUM_PUBLIC_KEY_SIZE, DILITHIUM_SECRET_KEY_SIZE, DILITHIUM_SIGNATURE_SIZE, type DilithiumKeypair, type DilithiumKeypairB64, type DilithiumSignature, HKDF_SHA256_MAX_OUTPUT, HKDF_SHA256_OUTPUT_SIZE, HKDF_SHA512_MAX_OUTPUT, HKDF_SHA512_OUTPUT_SIZE, type HkdfHash, type HkdfOptions, type HybridEnvelope, type HybridIdentity, type HybridPublicKeys, type HybridSecretKeys, KYBER_CIPHERTEXT_SIZE, KYBER_PUBLIC_KEY_SIZE, KYBER_SECRET_KEY_SIZE, KYBER_SEED_SIZE, KYBER_SHARED_SECRET_SIZE, KYBER_SUITE, type KyberEncapsulation, type KyberKeypair, type KyberKeypairB64, type KyberSuite, POLY1305_TAG_SIZE, SECRETBOX_KEY_SIZE, SECRETBOX_NONCE_SIZE, SECRETBOX_OVERHEAD, type SecretboxPayload, type X25519Keypair, type X25519KeypairHex, XCHACHA20_NONCE_SIZE, assertLen, b64, blake3, blake3DeriveKey, blake3Hex, blake3Mac, boxDecrypt, boxEncrypt, boxUnwrapWithX25519, boxWrapWithX25519, chaCha20Poly1305Decrypt, chaCha20Poly1305Encrypt, createChaCha20Poly1305, createXChaCha20Poly1305, deriveKeyFromShared, dilithiumSign, dilithiumSignRaw, dilithiumVerify, dilithiumVerifyRaw, fromB64, fromHex, generateDilithiumKeypair, generateDilithiumKeypairFromSeed, generateHybridIdentity, generateKyberKeypair, generateKyberKeypairFromSeed, generateX25519Keypair, generateX25519KeypairFromSeed, getPublicKeys, getSecretKeys, hkdfDerive, hkdfExpand, hkdfExtract, hkdfSha256, hkdfSplitForNoise, hkdfTripleSplitForNoise, hybridDecrypt, hybridDecryptToString, hybridEncrypt, isDilithiumAvailable, isKyberAvailable, kyberDecapsulate, kyberEncapsulate, kyberUnwrapKey, kyberWrapKey, rand12, rand24, rand32, randN, rotateHybridIdentity, secretboxDecrypt, secretboxDecryptString, secretboxEncrypt, secretboxEncryptString, secretboxOpenRaw, secretboxRaw, sha256, sha256String, textDecoder, textEncoder, toB64, toHex, u8, ub64, x25519SharedSecret, xChaCha20Poly1305Decrypt, xChaCha20Poly1305Encrypt };
|
package/dist/crypto/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { sha256 as sha256$1, sha512 } from '@noble/hashes/sha2.js';
|
|
2
2
|
import { hmac } from '@noble/hashes/hmac.js';
|
|
3
3
|
import nacl from 'tweetnacl';
|
|
4
|
+
import { ml_kem1024 } from '@noble/post-quantum/ml-kem.js';
|
|
5
|
+
import { OMNI_VERSIONS, DEPRECATED_VERSIONS } from '@omnituum/envelope-registry';
|
|
4
6
|
import { blake3 as blake3$1 } from '@noble/hashes/blake3.js';
|
|
5
7
|
import { chacha20poly1305, xchacha20poly1305 } from '@noble/ciphers/chacha.js';
|
|
6
8
|
import { hkdf, extract, expand } from '@noble/hashes/hkdf.js';
|
|
@@ -192,78 +194,42 @@ function x25519SharedSecret(ourSecretKey, theirPublicKey) {
|
|
|
192
194
|
function deriveKeyFromShared(shared, salt, info) {
|
|
193
195
|
return hkdfSha256(shared, { salt: u8(salt), info: u8(info), length: 32 });
|
|
194
196
|
}
|
|
195
|
-
var
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
kyberModule = k.kyber ?? k;
|
|
202
|
-
return kyberModule;
|
|
203
|
-
} catch (e) {
|
|
204
|
-
console.warn("[Kyber] Failed to load kyber-crystals:", e);
|
|
205
|
-
return null;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
197
|
+
var KYBER_SUITE = "ML-KEM-1024-FIPS203";
|
|
198
|
+
var KYBER_PUBLIC_KEY_SIZE = 1568;
|
|
199
|
+
var KYBER_SECRET_KEY_SIZE = 3168;
|
|
200
|
+
var KYBER_CIPHERTEXT_SIZE = 1568;
|
|
201
|
+
var KYBER_SHARED_SECRET_SIZE = 32;
|
|
202
|
+
var KYBER_SEED_SIZE = 64;
|
|
208
203
|
async function isKyberAvailable() {
|
|
209
|
-
|
|
210
|
-
return mod !== null;
|
|
204
|
+
return true;
|
|
211
205
|
}
|
|
212
206
|
async function generateKyberKeypair() {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
const kp = await fn.call(mod);
|
|
225
|
-
const pub = kp?.publicKey ?? kp?.public ?? kp?.pk;
|
|
226
|
-
const priv = kp?.privateKey ?? kp?.secretKey ?? kp?.secret ?? kp?.sk;
|
|
227
|
-
if (!pub || !priv) {
|
|
228
|
-
console.warn("[Kyber] Invalid keypair result");
|
|
229
|
-
return null;
|
|
230
|
-
}
|
|
231
|
-
return {
|
|
232
|
-
publicB64: b64(new Uint8Array(pub)),
|
|
233
|
-
secretB64: b64(new Uint8Array(priv))
|
|
234
|
-
};
|
|
235
|
-
} catch (e) {
|
|
236
|
-
console.warn("[Kyber] Key generation failed:", e);
|
|
237
|
-
return null;
|
|
207
|
+
const seed = randN(64);
|
|
208
|
+
const kp = ml_kem1024.keygen(seed);
|
|
209
|
+
return {
|
|
210
|
+
publicB64: b64(kp.publicKey),
|
|
211
|
+
secretB64: b64(kp.secretKey)
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function generateKyberKeypairFromSeed(seed) {
|
|
215
|
+
if (seed.length !== 64) {
|
|
216
|
+
throw new Error("Kyber seed must be 64 bytes");
|
|
238
217
|
}
|
|
218
|
+
const kp = ml_kem1024.keygen(seed);
|
|
219
|
+
return { publicKey: kp.publicKey, secretKey: kp.secretKey };
|
|
239
220
|
}
|
|
240
221
|
async function kyberEncapsulate(pubKeyB64) {
|
|
241
|
-
const kyber = await loadKyber();
|
|
242
|
-
if (!kyber?.encrypt) {
|
|
243
|
-
throw new Error("Kyber encrypt not available");
|
|
244
|
-
}
|
|
245
222
|
const pk = ub64(pubKeyB64);
|
|
246
|
-
const
|
|
247
|
-
const ctRaw = r?.ciphertext ?? r?.cyphertext ?? r?.ct ?? r?.bytes?.ciphertext ?? r?.bytes?.cyphertext ?? r?.bytes?.ct ?? (Array.isArray(r) ? r[0] : void 0);
|
|
248
|
-
const ssRaw = r?.key ?? r?.sharedSecret ?? r?.secret ?? r?.bytes?.key ?? r?.bytes?.sharedSecret ?? (Array.isArray(r) ? r[1] : void 0);
|
|
249
|
-
if (!ctRaw || !ssRaw) {
|
|
250
|
-
throw new Error("Kyber encapsulate failed: missing ciphertext or shared secret");
|
|
251
|
-
}
|
|
223
|
+
const enc = ml_kem1024.encapsulate(pk);
|
|
252
224
|
return {
|
|
253
|
-
ciphertext:
|
|
254
|
-
sharedSecret:
|
|
225
|
+
ciphertext: enc.cipherText,
|
|
226
|
+
sharedSecret: enc.sharedSecret
|
|
255
227
|
};
|
|
256
228
|
}
|
|
257
229
|
async function kyberDecapsulate(kemCiphertextB64, secretKeyB64) {
|
|
258
|
-
const kyber = await loadKyber();
|
|
259
|
-
if (!kyber?.decrypt && !kyber?.decapsulate) {
|
|
260
|
-
throw new Error("Kyber decrypt/decapsulate not available");
|
|
261
|
-
}
|
|
262
230
|
const ct = ub64(kemCiphertextB64);
|
|
263
231
|
const sk = ub64(secretKeyB64);
|
|
264
|
-
|
|
265
|
-
const key = r && (r.key ?? r.sharedSecret) ? r.key ?? r.sharedSecret : r;
|
|
266
|
-
return new Uint8Array(key);
|
|
232
|
+
return ml_kem1024.decapsulate(ct, sk);
|
|
267
233
|
}
|
|
268
234
|
function kyberWrapKey(sharedSecret, msgKey32) {
|
|
269
235
|
if (msgKey32.length !== 32) {
|
|
@@ -272,10 +238,7 @@ function kyberWrapKey(sharedSecret, msgKey32) {
|
|
|
272
238
|
const kek = sha256(sharedSecret);
|
|
273
239
|
const nonce = globalThis.crypto.getRandomValues(new Uint8Array(24));
|
|
274
240
|
const wrapped = nacl.secretbox(msgKey32, nonce, kek);
|
|
275
|
-
return {
|
|
276
|
-
nonce: b64(nonce),
|
|
277
|
-
wrapped: b64(wrapped)
|
|
278
|
-
};
|
|
241
|
+
return { nonce: b64(nonce), wrapped: b64(wrapped) };
|
|
279
242
|
}
|
|
280
243
|
function kyberUnwrapKey(sharedSecret, nonceB64, wrappedB64) {
|
|
281
244
|
const kek = sha256(sharedSecret);
|
|
@@ -338,7 +301,7 @@ async function dilithiumSign(message, secretKeyB64) {
|
|
|
338
301
|
}
|
|
339
302
|
const sk = fromB64(secretKeyB64);
|
|
340
303
|
const msg = typeof message === "string" ? new TextEncoder().encode(message) : message;
|
|
341
|
-
const signature = mod.sign(
|
|
304
|
+
const signature = mod.sign(msg, sk);
|
|
342
305
|
return {
|
|
343
306
|
signature: toB64(signature),
|
|
344
307
|
algorithm: "ML-DSA-65"
|
|
@@ -349,7 +312,7 @@ async function dilithiumSignRaw(message, secretKey) {
|
|
|
349
312
|
if (!mod) {
|
|
350
313
|
throw new Error("Dilithium library not available");
|
|
351
314
|
}
|
|
352
|
-
return mod.sign(
|
|
315
|
+
return mod.sign(message, secretKey);
|
|
353
316
|
}
|
|
354
317
|
async function dilithiumVerify(message, signatureB64, publicKeyB64) {
|
|
355
318
|
const mod = await loadDilithium();
|
|
@@ -360,7 +323,7 @@ async function dilithiumVerify(message, signatureB64, publicKeyB64) {
|
|
|
360
323
|
const sig = fromB64(signatureB64);
|
|
361
324
|
const msg = typeof message === "string" ? new TextEncoder().encode(message) : message;
|
|
362
325
|
try {
|
|
363
|
-
return mod.verify(
|
|
326
|
+
return mod.verify(sig, msg, pk);
|
|
364
327
|
} catch {
|
|
365
328
|
return false;
|
|
366
329
|
}
|
|
@@ -371,7 +334,7 @@ async function dilithiumVerifyRaw(message, signature, publicKey) {
|
|
|
371
334
|
throw new Error("Dilithium library not available");
|
|
372
335
|
}
|
|
373
336
|
try {
|
|
374
|
-
return mod.verify(
|
|
337
|
+
return mod.verify(signature, message, publicKey);
|
|
375
338
|
} catch {
|
|
376
339
|
return false;
|
|
377
340
|
}
|
|
@@ -380,10 +343,8 @@ var DILITHIUM_PUBLIC_KEY_SIZE = 1952;
|
|
|
380
343
|
var DILITHIUM_SECRET_KEY_SIZE = 4032;
|
|
381
344
|
var DILITHIUM_SIGNATURE_SIZE = 3309;
|
|
382
345
|
var DILITHIUM_ALGORITHM = "ML-DSA-65";
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
var ENVELOPE_VERSION = "omnituum.hybrid.v1";
|
|
386
|
-
var ENVELOPE_VERSION_LEGACY = "pqc-demo.hybrid.v1";
|
|
346
|
+
var ENVELOPE_VERSION = OMNI_VERSIONS.HYBRID_V1;
|
|
347
|
+
var ENVELOPE_VERSION_LEGACY = DEPRECATED_VERSIONS.PQC_DEMO_HYBRID_V1;
|
|
387
348
|
var ENVELOPE_SUITE = "x25519+kyber768";
|
|
388
349
|
var ENVELOPE_AEAD = "xsalsa20poly1305";
|
|
389
350
|
var SUPPORTED_ENVELOPE_VERSIONS = [
|
|
@@ -712,4 +673,4 @@ var HKDF_SHA512_OUTPUT_SIZE = 64;
|
|
|
712
673
|
var HKDF_SHA256_MAX_OUTPUT = 255 * 32;
|
|
713
674
|
var HKDF_SHA512_MAX_OUTPUT = 255 * 64;
|
|
714
675
|
|
|
715
|
-
export { BLAKE3_BLOCK_SIZE, BLAKE3_KEY_LENGTH, BLAKE3_OUTPUT_LENGTH, BOX_KEY_SIZE, BOX_NONCE_SIZE, CHACHA20_KEY_SIZE, CHACHA20_NONCE_SIZE, DILITHIUM_ALGORITHM, DILITHIUM_PUBLIC_KEY_SIZE, DILITHIUM_SECRET_KEY_SIZE, DILITHIUM_SIGNATURE_SIZE, HKDF_SHA256_MAX_OUTPUT, HKDF_SHA256_OUTPUT_SIZE, HKDF_SHA512_MAX_OUTPUT, HKDF_SHA512_OUTPUT_SIZE, POLY1305_TAG_SIZE, SECRETBOX_KEY_SIZE, SECRETBOX_NONCE_SIZE, SECRETBOX_OVERHEAD, XCHACHA20_NONCE_SIZE, assertLen, b64, blake3, blake3DeriveKey, blake3Hex, blake3Mac, boxDecrypt, boxEncrypt, boxUnwrapWithX25519, boxWrapWithX25519, chaCha20Poly1305Decrypt, chaCha20Poly1305Encrypt, createChaCha20Poly1305, createXChaCha20Poly1305, deriveKeyFromShared, dilithiumSign, dilithiumSignRaw, dilithiumVerify, dilithiumVerifyRaw, fromB64, fromHex, generateDilithiumKeypair, generateDilithiumKeypairFromSeed, generateHybridIdentity, generateKyberKeypair, generateX25519Keypair, generateX25519KeypairFromSeed, getPublicKeys, getSecretKeys, hkdfDerive, hkdfExpand, hkdfExtract, hkdfSha256, hkdfSplitForNoise, hkdfTripleSplitForNoise, hybridDecrypt, hybridDecryptToString, hybridEncrypt, isDilithiumAvailable, isKyberAvailable, kyberDecapsulate, kyberEncapsulate, kyberUnwrapKey, kyberWrapKey, rand12, rand24, rand32, randN, rotateHybridIdentity, secretboxDecrypt, secretboxDecryptString, secretboxEncrypt, secretboxEncryptString, secretboxOpenRaw, secretboxRaw, sha256, sha256String, textDecoder, textEncoder, toB64, toHex, u8, ub64, x25519SharedSecret, xChaCha20Poly1305Decrypt, xChaCha20Poly1305Encrypt };
|
|
676
|
+
export { BLAKE3_BLOCK_SIZE, BLAKE3_KEY_LENGTH, BLAKE3_OUTPUT_LENGTH, BOX_KEY_SIZE, BOX_NONCE_SIZE, CHACHA20_KEY_SIZE, CHACHA20_NONCE_SIZE, DILITHIUM_ALGORITHM, DILITHIUM_PUBLIC_KEY_SIZE, DILITHIUM_SECRET_KEY_SIZE, DILITHIUM_SIGNATURE_SIZE, HKDF_SHA256_MAX_OUTPUT, HKDF_SHA256_OUTPUT_SIZE, HKDF_SHA512_MAX_OUTPUT, HKDF_SHA512_OUTPUT_SIZE, KYBER_CIPHERTEXT_SIZE, KYBER_PUBLIC_KEY_SIZE, KYBER_SECRET_KEY_SIZE, KYBER_SEED_SIZE, KYBER_SHARED_SECRET_SIZE, KYBER_SUITE, POLY1305_TAG_SIZE, SECRETBOX_KEY_SIZE, SECRETBOX_NONCE_SIZE, SECRETBOX_OVERHEAD, XCHACHA20_NONCE_SIZE, assertLen, b64, blake3, blake3DeriveKey, blake3Hex, blake3Mac, boxDecrypt, boxEncrypt, boxUnwrapWithX25519, boxWrapWithX25519, chaCha20Poly1305Decrypt, chaCha20Poly1305Encrypt, createChaCha20Poly1305, createXChaCha20Poly1305, deriveKeyFromShared, dilithiumSign, dilithiumSignRaw, dilithiumVerify, dilithiumVerifyRaw, fromB64, fromHex, generateDilithiumKeypair, generateDilithiumKeypairFromSeed, generateHybridIdentity, generateKyberKeypair, generateKyberKeypairFromSeed, generateX25519Keypair, generateX25519KeypairFromSeed, getPublicKeys, getSecretKeys, hkdfDerive, hkdfExpand, hkdfExtract, hkdfSha256, hkdfSplitForNoise, hkdfTripleSplitForNoise, hybridDecrypt, hybridDecryptToString, hybridEncrypt, isDilithiumAvailable, isKyberAvailable, kyberDecapsulate, kyberEncapsulate, kyberUnwrapKey, kyberWrapKey, rand12, rand24, rand32, randN, rotateHybridIdentity, secretboxDecrypt, secretboxDecryptString, secretboxEncrypt, secretboxEncryptString, secretboxOpenRaw, secretboxRaw, sha256, sha256String, textDecoder, textEncoder, toB64, toHex, u8, ub64, x25519SharedSecret, xChaCha20Poly1305Decrypt, xChaCha20Poly1305Encrypt };
|