@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,366 @@
1
+ /**
2
+ * @fileoverview HQC-256 KEM algorithm implementation
3
+ * @module algorithms/kem/hqc/hqc-256
4
+ * @description
5
+ * HQC-256 is a code-based key encapsulation mechanism providing NIST security level 5.
6
+ * It is based on the Hamming Quasi-Cyclic (HQC) code construction.
7
+ *
8
+ * Key features:
9
+ * - Code-based cryptography (Hamming Quasi-Cyclic codes)
10
+ * - Security Level 5 (256-bit classical, quantum-resistant)
11
+ * - IND-CCA2 security
12
+ * - Competitive performance
13
+ *
14
+ * @see {@link https://pqc-hqc.org/} - HQC 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/hqc-256.deno.js`
25
+ : `../../../../dist/hqc-256.min.js`;
26
+
27
+ const module = await import(modulePath);
28
+ return module.default;
29
+ }
30
+
31
+ /**
32
+ * HQC-256-INFO algorithm constants and metadata
33
+ * @type {{readonly name: 'HQC-256', readonly identifier: 'HQC-256', readonly type: 'kem', readonly securityLevel: 5, readonly standardized: false, readonly description: string, readonly keySize: {readonly publicKey: 7245, readonly secretKey: 7317, readonly ciphertext: 14421, readonly sharedSecret: 64}}}
34
+ */
35
+ export const HQC_256_INFO = {
36
+ name: 'HQC-256',
37
+ identifier: 'HQC-256',
38
+ type: 'kem',
39
+ securityLevel: 5,
40
+ standardized: false,
41
+ description: 'HQC-256 code-based KEM (NIST Level 5, 256-bit quantum security)',
42
+ keySize: {
43
+ publicKey: 7245,
44
+ secretKey: 7317,
45
+ ciphertext: 14421,
46
+ sharedSecret: 64
47
+ }
48
+ };
49
+
50
+ /**
51
+ * Factory function to create a HQC-256 KEM instance
52
+ *
53
+ * @async
54
+ * @function createHQC256
55
+ * @returns {Promise<HQC256>} Initialized HQC-256 instance
56
+ * @throws {LibOQSInitError} If module initialization fails
57
+ *
58
+ * @example
59
+ * import { createHQC256 } from '@oqs/liboqs-js';
60
+ *
61
+ * const kem = await createHQC256();
62
+ * const { publicKey, secretKey } = kem.generateKeyPair();
63
+ * kem.destroy();
64
+ */
65
+ export async function createHQC256() {
66
+ const moduleFactory = await loadModule();
67
+ const wasmModule = await moduleFactory();
68
+ wasmModule._OQS_init();
69
+
70
+ const algoName = HQC_256_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('HQC-256', 'Failed to create KEM instance');
80
+ }
81
+
82
+ return new HQC256(wasmModule, kemPtr);
83
+ }
84
+
85
+ /**
86
+ * HQC-256 key encapsulation mechanism wrapper class
87
+ *
88
+ * @class HQC256
89
+ * @description
90
+ * High-level wrapper for HQC-256 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 createHQC256();
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 HQC256 {
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 HQC-256 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); // 7245 bytes
140
+ * console.log('Secret key:', secretKey.length); // 7317 bytes
141
+ */
142
+ generateKeyPair() {
143
+ this.#checkDestroyed();
144
+
145
+ const publicKey = new Uint8Array(HQC_256_INFO.keySize.publicKey);
146
+ const secretKey = new Uint8Array(HQC_256_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', 'HQC-256', '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 (7245 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); // 14421 bytes
182
+ * console.log('Shared secret:', sharedSecret.length); // 64 bytes
183
+ */
184
+ encapsulate(publicKey) {
185
+ this.#checkDestroyed();
186
+ this.#validatePublicKey(publicKey);
187
+
188
+ const ciphertext = new Uint8Array(HQC_256_INFO.keySize.ciphertext);
189
+ const sharedSecret = new Uint8Array(HQC_256_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', 'HQC-256', '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 (14421 bytes)
225
+ * @param {Uint8Array} secretKey - Secret key (7317 bytes)
226
+ * @returns {Uint8Array} Shared secret (64 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); // 64 bytes
234
+ */
235
+ decapsulate(ciphertext, secretKey) {
236
+ this.#checkDestroyed();
237
+ this.#validateCiphertext(ciphertext);
238
+ this.#validateSecretKey(secretKey);
239
+
240
+ const sharedSecret = new Uint8Array(HQC_256_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', 'HQC-256', '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 HQC_256_INFO} Algorithm metadata
305
+ *
306
+ * @example
307
+ * console.log(kem.info.name); // 'HQC-256'
308
+ * console.log(kem.info.securityLevel); // 5
309
+ * console.log(kem.info.keySize); // { publicKey: 7245, secretKey: 7317, ciphertext: 14421, sharedSecret: 64 }
310
+ */
311
+ get info() {
312
+ return HQC_256_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', 'HQC-256');
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 !== HQC_256_INFO.keySize.publicKey) {
332
+ throw new LibOQSValidationError(
333
+ `Invalid public key: expected ${HQC_256_INFO.keySize.publicKey} bytes, got ${publicKey?.length ?? 'null'}`,
334
+ 'HQC-256'
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 !== HQC_256_INFO.keySize.secretKey) {
346
+ throw new LibOQSValidationError(
347
+ `Invalid secret key: expected ${HQC_256_INFO.keySize.secretKey} bytes, got ${secretKey?.length ?? 'null'}`,
348
+ 'HQC-256'
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 !== HQC_256_INFO.keySize.ciphertext) {
360
+ throw new LibOQSValidationError(
361
+ `Invalid ciphertext: expected ${HQC_256_INFO.keySize.ciphertext} bytes, got ${ciphertext?.length ?? 'null'}`,
362
+ 'HQC-256'
363
+ );
364
+ }
365
+ }
366
+ }
@@ -0,0 +1,349 @@
1
+ /**
2
+ * @fileoverview Kyber1024 KEM algorithm implementation (DEPRECATED)
3
+ * @module algorithms/kem/kyber/kyber-1024
4
+ * @description
5
+ * Kyber1024 is a lattice-based key encapsulation mechanism providing NIST security level 5.
6
+ *
7
+ * **DEPRECATED:** Kyber has been superseded by ML-KEM (NIST FIPS 203). Use ML-KEM-1024 instead.
8
+ * It is part of the standard (Module-Lattice-Based Key-Encapsulation Mechanism).
9
+ *
10
+ * Key features:
11
+ * - Lattice-based cryptography (Module-LWE problem)
12
+ * - Security Level 5 (256-bit classical, quantum-resistant)
13
+ * - IND-CCA2 security
14
+ * - IND-CCA2 security
15
+ * - Highest security level in ML-KEM family
16
+ *
17
+ * @see {@link https://pq-crystals.org/kyber/} - Kyber specification
18
+ * @deprecated Use ML-KEM-1024 instead (NIST FIPS 203 standardized version
19
+ */
20
+
21
+ import { LibOQSError, LibOQSInitError, LibOQSOperationError, LibOQSValidationError } from '../../../core/errors.js';
22
+ import { isUint8Array } from '../../../core/validation.js';
23
+
24
+ // Dynamic module loading for cross-runtime compatibility
25
+ async function loadModule() {
26
+ const isDeno = typeof Deno !== 'undefined';
27
+ const modulePath = isDeno
28
+ ? `../../../../dist/kyber-1024.deno.js`
29
+ : `../../../../dist/kyber-1024.min.js`;
30
+
31
+ const module = await import(modulePath);
32
+ return module.default;
33
+ }
34
+
35
+ /**
36
+ * KYBER1024-INFO algorithm constants and metadata
37
+ * @type {{readonly name: 'Kyber1024', readonly identifier: 'Kyber1024', readonly type: 'kem', readonly securityLevel: 5, readonly standardized: false, readonly deprecated: true, readonly description: string, readonly keySize: {readonly publicKey: 1568, readonly secretKey: 3168, readonly ciphertext: 1568, readonly sharedSecret: 32}}}
38
+ */
39
+ export const KYBER1024_INFO = {
40
+ name: 'Kyber1024',
41
+ identifier: 'Kyber1024',
42
+ type: 'kem',
43
+ securityLevel: 5,
44
+ standardized: false,
45
+ deprecated: true,
46
+ description: 'Kyber1024 (256-bit quantum security) - DEPRECATED, use ML-KEM-1024',
47
+ keySize: {
48
+ publicKey: 1568,
49
+ secretKey: 3168,
50
+ ciphertext: 1568,
51
+ sharedSecret: 32
52
+ }
53
+ };
54
+
55
+ /**
56
+ * Factory function to create an Kyber1024 KEM instance
57
+ *
58
+ * @async
59
+ * @function createKyber1024
60
+ * @returns {Promise<Kyber1024>} Initialized Kyber1024 instance
61
+ * @throws {LibOQSInitError} If module initialization fails
62
+ *
63
+ * @example
64
+ * import { createKyber1024 } from '@oqs/liboqs-js';
65
+ *
66
+ * const kem = await createKyber1024();
67
+ * const { publicKey, secretKey } = kem.generateKeyPair();
68
+ * kem.destroy();
69
+ */
70
+ export async function createKyber1024() {
71
+ const moduleFactory = await loadModule();
72
+ const wasmModule = await moduleFactory();
73
+ wasmModule._OQS_init();
74
+
75
+ const algoName = KYBER1024_INFO.identifier;
76
+ const nameLen = wasmModule.lengthBytesUTF8(algoName);
77
+ const namePtr = wasmModule._malloc(nameLen + 1);
78
+ wasmModule.stringToUTF8(algoName, namePtr, nameLen + 1);
79
+
80
+ const kemPtr = wasmModule._OQS_KEM_new(namePtr);
81
+ wasmModule._free(namePtr);
82
+
83
+ if (!kemPtr) {
84
+ throw new LibOQSInitError('Kyber1024', 'Failed to create KEM instance');
85
+ }
86
+
87
+ return new Kyber1024(wasmModule, kemPtr);
88
+ }
89
+
90
+ /**
91
+ * Kyber1024 wrapper class providing high-level KEM operations
92
+ *
93
+ * This class wraps the low-level WASM module to provide a user-friendly
94
+ * interface for Kyber1024 operations with automatic memory management
95
+ * and input validation.
96
+ *
97
+ * @class Kyber1024
98
+ * @example
99
+ * import LibOQS_ml_kem_1024 from '@oqs/liboqs-js/kyber-1024';
100
+ * import { createKyber1024 } from '@oqs/liboqs-js/algorithms/kyber-1024';
101
+ *
102
+ * const kem = await createKyber1024(LibOQS_ml_kem_1024);
103
+ * const { publicKey, secretKey } = kem.generateKeyPair();
104
+ * const { ciphertext, sharedSecret } = kem.encapsulate(publicKey);
105
+ * kem.destroy();
106
+ */
107
+ export class Kyber1024 {
108
+ /** @type {Object} @private */
109
+ #wasmModule;
110
+ /** @type {number} @private */
111
+ #kemPtr;
112
+ /** @type {boolean} @private */
113
+ #destroyed = false;
114
+
115
+ /**
116
+ * @param {Object} wasmModule - Emscripten WASM module
117
+ * @param {number} kemPtr - Pointer to KEM instance
118
+ * @private
119
+ */
120
+ constructor(wasmModule, kemPtr) {
121
+ this.#wasmModule = wasmModule;
122
+ this.#kemPtr = kemPtr;
123
+ }
124
+
125
+ /**
126
+ * Generate a new keypair for Kyber1024
127
+ *
128
+ * Generates a public/private keypair using the algorithm's internal
129
+ * random number generator. The secret key must be kept confidential.
130
+ *
131
+ * @returns {{publicKey: Uint8Array, secretKey: Uint8Array}}
132
+ * @throws {LibOQSOperationError} If keypair generation fails
133
+ * @throws {LibOQSError} If instance has been destroyed
134
+ * @example
135
+ * const { publicKey, secretKey } = kem.generateKeyPair();
136
+ * // publicKey: 1568 bytes
137
+ * // secretKey: 3168 bytes (keep confidential!)
138
+ */
139
+ generateKeyPair() {
140
+ this.#checkDestroyed();
141
+
142
+ const publicKeyPtr = this.#wasmModule._malloc(KYBER1024_INFO.keySize.publicKey);
143
+ const secretKeyPtr = this.#wasmModule._malloc(KYBER1024_INFO.keySize.secretKey);
144
+
145
+ try {
146
+ const result = this.#wasmModule._OQS_KEM_keypair(this.#kemPtr, publicKeyPtr, secretKeyPtr);
147
+
148
+ if (result !== 0) {
149
+ throw new LibOQSOperationError('keypair', 'Kyber1024', `Error code: ${result}`);
150
+ }
151
+
152
+ const publicKey = new Uint8Array(KYBER1024_INFO.keySize.publicKey);
153
+ const secretKey = new Uint8Array(KYBER1024_INFO.keySize.secretKey);
154
+
155
+ publicKey.set(this.#wasmModule.HEAPU8.subarray(publicKeyPtr, publicKeyPtr + KYBER1024_INFO.keySize.publicKey));
156
+ secretKey.set(this.#wasmModule.HEAPU8.subarray(secretKeyPtr, secretKeyPtr + KYBER1024_INFO.keySize.secretKey));
157
+
158
+ return { publicKey, secretKey };
159
+
160
+ } finally {
161
+ this.#wasmModule._free(publicKeyPtr);
162
+ this.#wasmModule._free(secretKeyPtr);
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Encapsulate a shared secret using a public key
168
+ *
169
+ * Generates a random shared secret and encapsulates it using the
170
+ * provided public key. The shared secret can be used for symmetric
171
+ * encryption.
172
+ *
173
+ * @param {Uint8Array} publicKey - Recipient's public key (1568 bytes)
174
+ * @returns {{ciphertext: Uint8Array, sharedSecret: Uint8Array}}
175
+ * @throws {LibOQSValidationError} If public key is invalid
176
+ * @throws {LibOQSOperationError} If encapsulation fails
177
+ * @throws {LibOQSError} If instance has been destroyed
178
+ * @example
179
+ * const { ciphertext, sharedSecret } = kem.encapsulate(recipientPublicKey);
180
+ * // ciphertext: 1568 bytes (send to recipient)
181
+ * // sharedSecret: 32 bytes (use for symmetric encryption)
182
+ */
183
+ encapsulate(publicKey) {
184
+ this.#checkDestroyed();
185
+ this.#validatePublicKey(publicKey);
186
+
187
+ const publicKeyPtr = this.#wasmModule._malloc(KYBER1024_INFO.keySize.publicKey);
188
+ const ciphertextPtr = this.#wasmModule._malloc(KYBER1024_INFO.keySize.ciphertext);
189
+ const sharedSecretPtr = this.#wasmModule._malloc(KYBER1024_INFO.keySize.sharedSecret);
190
+
191
+ try {
192
+ this.#wasmModule.HEAPU8.set(publicKey, publicKeyPtr);
193
+
194
+ const result = this.#wasmModule._OQS_KEM_encaps(
195
+ this.#kemPtr,
196
+ ciphertextPtr,
197
+ sharedSecretPtr,
198
+ publicKeyPtr
199
+ );
200
+
201
+ if (result !== 0) {
202
+ throw new LibOQSOperationError('encaps', 'Kyber1024', `Error code: ${result}`);
203
+ }
204
+
205
+ const ciphertext = new Uint8Array(KYBER1024_INFO.keySize.ciphertext);
206
+ const sharedSecret = new Uint8Array(KYBER1024_INFO.keySize.sharedSecret);
207
+
208
+ ciphertext.set(this.#wasmModule.HEAPU8.subarray(ciphertextPtr, ciphertextPtr + KYBER1024_INFO.keySize.ciphertext));
209
+ sharedSecret.set(this.#wasmModule.HEAPU8.subarray(sharedSecretPtr, sharedSecretPtr + KYBER1024_INFO.keySize.sharedSecret));
210
+
211
+ return { ciphertext, sharedSecret };
212
+
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
+ * Recovers the shared secret from a ciphertext using the secret key.
224
+ * The recovered shared secret will match the one generated during
225
+ * encapsulation.
226
+ *
227
+ * @param {Uint8Array} ciphertext - Ciphertext received (1568 bytes)
228
+ * @param {Uint8Array} secretKey - Recipient's secret key (3168 bytes)
229
+ * @returns {Uint8Array} Recovered shared secret (32 bytes)
230
+ * @throws {LibOQSValidationError} If inputs are invalid
231
+ * @throws {LibOQSOperationError} If decapsulation fails
232
+ * @throws {LibOQSError} If instance has been destroyed
233
+ * @example
234
+ * const sharedSecret = kem.decapsulate(ciphertext, mySecretKey);
235
+ * // sharedSecret: 32 bytes (matches sender's shared secret)
236
+ */
237
+ decapsulate(ciphertext, secretKey) {
238
+ this.#checkDestroyed();
239
+ this.#validateCiphertext(ciphertext);
240
+ this.#validateSecretKey(secretKey);
241
+
242
+ const ciphertextPtr = this.#wasmModule._malloc(KYBER1024_INFO.keySize.ciphertext);
243
+ const secretKeyPtr = this.#wasmModule._malloc(KYBER1024_INFO.keySize.secretKey);
244
+ const sharedSecretPtr = this.#wasmModule._malloc(KYBER1024_INFO.keySize.sharedSecret);
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('decaps', 'Kyber1024', `Error code: ${result}`);
259
+ }
260
+
261
+ const sharedSecret = new Uint8Array(KYBER1024_INFO.keySize.sharedSecret);
262
+ sharedSecret.set(this.#wasmModule.HEAPU8.subarray(sharedSecretPtr, sharedSecretPtr + KYBER1024_INFO.keySize.sharedSecret));
263
+
264
+ return sharedSecret;
265
+
266
+ } finally {
267
+ this.#wasmModule._free(ciphertextPtr);
268
+ this.#wasmModule._free(secretKeyPtr);
269
+ this.#wasmModule._free(sharedSecretPtr);
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Clean up resources and free WASM memory
275
+ *
276
+ * This method should be called when you're done using the instance
277
+ * to free WASM memory. After calling destroy(), the instance cannot
278
+ * be used for further operations.
279
+ *
280
+ * @example
281
+ * const kem = await createKyber1024(LibOQS_ml_kem_1024);
282
+ * // ... use kem ...
283
+ * kem.destroy();
284
+ */
285
+ destroy() {
286
+ if (!this.#destroyed) {
287
+ if (this.#kemPtr) {
288
+ this.#wasmModule._OQS_KEM_free(this.#kemPtr);
289
+ this.#kemPtr = null;
290
+ }
291
+ this.#destroyed = true;
292
+ }
293
+ }
294
+
295
+ /**
296
+ * Enables automatic cleanup via `using` declarations
297
+ * @example
298
+ * using instance = await create...();
299
+ * // automatically cleaned up at end of scope
300
+ */
301
+ [Symbol.dispose]() {
302
+ this.destroy();
303
+ }
304
+
305
+ /**
306
+ * Get algorithm information and constants
307
+ * @returns {typeof KYBER1024_INFO} Algorithm metadata (copy of KYBER1024_INFO)
308
+ * @example
309
+ * const info = kem.info;
310
+ * console.log(info.keySize.publicKey); // 1568
311
+ */
312
+ get info() {
313
+ return KYBER1024_INFO;
314
+ }
315
+
316
+ #checkDestroyed() {
317
+ if (this.#destroyed) {
318
+ throw new LibOQSError('Instance has been destroyed', 'Kyber1024');
319
+ }
320
+ }
321
+
322
+ #validatePublicKey(publicKey) {
323
+ if (!isUint8Array(publicKey) || publicKey.length !== KYBER1024_INFO.keySize.publicKey) {
324
+ throw new LibOQSValidationError(
325
+ `Invalid public key: expected ${KYBER1024_INFO.keySize.publicKey} bytes, got ${publicKey?.length ?? 'null'}`,
326
+ 'Kyber1024'
327
+ );
328
+ }
329
+ }
330
+
331
+ #validateSecretKey(secretKey) {
332
+ if (!isUint8Array(secretKey) || secretKey.length !== KYBER1024_INFO.keySize.secretKey) {
333
+ throw new LibOQSValidationError(
334
+ `Invalid secret key: expected ${KYBER1024_INFO.keySize.secretKey} bytes, got ${secretKey?.length ?? 'null'}`,
335
+ 'Kyber1024'
336
+ );
337
+ }
338
+ }
339
+
340
+ #validateCiphertext(ciphertext) {
341
+ if (!isUint8Array(ciphertext) || ciphertext.length !== KYBER1024_INFO.keySize.ciphertext) {
342
+ throw new LibOQSValidationError(
343
+ `Invalid ciphertext: expected ${KYBER1024_INFO.keySize.ciphertext} bytes, got ${ciphertext?.length ?? 'null'}`,
344
+ 'Kyber1024'
345
+ );
346
+ }
347
+ }
348
+ }
349
+