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