@oqs/liboqs-js 0.15.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/LICENSE.md +50 -0
- package/README.md +829 -0
- package/bin/cli.js +16 -0
- package/dist/classic-mceliece-348864.deno.js +0 -0
- package/dist/classic-mceliece-348864.min.js +0 -0
- package/dist/classic-mceliece-348864f.deno.js +0 -0
- package/dist/classic-mceliece-348864f.min.js +0 -0
- package/dist/classic-mceliece-460896.deno.js +0 -0
- package/dist/classic-mceliece-460896.min.js +0 -0
- package/dist/classic-mceliece-460896f.deno.js +0 -0
- package/dist/classic-mceliece-460896f.min.js +0 -0
- package/dist/classic-mceliece-6688128.deno.js +0 -0
- package/dist/classic-mceliece-6688128.min.js +0 -0
- package/dist/classic-mceliece-6688128f.deno.js +0 -0
- package/dist/classic-mceliece-6688128f.min.js +0 -0
- package/dist/classic-mceliece-6960119.deno.js +0 -0
- package/dist/classic-mceliece-6960119.min.js +0 -0
- package/dist/classic-mceliece-6960119f.deno.js +0 -0
- package/dist/classic-mceliece-6960119f.min.js +0 -0
- package/dist/classic-mceliece-8192128.deno.js +0 -0
- package/dist/classic-mceliece-8192128.min.js +0 -0
- package/dist/classic-mceliece-8192128f.deno.js +0 -0
- package/dist/classic-mceliece-8192128f.min.js +0 -0
- package/dist/cross-rsdp-128-balanced.deno.js +0 -0
- package/dist/cross-rsdp-128-balanced.min.js +0 -0
- package/dist/cross-rsdp-128-fast.deno.js +0 -0
- package/dist/cross-rsdp-128-fast.min.js +0 -0
- package/dist/cross-rsdp-128-small.deno.js +0 -0
- package/dist/cross-rsdp-128-small.min.js +0 -0
- package/dist/cross-rsdp-192-balanced.deno.js +0 -0
- package/dist/cross-rsdp-192-balanced.min.js +0 -0
- package/dist/cross-rsdp-192-fast.deno.js +0 -0
- package/dist/cross-rsdp-192-fast.min.js +0 -0
- package/dist/cross-rsdp-192-small.deno.js +0 -0
- package/dist/cross-rsdp-192-small.min.js +0 -0
- package/dist/cross-rsdp-256-balanced.deno.js +0 -0
- package/dist/cross-rsdp-256-balanced.min.js +0 -0
- package/dist/cross-rsdp-256-fast.deno.js +0 -0
- package/dist/cross-rsdp-256-fast.min.js +0 -0
- package/dist/cross-rsdp-256-small.deno.js +0 -0
- package/dist/cross-rsdp-256-small.min.js +0 -0
- package/dist/cross-rsdpg-128-balanced.deno.js +0 -0
- package/dist/cross-rsdpg-128-balanced.min.js +0 -0
- package/dist/cross-rsdpg-128-fast.deno.js +0 -0
- package/dist/cross-rsdpg-128-fast.min.js +0 -0
- package/dist/cross-rsdpg-128-small.deno.js +0 -0
- package/dist/cross-rsdpg-128-small.min.js +0 -0
- package/dist/cross-rsdpg-192-balanced.deno.js +0 -0
- package/dist/cross-rsdpg-192-balanced.min.js +0 -0
- package/dist/cross-rsdpg-192-fast.deno.js +0 -0
- package/dist/cross-rsdpg-192-fast.min.js +0 -0
- package/dist/cross-rsdpg-192-small.deno.js +0 -0
- package/dist/cross-rsdpg-192-small.min.js +0 -0
- package/dist/cross-rsdpg-256-balanced.deno.js +0 -0
- package/dist/cross-rsdpg-256-balanced.min.js +0 -0
- package/dist/cross-rsdpg-256-fast.deno.js +0 -0
- package/dist/cross-rsdpg-256-fast.min.js +0 -0
- package/dist/cross-rsdpg-256-small.deno.js +0 -0
- package/dist/cross-rsdpg-256-small.min.js +0 -0
- package/dist/falcon-1024.deno.js +0 -0
- package/dist/falcon-1024.min.js +0 -0
- package/dist/falcon-512.deno.js +0 -0
- package/dist/falcon-512.min.js +0 -0
- package/dist/falcon-padded-1024.deno.js +0 -0
- package/dist/falcon-padded-1024.min.js +0 -0
- package/dist/falcon-padded-512.deno.js +0 -0
- package/dist/falcon-padded-512.min.js +0 -0
- package/dist/frodokem-1344-aes.deno.js +0 -0
- package/dist/frodokem-1344-aes.min.js +0 -0
- package/dist/frodokem-1344-shake.deno.js +0 -0
- package/dist/frodokem-1344-shake.min.js +0 -0
- package/dist/frodokem-640-aes.deno.js +0 -0
- package/dist/frodokem-640-aes.min.js +0 -0
- package/dist/frodokem-640-shake.deno.js +0 -0
- package/dist/frodokem-640-shake.min.js +0 -0
- package/dist/frodokem-976-aes.deno.js +0 -0
- package/dist/frodokem-976-aes.min.js +0 -0
- package/dist/frodokem-976-shake.deno.js +0 -0
- package/dist/frodokem-976-shake.min.js +0 -0
- package/dist/hqc-128.deno.js +0 -0
- package/dist/hqc-128.min.js +0 -0
- package/dist/hqc-192.deno.js +0 -0
- package/dist/hqc-192.min.js +0 -0
- package/dist/hqc-256.deno.js +0 -0
- package/dist/hqc-256.min.js +0 -0
- package/dist/kyber-1024.deno.js +0 -0
- package/dist/kyber-1024.min.js +0 -0
- package/dist/kyber-512.deno.js +0 -0
- package/dist/kyber-512.min.js +0 -0
- package/dist/kyber-768.deno.js +0 -0
- package/dist/kyber-768.min.js +0 -0
- package/dist/mayo-1.deno.js +0 -0
- package/dist/mayo-1.min.js +0 -0
- package/dist/mayo-2.deno.js +0 -0
- package/dist/mayo-2.min.js +0 -0
- package/dist/mayo-3.deno.js +0 -0
- package/dist/mayo-3.min.js +0 -0
- package/dist/mayo-5.deno.js +0 -0
- package/dist/mayo-5.min.js +0 -0
- package/dist/ml-dsa-44.deno.js +0 -0
- package/dist/ml-dsa-44.min.js +0 -0
- package/dist/ml-dsa-65.deno.js +0 -0
- package/dist/ml-dsa-65.min.js +0 -0
- package/dist/ml-dsa-87.deno.js +0 -0
- package/dist/ml-dsa-87.min.js +0 -0
- package/dist/ml-kem-1024.deno.js +0 -0
- package/dist/ml-kem-1024.min.js +0 -0
- package/dist/ml-kem-512.deno.js +0 -0
- package/dist/ml-kem-512.min.js +0 -0
- package/dist/ml-kem-768.deno.js +0 -0
- package/dist/ml-kem-768.min.js +0 -0
- package/dist/ntru-hps-2048-509.deno.js +0 -0
- package/dist/ntru-hps-2048-509.min.js +0 -0
- package/dist/ntru-hps-2048-677.deno.js +0 -0
- package/dist/ntru-hps-2048-677.min.js +0 -0
- package/dist/ntru-hps-4096-1229.deno.js +0 -0
- package/dist/ntru-hps-4096-1229.min.js +0 -0
- package/dist/ntru-hps-4096-821.deno.js +0 -0
- package/dist/ntru-hps-4096-821.min.js +0 -0
- package/dist/ntru-hrss-1373.deno.js +0 -0
- package/dist/ntru-hrss-1373.min.js +0 -0
- package/dist/ntru-hrss-701.deno.js +0 -0
- package/dist/ntru-hrss-701.min.js +0 -0
- package/dist/ov-iii-pkc-skc.deno.js +0 -0
- package/dist/ov-iii-pkc-skc.min.js +0 -0
- package/dist/ov-iii-pkc.deno.js +0 -0
- package/dist/ov-iii-pkc.min.js +0 -0
- package/dist/ov-iii.deno.js +0 -0
- package/dist/ov-iii.min.js +0 -0
- package/dist/ov-ip-pkc-skc.deno.js +0 -0
- package/dist/ov-ip-pkc-skc.min.js +0 -0
- package/dist/ov-ip-pkc.deno.js +0 -0
- package/dist/ov-ip-pkc.min.js +0 -0
- package/dist/ov-ip.deno.js +0 -0
- package/dist/ov-ip.min.js +0 -0
- package/dist/ov-is-pkc-skc.deno.js +0 -0
- package/dist/ov-is-pkc-skc.min.js +0 -0
- package/dist/ov-is-pkc.deno.js +0 -0
- package/dist/ov-is-pkc.min.js +0 -0
- package/dist/ov-is.deno.js +0 -0
- package/dist/ov-is.min.js +0 -0
- package/dist/ov-v-pkc-skc.deno.js +0 -0
- package/dist/ov-v-pkc-skc.min.js +0 -0
- package/dist/ov-v-pkc.deno.js +0 -0
- package/dist/ov-v-pkc.min.js +0 -0
- package/dist/ov-v.deno.js +0 -0
- package/dist/ov-v.min.js +0 -0
- package/dist/slh-dsa-sha2-128f.deno.js +0 -0
- package/dist/slh-dsa-sha2-128f.min.js +0 -0
- package/dist/slh-dsa-sha2-128s.deno.js +0 -0
- package/dist/slh-dsa-sha2-128s.min.js +0 -0
- package/dist/slh-dsa-sha2-192f.deno.js +0 -0
- package/dist/slh-dsa-sha2-192f.min.js +0 -0
- package/dist/slh-dsa-sha2-192s.deno.js +0 -0
- package/dist/slh-dsa-sha2-192s.min.js +0 -0
- package/dist/slh-dsa-sha2-256f.deno.js +0 -0
- package/dist/slh-dsa-sha2-256f.min.js +0 -0
- package/dist/slh-dsa-sha2-256s.deno.js +0 -0
- package/dist/slh-dsa-sha2-256s.min.js +0 -0
- package/dist/slh-dsa-shake-128f.deno.js +0 -0
- package/dist/slh-dsa-shake-128f.min.js +0 -0
- package/dist/slh-dsa-shake-128s.deno.js +0 -0
- package/dist/slh-dsa-shake-128s.min.js +0 -0
- package/dist/slh-dsa-shake-192f.deno.js +0 -0
- package/dist/slh-dsa-shake-192f.min.js +0 -0
- package/dist/slh-dsa-shake-192s.deno.js +0 -0
- package/dist/slh-dsa-shake-192s.min.js +0 -0
- package/dist/slh-dsa-shake-256f.deno.js +0 -0
- package/dist/slh-dsa-shake-256f.min.js +0 -0
- package/dist/slh-dsa-shake-256s.deno.js +0 -0
- package/dist/slh-dsa-shake-256s.min.js +0 -0
- package/dist/snova-24-5-4-esk.deno.js +0 -0
- package/dist/snova-24-5-4-esk.min.js +0 -0
- package/dist/snova-24-5-4-shake-esk.deno.js +0 -0
- package/dist/snova-24-5-4-shake-esk.min.js +0 -0
- package/dist/snova-24-5-4-shake.deno.js +0 -0
- package/dist/snova-24-5-4-shake.min.js +0 -0
- package/dist/snova-24-5-4.deno.js +0 -0
- package/dist/snova-24-5-4.min.js +0 -0
- package/dist/snova-24-5-5.deno.js +0 -0
- package/dist/snova-24-5-5.min.js +0 -0
- package/dist/snova-25-8-3.deno.js +0 -0
- package/dist/snova-25-8-3.min.js +0 -0
- package/dist/snova-29-6-5.deno.js +0 -0
- package/dist/snova-29-6-5.min.js +0 -0
- package/dist/snova-37-17-2.deno.js +0 -0
- package/dist/snova-37-17-2.min.js +0 -0
- package/dist/snova-37-8-4.deno.js +0 -0
- package/dist/snova-37-8-4.min.js +0 -0
- package/dist/snova-49-11-3.deno.js +0 -0
- package/dist/snova-49-11-3.min.js +0 -0
- package/dist/snova-56-25-2.deno.js +0 -0
- package/dist/snova-56-25-2.min.js +0 -0
- package/dist/snova-60-10-4.deno.js +0 -0
- package/dist/snova-60-10-4.min.js +0 -0
- package/dist/sntrup761.deno.js +0 -0
- package/dist/sntrup761.min.js +0 -0
- package/package.json +108 -0
- package/src/algorithms/kem/classic-mceliece/classic-mceliece-348864.js +336 -0
- package/src/algorithms/kem/classic-mceliece/classic-mceliece-348864f.js +336 -0
- package/src/algorithms/kem/classic-mceliece/classic-mceliece-460896.js +336 -0
- package/src/algorithms/kem/classic-mceliece/classic-mceliece-460896f.js +336 -0
- package/src/algorithms/kem/classic-mceliece/classic-mceliece-6688128.js +336 -0
- package/src/algorithms/kem/classic-mceliece/classic-mceliece-6688128f.js +336 -0
- package/src/algorithms/kem/classic-mceliece/classic-mceliece-6960119.js +336 -0
- package/src/algorithms/kem/classic-mceliece/classic-mceliece-6960119f.js +336 -0
- package/src/algorithms/kem/classic-mceliece/classic-mceliece-8192128.js +336 -0
- package/src/algorithms/kem/classic-mceliece/classic-mceliece-8192128f.js +336 -0
- package/src/algorithms/kem/frodokem/efrodokem-1344-aes.js +366 -0
- package/src/algorithms/kem/frodokem/efrodokem-1344-shake.js +366 -0
- package/src/algorithms/kem/frodokem/efrodokem-640-aes.js +366 -0
- package/src/algorithms/kem/frodokem/efrodokem-640-shake.js +366 -0
- package/src/algorithms/kem/frodokem/efrodokem-976-aes.js +366 -0
- package/src/algorithms/kem/frodokem/efrodokem-976-shake.js +366 -0
- package/src/algorithms/kem/frodokem/frodokem-1344-aes.js +366 -0
- package/src/algorithms/kem/frodokem/frodokem-1344-shake.js +366 -0
- package/src/algorithms/kem/frodokem/frodokem-640-aes.js +366 -0
- package/src/algorithms/kem/frodokem/frodokem-640-shake.js +366 -0
- package/src/algorithms/kem/frodokem/frodokem-976-aes.js +366 -0
- package/src/algorithms/kem/frodokem/frodokem-976-shake.js +366 -0
- package/src/algorithms/kem/hqc/hqc-128.js +366 -0
- package/src/algorithms/kem/hqc/hqc-192.js +366 -0
- package/src/algorithms/kem/hqc/hqc-256.js +366 -0
- package/src/algorithms/kem/kyber/kyber-1024.js +349 -0
- package/src/algorithms/kem/kyber/kyber-512.js +347 -0
- package/src/algorithms/kem/kyber/kyber-768.js +348 -0
- package/src/algorithms/kem/ml-kem/ml-kem-1024.js +345 -0
- package/src/algorithms/kem/ml-kem/ml-kem-512.js +345 -0
- package/src/algorithms/kem/ml-kem/ml-kem-768.js +344 -0
- package/src/algorithms/kem/ntru/ntru-hps-2048-509.js +366 -0
- package/src/algorithms/kem/ntru/ntru-hps-2048-677.js +366 -0
- package/src/algorithms/kem/ntru/ntru-hps-4096-1229.js +366 -0
- package/src/algorithms/kem/ntru/ntru-hps-4096-821.js +366 -0
- package/src/algorithms/kem/ntru/ntru-hrss-1373.js +366 -0
- package/src/algorithms/kem/ntru/ntru-hrss-701.js +366 -0
- package/src/algorithms/kem/ntru/sntrup761.js +367 -0
- package/src/algorithms/sig/cross/cross-rsdp-128-balanced.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdp-128-fast.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdp-128-small.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdp-192-balanced.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdp-192-fast.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdp-192-small.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdp-256-balanced.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdp-256-fast.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdp-256-small.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdpg-128-balanced.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdpg-128-fast.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdpg-128-small.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdpg-192-balanced.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdpg-192-fast.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdpg-192-small.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdpg-256-balanced.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdpg-256-fast.js +391 -0
- package/src/algorithms/sig/cross/cross-rsdpg-256-small.js +391 -0
- package/src/algorithms/sig/falcon/falcon-1024.js +378 -0
- package/src/algorithms/sig/falcon/falcon-512.js +379 -0
- package/src/algorithms/sig/falcon/falcon-padded-1024.js +380 -0
- package/src/algorithms/sig/falcon/falcon-padded-512.js +380 -0
- package/src/algorithms/sig/mayo/mayo-1.js +390 -0
- package/src/algorithms/sig/mayo/mayo-2.js +390 -0
- package/src/algorithms/sig/mayo/mayo-3.js +390 -0
- package/src/algorithms/sig/mayo/mayo-5.js +390 -0
- package/src/algorithms/sig/ml-dsa/ml-dsa-44.js +338 -0
- package/src/algorithms/sig/ml-dsa/ml-dsa-65.js +338 -0
- package/src/algorithms/sig/ml-dsa/ml-dsa-87.js +338 -0
- package/src/algorithms/sig/slh-dsa/slh-dsa-sha2-128f.js +367 -0
- package/src/algorithms/sig/slh-dsa/slh-dsa-sha2-128s.js +367 -0
- package/src/algorithms/sig/slh-dsa/slh-dsa-sha2-192f.js +367 -0
- package/src/algorithms/sig/slh-dsa/slh-dsa-sha2-192s.js +367 -0
- package/src/algorithms/sig/slh-dsa/slh-dsa-sha2-256f.js +367 -0
- package/src/algorithms/sig/slh-dsa/slh-dsa-sha2-256s.js +367 -0
- package/src/algorithms/sig/slh-dsa/slh-dsa-shake-128f.js +367 -0
- package/src/algorithms/sig/slh-dsa/slh-dsa-shake-128s.js +367 -0
- package/src/algorithms/sig/slh-dsa/slh-dsa-shake-192f.js +367 -0
- package/src/algorithms/sig/slh-dsa/slh-dsa-shake-192s.js +367 -0
- package/src/algorithms/sig/slh-dsa/slh-dsa-shake-256f.js +367 -0
- package/src/algorithms/sig/slh-dsa/slh-dsa-shake-256s.js +367 -0
- package/src/algorithms/sig/snova/snova-24-5-4-esk.js +391 -0
- package/src/algorithms/sig/snova/snova-24-5-4-shake-esk.js +391 -0
- package/src/algorithms/sig/snova/snova-24-5-4-shake.js +391 -0
- package/src/algorithms/sig/snova/snova-24-5-4.js +391 -0
- package/src/algorithms/sig/snova/snova-24-5-5.js +391 -0
- package/src/algorithms/sig/snova/snova-25-8-3.js +391 -0
- package/src/algorithms/sig/snova/snova-29-6-5.js +391 -0
- package/src/algorithms/sig/snova/snova-37-17-2.js +391 -0
- package/src/algorithms/sig/snova/snova-37-8-4.js +391 -0
- package/src/algorithms/sig/snova/snova-49-11-3.js +391 -0
- package/src/algorithms/sig/snova/snova-56-25-2.js +391 -0
- package/src/algorithms/sig/snova/snova-60-10-4.js +391 -0
- package/src/algorithms/sig/uov/ov-iii-pkc-skc.js +390 -0
- package/src/algorithms/sig/uov/ov-iii-pkc.js +390 -0
- package/src/algorithms/sig/uov/ov-iii.js +390 -0
- package/src/algorithms/sig/uov/ov-ip-pkc-skc.js +390 -0
- package/src/algorithms/sig/uov/ov-ip-pkc.js +390 -0
- package/src/algorithms/sig/uov/ov-ip.js +390 -0
- package/src/algorithms/sig/uov/ov-is-pkc-skc.js +390 -0
- package/src/algorithms/sig/uov/ov-is-pkc.js +390 -0
- package/src/algorithms/sig/uov/ov-is.js +390 -0
- package/src/algorithms/sig/uov/ov-v-pkc-skc.js +390 -0
- package/src/algorithms/sig/uov/ov-v-pkc.js +390 -0
- package/src/algorithms/sig/uov/ov-v.js +390 -0
- package/src/cli/algorithms.js +254 -0
- package/src/cli/commands/info.js +35 -0
- package/src/cli/commands/kem.js +91 -0
- package/src/cli/commands/list.js +30 -0
- package/src/cli/commands/sig.js +98 -0
- package/src/cli/index.js +86 -0
- package/src/cli/io.js +147 -0
- package/src/cli/parser.js +64 -0
- package/src/core/errors.js +75 -0
- package/src/core/validation.js +28 -0
- package/src/index.js +164 -0
- package/src/kem.js +60 -0
- package/src/sig.js +87 -0
- package/src/types/algorithms.d.ts +1543 -0
- package/src/types/errors.d.ts +60 -0
- package/src/types/index.d.ts +9 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Classic-McEliece-8192128f KEM algorithm implementation
|
|
3
|
+
* @module algorithms/kem/classic-mceliece/classic-mceliece-8192128f
|
|
4
|
+
* @description
|
|
5
|
+
* Classic-McEliece-8192128f is a code-based key encapsulation mechanism providing NIST security level 5.
|
|
6
|
+
* It is based on the McEliece cryptosystem using binary Goppa codes.
|
|
7
|
+
*
|
|
8
|
+
* Key features:
|
|
9
|
+
* - Code-based cryptography (Goppa codes)
|
|
10
|
+
* - Security Level 5 (256-bit classical, quantum-resistant)
|
|
11
|
+
* - Extremely conservative security margin
|
|
12
|
+
* - IND-CCA2 security
|
|
13
|
+
* - Very large public keys, small ciphertexts
|
|
14
|
+
*
|
|
15
|
+
* @see {@link https://classic.mceliece.org/} - Classic McEliece specification
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { LibOQSError, LibOQSInitError, LibOQSOperationError, LibOQSValidationError } from '../../../core/errors.js';
|
|
19
|
+
import { isUint8Array } from '../../../core/validation.js';
|
|
20
|
+
|
|
21
|
+
// Dynamic module loading for cross-runtime compatibility
|
|
22
|
+
async function loadModule() {
|
|
23
|
+
const isDeno = typeof Deno !== 'undefined';
|
|
24
|
+
const modulePath = isDeno
|
|
25
|
+
? `../../../../dist/classic-mceliece-8192128f.deno.js`
|
|
26
|
+
: `../../../../dist/classic-mceliece-8192128f.min.js`;
|
|
27
|
+
|
|
28
|
+
const module = await import(modulePath);
|
|
29
|
+
return module.default;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* CLASSIC-MCELIECE-8192128F-INFO algorithm constants and metadata
|
|
34
|
+
* @type {{readonly name: 'Classic-McEliece-8192128f', readonly identifier: 'Classic-McEliece-8192128f', readonly type: 'kem', readonly securityLevel: 5, readonly standardized: false, readonly description: string, readonly keySize: {readonly publicKey: 1357824, readonly secretKey: 14120, readonly ciphertext: 208, readonly sharedSecret: 32}}}
|
|
35
|
+
*/
|
|
36
|
+
export const CLASSIC_MCELIECE_8192128F_INFO = {
|
|
37
|
+
name: 'Classic-McEliece-8192128f',
|
|
38
|
+
identifier: 'Classic-McEliece-8192128f',
|
|
39
|
+
type: 'kem',
|
|
40
|
+
securityLevel: 5,
|
|
41
|
+
standardized: false,
|
|
42
|
+
description: 'Classic McEliece 8192128f code-based KEM (NIST Level 5, 256-bit quantum security)',
|
|
43
|
+
keySize: {
|
|
44
|
+
publicKey: 1357824,
|
|
45
|
+
secretKey: 14120,
|
|
46
|
+
ciphertext: 208,
|
|
47
|
+
sharedSecret: 32
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Load and initialize Classic-McEliece-8192128f module
|
|
53
|
+
* @returns {Promise<ClassicMcEliece8192128f>} Initialized Classic-McEliece-8192128f instance
|
|
54
|
+
* @throws {LibOQSInitError} If initialization fails
|
|
55
|
+
* @example
|
|
56
|
+
* import { createClassicMcEliece8192128f } from '@oqs/liboqs-js';
|
|
57
|
+
* const kem = await createClassicMcEliece8192128f();
|
|
58
|
+
*/
|
|
59
|
+
export async function createClassicMcEliece8192128f() {
|
|
60
|
+
const moduleFactory = await loadModule();
|
|
61
|
+
const wasmModule = await moduleFactory();
|
|
62
|
+
wasmModule._OQS_init();
|
|
63
|
+
|
|
64
|
+
const algoName = CLASSIC_MCELIECE_8192128F_INFO.identifier;
|
|
65
|
+
const nameLen = wasmModule.lengthBytesUTF8(algoName);
|
|
66
|
+
const namePtr = wasmModule._malloc(nameLen + 1);
|
|
67
|
+
wasmModule.stringToUTF8(algoName, namePtr, nameLen + 1);
|
|
68
|
+
|
|
69
|
+
const kemPtr = wasmModule._OQS_KEM_new(namePtr);
|
|
70
|
+
wasmModule._free(namePtr);
|
|
71
|
+
|
|
72
|
+
if (!kemPtr) {
|
|
73
|
+
throw new LibOQSInitError('Classic-McEliece-8192128f', 'Failed to create KEM instance');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return new ClassicMcEliece8192128f(wasmModule, kemPtr);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Classic-McEliece-8192128f wrapper class providing high-level KEM operations
|
|
81
|
+
*
|
|
82
|
+
* This class wraps the low-level WASM module to provide a user-friendly
|
|
83
|
+
* interface for Classic-McEliece-8192128f operations with automatic memory management
|
|
84
|
+
* and input validation.
|
|
85
|
+
*
|
|
86
|
+
* @class ClassicMcEliece8192128f
|
|
87
|
+
* @example
|
|
88
|
+
* import { createClassicMcEliece8192128f } from '@oqs/liboqs-js';
|
|
89
|
+
*
|
|
90
|
+
* const kem = await createClassicMcEliece8192128f();
|
|
91
|
+
* const { publicKey, secretKey } = kem.generateKeyPair();
|
|
92
|
+
* const { ciphertext, sharedSecret } = kem.encapsulate(publicKey);
|
|
93
|
+
* kem.destroy();
|
|
94
|
+
*/
|
|
95
|
+
export class ClassicMcEliece8192128f {
|
|
96
|
+
/** @type {Object} @private */
|
|
97
|
+
#wasmModule;
|
|
98
|
+
/** @type {number} @private */
|
|
99
|
+
#kemPtr;
|
|
100
|
+
/** @type {boolean} @private */
|
|
101
|
+
#destroyed = false;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @param {Object} wasmModule - Emscripten WASM module
|
|
105
|
+
* @param {number} kemPtr - Pointer to KEM instance
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
constructor(wasmModule, kemPtr) {
|
|
109
|
+
this.#wasmModule = wasmModule;
|
|
110
|
+
this.#kemPtr = kemPtr;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Generate a new keypair for Classic-McEliece-8192128f
|
|
115
|
+
*
|
|
116
|
+
* Generates a public/private keypair using the algorithm's internal
|
|
117
|
+
* random number generator. The secret key must be kept confidential.
|
|
118
|
+
*
|
|
119
|
+
* @returns {{publicKey: Uint8Array, secretKey: Uint8Array}}
|
|
120
|
+
* @throws {LibOQSOperationError} If keypair generation fails
|
|
121
|
+
* @throws {LibOQSError} If instance has been destroyed
|
|
122
|
+
* @example
|
|
123
|
+
* const { publicKey, secretKey } = kem.generateKeyPair();
|
|
124
|
+
* // publicKey: 1357824 bytes
|
|
125
|
+
* // secretKey: 14120 bytes (keep confidential!)
|
|
126
|
+
*/
|
|
127
|
+
generateKeyPair() {
|
|
128
|
+
this.#checkDestroyed();
|
|
129
|
+
|
|
130
|
+
const publicKeyPtr = this.#wasmModule._malloc(CLASSIC_MCELIECE_8192128F_INFO.keySize.publicKey);
|
|
131
|
+
const secretKeyPtr = this.#wasmModule._malloc(CLASSIC_MCELIECE_8192128F_INFO.keySize.secretKey);
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
const result = this.#wasmModule._OQS_KEM_keypair(this.#kemPtr, publicKeyPtr, secretKeyPtr);
|
|
135
|
+
|
|
136
|
+
if (result !== 0) {
|
|
137
|
+
throw new LibOQSOperationError('keypair', 'Classic-McEliece-8192128f', `Error code: ${result}`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const publicKey = new Uint8Array(CLASSIC_MCELIECE_8192128F_INFO.keySize.publicKey);
|
|
141
|
+
const secretKey = new Uint8Array(CLASSIC_MCELIECE_8192128F_INFO.keySize.secretKey);
|
|
142
|
+
|
|
143
|
+
publicKey.set(this.#wasmModule.HEAPU8.subarray(publicKeyPtr, publicKeyPtr + CLASSIC_MCELIECE_8192128F_INFO.keySize.publicKey));
|
|
144
|
+
secretKey.set(this.#wasmModule.HEAPU8.subarray(secretKeyPtr, secretKeyPtr + CLASSIC_MCELIECE_8192128F_INFO.keySize.secretKey));
|
|
145
|
+
|
|
146
|
+
return { publicKey, secretKey };
|
|
147
|
+
|
|
148
|
+
} finally {
|
|
149
|
+
this.#wasmModule._free(publicKeyPtr);
|
|
150
|
+
this.#wasmModule._free(secretKeyPtr);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Encapsulate a shared secret using a public key
|
|
156
|
+
*
|
|
157
|
+
* Generates a random shared secret and encapsulates it using the
|
|
158
|
+
* provided public key. The shared secret can be used for symmetric
|
|
159
|
+
* encryption.
|
|
160
|
+
*
|
|
161
|
+
* @param {Uint8Array} publicKey - Recipient's public key (1357824 bytes)
|
|
162
|
+
* @returns {{ciphertext: Uint8Array, sharedSecret: Uint8Array}}
|
|
163
|
+
* @throws {LibOQSValidationError} If public key is invalid
|
|
164
|
+
* @throws {LibOQSOperationError} If encapsulation fails
|
|
165
|
+
* @throws {LibOQSError} If instance has been destroyed
|
|
166
|
+
* @example
|
|
167
|
+
* const { ciphertext, sharedSecret } = kem.encapsulate(recipientPublicKey);
|
|
168
|
+
* // ciphertext: 208 bytes (send to recipient)
|
|
169
|
+
* // sharedSecret: 32 bytes (use for symmetric encryption)
|
|
170
|
+
*/
|
|
171
|
+
encapsulate(publicKey) {
|
|
172
|
+
this.#checkDestroyed();
|
|
173
|
+
this.#validatePublicKey(publicKey);
|
|
174
|
+
|
|
175
|
+
const publicKeyPtr = this.#wasmModule._malloc(CLASSIC_MCELIECE_8192128F_INFO.keySize.publicKey);
|
|
176
|
+
const ciphertextPtr = this.#wasmModule._malloc(CLASSIC_MCELIECE_8192128F_INFO.keySize.ciphertext);
|
|
177
|
+
const sharedSecretPtr = this.#wasmModule._malloc(CLASSIC_MCELIECE_8192128F_INFO.keySize.sharedSecret);
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
this.#wasmModule.HEAPU8.set(publicKey, publicKeyPtr);
|
|
181
|
+
|
|
182
|
+
const result = this.#wasmModule._OQS_KEM_encaps(
|
|
183
|
+
this.#kemPtr,
|
|
184
|
+
ciphertextPtr,
|
|
185
|
+
sharedSecretPtr,
|
|
186
|
+
publicKeyPtr
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
if (result !== 0) {
|
|
190
|
+
throw new LibOQSOperationError('encaps', 'Classic-McEliece-8192128f', `Error code: ${result}`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const ciphertext = new Uint8Array(CLASSIC_MCELIECE_8192128F_INFO.keySize.ciphertext);
|
|
194
|
+
const sharedSecret = new Uint8Array(CLASSIC_MCELIECE_8192128F_INFO.keySize.sharedSecret);
|
|
195
|
+
|
|
196
|
+
ciphertext.set(this.#wasmModule.HEAPU8.subarray(ciphertextPtr, ciphertextPtr + CLASSIC_MCELIECE_8192128F_INFO.keySize.ciphertext));
|
|
197
|
+
sharedSecret.set(this.#wasmModule.HEAPU8.subarray(sharedSecretPtr, sharedSecretPtr + CLASSIC_MCELIECE_8192128F_INFO.keySize.sharedSecret));
|
|
198
|
+
|
|
199
|
+
return { ciphertext, sharedSecret };
|
|
200
|
+
|
|
201
|
+
} finally {
|
|
202
|
+
this.#wasmModule._free(publicKeyPtr);
|
|
203
|
+
this.#wasmModule._free(ciphertextPtr);
|
|
204
|
+
this.#wasmModule._free(sharedSecretPtr);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Decapsulate a shared secret using a secret key
|
|
210
|
+
*
|
|
211
|
+
* Recovers the shared secret from a ciphertext using the secret key.
|
|
212
|
+
* The recovered shared secret will match the one generated during
|
|
213
|
+
* encapsulation.
|
|
214
|
+
*
|
|
215
|
+
* @param {Uint8Array} ciphertext - Ciphertext received (208 bytes)
|
|
216
|
+
* @param {Uint8Array} secretKey - Recipient's secret key (14120 bytes)
|
|
217
|
+
* @returns {Uint8Array} Recovered shared secret (32 bytes)
|
|
218
|
+
* @throws {LibOQSValidationError} If inputs are invalid
|
|
219
|
+
* @throws {LibOQSOperationError} If decapsulation fails
|
|
220
|
+
* @throws {LibOQSError} If instance has been destroyed
|
|
221
|
+
* @example
|
|
222
|
+
* const sharedSecret = kem.decapsulate(ciphertext, mySecretKey);
|
|
223
|
+
* // sharedSecret: 32 bytes (matches sender's shared secret)
|
|
224
|
+
*/
|
|
225
|
+
decapsulate(ciphertext, secretKey) {
|
|
226
|
+
this.#checkDestroyed();
|
|
227
|
+
this.#validateCiphertext(ciphertext);
|
|
228
|
+
this.#validateSecretKey(secretKey);
|
|
229
|
+
|
|
230
|
+
const ciphertextPtr = this.#wasmModule._malloc(CLASSIC_MCELIECE_8192128F_INFO.keySize.ciphertext);
|
|
231
|
+
const secretKeyPtr = this.#wasmModule._malloc(CLASSIC_MCELIECE_8192128F_INFO.keySize.secretKey);
|
|
232
|
+
const sharedSecretPtr = this.#wasmModule._malloc(CLASSIC_MCELIECE_8192128F_INFO.keySize.sharedSecret);
|
|
233
|
+
|
|
234
|
+
try {
|
|
235
|
+
this.#wasmModule.HEAPU8.set(ciphertext, ciphertextPtr);
|
|
236
|
+
this.#wasmModule.HEAPU8.set(secretKey, secretKeyPtr);
|
|
237
|
+
|
|
238
|
+
const result = this.#wasmModule._OQS_KEM_decaps(
|
|
239
|
+
this.#kemPtr,
|
|
240
|
+
sharedSecretPtr,
|
|
241
|
+
ciphertextPtr,
|
|
242
|
+
secretKeyPtr
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
if (result !== 0) {
|
|
246
|
+
throw new LibOQSOperationError('decaps', 'Classic-McEliece-8192128f', `Error code: ${result}`);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const sharedSecret = new Uint8Array(CLASSIC_MCELIECE_8192128F_INFO.keySize.sharedSecret);
|
|
250
|
+
sharedSecret.set(this.#wasmModule.HEAPU8.subarray(sharedSecretPtr, sharedSecretPtr + CLASSIC_MCELIECE_8192128F_INFO.keySize.sharedSecret));
|
|
251
|
+
|
|
252
|
+
return sharedSecret;
|
|
253
|
+
|
|
254
|
+
} finally {
|
|
255
|
+
this.#wasmModule._free(ciphertextPtr);
|
|
256
|
+
this.#wasmModule._free(secretKeyPtr);
|
|
257
|
+
this.#wasmModule._free(sharedSecretPtr);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Clean up resources and free WASM memory
|
|
263
|
+
*
|
|
264
|
+
* This method should be called when you're done using the instance
|
|
265
|
+
* to free WASM memory. After calling destroy(), the instance cannot
|
|
266
|
+
* be used for further operations.
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* const kem = await createClassicMcEliece8192128f();
|
|
270
|
+
* // ... use kem ...
|
|
271
|
+
* kem.destroy();
|
|
272
|
+
*/
|
|
273
|
+
destroy() {
|
|
274
|
+
if (!this.#destroyed) {
|
|
275
|
+
if (this.#kemPtr) {
|
|
276
|
+
this.#wasmModule._OQS_KEM_free(this.#kemPtr);
|
|
277
|
+
this.#kemPtr = null;
|
|
278
|
+
}
|
|
279
|
+
this.#destroyed = true;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Enables automatic cleanup via `using` declarations
|
|
285
|
+
* @example
|
|
286
|
+
* using instance = await create...();
|
|
287
|
+
* // automatically cleaned up at end of scope
|
|
288
|
+
*/
|
|
289
|
+
[Symbol.dispose]() {
|
|
290
|
+
this.destroy();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Get algorithm information and constants
|
|
295
|
+
* @returns {typeof CLASSIC_MCELIECE_8192128F_INFO} Algorithm metadata (copy of CLASSIC_MCELIECE_8192128F_INFO)
|
|
296
|
+
* @example
|
|
297
|
+
* const info = kem.info;
|
|
298
|
+
* console.log(info.keySize.publicKey); // 1357824
|
|
299
|
+
*/
|
|
300
|
+
get info() {
|
|
301
|
+
return CLASSIC_MCELIECE_8192128F_INFO;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
#checkDestroyed() {
|
|
305
|
+
if (this.#destroyed) {
|
|
306
|
+
throw new LibOQSError('Instance has been destroyed', 'Classic-McEliece-8192128f');
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
#validatePublicKey(publicKey) {
|
|
311
|
+
if (!isUint8Array(publicKey) || publicKey.length !== CLASSIC_MCELIECE_8192128F_INFO.keySize.publicKey) {
|
|
312
|
+
throw new LibOQSValidationError(
|
|
313
|
+
`Invalid public key: expected ${CLASSIC_MCELIECE_8192128F_INFO.keySize.publicKey} bytes, got ${publicKey?.length ?? 'null'}`,
|
|
314
|
+
'Classic-McEliece-8192128f'
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
#validateSecretKey(secretKey) {
|
|
320
|
+
if (!isUint8Array(secretKey) || secretKey.length !== CLASSIC_MCELIECE_8192128F_INFO.keySize.secretKey) {
|
|
321
|
+
throw new LibOQSValidationError(
|
|
322
|
+
`Invalid secret key: expected ${CLASSIC_MCELIECE_8192128F_INFO.keySize.secretKey} bytes, got ${secretKey?.length ?? 'null'}`,
|
|
323
|
+
'Classic-McEliece-8192128f'
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
#validateCiphertext(ciphertext) {
|
|
329
|
+
if (!isUint8Array(ciphertext) || ciphertext.length !== CLASSIC_MCELIECE_8192128F_INFO.keySize.ciphertext) {
|
|
330
|
+
throw new LibOQSValidationError(
|
|
331
|
+
`Invalid ciphertext: expected ${CLASSIC_MCELIECE_8192128F_INFO.keySize.ciphertext} bytes, got ${ciphertext?.length ?? 'null'}`,
|
|
332
|
+
'Classic-McEliece-8192128f'
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview eFrodoKEM-1344-AES KEM algorithm implementation
|
|
3
|
+
* @module algorithms/kem/frodokem/efrodokem-1344-aes
|
|
4
|
+
* @description
|
|
5
|
+
* eFrodoKEM-1344-AES is a lattice-based key encapsulation mechanism providing NIST security level 5.
|
|
6
|
+
* It uses learning with errors (LWE) and AES for pseudorandom generation.
|
|
7
|
+
*
|
|
8
|
+
* Key features:
|
|
9
|
+
* - Lattice-based cryptography (LWE problem)
|
|
10
|
+
* - Security Level 5 (256-bit classical, quantum-resistant)
|
|
11
|
+
* - Conservative security margin
|
|
12
|
+
* - AES-based pseudorandom generation
|
|
13
|
+
*
|
|
14
|
+
* @see {@link https://frodokem.org/} - FrodoKEM specification
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { LibOQSError, LibOQSInitError, LibOQSOperationError, LibOQSValidationError } from '../../../core/errors.js';
|
|
18
|
+
import { isUint8Array } from '../../../core/validation.js';
|
|
19
|
+
|
|
20
|
+
// Dynamic module loading for cross-runtime compatibility
|
|
21
|
+
async function loadModule() {
|
|
22
|
+
const isDeno = typeof Deno !== 'undefined';
|
|
23
|
+
const modulePath = isDeno
|
|
24
|
+
? `../../../../dist/frodokem-1344-aes.deno.js`
|
|
25
|
+
: `../../../../dist/frodokem-1344-aes.min.js`;
|
|
26
|
+
|
|
27
|
+
const module = await import(modulePath);
|
|
28
|
+
return module.default;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* EFRODOKEM-1344-AES-INFO algorithm constants and metadata
|
|
33
|
+
* @type {{readonly name: 'eFrodoKEM-1344-AES', readonly identifier: 'eFrodoKEM-1344-AES', readonly type: 'kem', readonly securityLevel: 5, readonly standardized: false, readonly description: string, readonly keySize: {readonly publicKey: 21520, readonly secretKey: 43088, readonly ciphertext: 21632, readonly sharedSecret: 32}}}
|
|
34
|
+
*/
|
|
35
|
+
export const EFRODOKEM_1344_AES_INFO = {
|
|
36
|
+
name: 'eFrodoKEM-1344-AES',
|
|
37
|
+
identifier: 'eFrodoKEM-1344-AES',
|
|
38
|
+
type: 'kem',
|
|
39
|
+
securityLevel: 5,
|
|
40
|
+
standardized: false,
|
|
41
|
+
description: 'eFrodoKEM-1344-AES lattice-based KEM (NIST Level 5, 256-bit quantum security, AES)',
|
|
42
|
+
keySize: {
|
|
43
|
+
publicKey: 21520,
|
|
44
|
+
secretKey: 43088,
|
|
45
|
+
ciphertext: 21632,
|
|
46
|
+
sharedSecret: 32
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Factory function to create a eFrodoKEM-1344-AES KEM instance
|
|
52
|
+
*
|
|
53
|
+
* @async
|
|
54
|
+
* @function createEFrodoKEM1344AES
|
|
55
|
+
* @returns {Promise<EFrodoKEM1344AES>} Initialized eFrodoKEM-1344-AES instance
|
|
56
|
+
* @throws {LibOQSInitError} If module initialization fails
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* import { createEFrodoKEM1344AES } from '@oqs/liboqs-js';
|
|
60
|
+
*
|
|
61
|
+
* const kem = await createEFrodoKEM1344AES();
|
|
62
|
+
* const { publicKey, secretKey } = kem.generateKeyPair();
|
|
63
|
+
* kem.destroy();
|
|
64
|
+
*/
|
|
65
|
+
export async function createEFrodoKEM1344AES() {
|
|
66
|
+
const moduleFactory = await loadModule();
|
|
67
|
+
const wasmModule = await moduleFactory();
|
|
68
|
+
wasmModule._OQS_init();
|
|
69
|
+
|
|
70
|
+
const algoName = EFRODOKEM_1344_AES_INFO.identifier;
|
|
71
|
+
const nameLen = wasmModule.lengthBytesUTF8(algoName);
|
|
72
|
+
const namePtr = wasmModule._malloc(nameLen + 1);
|
|
73
|
+
wasmModule.stringToUTF8(algoName, namePtr, nameLen + 1);
|
|
74
|
+
|
|
75
|
+
const kemPtr = wasmModule._OQS_KEM_new(namePtr);
|
|
76
|
+
wasmModule._free(namePtr);
|
|
77
|
+
|
|
78
|
+
if (!kemPtr) {
|
|
79
|
+
throw new LibOQSInitError('eFrodoKEM-1344-AES', 'Failed to create KEM instance');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return new EFrodoKEM1344AES(wasmModule, kemPtr);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* eFrodoKEM-1344-AES key encapsulation mechanism wrapper class
|
|
87
|
+
*
|
|
88
|
+
* @class EFrodoKEM1344AES
|
|
89
|
+
* @description
|
|
90
|
+
* High-level wrapper for eFrodoKEM-1344-AES KEM operations. Provides secure key generation,
|
|
91
|
+
* encapsulation, and decapsulation with automatic memory management.
|
|
92
|
+
*
|
|
93
|
+
* Memory Management:
|
|
94
|
+
* - All WASM memory is managed internally
|
|
95
|
+
* - Call destroy() when finished to free resources
|
|
96
|
+
* - Do not use instance after calling destroy()
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* const kem = await createEFrodoKEM1344AES();
|
|
100
|
+
*
|
|
101
|
+
* // Generate keypair
|
|
102
|
+
* const { publicKey, secretKey } = kem.generateKeyPair();
|
|
103
|
+
*
|
|
104
|
+
* // Encapsulate
|
|
105
|
+
* const { ciphertext, sharedSecret } = kem.encapsulate(publicKey);
|
|
106
|
+
*
|
|
107
|
+
* // Decapsulate
|
|
108
|
+
* const recoveredSecret = kem.decapsulate(ciphertext, secretKey);
|
|
109
|
+
*
|
|
110
|
+
* // Cleanup
|
|
111
|
+
* kem.destroy();
|
|
112
|
+
*/
|
|
113
|
+
export class EFrodoKEM1344AES {
|
|
114
|
+
/** @type {Object} @private */ #wasmModule;
|
|
115
|
+
/** @type {number} @private */ #kemPtr;
|
|
116
|
+
/** @type {boolean} @private */ #destroyed = false;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @private
|
|
120
|
+
* @constructor
|
|
121
|
+
* @param {Object} wasmModule - Emscripten WASM module
|
|
122
|
+
* @param {number} kemPtr - Pointer to OQS_KEM structure
|
|
123
|
+
*/
|
|
124
|
+
constructor(wasmModule, kemPtr) {
|
|
125
|
+
this.#wasmModule = wasmModule;
|
|
126
|
+
this.#kemPtr = kemPtr;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Generate a new eFrodoKEM-1344-AES keypair
|
|
131
|
+
*
|
|
132
|
+
* @async
|
|
133
|
+
* @returns {{publicKey: Uint8Array, secretKey: Uint8Array}}
|
|
134
|
+
* @throws {LibOQSError} If instance is destroyed
|
|
135
|
+
* @throws {LibOQSOperationError} If key generation fails
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* const { publicKey, secretKey } = kem.generateKeyPair();
|
|
139
|
+
* console.log('Public key:', publicKey.length); // 21520 bytes
|
|
140
|
+
* console.log('Secret key:', secretKey.length); // 43088 bytes
|
|
141
|
+
*/
|
|
142
|
+
generateKeyPair() {
|
|
143
|
+
this.#checkDestroyed();
|
|
144
|
+
|
|
145
|
+
const publicKey = new Uint8Array(EFRODOKEM_1344_AES_INFO.keySize.publicKey);
|
|
146
|
+
const secretKey = new Uint8Array(EFRODOKEM_1344_AES_INFO.keySize.secretKey);
|
|
147
|
+
|
|
148
|
+
const publicKeyPtr = this.#wasmModule._malloc(publicKey.length);
|
|
149
|
+
const secretKeyPtr = this.#wasmModule._malloc(secretKey.length);
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
const result = this.#wasmModule._OQS_KEM_keypair(this.#kemPtr, publicKeyPtr, secretKeyPtr);
|
|
153
|
+
|
|
154
|
+
if (result !== 0) {
|
|
155
|
+
throw new LibOQSOperationError('generateKeyPair', 'eFrodoKEM-1344-AES', 'Key generation failed');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
publicKey.set(this.#wasmModule.HEAPU8.subarray(publicKeyPtr, publicKeyPtr + publicKey.length));
|
|
159
|
+
secretKey.set(this.#wasmModule.HEAPU8.subarray(secretKeyPtr, secretKeyPtr + secretKey.length));
|
|
160
|
+
|
|
161
|
+
return { publicKey, secretKey };
|
|
162
|
+
} finally {
|
|
163
|
+
this.#wasmModule._free(publicKeyPtr);
|
|
164
|
+
this.#wasmModule._free(secretKeyPtr);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Encapsulate a shared secret using a public key
|
|
170
|
+
*
|
|
171
|
+
* @async
|
|
172
|
+
* @param {Uint8Array} publicKey - Public key (21520 bytes)
|
|
173
|
+
* @returns {{ciphertext: Uint8Array, sharedSecret: Uint8Array}}
|
|
174
|
+
* @returns {Uint8Array} returns.sharedSecret - Shared secret Ciphertext and shared secret
|
|
175
|
+
* @throws {LibOQSError} If instance is destroyed
|
|
176
|
+
* @throws {LibOQSValidationError} If public key size is invalid
|
|
177
|
+
* @throws {LibOQSOperationError} If encapsulation fails
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* const { ciphertext, sharedSecret } = kem.encapsulate(publicKey);
|
|
181
|
+
* console.log('Ciphertext:', ciphertext.length); // 21632 bytes
|
|
182
|
+
* console.log('Shared secret:', sharedSecret.length); // 32 bytes
|
|
183
|
+
*/
|
|
184
|
+
encapsulate(publicKey) {
|
|
185
|
+
this.#checkDestroyed();
|
|
186
|
+
this.#validatePublicKey(publicKey);
|
|
187
|
+
|
|
188
|
+
const ciphertext = new Uint8Array(EFRODOKEM_1344_AES_INFO.keySize.ciphertext);
|
|
189
|
+
const sharedSecret = new Uint8Array(EFRODOKEM_1344_AES_INFO.keySize.sharedSecret);
|
|
190
|
+
|
|
191
|
+
const publicKeyPtr = this.#wasmModule._malloc(publicKey.length);
|
|
192
|
+
const ciphertextPtr = this.#wasmModule._malloc(ciphertext.length);
|
|
193
|
+
const sharedSecretPtr = this.#wasmModule._malloc(sharedSecret.length);
|
|
194
|
+
|
|
195
|
+
try {
|
|
196
|
+
this.#wasmModule.HEAPU8.set(publicKey, publicKeyPtr);
|
|
197
|
+
|
|
198
|
+
const result = this.#wasmModule._OQS_KEM_encaps(
|
|
199
|
+
this.#kemPtr,
|
|
200
|
+
ciphertextPtr,
|
|
201
|
+
sharedSecretPtr,
|
|
202
|
+
publicKeyPtr
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
if (result !== 0) {
|
|
206
|
+
throw new LibOQSOperationError('encapsulate', 'eFrodoKEM-1344-AES', 'Encapsulation failed');
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
ciphertext.set(this.#wasmModule.HEAPU8.subarray(ciphertextPtr, ciphertextPtr + ciphertext.length));
|
|
210
|
+
sharedSecret.set(this.#wasmModule.HEAPU8.subarray(sharedSecretPtr, sharedSecretPtr + sharedSecret.length));
|
|
211
|
+
|
|
212
|
+
return { ciphertext, sharedSecret };
|
|
213
|
+
} finally {
|
|
214
|
+
this.#wasmModule._free(publicKeyPtr);
|
|
215
|
+
this.#wasmModule._free(ciphertextPtr);
|
|
216
|
+
this.#wasmModule._free(sharedSecretPtr);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Decapsulate a shared secret using a secret key
|
|
222
|
+
*
|
|
223
|
+
* @async
|
|
224
|
+
* @param {Uint8Array} ciphertext - Ciphertext (21632 bytes)
|
|
225
|
+
* @param {Uint8Array} secretKey - Secret key (43088 bytes)
|
|
226
|
+
* @returns {Uint8Array} Shared secret (32 bytes)
|
|
227
|
+
* @throws {LibOQSError} If instance is destroyed
|
|
228
|
+
* @throws {LibOQSValidationError} If ciphertext or secret key size is invalid
|
|
229
|
+
* @throws {LibOQSOperationError} If decapsulation fails
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* const sharedSecret = kem.decapsulate(ciphertext, secretKey);
|
|
233
|
+
* console.log('Recovered secret:', sharedSecret.length); // 32 bytes
|
|
234
|
+
*/
|
|
235
|
+
decapsulate(ciphertext, secretKey) {
|
|
236
|
+
this.#checkDestroyed();
|
|
237
|
+
this.#validateCiphertext(ciphertext);
|
|
238
|
+
this.#validateSecretKey(secretKey);
|
|
239
|
+
|
|
240
|
+
const sharedSecret = new Uint8Array(EFRODOKEM_1344_AES_INFO.keySize.sharedSecret);
|
|
241
|
+
|
|
242
|
+
const ciphertextPtr = this.#wasmModule._malloc(ciphertext.length);
|
|
243
|
+
const secretKeyPtr = this.#wasmModule._malloc(secretKey.length);
|
|
244
|
+
const sharedSecretPtr = this.#wasmModule._malloc(sharedSecret.length);
|
|
245
|
+
|
|
246
|
+
try {
|
|
247
|
+
this.#wasmModule.HEAPU8.set(ciphertext, ciphertextPtr);
|
|
248
|
+
this.#wasmModule.HEAPU8.set(secretKey, secretKeyPtr);
|
|
249
|
+
|
|
250
|
+
const result = this.#wasmModule._OQS_KEM_decaps(
|
|
251
|
+
this.#kemPtr,
|
|
252
|
+
sharedSecretPtr,
|
|
253
|
+
ciphertextPtr,
|
|
254
|
+
secretKeyPtr
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
if (result !== 0) {
|
|
258
|
+
throw new LibOQSOperationError('decapsulate', 'eFrodoKEM-1344-AES', 'Decapsulation failed');
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
sharedSecret.set(this.#wasmModule.HEAPU8.subarray(sharedSecretPtr, sharedSecretPtr + sharedSecret.length));
|
|
262
|
+
|
|
263
|
+
return sharedSecret;
|
|
264
|
+
} finally {
|
|
265
|
+
this.#wasmModule._free(ciphertextPtr);
|
|
266
|
+
this.#wasmModule._free(secretKeyPtr);
|
|
267
|
+
this.#wasmModule._free(sharedSecretPtr);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Free WASM resources
|
|
273
|
+
*
|
|
274
|
+
* @description
|
|
275
|
+
* Releases all WASM memory associated with this instance.
|
|
276
|
+
* The instance cannot be used after calling destroy().
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* kem.destroy();
|
|
280
|
+
* // kem is now unusable
|
|
281
|
+
*/
|
|
282
|
+
destroy() {
|
|
283
|
+
if (!this.#destroyed && this.#kemPtr) {
|
|
284
|
+
this.#wasmModule._OQS_KEM_free(this.#kemPtr);
|
|
285
|
+
this.#kemPtr = null;
|
|
286
|
+
this.#destroyed = true;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Enables automatic cleanup via `using` declarations
|
|
292
|
+
* @example
|
|
293
|
+
* using instance = await create...();
|
|
294
|
+
* // automatically cleaned up at end of scope
|
|
295
|
+
*/
|
|
296
|
+
[Symbol.dispose]() {
|
|
297
|
+
this.destroy();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Get algorithm information
|
|
302
|
+
*
|
|
303
|
+
* @readonly
|
|
304
|
+
* @returns {typeof EFRODOKEM_1344_AES_INFO} Algorithm metadata
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* console.log(kem.info.name); // 'eFrodoKEM-1344-AES'
|
|
308
|
+
* console.log(kem.info.securityLevel); // 5
|
|
309
|
+
* console.log(kem.info.keySize); // { publicKey: 21520, secretKey: 43088, ciphertext: 21632, sharedSecret: 32 }
|
|
310
|
+
*/
|
|
311
|
+
get info() {
|
|
312
|
+
return EFRODOKEM_1344_AES_INFO;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* @private
|
|
317
|
+
* @throws {LibOQSError} If instance is destroyed
|
|
318
|
+
*/
|
|
319
|
+
#checkDestroyed() {
|
|
320
|
+
if (this.#destroyed) {
|
|
321
|
+
throw new LibOQSError('Instance has been destroyed', 'eFrodoKEM-1344-AES');
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* @private
|
|
327
|
+
* @param {Uint8Array} publicKey
|
|
328
|
+
* @throws {LibOQSValidationError} If public key size is invalid
|
|
329
|
+
*/
|
|
330
|
+
#validatePublicKey(publicKey) {
|
|
331
|
+
if (!isUint8Array(publicKey) || publicKey.length !== EFRODOKEM_1344_AES_INFO.keySize.publicKey) {
|
|
332
|
+
throw new LibOQSValidationError(
|
|
333
|
+
`Invalid public key: expected ${EFRODOKEM_1344_AES_INFO.keySize.publicKey} bytes, got ${publicKey?.length ?? 'null'}`,
|
|
334
|
+
'eFrodoKEM-1344-AES'
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* @private
|
|
341
|
+
* @param {Uint8Array} secretKey
|
|
342
|
+
* @throws {LibOQSValidationError} If secret key size is invalid
|
|
343
|
+
*/
|
|
344
|
+
#validateSecretKey(secretKey) {
|
|
345
|
+
if (!isUint8Array(secretKey) || secretKey.length !== EFRODOKEM_1344_AES_INFO.keySize.secretKey) {
|
|
346
|
+
throw new LibOQSValidationError(
|
|
347
|
+
`Invalid secret key: expected ${EFRODOKEM_1344_AES_INFO.keySize.secretKey} bytes, got ${secretKey?.length ?? 'null'}`,
|
|
348
|
+
'eFrodoKEM-1344-AES'
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* @private
|
|
355
|
+
* @param {Uint8Array} ciphertext
|
|
356
|
+
* @throws {LibOQSValidationError} If ciphertext size is invalid
|
|
357
|
+
*/
|
|
358
|
+
#validateCiphertext(ciphertext) {
|
|
359
|
+
if (!isUint8Array(ciphertext) || ciphertext.length !== EFRODOKEM_1344_AES_INFO.keySize.ciphertext) {
|
|
360
|
+
throw new LibOQSValidationError(
|
|
361
|
+
`Invalid ciphertext: expected ${EFRODOKEM_1344_AES_INFO.keySize.ciphertext} bytes, got ${ciphertext?.length ?? 'null'}`,
|
|
362
|
+
'eFrodoKEM-1344-AES'
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|