@f0rest8/metamorphic-crypto 0.6.0 → 0.7.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @f0rest8/metamorphic-crypto
2
2
 
3
- Zero-knowledge end-to-end encryption with post-quantum hybrid KEM (ML-KEM-512/768/1024 + X25519).
3
+ Zero-knowledge end-to-end encryption with post-quantum hybrid KEM (ML-KEM-512/768/1024 + X25519), hybrid PQ signatures (ML-DSA + Ed25519), and an opt-in CNSA 2.0 suite axis.
4
4
 
5
5
  Built for [Metamorphic](https://metamorphic.app) and [Mosslet](https://mosslet.com) — privacy-first apps by [Moss Piglet Corporation](https://mosspiglet.dev) where all user data is encrypted client-side and the server only stores opaque ciphertext.
6
6
 
@@ -218,6 +218,49 @@ across native Rust, WASM, and the Elixir NIF.
218
218
  > composite remains at least as strong as Ed25519 even if a flaw is found in the
219
219
  > young post-quantum implementation. Pinned and tracked for the FIPS-mode roadmap.
220
220
 
221
+ ### CNSA 2.0 suite axis (opt-in)
222
+
223
+ Everything above is the default **`hybrid`** suite (classical+PQ strict-AND). If
224
+ you have no specific mandate, that is the recommended choice. For deployments
225
+ that must follow the NSA's **CNSA 2.0** suite (NIST IR 8547), a `suite` argument
226
+ raises the posture. It is **orthogonal** to the `"cat1"`/`"cat3"`/`"cat5"` level,
227
+ so you have two independent knobs.
228
+
229
+ | `suite` string | What it is | Status |
230
+ |----------------|------------|--------|
231
+ | `"hybrid"` | Existing classical+PQ strict-AND. Byte-for-byte unchanged. | **Default, recommended** |
232
+ | `"hybridMatched"` | Classical partner matched to the PQ category (KEM: Cat-3→X448, Cat-5→P-521 · Sign: Cat-3→Ed448, Cat-5→ECDSA-P-521) | Opt-in |
233
+ | `"pureCnsa2"` | Pure post-quantum, no classical half (ML-KEM-1024 / AES-256-GCM; ML-DSA-87) | Opt-in, **Cat-5 only** |
234
+
235
+ ```js
236
+ import {
237
+ generateHybridKeyPairSuite, hybridSealSuite, hybridOpenWithContext,
238
+ generateSigningKeyPairSuite, sign, verify,
239
+ } from "@f0rest8/metamorphic-crypto";
240
+
241
+ // Pure CNSA-2.0 KEM box (ML-KEM-1024 + AES-256-GCM)
242
+ const kp = generateHybridKeyPairSuite("pureCnsa2", "cat5"); // { publicKey, secretKey }
243
+ const sealed = hybridSealSuite(plaintextBase64, kp.publicKey, "pureCnsa2", "cat5");
244
+ // Open with the context label used at seal time (default "metamorphic/seal/v1"):
245
+ const opened = hybridOpenWithContext(sealed, kp.secretKey, "metamorphic/seal/v1"); // base64
246
+
247
+ // Pure ML-DSA-87 signatures — sign/verify auto-detect the suite from the tag
248
+ const sk = generateSigningKeyPairSuite("pureCnsa2", "cat5");
249
+ const sig = sign(btoa("checkpoint"), "metamorphic/sign/v1", sk.secretKey);
250
+ const ok = verify(btoa("checkpoint"), "metamorphic/sign/v1", sig, sk.publicKey); // true
251
+ ```
252
+
253
+ The new suites bind a versioned **context label** (`"<namespace>/<purpose>/v<major>"`)
254
+ into the seal — use `hybridSealSuiteWithContext(..., "mosslet/seal/v1")` for a
255
+ custom per-tenant namespace and open with the same label. `sealForUserWithSuite`
256
+ mirrors `sealForUser` with the suite/level appended (legacy X25519 fallback when
257
+ no PQ key is present).
258
+
259
+ > **Honest claims.** "CNSA 2.0 algorithm suite, NCC-audited components,
260
+ > pure-Rust, memory-safe (`forbid-unsafe`)" — **not** "FIPS 140-3 validated."
261
+ > `pureCnsa2` drops the classical backstop, so the strict-AND `hybrid` default
262
+ > stays recommended until the lattice implementations are independently audited.
263
+
221
264
  ## Security levels
222
265
 
223
266
  | Level | ML-KEM | NIST Category | Equivalent | Default |
@@ -77,6 +77,11 @@ export function generateHybridKeyPair1024(): any;
77
77
  */
78
78
  export function generateHybridKeyPair512(): any;
79
79
 
80
+ /**
81
+ * Generate a keypair for `(suite, level)`. Returns JSON: `{ publicKey, secretKey }`.
82
+ */
83
+ export function generateHybridKeyPairSuite(suite: string, level: string): any;
84
+
80
85
  /**
81
86
  * Generate a random 32-byte symmetric key (base64).
82
87
  */
@@ -105,6 +110,35 @@ export function generateSalt(): string;
105
110
  */
106
111
  export function generateSigningKeyPair(level: string): any;
107
112
 
113
+ /**
114
+ * Generate a signing keypair for a full CNSA-2.0 `(suite, level)`.
115
+ *
116
+ * `suite` is `"hybrid"` (default), `"hybridMatched"` (Cat-3→Ed448,
117
+ * Cat-5→ECDSA-P-521), or `"pureCnsa2"` (ML-DSA-87 only, Cat-5). `level` is
118
+ * `"cat2"`/`"cat3"`/`"cat5"`. `sign` / `verify` / `deriveSigningPublicKey`
119
+ * auto-detect the suite from the key/signature version tag, so no suite
120
+ * argument is needed there. Returns JSON: `{ publicKey, secretKey }`.
121
+ */
122
+ export function generateSigningKeyPairSuite(suite: string, level: string): any;
123
+
124
+ /**
125
+ * Open a CNSA-2.0 (or legacy) hybrid ciphertext, supplying the context label
126
+ * used at seal time for the new suites. Returns base64-encoded plaintext.
127
+ */
128
+ export function hybridOpenWithContext(ciphertext_b64: string, seed_b64: string, context_label: string): string;
129
+
130
+ /**
131
+ * Seal plaintext (base64) to a `(suite, level)` combined public key, binding
132
+ * the default `"metamorphic/seal/v1"` context label. Returns base64 ciphertext.
133
+ */
134
+ export function hybridSealSuite(plaintext_b64: string, combined_pk_b64: string, suite: string, level: string): string;
135
+
136
+ /**
137
+ * Seal plaintext (base64) to a `(suite, level)` combined public key, binding a
138
+ * custom `context_label`. Returns base64 ciphertext.
139
+ */
140
+ export function hybridSealSuiteWithContext(plaintext_b64: string, combined_pk_b64: string, suite: string, level: string, context_label: string): string;
141
+
108
142
  /**
109
143
  * Check if a base64 ciphertext is hybrid (v2/v3) format.
110
144
  */
@@ -134,6 +168,12 @@ export function sealForUser(plaintext_b64: string, public_key_b64: string, pq_pu
134
168
  */
135
169
  export function sealForUserWithLevel(plaintext_b64: string, public_key_b64: string, pq_public_key_b64: string | null | undefined, level: string): string;
136
170
 
171
+ /**
172
+ * Seal plaintext (base64) to a user's key(s) under a full `(suite, level)`.
173
+ * Falls back to legacy X25519 if `pq_public_key_b64` is absent/empty.
174
+ */
175
+ export function sealForUserWithSuite(plaintext_b64: string, public_key_b64: string, pq_public_key_b64: string | null | undefined, suite: string, level: string): string;
176
+
137
177
  /**
138
178
  * SHA-256 (SHA-2) digest of base64-encoded `data`. Returns the 32-byte digest as base64.
139
179
  */
@@ -202,6 +242,11 @@ export interface InitOutput {
202
242
  readonly generateHybridKeyPair: () => number;
203
243
  readonly generateHybridKeyPair1024: () => number;
204
244
  readonly isHybridCiphertext: (a: number, b: number) => number;
245
+ readonly generateHybridKeyPairSuite: (a: number, b: number, c: number, d: number, e: number) => void;
246
+ readonly hybridSealSuite: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
247
+ readonly hybridSealSuiteWithContext: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number) => void;
248
+ readonly hybridOpenWithContext: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
249
+ readonly sealForUserWithSuite: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number) => void;
205
250
  readonly generateKey: (a: number) => void;
206
251
  readonly generateKeyPair: () => number;
207
252
  readonly generateSalt: (a: number) => void;
@@ -216,13 +261,14 @@ export interface InitOutput {
216
261
  readonly sha256: (a: number, b: number, c: number) => void;
217
262
  readonly sha512: (a: number, b: number, c: number) => void;
218
263
  readonly generateSigningKeyPair: (a: number, b: number, c: number) => void;
264
+ readonly generateSigningKeyPairSuite: (a: number, b: number, c: number, d: number, e: number) => void;
219
265
  readonly deriveSigningPublicKey: (a: number, b: number, c: number) => void;
220
266
  readonly sign: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
221
267
  readonly verify: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
222
- readonly decryptPrivateKeyWithRecovery: (a: number, b: number, c: number, d: number, e: number) => void;
223
- readonly decryptSecretboxToString: (a: number, b: number, c: number, d: number, e: number) => void;
224
- readonly encryptSecretboxString: (a: number, b: number, c: number, d: number, e: number) => void;
225
268
  readonly encryptPrivateKeyForRecovery: (a: number, b: number, c: number, d: number, e: number) => void;
269
+ readonly encryptSecretboxString: (a: number, b: number, c: number, d: number, e: number) => void;
270
+ readonly decryptSecretboxToString: (a: number, b: number, c: number, d: number, e: number) => void;
271
+ readonly decryptPrivateKeyWithRecovery: (a: number, b: number, c: number, d: number, e: number) => void;
226
272
  readonly __wbindgen_export: (a: number, b: number) => number;
227
273
  readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
228
274
  readonly __wbindgen_export3: (a: number) => void;
@@ -448,6 +448,32 @@ export function generateHybridKeyPair512() {
448
448
  return takeObject(ret);
449
449
  }
450
450
 
451
+ /**
452
+ * Generate a keypair for `(suite, level)`. Returns JSON: `{ publicKey, secretKey }`.
453
+ * @param {string} suite
454
+ * @param {string} level
455
+ * @returns {any}
456
+ */
457
+ export function generateHybridKeyPairSuite(suite, level) {
458
+ try {
459
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
460
+ const ptr0 = passStringToWasm0(suite, wasm.__wbindgen_export, wasm.__wbindgen_export2);
461
+ const len0 = WASM_VECTOR_LEN;
462
+ const ptr1 = passStringToWasm0(level, wasm.__wbindgen_export, wasm.__wbindgen_export2);
463
+ const len1 = WASM_VECTOR_LEN;
464
+ wasm.generateHybridKeyPairSuite(retptr, ptr0, len0, ptr1, len1);
465
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
466
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
467
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
468
+ if (r2) {
469
+ throw takeObject(r1);
470
+ }
471
+ return takeObject(r0);
472
+ } finally {
473
+ wasm.__wbindgen_add_to_stack_pointer(16);
474
+ }
475
+ }
476
+
451
477
  /**
452
478
  * Generate a random 32-byte symmetric key (base64).
453
479
  * @returns {string}
@@ -545,6 +571,164 @@ export function generateSigningKeyPair(level) {
545
571
  }
546
572
  }
547
573
 
574
+ /**
575
+ * Generate a signing keypair for a full CNSA-2.0 `(suite, level)`.
576
+ *
577
+ * `suite` is `"hybrid"` (default), `"hybridMatched"` (Cat-3→Ed448,
578
+ * Cat-5→ECDSA-P-521), or `"pureCnsa2"` (ML-DSA-87 only, Cat-5). `level` is
579
+ * `"cat2"`/`"cat3"`/`"cat5"`. `sign` / `verify` / `deriveSigningPublicKey`
580
+ * auto-detect the suite from the key/signature version tag, so no suite
581
+ * argument is needed there. Returns JSON: `{ publicKey, secretKey }`.
582
+ * @param {string} suite
583
+ * @param {string} level
584
+ * @returns {any}
585
+ */
586
+ export function generateSigningKeyPairSuite(suite, level) {
587
+ try {
588
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
589
+ const ptr0 = passStringToWasm0(suite, wasm.__wbindgen_export, wasm.__wbindgen_export2);
590
+ const len0 = WASM_VECTOR_LEN;
591
+ const ptr1 = passStringToWasm0(level, wasm.__wbindgen_export, wasm.__wbindgen_export2);
592
+ const len1 = WASM_VECTOR_LEN;
593
+ wasm.generateSigningKeyPairSuite(retptr, ptr0, len0, ptr1, len1);
594
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
595
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
596
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
597
+ if (r2) {
598
+ throw takeObject(r1);
599
+ }
600
+ return takeObject(r0);
601
+ } finally {
602
+ wasm.__wbindgen_add_to_stack_pointer(16);
603
+ }
604
+ }
605
+
606
+ /**
607
+ * Open a CNSA-2.0 (or legacy) hybrid ciphertext, supplying the context label
608
+ * used at seal time for the new suites. Returns base64-encoded plaintext.
609
+ * @param {string} ciphertext_b64
610
+ * @param {string} seed_b64
611
+ * @param {string} context_label
612
+ * @returns {string}
613
+ */
614
+ export function hybridOpenWithContext(ciphertext_b64, seed_b64, context_label) {
615
+ let deferred5_0;
616
+ let deferred5_1;
617
+ try {
618
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
619
+ const ptr0 = passStringToWasm0(ciphertext_b64, wasm.__wbindgen_export, wasm.__wbindgen_export2);
620
+ const len0 = WASM_VECTOR_LEN;
621
+ const ptr1 = passStringToWasm0(seed_b64, wasm.__wbindgen_export, wasm.__wbindgen_export2);
622
+ const len1 = WASM_VECTOR_LEN;
623
+ const ptr2 = passStringToWasm0(context_label, wasm.__wbindgen_export, wasm.__wbindgen_export2);
624
+ const len2 = WASM_VECTOR_LEN;
625
+ wasm.hybridOpenWithContext(retptr, ptr0, len0, ptr1, len1, ptr2, len2);
626
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
627
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
628
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
629
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
630
+ var ptr4 = r0;
631
+ var len4 = r1;
632
+ if (r3) {
633
+ ptr4 = 0; len4 = 0;
634
+ throw takeObject(r2);
635
+ }
636
+ deferred5_0 = ptr4;
637
+ deferred5_1 = len4;
638
+ return getStringFromWasm0(ptr4, len4);
639
+ } finally {
640
+ wasm.__wbindgen_add_to_stack_pointer(16);
641
+ wasm.__wbindgen_export4(deferred5_0, deferred5_1, 1);
642
+ }
643
+ }
644
+
645
+ /**
646
+ * Seal plaintext (base64) to a `(suite, level)` combined public key, binding
647
+ * the default `"metamorphic/seal/v1"` context label. Returns base64 ciphertext.
648
+ * @param {string} plaintext_b64
649
+ * @param {string} combined_pk_b64
650
+ * @param {string} suite
651
+ * @param {string} level
652
+ * @returns {string}
653
+ */
654
+ export function hybridSealSuite(plaintext_b64, combined_pk_b64, suite, level) {
655
+ let deferred6_0;
656
+ let deferred6_1;
657
+ try {
658
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
659
+ const ptr0 = passStringToWasm0(plaintext_b64, wasm.__wbindgen_export, wasm.__wbindgen_export2);
660
+ const len0 = WASM_VECTOR_LEN;
661
+ const ptr1 = passStringToWasm0(combined_pk_b64, wasm.__wbindgen_export, wasm.__wbindgen_export2);
662
+ const len1 = WASM_VECTOR_LEN;
663
+ const ptr2 = passStringToWasm0(suite, wasm.__wbindgen_export, wasm.__wbindgen_export2);
664
+ const len2 = WASM_VECTOR_LEN;
665
+ const ptr3 = passStringToWasm0(level, wasm.__wbindgen_export, wasm.__wbindgen_export2);
666
+ const len3 = WASM_VECTOR_LEN;
667
+ wasm.hybridSealSuite(retptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
668
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
669
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
670
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
671
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
672
+ var ptr5 = r0;
673
+ var len5 = r1;
674
+ if (r3) {
675
+ ptr5 = 0; len5 = 0;
676
+ throw takeObject(r2);
677
+ }
678
+ deferred6_0 = ptr5;
679
+ deferred6_1 = len5;
680
+ return getStringFromWasm0(ptr5, len5);
681
+ } finally {
682
+ wasm.__wbindgen_add_to_stack_pointer(16);
683
+ wasm.__wbindgen_export4(deferred6_0, deferred6_1, 1);
684
+ }
685
+ }
686
+
687
+ /**
688
+ * Seal plaintext (base64) to a `(suite, level)` combined public key, binding a
689
+ * custom `context_label`. Returns base64 ciphertext.
690
+ * @param {string} plaintext_b64
691
+ * @param {string} combined_pk_b64
692
+ * @param {string} suite
693
+ * @param {string} level
694
+ * @param {string} context_label
695
+ * @returns {string}
696
+ */
697
+ export function hybridSealSuiteWithContext(plaintext_b64, combined_pk_b64, suite, level, context_label) {
698
+ let deferred7_0;
699
+ let deferred7_1;
700
+ try {
701
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
702
+ const ptr0 = passStringToWasm0(plaintext_b64, wasm.__wbindgen_export, wasm.__wbindgen_export2);
703
+ const len0 = WASM_VECTOR_LEN;
704
+ const ptr1 = passStringToWasm0(combined_pk_b64, wasm.__wbindgen_export, wasm.__wbindgen_export2);
705
+ const len1 = WASM_VECTOR_LEN;
706
+ const ptr2 = passStringToWasm0(suite, wasm.__wbindgen_export, wasm.__wbindgen_export2);
707
+ const len2 = WASM_VECTOR_LEN;
708
+ const ptr3 = passStringToWasm0(level, wasm.__wbindgen_export, wasm.__wbindgen_export2);
709
+ const len3 = WASM_VECTOR_LEN;
710
+ const ptr4 = passStringToWasm0(context_label, wasm.__wbindgen_export, wasm.__wbindgen_export2);
711
+ const len4 = WASM_VECTOR_LEN;
712
+ wasm.hybridSealSuiteWithContext(retptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4);
713
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
714
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
715
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
716
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
717
+ var ptr6 = r0;
718
+ var len6 = r1;
719
+ if (r3) {
720
+ ptr6 = 0; len6 = 0;
721
+ throw takeObject(r2);
722
+ }
723
+ deferred7_0 = ptr6;
724
+ deferred7_1 = len6;
725
+ return getStringFromWasm0(ptr6, len6);
726
+ } finally {
727
+ wasm.__wbindgen_add_to_stack_pointer(16);
728
+ wasm.__wbindgen_export4(deferred7_0, deferred7_1, 1);
729
+ }
730
+ }
731
+
548
732
  /**
549
733
  * Check if a base64 ciphertext is hybrid (v2/v3) format.
550
734
  * @param {string} ciphertext_b64
@@ -704,6 +888,51 @@ export function sealForUserWithLevel(plaintext_b64, public_key_b64, pq_public_ke
704
888
  }
705
889
  }
706
890
 
891
+ /**
892
+ * Seal plaintext (base64) to a user's key(s) under a full `(suite, level)`.
893
+ * Falls back to legacy X25519 if `pq_public_key_b64` is absent/empty.
894
+ * @param {string} plaintext_b64
895
+ * @param {string} public_key_b64
896
+ * @param {string | null | undefined} pq_public_key_b64
897
+ * @param {string} suite
898
+ * @param {string} level
899
+ * @returns {string}
900
+ */
901
+ export function sealForUserWithSuite(plaintext_b64, public_key_b64, pq_public_key_b64, suite, level) {
902
+ let deferred7_0;
903
+ let deferred7_1;
904
+ try {
905
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
906
+ const ptr0 = passStringToWasm0(plaintext_b64, wasm.__wbindgen_export, wasm.__wbindgen_export2);
907
+ const len0 = WASM_VECTOR_LEN;
908
+ const ptr1 = passStringToWasm0(public_key_b64, wasm.__wbindgen_export, wasm.__wbindgen_export2);
909
+ const len1 = WASM_VECTOR_LEN;
910
+ var ptr2 = isLikeNone(pq_public_key_b64) ? 0 : passStringToWasm0(pq_public_key_b64, wasm.__wbindgen_export, wasm.__wbindgen_export2);
911
+ var len2 = WASM_VECTOR_LEN;
912
+ const ptr3 = passStringToWasm0(suite, wasm.__wbindgen_export, wasm.__wbindgen_export2);
913
+ const len3 = WASM_VECTOR_LEN;
914
+ const ptr4 = passStringToWasm0(level, wasm.__wbindgen_export, wasm.__wbindgen_export2);
915
+ const len4 = WASM_VECTOR_LEN;
916
+ wasm.sealForUserWithSuite(retptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4);
917
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
918
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
919
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
920
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
921
+ var ptr6 = r0;
922
+ var len6 = r1;
923
+ if (r3) {
924
+ ptr6 = 0; len6 = 0;
925
+ throw takeObject(r2);
926
+ }
927
+ deferred7_0 = ptr6;
928
+ deferred7_1 = len6;
929
+ return getStringFromWasm0(ptr6, len6);
930
+ } finally {
931
+ wasm.__wbindgen_add_to_stack_pointer(16);
932
+ wasm.__wbindgen_export4(deferred7_0, deferred7_1, 1);
933
+ }
934
+ }
935
+
707
936
  /**
708
937
  * SHA-256 (SHA-2) digest of base64-encoded `data`. Returns the 32-byte digest as base64.
709
938
  * @param {string} data_b64
@@ -992,34 +1221,34 @@ export function verify(message_b64, context, signature_b64, public_key_b64) {
992
1221
  function __wbg_get_imports() {
993
1222
  const import0 = {
994
1223
  __proto__: null,
995
- __wbg___wbindgen_debug_string_56c147eb1a51f0c4: function(arg0, arg1) {
1224
+ __wbg___wbindgen_debug_string_c25d447a39f5578f: function(arg0, arg1) {
996
1225
  const ret = debugString(getObject(arg1));
997
1226
  const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);
998
1227
  const len1 = WASM_VECTOR_LEN;
999
1228
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
1000
1229
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
1001
1230
  },
1002
- __wbg___wbindgen_is_function_147961669f068cd4: function(arg0) {
1231
+ __wbg___wbindgen_is_function_1ff95bcc5517c252: function(arg0) {
1003
1232
  const ret = typeof(getObject(arg0)) === 'function';
1004
1233
  return ret;
1005
1234
  },
1006
- __wbg___wbindgen_is_object_3a2c414391dbf751: function(arg0) {
1235
+ __wbg___wbindgen_is_object_a27215656b807791: function(arg0) {
1007
1236
  const val = getObject(arg0);
1008
1237
  const ret = typeof(val) === 'object' && val !== null;
1009
1238
  return ret;
1010
1239
  },
1011
- __wbg___wbindgen_is_string_6541b0f6ecd4e8e5: function(arg0) {
1240
+ __wbg___wbindgen_is_string_ea5e6cc2e4141dfe: function(arg0) {
1012
1241
  const ret = typeof(getObject(arg0)) === 'string';
1013
1242
  return ret;
1014
1243
  },
1015
- __wbg___wbindgen_is_undefined_4410e3c20a99fa97: function(arg0) {
1244
+ __wbg___wbindgen_is_undefined_c05833b95a3cf397: function(arg0) {
1016
1245
  const ret = getObject(arg0) === undefined;
1017
1246
  return ret;
1018
1247
  },
1019
- __wbg___wbindgen_throw_bbadd78c1bac3a77: function(arg0, arg1) {
1248
+ __wbg___wbindgen_throw_344f42d3211c4765: function(arg0, arg1) {
1020
1249
  throw new Error(getStringFromWasm0(arg0, arg1));
1021
1250
  },
1022
- __wbg_call_ec09a4cf93377d3a: function() { return handleError(function (arg0, arg1, arg2) {
1251
+ __wbg_call_a6e5c5dce5018821: function() { return handleError(function (arg0, arg1, arg2) {
1023
1252
  const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));
1024
1253
  return addHeapObject(ret);
1025
1254
  }, arguments); },
@@ -1030,7 +1259,7 @@ function __wbg_get_imports() {
1030
1259
  __wbg_getRandomValues_c44a50d8cfdaebeb: function() { return handleError(function (arg0, arg1) {
1031
1260
  getObject(arg0).getRandomValues(getObject(arg1));
1032
1261
  }, arguments); },
1033
- __wbg_length_68a9d5278d084f4f: function(arg0) {
1262
+ __wbg_length_1f0964f4a5e2c6d8: function(arg0) {
1034
1263
  const ret = getObject(arg0).length;
1035
1264
  return ret;
1036
1265
  },
@@ -1038,11 +1267,11 @@ function __wbg_get_imports() {
1038
1267
  const ret = getObject(arg0).msCrypto;
1039
1268
  return addHeapObject(ret);
1040
1269
  },
1041
- __wbg_new_20b778a4c5c691c3: function() {
1270
+ __wbg_new_da52cf8fe3429cb2: function() {
1042
1271
  const ret = new Object();
1043
1272
  return addHeapObject(ret);
1044
1273
  },
1045
- __wbg_new_with_length_4b57a7a5dc67221c: function(arg0) {
1274
+ __wbg_new_with_length_e6785c33c8e4cce8: function(arg0) {
1046
1275
  const ret = new Uint8Array(arg0 >>> 0);
1047
1276
  return addHeapObject(ret);
1048
1277
  },
@@ -1054,7 +1283,7 @@ function __wbg_get_imports() {
1054
1283
  const ret = getObject(arg0).process;
1055
1284
  return addHeapObject(ret);
1056
1285
  },
1057
- __wbg_prototypesetcall_956c7493c68e29b4: function(arg0, arg1, arg2) {
1286
+ __wbg_prototypesetcall_4770620bbe4688a0: function(arg0, arg1, arg2) {
1058
1287
  Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), getObject(arg2));
1059
1288
  },
1060
1289
  __wbg_randomFillSync_6c25eac9869eb53c: function() { return handleError(function (arg0, arg1) {
@@ -1064,27 +1293,27 @@ function __wbg_get_imports() {
1064
1293
  const ret = module.require;
1065
1294
  return addHeapObject(ret);
1066
1295
  }, arguments); },
1067
- __wbg_set_a6ba3ac0e634b822: function() { return handleError(function (arg0, arg1, arg2) {
1296
+ __wbg_set_8535240470bf2500: function() { return handleError(function (arg0, arg1, arg2) {
1068
1297
  const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
1069
1298
  return ret;
1070
1299
  }, arguments); },
1071
- __wbg_static_accessor_GLOBAL_60a4124bab7dcc9a: function() {
1300
+ __wbg_static_accessor_GLOBAL_4ef717fb391d88b7: function() {
1072
1301
  const ret = typeof global === 'undefined' ? null : global;
1073
1302
  return isLikeNone(ret) ? 0 : addHeapObject(ret);
1074
1303
  },
1075
- __wbg_static_accessor_GLOBAL_THIS_95ca6460658b5d13: function() {
1304
+ __wbg_static_accessor_GLOBAL_THIS_8d1badc68b5a74f4: function() {
1076
1305
  const ret = typeof globalThis === 'undefined' ? null : globalThis;
1077
1306
  return isLikeNone(ret) ? 0 : addHeapObject(ret);
1078
1307
  },
1079
- __wbg_static_accessor_SELF_4c95f759a91e9aae: function() {
1308
+ __wbg_static_accessor_SELF_146583524fe1469b: function() {
1080
1309
  const ret = typeof self === 'undefined' ? null : self;
1081
1310
  return isLikeNone(ret) ? 0 : addHeapObject(ret);
1082
1311
  },
1083
- __wbg_static_accessor_WINDOW_44b435597f9e9ee7: function() {
1312
+ __wbg_static_accessor_WINDOW_f2829a2234d7819e: function() {
1084
1313
  const ret = typeof window === 'undefined' ? null : window;
1085
1314
  return isLikeNone(ret) ? 0 : addHeapObject(ret);
1086
1315
  },
1087
- __wbg_subarray_42216645a367cd7a: function(arg0, arg1, arg2) {
1316
+ __wbg_subarray_3ed232c8a6baee09: function(arg0, arg1, arg2) {
1088
1317
  const ret = getObject(arg0).subarray(arg1 >>> 0, arg2 >>> 0);
1089
1318
  return addHeapObject(ret);
1090
1319
  },
Binary file
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@f0rest8/metamorphic-crypto",
3
3
  "type": "module",
4
- "description": "Zero-knowledge end-to-end encryption with post-quantum hybrid KEM (ML-KEM-512/768/1024 + X25519)",
5
- "version": "0.6.0",
4
+ "description": "Zero-knowledge end-to-end encryption with post-quantum hybrid KEM (ML-KEM + X25519) and an opt-in CNSA 2.0 suite axis (matched-strength hybrid + pure ML-KEM-1024 / ML-DSA-87 / AES-256-GCM)",
5
+ "version": "0.7.1",
6
6
  "license": "MIT OR Apache-2.0",
7
7
  "repository": {
8
8
  "type": "git",