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