leviathan-crypto 1.3.1 → 2.0.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 (124) hide show
  1. package/CLAUDE.md +129 -76
  2. package/README.md +166 -221
  3. package/SECURITY.md +89 -37
  4. package/dist/chacha20/cipher-suite.d.ts +4 -0
  5. package/dist/chacha20/cipher-suite.js +78 -0
  6. package/dist/chacha20/embedded.d.ts +1 -0
  7. package/dist/chacha20/embedded.js +27 -0
  8. package/dist/chacha20/index.d.ts +20 -7
  9. package/dist/chacha20/index.js +41 -14
  10. package/dist/chacha20/ops.d.ts +1 -1
  11. package/dist/chacha20/ops.js +19 -18
  12. package/dist/chacha20/pool-worker.js +77 -0
  13. package/dist/ct-wasm.d.ts +1 -0
  14. package/dist/ct-wasm.js +3 -0
  15. package/dist/ct.wasm +0 -0
  16. package/dist/docs/aead.md +320 -0
  17. package/dist/docs/architecture.md +419 -285
  18. package/dist/docs/argon2id.md +42 -30
  19. package/dist/docs/chacha20.md +218 -150
  20. package/dist/docs/exports.md +241 -0
  21. package/dist/docs/fortuna.md +65 -74
  22. package/dist/docs/init.md +172 -178
  23. package/dist/docs/loader.md +87 -132
  24. package/dist/docs/serpent.md +134 -565
  25. package/dist/docs/sha2.md +91 -103
  26. package/dist/docs/sha3.md +70 -36
  27. package/dist/docs/types.md +93 -16
  28. package/dist/docs/utils.md +114 -41
  29. package/dist/embedded/chacha20.d.ts +1 -1
  30. package/dist/embedded/chacha20.js +2 -1
  31. package/dist/embedded/kyber.d.ts +1 -0
  32. package/dist/embedded/kyber.js +3 -0
  33. package/dist/embedded/serpent.d.ts +1 -1
  34. package/dist/embedded/serpent.js +2 -1
  35. package/dist/embedded/sha2.d.ts +1 -1
  36. package/dist/embedded/sha2.js +2 -1
  37. package/dist/embedded/sha3.d.ts +1 -1
  38. package/dist/embedded/sha3.js +2 -1
  39. package/dist/errors.d.ts +10 -0
  40. package/dist/{serpent/seal.js → errors.js} +14 -46
  41. package/dist/fortuna.d.ts +2 -8
  42. package/dist/fortuna.js +11 -9
  43. package/dist/index.d.ts +25 -9
  44. package/dist/index.js +36 -7
  45. package/dist/init.d.ts +3 -7
  46. package/dist/init.js +18 -35
  47. package/dist/keccak/embedded.d.ts +1 -0
  48. package/dist/keccak/embedded.js +27 -0
  49. package/dist/keccak/index.d.ts +4 -0
  50. package/dist/keccak/index.js +31 -0
  51. package/dist/kyber/embedded.d.ts +1 -0
  52. package/dist/kyber/embedded.js +27 -0
  53. package/dist/kyber/indcpa.d.ts +49 -0
  54. package/dist/kyber/indcpa.js +352 -0
  55. package/dist/kyber/index.d.ts +38 -0
  56. package/dist/kyber/index.js +150 -0
  57. package/dist/kyber/kem.d.ts +21 -0
  58. package/dist/kyber/kem.js +160 -0
  59. package/dist/kyber/params.d.ts +14 -0
  60. package/dist/kyber/params.js +37 -0
  61. package/dist/kyber/suite.d.ts +13 -0
  62. package/dist/kyber/suite.js +93 -0
  63. package/dist/kyber/types.d.ts +98 -0
  64. package/dist/kyber/types.js +25 -0
  65. package/dist/kyber/validate.d.ts +19 -0
  66. package/dist/kyber/validate.js +68 -0
  67. package/dist/kyber.wasm +0 -0
  68. package/dist/loader.d.ts +19 -4
  69. package/dist/loader.js +91 -25
  70. package/dist/serpent/cipher-suite.d.ts +4 -0
  71. package/dist/serpent/cipher-suite.js +121 -0
  72. package/dist/serpent/embedded.d.ts +1 -0
  73. package/dist/serpent/embedded.js +27 -0
  74. package/dist/serpent/index.d.ts +6 -37
  75. package/dist/serpent/index.js +9 -118
  76. package/dist/serpent/pool-worker.d.ts +1 -0
  77. package/dist/serpent/pool-worker.js +202 -0
  78. package/dist/serpent/serpent-cbc.d.ts +30 -0
  79. package/dist/serpent/serpent-cbc.js +136 -0
  80. package/dist/sha2/embedded.d.ts +1 -0
  81. package/dist/sha2/embedded.js +27 -0
  82. package/dist/sha2/hkdf.js +6 -2
  83. package/dist/sha2/index.d.ts +3 -2
  84. package/dist/sha2/index.js +3 -4
  85. package/dist/sha3/embedded.d.ts +1 -0
  86. package/dist/sha3/embedded.js +27 -0
  87. package/dist/sha3/index.d.ts +3 -2
  88. package/dist/sha3/index.js +3 -4
  89. package/dist/stream/constants.d.ts +6 -0
  90. package/dist/stream/constants.js +30 -0
  91. package/dist/stream/header.d.ts +9 -0
  92. package/dist/stream/header.js +77 -0
  93. package/dist/stream/index.d.ts +7 -0
  94. package/dist/stream/index.js +27 -0
  95. package/dist/stream/open-stream.d.ts +21 -0
  96. package/dist/stream/open-stream.js +146 -0
  97. package/dist/stream/seal-stream-pool.d.ts +38 -0
  98. package/dist/stream/seal-stream-pool.js +391 -0
  99. package/dist/stream/seal-stream.d.ts +20 -0
  100. package/dist/stream/seal-stream.js +142 -0
  101. package/dist/stream/seal.d.ts +9 -0
  102. package/dist/stream/seal.js +75 -0
  103. package/dist/stream/types.d.ts +24 -0
  104. package/dist/stream/types.js +26 -0
  105. package/dist/utils.d.ts +12 -7
  106. package/dist/utils.js +75 -19
  107. package/dist/wasm-source.d.ts +12 -0
  108. package/dist/wasm-source.js +26 -0
  109. package/package.json +13 -5
  110. package/dist/chacha20/pool.d.ts +0 -52
  111. package/dist/chacha20/pool.js +0 -188
  112. package/dist/chacha20/pool.worker.js +0 -37
  113. package/dist/docs/chacha20_pool.md +0 -309
  114. package/dist/docs/wasm.md +0 -194
  115. package/dist/serpent/seal.d.ts +0 -8
  116. package/dist/serpent/stream-pool.d.ts +0 -48
  117. package/dist/serpent/stream-pool.js +0 -285
  118. package/dist/serpent/stream-sealer.d.ts +0 -50
  119. package/dist/serpent/stream-sealer.js +0 -341
  120. package/dist/serpent/stream.d.ts +0 -28
  121. package/dist/serpent/stream.js +0 -205
  122. package/dist/serpent/stream.worker.d.ts +0 -32
  123. package/dist/serpent/stream.worker.js +0 -117
  124. /package/dist/chacha20/{pool.worker.d.ts → pool-worker.d.ts} +0 -0
@@ -1 +1 @@
1
- export declare const WASM_BASE64 = "AGFzbQEAAAABEQRgAABgAAF/YAF/AGACf38AAxsaAQEBAQEBAQEDAAAAAAAAAAICAAAAAAIAAAAFBAEBAwMHgQMZC2dldE1vZHVsZUlkAAAOZ2V0U3RhdGVPZmZzZXQAAQ1nZXRSYXRlT2Zmc2V0AAIRZ2V0QWJzb3JiZWRPZmZzZXQAAw9nZXREc0J5dGVPZmZzZXQABA5nZXRJbnB1dE9mZnNldAAFDGdldE91dE9mZnNldAAGDmdldE1lbW9yeVBhZ2VzAAcMc2hhM18yMjRJbml0AAkMc2hhM18yNTZJbml0AAoMc2hhM18zODRJbml0AAsMc2hhM181MTJJbml0AAwMc2hha2UxMjhJbml0AA0Mc2hha2UyNTZJbml0AA4Ma2VjY2FrQWJzb3JiABALa2VjY2FrRmluYWwAEQ1zaGEzXzIyNEZpbmFsABINc2hhM18yNTZGaW5hbAATDXNoYTNfMzg0RmluYWwAFA1zaGEzXzUxMkZpbmFsABUKc2hha2VGaW5hbAAWCHNoYWtlUGFkABcRc2hha2VTcXVlZXplQmxvY2sAGAt3aXBlQnVmZmVycwAZBm1lbW9yeQIADAECCqsSGgQAQQMLBABBAAsFAEHIAQsFAEHMAQsFAEHQAQsFAEHRAQsFAEH5AgsEAD8ACy8AQQBBAEHIAfwLAEHRAUEAQagB/AsAQcgBIAA2AgBBzAFBADYCAEHQASABOgAACwkAQZABQQYQCAsJAEGIAUEGEAgLCQBB6ABBBhAICwkAQcgAQQYQCAsJAEGoAUEfEAgLCQBBiAFBHxAIC+INAil+AX9BACkDACEAQQgpAwAhAUEQKQMAIQVBGCkDACEDQSApAwAhB0EoKQMAIQJBMCkDACEEQTgpAwAhBkHAACkDACEKQcgAKQMAIQhB0AApAwAhCUHYACkDACELQeAAKQMAIQxB6AApAwAhDUHwACkDACEOQfgAKQMAIQ9BgAEpAwAhEEGIASkDACERQZABKQMAIRJBmAEpAwAhE0GgASkDACEUQagBKQMAIRVBsAEpAwAhFkG4ASkDACEXQcABKQMAIRgDQCApQRhIBEAgByAIhSAOhSAThSAYhSIZIAEgBIUgC4UgEIUgFYUiGkIBhiAaQj+IhIUhHiAAIAKFIAmFIA+FIBSFIhsgBSAGhSAMhSARhSAWhSIcQgGGIBxCP4iEhSEfIBogAyAKhSANhSAShSAXhSIaQgGGIBpCP4iEhSEgIAMgHCAZQgGGIBlCP4iEhSIhhSIDQhyGIANCJIiEISIgASAfhSIBQgGGIAFCP4iEISUgByAaIBtCAYYgG0I/iISFIiOFIgFCG4YgAUIliIQhJCAFICCFIgFCPoYgAUICiIQhJiAGICCFIgFCBoYgAUI6iIQhJyACIB6FIgFCJIYgAUIciIQhKCAKICGFIgFCN4YgAUIJiIQhGSALIB+FIgFCCoYgAUI2iIQhGiAOICOFIgFCJ4YgAUIZiIQhGyAPIB6FIgFCKYYgAUIXiIQhHCAVIB+FIgFCAoYgAUI+iIQhHSAAIB6FIgAgAIQiAiAMICCFIgBCK4YgAEIViIQiAyAEIB+FIgBCLIYgAEIUiIQiBEJ/hYOFIQAgBCASICGFIgFCFYYgAUIriIQiBiADQn+Fg4UhASADIBggI4UiA0IOhiADQjKIhCIHIAZCf4WDhSEFIAYgB0J/hSACg4UhAyAHIAJCf4UgBIOFIQcgIiAJIB6FIgJCA4YgAkI9iIQiBiAIICOFIgJCFIYgAkIsiIQiCEJ/hYOFIQIgCCAQIB+FIgRCLYYgBEITiIQiCSAGQn+Fg4UhBCAGIBYgIIUiBkI9hiAGQgOIhCILIAlCf4WDhSEGIAkgC0J/hSAig4UhCiALICJCf4UgCIOFIQggJSANICGFIglCGYYgCUIniIQiDCAnQn+Fg4UhCSAnIBMgI4UiC0IIhiALQjiIhCINIAxCf4WDhSELIAwgFCAehSIMQhKGIAxCLoiEIg4gDUJ/hYOFIQwgDSAOQn+FICWDhSENIA4gJUJ/hSAng4UhDiAkIChCf4UgGoOFIQ8gKCARICCFIhBCD4YgEEIxiIQiEiAaQn+Fg4UhECAaIBcgIYUiEUI4hiARQgiIhCITIBJCf4WDhSERIBIgE0J/hSAkg4UhEiATICRCf4UgKIOFIRMgJiAZQn+FIBuDhSEUIBkgG0J/hSAcg4UhFSAbIBxCf4UgHYOFIRYgHCAdQn+FICaDhSEXIB0gJkJ/hSAZg4UhGCApBH4gKUEBRgR+IABCgoEChQUgKUECRgR+IABCioGCgICAgICAf4UFIClBA0YEfiAAQoCAgoCIgICAgH+FBSApQQRGBH4gAEKLgQKFBSApQQVGBH4gAEKBgICACIUFIClBBkYEfiAAQoGBgoCIgICAgH+FBSApQQdGBH4gAEKJgIKAgICAgIB/hQUgKUEIRgR+IABCigGFBSApQQlGBH4gAEKIAYUFIClBCkYEfiAAQomAgoAIhQUgKUELRgR+IABCioCAgAiFBSApQQxGBH4gAEKLgYKACIUFIClBDUYEfiAAQouBgICAgICAgH+FBSApQQ5GBH4gAEKJgYKAgICAgIB/hQUgKUEPRgR+IABCg4CCgICAgICAf4UFIClBEEYEfiAAQoKAgoCAgICAgH+FBSApQRFGBH4gAEKAgYCAgICAgIB/hQUgKUESRgR+IABCioAChQUgKUETRgR+IABCioCAgIiAgICAf4UFIClBFEYEfiAAQoGBgoCIgICAgH+FBSAAQoCBgoCAgICAgH+FIABCgYCAgAiFIABCiICCgIiAgICAf4UgKUEWRhsgKUEVRhsLCwsLCwsLCwsLCwsLCwsLCwsLCwUgAEIBhQshACApQQFqISkMAQsLQQAgADcDAEEIIAE3AwBBECAFNwMAQRggAzcDAEEgIAc3AwBBKCACNwMAQTAgBDcDAEE4IAY3AwBBwAAgCjcDAEHIACAINwMAQdAAIAk3AwBB2AAgCzcDAEHgACAMNwMAQegAIA03AwBB8AAgDjcDAEH4ACAPNwMAQYABIBA3AwBBiAEgETcDAEGQASASNwMAQZgBIBM3AwBBoAEgFDcDAEGoASAVNwMAQbABIBY3AwBBuAEgFzcDAEHAASAYNwMAC40BAQZ/QcgBKAIAIQRBzAEoAgAhAQNAIAAgBUoEQCAAIAVrIgMgBCABayICIAIgA0obIQNBACEGA0AgAyAGSgRAIAEgBmoiAiAFQdEBaiAGai0AACACLQAAczoAACAGQQFqIQYMAQsLIAMgBWohBSAEIAEgA2oiAUYEQBAPQQAhAQsMAQsLQcwBIAE2AgALVwEDf0HIASgCACEDQcwBKAIAIgJB0AEtAAAgAi0AAHM6AAAgA0EBayICIAItAABBgAFzOgAAEA8DQCAAIAFKBEAgASABLQAAOgD5AiABQQFqIQEMAQsLCwYAQRwQEQsGAEEgEBELBgBBMBARCwcAQcAAEBELBgAgABARCzgBAn9ByAEoAgAhAUHMASgCACIAQdABLQAAIAAtAABzOgAAIAFBAWsiACAALQAAQYABczoAABAPCy0BAn9ByAEoAgAhAQNAIAAgAUgEQCAAIAAtAAA6APkCIABBAWohAAwBCwsQDws6AEEAQQBByAH8CwBB0QFBAEGoAfwLAEH5AkEAQagB/AsAQcgBQQA2AgBBzAFBADYCAEHQAUEAOgAACwt3AgBBjAgLAXwAQZgIC2kEAAAAZAAAAAAAAAABAAAAPgAAABwAAAAbAAAAJAAAACwAAAAGAAAANwAAABQAAAADAAAACgAAACsAAAAZAAAAJwAAACkAAAAtAAAADwAAABUAAAAIAAAAEgAAAAIAAAA9AAAAOAAAAA4AIRBzb3VyY2VNYXBwaW5nVVJMDy4vc2hhMy53YXNtLm1hcA==";
1
+ export declare const WASM_GZ_BASE64 = "H4sIAAAAAAAAA3WWTUwcRxbHX3X39Hz0fH8Aw4zjf3fAMLJxbLKxEZIdqrVCcRQrUaLVHtcT02YBY1jPICurlRk8XaPeL8lHH3O0tJccc/SRgw/klmO0Jx9zjKU9rF7VDJhVtpH6V/9/vXrv9UOCom5vVxCRqDj3iO6ROLwnDumedXhIdmtWjB+bzGNZ+k1EKUcI204f2U1vM+rf3ds4eBjd2SAqbkb9r/rdfvT5gwe9qE+isBn1vzzTVmUz6suve3uPv442xp5d2oz6v+2F35xGOZzmzqP9g/7YSOU3o/7np9Ll/bvR7t7jb77obkY9Sud7f+x++Ifl5d/cebTVp+xYfnRDy5yRH66YXc/Ij64va5lnuRNdX17RsmDk5GwxvxPdv9/dMT1T2TNyfetR9yFVCpOyRlcLk7pG1wqTwkbXC5PKRjdyupYRUxktvuhu0HRFL7/600EU/TkKH+7d36EZ78nWfhQePHgQPe5R093Vn29RXli5f1VnHZK255AkL0XyWPD7tX6f6PcP+v3W8hz6mLwPSPLPsfiPx1uS5Eu9PBagGxaflJonAmKVyMuSfC6kW87wKjldvaHJ6vh09VLIi6dxvPp3weo8FYeSOjb5JDMMIcuMlJxh2BKMtFxkWPIaw5ErDFe+0gdz8lgzI080s/JHTU/+pJmXbzQL8mfNovxFsyQHglmWiWZFPtesyheaNfmtZl2+1GzI7zSn5Pea0/KV5oy9ho6c+cRZQxoZhaJCTWFGBU0IOAqeQlmhoYLZUIwwG36cxMp/DwRLIatQUqiroIUUXIW8QkVhSgVtjm2b2IuYhY2cQkGhqjB9PhNgo40mO03tBL4K7LA9gh3OJbEfQOCiCgQHCA7w55HGLFpstMyJ93m/xfvzSezPIQWwc5sdK4n9S3CN47KzmsT+Aiy8x84cO+0k9heRg8/OTXaySew34ZnKOXZuJLE/iyJ0rQV2mknst1AyeTrsTCex30bDnLLYuZ3E/gUQxxAoDizkuRMKL49AYSOJAxsOx1N4hZ16EgdOeKiGyic4qJqWGpzqchIHLmyzKWBjhnuxwyJPajmJgzRcs5mCi3R4qGANlW8jDYuFM1R+GgGy3IwV2iNY4S2dM8OJrLDOzpUkDjImjYUMytybEy6N4IS1JA6ykxoOXEzxp7jhrRHc0E7iwEPWbLrIwuOawVD5OXgIWGSGys9gHgX+qGzYHCEbLiRxkMeCOZbFAmrcixdmRvDClSQOCsibTQ951Ln1fFgdIR9eTeKgiILZzKOAIteYHyq/gCLmWSwMlV/EHBZZzA6VX8IiKtx0OSyNUA6vJ3FQxazJUcYsprm1SrgyQiXMJHFQQ9VsVlBFjdPMDZVfRQ1zLBaHyq/hEposWkPl19FEi0V7qPwGWmizuDBU/hTauMDi0lD507iASyyaQ+XPoOM8RUeKdecpKHx2ZKkUOtIy8m9Hzwb6OdSubdzB4NkgOXMd4/59fDRl5NFgMMhowx0bR+dOpY3718G5CplxXaFV1qjEqNzZCZPYGwefVspPOplEFCbG4N0ixXGi8x9XMu7wfEPl8VzOu5XxIM7nrU76MYOonbX3znfXf2UanOk0/+ns+MvPJo2OnFpvoSMb6y3vVx7OIpTnE/8yt/1OXnieJNBNm2QGglFGijEDmwGkGYuwGNfgMFbgMl4RcsxjQoZ5QsgyfyR4zJ8IeeYbQoH5M6HI/IVQYg4EysxEoMJ8LlBlvhCoMb8VqDNfCjSY3wlMMb8XmNb1BWZu2uT9Uwj3UB6LRYv/cb3WFPYaCKlPHY0d/SdM7AQWLNiftnxbku/aa7DhcoiAux1YSMkfxDbc7SUiWEtEvVUiuDwolwcFG6ltP8WZYG8HYt1ZK5ck+cLTY3wtIG5Y5P1e2JNubNNNYMkTcS6pLU0zS8RjYKtc0h0L0w5Hr9JbC4KrC87vuSTb5QoDBtfKFS/NvwYtwVgR1qS2GNemcW2a1BZc2+jT2t7SOwdNI5/o0dGkEeJGiBspl7zV/3ODeWu9c5mR/3OZkcSXGe+JRfIfGU/8heSLjLflENHG+ILLV+HbRNQmohYRzRHRFSJyiegmEdWJiC/DOSK6TERNIlogog4R90klImoQUYaIquOr8i0iWiGiIvnl3t7B4/vR3e7+/tajzd99+Vnp6gd8I7z6pNvbvbrb3f8vce16BY8LAAA=";
@@ -1,2 +1,3 @@
1
1
  // Generated by scripts/embed-wasm.ts — do not edit
2
- export const WASM_BASE64 = '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';
2
+ // gzip-compressed WASM binary, base64-encoded. Decoded and decompressed by loadEmbedded().
3
+ export const WASM_GZ_BASE64 = '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';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Thrown when AEAD authentication fails.
3
+ *
4
+ * `cipher` is the cipher name passed by the call site (e.g. `'serpent'`,
5
+ * `'chacha20-poly1305'`, `'xchacha20-poly1305'`). The class appends
6
+ * `': authentication failed'` — do not include that text in the cipher name.
7
+ */
8
+ export declare class AuthenticationError extends Error {
9
+ constructor(cipher: string);
10
+ }
@@ -19,52 +19,20 @@
19
19
  // ▀██████▀ ▀████▄▄▄████▀ for its {ab,mis,}use.
20
20
  // ▀█████▀▀
21
21
  //
22
- // src/ts/serpent/seal.ts
22
+ // src/ts/errors.ts
23
23
  //
24
- // SerpentSeal authenticated Serpent-256 encryption.
25
- // Encrypt-then-MAC: SerpentCbc + HMAC-SHA256. Tier 2 pure-TS composition.
26
- import { SerpentCbc, _serpentReady } from './index.js';
27
- import { HMAC_SHA256, _sha2Ready } from '../sha2/index.js';
28
- import { concat, constantTimeEqual } from '../utils.js';
29
- export class SerpentSeal {
30
- _cbc;
31
- _hmac;
32
- constructor() {
33
- if (!_serpentReady() || !_sha2Ready())
34
- throw new Error('leviathan-crypto: call init([\'serpent\', \'sha2\']) before using SerpentSeal');
35
- this._cbc = new SerpentCbc({ dangerUnauthenticated: true });
36
- this._hmac = new HMAC_SHA256();
37
- }
38
- // _iv: test seam only — inject a fixed IV for deterministic KAT vectors
39
- encrypt(key, plaintext, _iv) {
40
- if (key.length !== 64)
41
- throw new RangeError(`SerpentSeal key must be 64 bytes (got ${key.length})`);
42
- const encKey = key.subarray(0, 32);
43
- const macKey = key.subarray(32, 64);
44
- const iv = (_iv && _iv.length === 16) ? _iv : new Uint8Array(16);
45
- if (!_iv || _iv.length !== 16)
46
- crypto.getRandomValues(iv);
47
- const ciphertext = this._cbc.encrypt(encKey, iv, plaintext);
48
- const tag = this._hmac.hash(macKey, concat(iv, ciphertext));
49
- return concat(concat(iv, ciphertext), tag);
50
- }
51
- decrypt(key, data) {
52
- if (key.length !== 64)
53
- throw new RangeError(`SerpentSeal key must be 64 bytes (got ${key.length})`);
54
- if (data.length < 64)
55
- throw new RangeError('SerpentSeal ciphertext too short');
56
- const encKey = key.subarray(0, 32);
57
- const macKey = key.subarray(32, 64);
58
- const iv = data.subarray(0, 16);
59
- const tag = data.subarray(data.length - 32);
60
- const ciphertext = data.subarray(16, data.length - 32);
61
- const expectedTag = this._hmac.hash(macKey, concat(iv, ciphertext));
62
- if (!constantTimeEqual(tag, expectedTag))
63
- throw new Error('SerpentSeal: authentication failed');
64
- return this._cbc.decrypt(encKey, iv, ciphertext);
65
- }
66
- dispose() {
67
- this._cbc.dispose();
68
- this._hmac.dispose();
24
+ // Typed error classes for leviathan-crypto.
25
+ /**
26
+ * Thrown when AEAD authentication fails.
27
+ *
28
+ * `cipher` is the cipher name passed by the call site (e.g. `'serpent'`,
29
+ * `'chacha20-poly1305'`, `'xchacha20-poly1305'`). The class appends
30
+ * `': authentication failed'` — do not include that text in the cipher name.
31
+ */
32
+ export class AuthenticationError extends Error {
33
+ constructor(cipher) {
34
+ super(`${cipher}: authentication failed`);
35
+ this.name = 'AuthenticationError';
36
+ Object.setPrototypeOf(this, AuthenticationError.prototype);
69
37
  }
70
38
  }
package/dist/fortuna.d.ts CHANGED
@@ -30,20 +30,14 @@ export declare class Fortuna {
30
30
  entropy?: Uint8Array;
31
31
  }): Promise<Fortuna>;
32
32
  private constructor();
33
- /** Get n random bytes. Returns undefined if not yet seeded (reseedCnt === 0). */
34
- get(length: number): Uint8Array | undefined;
33
+ /** Get n random bytes. Always returns Uint8Array instance is guaranteed seeded after create(). */
34
+ get(length: number): Uint8Array;
35
35
  /** Add external entropy to the pools. */
36
36
  addEntropy(entropy: Uint8Array): void;
37
37
  /** Get estimated available entropy in bytes. */
38
38
  getEntropy(): number;
39
39
  /** Permanently dispose this instance. Wipes key material, stops all collectors. */
40
40
  stop(): void;
41
- /** @internal — exposed for testing key replacement */
42
- _getGenKey(): Uint8Array;
43
- /** @internal — exposed for testing pool state */
44
- _getPoolEntropy(): number[];
45
- /** @internal — exposed for testing reseed count */
46
- _getReseedCnt(): number;
47
41
  /** Generate n blocks of 16 bytes each. — spec §9.4 */
48
42
  private generateBlocks;
49
43
  /** Get length pseudo-random bytes. — spec §9.4 */
package/dist/fortuna.js CHANGED
@@ -23,7 +23,7 @@
23
23
  //
24
24
  // Fortuna CSPRNG — Ferguson & Schneier, Practical Cryptography (2003), Chapter 9.
25
25
  // Backed by WASM Serpent-256 ECB (generator) and WASM SHA-256 (accumulator pools).
26
- // Requires init(['serpent', 'sha2']) before Fortuna.create().
26
+ // Requires init({ serpent: ..., sha2: ... }) before Fortuna.create().
27
27
  import { isInitialized } from './init.js';
28
28
  import { Serpent } from './serpent/index.js';
29
29
  import { SHA256 } from './sha2/index.js';
@@ -63,11 +63,15 @@ export class Fortuna {
63
63
  // ── Static factory ────────────────────────────────────────────────────
64
64
  static async create(opts) {
65
65
  if (!isInitialized('serpent'))
66
- throw new Error('leviathan-crypto: call init([\'serpent\', \'sha2\']) before using Fortuna');
66
+ throw new Error('leviathan-crypto: call init({ serpent: ..., sha2: ... }) before using Fortuna');
67
67
  if (!isInitialized('sha2'))
68
- throw new Error('leviathan-crypto: call init([\'serpent\', \'sha2\']) before using Fortuna');
68
+ throw new Error('leviathan-crypto: call init({ serpent: ..., sha2: ... }) before using Fortuna');
69
69
  const f = new Fortuna(opts?.msPerReseed ?? Fortuna.MS_PER_RESEED);
70
70
  f.initialize(opts?.entropy);
71
+ // Force the first reseed — pool[0] is saturated by initialize(),
72
+ // so this call triggers an immediate reseed and guarantees get() never
73
+ // returns undefined. The byte is discarded.
74
+ f.get(1);
71
75
  return f;
72
76
  }
73
77
  constructor(msPerReseed) {
@@ -91,7 +95,7 @@ export class Fortuna {
91
95
  }
92
96
  }
93
97
  // ── Public API ────────────────────────────────────────────────────────
94
- /** Get n random bytes. Returns undefined if not yet seeded (reseedCnt === 0). */
98
+ /** Get n random bytes. Always returns Uint8Array instance is guaranteed seeded after create(). */
95
99
  get(length) {
96
100
  if (this.disposed)
97
101
  throw new Error('Fortuna instance has been disposed');
@@ -117,8 +121,6 @@ export class Fortuna {
117
121
  this.entropyLevel -= strength;
118
122
  this.reseed(seed);
119
123
  }
120
- if (this.reseedCnt === 0)
121
- return undefined;
122
124
  return this.pseudoRandomData(length);
123
125
  }
124
126
  /** Add external entropy to the pools. */
@@ -171,8 +173,8 @@ export class Fortuna {
171
173
  }
172
174
  /** Get length pseudo-random bytes. — spec §9.4 */
173
175
  pseudoRandomData(length) {
174
- // Generate ceil(length/16) + 1 blocks — +1 ensures extra block before key replacement
175
- const blocks = Math.ceil(length / 16) + 1;
176
+ // Generate ceil(length/16) blocks — spec §9.4
177
+ const blocks = Math.ceil(length / 16);
176
178
  const raw = this.generateBlocks(blocks);
177
179
  const output = raw.slice(0, length);
178
180
  // Key replacement — mandatory forward secrecy (spec §9.4)
@@ -205,7 +207,7 @@ export class Fortuna {
205
207
  id[3] = (this.eventId >>> 24) & 0xff;
206
208
  this.eventId = (this.eventId + 1) >>> 0; // u32 wrap
207
209
  // Chain: poolHash[i] = SHA256(poolHash[i] ‖ id ‖ data)
208
- this.poolHash[poolIdx] = this.sha.hash(concat(concat(this.poolHash[poolIdx], id), data));
210
+ this.poolHash[poolIdx] = this.sha.hash(concat(this.poolHash[poolIdx], id, data));
209
211
  this.poolEntropy[poolIdx] += entropyBits;
210
212
  this.entropyLevel += entropyBits;
211
213
  }
package/dist/index.d.ts CHANGED
@@ -1,13 +1,29 @@
1
- import type { Module, Mode, InitOpts } from './init.js';
2
- export declare function init(modules: Module | Module[], mode?: Mode, opts?: InitOpts): Promise<void>;
3
- export { type Module, type Mode, type InitOpts, isInitialized, _resetForTesting } from './init.js';
4
- export { serpentInit, SerpentSeal, Serpent, SerpentCtr, SerpentCbc, SerpentStream, SerpentStreamPool, SerpentStreamSealer, SerpentStreamOpener, _serpentReady } from './serpent/index.js';
5
- export type { StreamPoolOpts } from './serpent/index.js';
6
- export { chacha20Init, ChaCha20, Poly1305, ChaCha20Poly1305, XChaCha20Poly1305, _chachaReady } from './chacha20/index.js';
7
- export { XChaCha20Poly1305Pool } from './chacha20/pool.js';
8
- export type { PoolOpts } from './chacha20/pool.js';
1
+ import type { Module } from './init.js';
2
+ import type { WasmSource } from './wasm-source.js';
3
+ /**
4
+ * Load one or more WASM modules. Each key is a module name; the value is the
5
+ * WasmSource to load it from (embedded blob, URL, ArrayBuffer, etc.).
6
+ *
7
+ * ```ts
8
+ * import { init } from 'leviathan-crypto';
9
+ * import { serpentWasm } from 'leviathan-crypto/serpent/embedded';
10
+ * import { sha2Wasm } from 'leviathan-crypto/sha2/embedded';
11
+ * await init({ serpent: serpentWasm, sha2: sha2Wasm });
12
+ * ```
13
+ */
14
+ export declare function init(sources: Partial<Record<Module, WasmSource>>): Promise<void>;
15
+ export type { Module, WasmSource };
16
+ export { isInitialized, _resetForTesting } from './init.js';
17
+ export { AuthenticationError } from './errors.js';
18
+ export { serpentInit, Serpent, SerpentCtr, SerpentCbc, SerpentCipher, _serpentReady } from './serpent/index.js';
19
+ export { chacha20Init, ChaCha20, Poly1305, ChaCha20Poly1305, XChaCha20Poly1305, XChaCha20Cipher, _chachaReady } from './chacha20/index.js';
9
20
  export { sha2Init, SHA256, SHA512, SHA384, HMAC_SHA256, HMAC_SHA512, HMAC_SHA384, HKDF_SHA256, HKDF_SHA512, _sha2Ready } from './sha2/index.js';
10
21
  export { sha3Init, SHA3_224, SHA3_256, SHA3_384, SHA3_512, SHAKE128, SHAKE256, _sha3Ready } from './sha3/index.js';
22
+ export { keccakInit } from './keccak/index.js';
23
+ export { kyberInit, MlKem512, MlKem768, MlKem1024, MlKemBase, KyberSuite, _kyberReady } from './kyber/index.js';
24
+ export type { KyberKeyPair, KyberEncapsulation, KyberParams } from './kyber/index.js';
25
+ export { SealStream, OpenStream, Seal, SealStreamPool, FLAG_FRAMED, TAG_DATA, TAG_FINAL, HEADER_SIZE, CHUNK_MIN, CHUNK_MAX } from './stream/index.js';
26
+ export type { CipherSuite, DerivedKeys, SealStreamOpts, PoolOpts } from './stream/index.js';
11
27
  export { Fortuna } from './fortuna.js';
12
28
  export type { Hash, KeyedHash, Blockcipher, Streamcipher, AEAD } from './types.js';
13
- export { hexToBytes, bytesToHex, utf8ToBytes, bytesToUtf8, base64ToBytes, bytesToBase64, constantTimeEqual, wipe, xor, concat, randomBytes, } from './utils.js';
29
+ export { hexToBytes, bytesToHex, utf8ToBytes, bytesToUtf8, base64ToBytes, bytesToBase64, constantTimeEqual, CT_MAX_BYTES, wipe, xor, concat, randomBytes, hasSIMD, } from './utils.js';
package/dist/index.js CHANGED
@@ -24,21 +24,50 @@ import { serpentInit } from './serpent/index.js';
24
24
  import { chacha20Init } from './chacha20/index.js';
25
25
  import { sha2Init } from './sha2/index.js';
26
26
  import { sha3Init } from './sha3/index.js';
27
+ import { keccakInit } from './keccak/index.js';
28
+ import { kyberInit } from './kyber/index.js';
29
+ import { hasSIMD } from './utils.js';
27
30
  const _dispatchers = {
28
31
  serpent: serpentInit,
29
32
  chacha20: chacha20Init,
30
33
  sha2: sha2Init,
31
34
  sha3: sha3Init,
35
+ keccak: keccakInit,
36
+ kyber: kyberInit,
32
37
  };
33
- export async function init(modules, mode = 'embedded', opts) {
34
- const list = Array.isArray(modules) ? modules : [modules];
35
- await Promise.all(list.map(mod => _dispatchers[mod](mode, opts)));
38
+ /**
39
+ * Load one or more WASM modules. Each key is a module name; the value is the
40
+ * WasmSource to load it from (embedded blob, URL, ArrayBuffer, etc.).
41
+ *
42
+ * ```ts
43
+ * import { init } from 'leviathan-crypto';
44
+ * import { serpentWasm } from 'leviathan-crypto/serpent/embedded';
45
+ * import { sha2Wasm } from 'leviathan-crypto/sha2/embedded';
46
+ * await init({ serpent: serpentWasm, sha2: sha2Wasm });
47
+ * ```
48
+ */
49
+ export async function init(sources) {
50
+ const entries = Object.entries(sources);
51
+ // SIMD preflight — serpent, chacha20, and kyber modules contain SIMD instructions
52
+ if (('serpent' in sources || 'chacha20' in sources || 'kyber' in sources) && !hasSIMD())
53
+ throw new Error('leviathan-crypto: serpent, chacha20, and kyber require WebAssembly SIMD — '
54
+ + 'this runtime does not support it');
55
+ for (const [mod, src] of entries) {
56
+ if (!Object.hasOwn(_dispatchers, mod))
57
+ throw new Error(`leviathan-crypto: unknown module "${mod}" — expected one of: ${Object.keys(_dispatchers).join(', ')}`);
58
+ if (src == null)
59
+ throw new TypeError(`leviathan-crypto: source for "${mod}" is null or undefined`);
60
+ }
61
+ await Promise.all(entries.map(([mod, src]) => _dispatchers[mod](src)));
36
62
  }
37
63
  export { isInitialized, _resetForTesting } from './init.js';
38
- export { serpentInit, SerpentSeal, Serpent, SerpentCtr, SerpentCbc, SerpentStream, SerpentStreamPool, SerpentStreamSealer, SerpentStreamOpener, _serpentReady } from './serpent/index.js';
39
- export { chacha20Init, ChaCha20, Poly1305, ChaCha20Poly1305, XChaCha20Poly1305, _chachaReady } from './chacha20/index.js';
40
- export { XChaCha20Poly1305Pool } from './chacha20/pool.js';
64
+ export { AuthenticationError } from './errors.js';
65
+ export { serpentInit, Serpent, SerpentCtr, SerpentCbc, SerpentCipher, _serpentReady } from './serpent/index.js';
66
+ export { chacha20Init, ChaCha20, Poly1305, ChaCha20Poly1305, XChaCha20Poly1305, XChaCha20Cipher, _chachaReady } from './chacha20/index.js';
41
67
  export { sha2Init, SHA256, SHA512, SHA384, HMAC_SHA256, HMAC_SHA512, HMAC_SHA384, HKDF_SHA256, HKDF_SHA512, _sha2Ready } from './sha2/index.js';
42
68
  export { sha3Init, SHA3_224, SHA3_256, SHA3_384, SHA3_512, SHAKE128, SHAKE256, _sha3Ready } from './sha3/index.js';
69
+ export { keccakInit } from './keccak/index.js';
70
+ export { kyberInit, MlKem512, MlKem768, MlKem1024, MlKemBase, KyberSuite, _kyberReady } from './kyber/index.js';
71
+ export { SealStream, OpenStream, Seal, SealStreamPool, FLAG_FRAMED, TAG_DATA, TAG_FINAL, HEADER_SIZE, CHUNK_MIN, CHUNK_MAX } from './stream/index.js';
43
72
  export { Fortuna } from './fortuna.js';
44
- export { hexToBytes, bytesToHex, utf8ToBytes, bytesToUtf8, base64ToBytes, bytesToBase64, constantTimeEqual, wipe, xor, concat, randomBytes, } from './utils.js';
73
+ export { hexToBytes, bytesToHex, utf8ToBytes, bytesToUtf8, base64ToBytes, bytesToBase64, constantTimeEqual, CT_MAX_BYTES, wipe, xor, concat, randomBytes, hasSIMD, } from './utils.js';
package/dist/init.d.ts CHANGED
@@ -1,10 +1,6 @@
1
- export type Module = 'serpent' | 'chacha20' | 'sha2' | 'sha3';
2
- export type Mode = 'embedded' | 'streaming' | 'manual';
3
- export interface InitOpts {
4
- wasmUrl?: URL | string;
5
- wasmBinary?: Partial<Record<Module, Uint8Array | ArrayBuffer>>;
6
- }
7
- export declare function initModule(mod: Module, embeddedThunk: () => Promise<string>, mode?: Mode, opts?: InitOpts): Promise<void>;
1
+ import type { WasmSource } from './wasm-source.js';
2
+ export type Module = 'serpent' | 'chacha20' | 'sha2' | 'sha3' | 'keccak' | 'kyber';
3
+ export declare function initModule(mod: Module, source: WasmSource): Promise<void>;
8
4
  export declare function getInstance(mod: Module): WebAssembly.Instance;
9
5
  export declare function isInitialized(mod: Module): boolean;
10
6
  /** Reset all cached instances — for testing only */
package/dist/init.js CHANGED
@@ -1,47 +1,30 @@
1
- // Module-scope cache: one WebAssembly.Instance per module
1
+ import { loadWasm } from './loader.js';
2
+ import { hasSIMD } from './utils.js';
3
+ // 'keccak' is an alias for 'sha3' — same WASM binary, same instance slot
4
+ const ALIASES = { keccak: 'sha3' };
5
+ function resolve(mod) {
6
+ return ALIASES[mod] ?? mod;
7
+ }
8
+ // Module-scope cache: one WebAssembly.Instance per canonical module
2
9
  const instances = new Map();
3
- // Map from public module name to WASM filename
4
- const WASM_FILES = {
5
- serpent: 'serpent.wasm',
6
- chacha20: 'chacha20.wasm',
7
- sha2: 'sha2.wasm',
8
- sha3: 'sha3.wasm',
9
- };
10
- export async function initModule(mod, embeddedThunk, mode = 'embedded', opts) {
11
- if (instances.has(mod))
10
+ export async function initModule(mod, source) {
11
+ const resolved = resolve(mod);
12
+ if (instances.has(resolved))
12
13
  return;
13
- let instance;
14
- if (mode === 'embedded') {
15
- const { loadEmbedded } = await import('./loader.js');
16
- instance = await loadEmbedded(embeddedThunk);
17
- }
18
- else if (mode === 'streaming') {
19
- if (!opts?.wasmUrl)
20
- throw new Error('leviathan-crypto: streaming mode requires wasmUrl');
21
- const { loadStreaming } = await import('./loader.js');
22
- instance = await loadStreaming(mod, opts.wasmUrl, WASM_FILES[mod]);
23
- }
24
- else if (mode === 'manual') {
25
- const binary = opts?.wasmBinary?.[mod];
26
- if (!binary)
27
- throw new Error(`leviathan-crypto: manual mode requires wasmBinary['${mod}']`);
28
- const { loadManual } = await import('./loader.js');
29
- instance = await loadManual(binary);
30
- }
31
- else {
32
- throw new Error(`leviathan-crypto: unknown mode '${mode}'`);
33
- }
34
- instances.set(mod, instance);
14
+ if ((resolved === 'serpent' || resolved === 'chacha20' || resolved === 'kyber') && !hasSIMD())
15
+ throw new Error('leviathan-crypto: serpent, chacha20, and kyber require WebAssembly SIMD — '
16
+ + 'this runtime does not support it');
17
+ instances.set(resolved, await loadWasm(source));
35
18
  }
36
19
  export function getInstance(mod) {
37
- const inst = instances.get(mod);
20
+ const inst = instances.get(resolve(mod));
38
21
  if (!inst) {
39
- throw new Error(`leviathan-crypto: call init(['${mod}']) before using this class`);
22
+ throw new Error(`leviathan-crypto: call init({ ${mod}: ... }) before using this class`);
40
23
  }
41
24
  return inst;
42
25
  }
43
26
  export function isInitialized(mod) {
44
- return instances.has(mod);
27
+ return instances.has(resolve(mod));
45
28
  }
46
29
  /** Reset all cached instances — for testing only */
47
30
  export function _resetForTesting() {
@@ -0,0 +1 @@
1
+ export { WASM_GZ_BASE64 as keccakWasm } from '../embedded/sha3.js';
@@ -0,0 +1,27 @@
1
+ // ▄▄▄▄▄▄▄▄▄▄
2
+ // ▄████████████████████▄▄ ▒ ▄▀▀ ▒ ▒ █ ▄▀▄ ▀█▀ █ ▒ ▄▀▄ █▀▄
3
+ // ▄██████████████████████ ▀████▄ ▓ ▓▀ ▓ ▓ ▓ ▓▄▓ ▓ ▓▀▓ ▓▄▓ ▓ ▓
4
+ // ▄█████████▀▀▀ ▀███████▄▄███████▌ ▀▄ ▀▄▄ ▀▄▀ ▒ ▒ ▒ ▒ ▒ █ ▒ ▒ ▒ █
5
+ // ▐████████▀ ▄▄▄▄ ▀████████▀██▀█▌
6
+ // ████████ ███▀▀ ████▀ █▀ █▀ Leviathan Crypto Library
7
+ // ███████▌ ▀██▀ ███
8
+ // ███████ ▀███ ▀██ ▀█▄ Repository & Mirror:
9
+ // ▀██████ ▄▄██ ▀▀ ██▄ github.com/xero/leviathan-crypto
10
+ // ▀█████▄ ▄██▄ ▄▀▄▀ unpkg.com/leviathan-crypto
11
+ // ▀████▄ ▄██▄
12
+ // ▐████ ▐███ Author: xero (https://x-e.ro)
13
+ // ▄▄██████████ ▐███ ▄▄ License: MIT
14
+ // ▄██▀▀▀▀▀▀▀▀▀▀ ▄████ ▄██▀
15
+ // ▄▀ ▄▄█████████▄▄ ▀▀▀▀▀ ▄███ This file is provided completely
16
+ // ▄██████▀▀▀▀▀▀██████▄ ▀▄▄▄▄████▀ free, "as is", and without
17
+ // ████▀ ▄▄▄▄▄▄▄ ▀████▄ ▀█████▀ ▄▄▄▄ warranty of any kind. The author
18
+ // █████▄▄█████▀▀▀▀▀▀▄ ▀███▄ ▄████ assumes absolutely no liability
19
+ // ▀██████▀ ▀████▄▄▄████▀ for its {ab,mis,}use.
20
+ // ▀█████▀▀
21
+ //
22
+ // src/ts/keccak/embedded.ts
23
+ //
24
+ // Re-exports the sha3 WASM blob under the keccak name.
25
+ // The keccak alias shares the sha3 binary — no separate keccak.wasm exists.
26
+ // Import via `leviathan-crypto/keccak/embedded`.
27
+ export { WASM_GZ_BASE64 as keccakWasm } from '../embedded/sha3.js';
@@ -0,0 +1,4 @@
1
+ import type { WasmSource } from '../wasm-source.js';
2
+ export declare function keccakInit(source: WasmSource): Promise<void>;
3
+ export type { WasmSource };
4
+ export { SHA3_224, SHA3_256, SHA3_384, SHA3_512, SHAKE128, SHAKE256 } from '../sha3/index.js';
@@ -0,0 +1,31 @@
1
+ // ▄▄▄▄▄▄▄▄▄▄
2
+ // ▄████████████████████▄▄ ▒ ▄▀▀ ▒ ▒ █ ▄▀▄ ▀█▀ █ ▒ ▄▀▄ █▀▄
3
+ // ▄██████████████████████ ▀████▄ ▓ ▓▀ ▓ ▓ ▓ ▓▄▓ ▓ ▓▀▓ ▓▄▓ ▓ ▓
4
+ // ▄█████████▀▀▀ ▀███████▄▄███████▌ ▀▄ ▀▄▄ ▀▄▀ ▒ ▒ ▒ ▒ ▒ █ ▒ ▒ ▒ █
5
+ // ▐████████▀ ▄▄▄▄ ▀████████▀██▀█▌
6
+ // ████████ ███▀▀ ████▀ █▀ █▀ Leviathan Crypto Library
7
+ // ███████▌ ▀██▀ ███
8
+ // ███████ ▀███ ▀██ ▀█▄ Repository & Mirror:
9
+ // ▀██████ ▄▄██ ▀▀ ██▄ github.com/xero/leviathan-crypto
10
+ // ▀█████▄ ▄██▄ ▄▀▄▀ unpkg.com/leviathan-crypto
11
+ // ▀████▄ ▄██▄
12
+ // ▐████ ▐███ Author: xero (https://x-e.ro)
13
+ // ▄▄██████████ ▐███ ▄▄ License: MIT
14
+ // ▄██▀▀▀▀▀▀▀▀▀▀ ▄████ ▄██▀
15
+ // ▄▀ ▄▄█████████▄▄ ▀▀▀▀▀ ▄███ This file is provided completely
16
+ // ▄██████▀▀▀▀▀▀██████▄ ▀▄▄▄▄████▀ free, "as is", and without
17
+ // ████▀ ▄▄▄▄▄▄▄ ▀████▄ ▀█████▀ ▄▄▄▄ warranty of any kind. The author
18
+ // █████▄▄█████▀▀▀▀▀▀▄ ▀███▄ ▄████ assumes absolutely no liability
19
+ // ▀██████▀ ▀████▄▄▄████▀ for its {ab,mis,}use.
20
+ // ▀█████▀▀
21
+ //
22
+ // src/ts/keccak/index.ts
23
+ //
24
+ // Keccak alias subpath — resolves to the sha3 WASM module slot.
25
+ // Consumers who prefer the Keccak name (e.g. Kyber/ML-KEM implementations)
26
+ // can import from `leviathan-crypto/keccak` instead of `leviathan-crypto/sha3`.
27
+ import { initModule } from '../init.js';
28
+ export async function keccakInit(source) {
29
+ return initModule('keccak', source);
30
+ }
31
+ export { SHA3_224, SHA3_256, SHA3_384, SHA3_512, SHAKE128, SHAKE256 } from '../sha3/index.js';
@@ -0,0 +1 @@
1
+ export { WASM_GZ_BASE64 as kyberWasm } from '../embedded/kyber.js';
@@ -0,0 +1,27 @@
1
+ // ▄▄▄▄▄▄▄▄▄▄
2
+ // ▄████████████████████▄▄ ▒ ▄▀▀ ▒ ▒ █ ▄▀▄ ▀█▀ █ ▒ ▄▀▄ █▀▄
3
+ // ▄██████████████████████ ▀████▄ ▓ ▓▀ ▓ ▓ ▓ ▓▄▓ ▓ ▓▀▓ ▓▄▓ ▓ ▓
4
+ // ▄█████████▀▀▀ ▀███████▄▄███████▌ ▀▄ ▀▄▄ ▀▄▀ ▒ ▒ ▒ ▒ ▒ █ ▒ ▒ ▒ █
5
+ // ▐████████▀ ▄▄▄▄ ▀████████▀██▀█▌
6
+ // ████████ ███▀▀ ████▀ █▀ █▀ Leviathan Crypto Library
7
+ // ███████▌ ▀██▀ ███
8
+ // ███████ ▀███ ▀██ ▀█▄ Repository & Mirror:
9
+ // ▀██████ ▄▄██ ▀▀ ██▄ github.com/xero/leviathan-crypto
10
+ // ▀█████▄ ▄██▄ ▄▀▄▀ unpkg.com/leviathan-crypto
11
+ // ▀████▄ ▄██▄
12
+ // ▐████ ▐███ Author: xero (https://x-e.ro)
13
+ // ▄▄██████████ ▐███ ▄▄ License: MIT
14
+ // ▄██▀▀▀▀▀▀▀▀▀▀ ▄████ ▄██▀
15
+ // ▄▀ ▄▄█████████▄▄ ▀▀▀▀▀ ▄███ This file is provided completely
16
+ // ▄██████▀▀▀▀▀▀██████▄ ▀▄▄▄▄████▀ free, "as is", and without
17
+ // ████▀ ▄▄▄▄▄▄▄ ▀████▄ ▀█████▀ ▄▄▄▄ warranty of any kind. The author
18
+ // █████▄▄█████▀▀▀▀▀▀▄ ▀███▄ ▄████ assumes absolutely no liability
19
+ // ▀██████▀ ▀████▄▄▄████▀ for its {ab,mis,}use.
20
+ // ▀█████▀▀
21
+ //
22
+ // src/ts/kyber/embedded.ts
23
+ //
24
+ // Exports the gzip+base64 kyber WASM blob for use as a WasmSource.
25
+ // This is the only file in the kyber subpath that references the embedded blob.
26
+ // Import via `leviathan-crypto/kyber/embedded`.
27
+ export { WASM_GZ_BASE64 as kyberWasm } from '../embedded/kyber.js';
@@ -0,0 +1,49 @@
1
+ import type { KyberExports, Sha3Exports } from './types.js';
2
+ import type { KyberParams } from './params.js';
3
+ /** SHA3-512(msg) → 64 bytes. Resets sha3 state. */
4
+ export declare function sha3_512Hash(sx: Sha3Exports, msg: Uint8Array): Uint8Array;
5
+ /** SHA3-256(msg) → 32 bytes. Resets sha3 state. */
6
+ export declare function sha3_256Hash(sx: Sha3Exports, msg: Uint8Array): Uint8Array;
7
+ /**
8
+ * SHAKE256(msg, n) → n bytes. Resets sha3 state.
9
+ * Used for J function (z || c) and PRF seeding in kem.ts.
10
+ */
11
+ export declare function shake256Hash(sx: Sha3Exports, msg: Uint8Array, n: number): Uint8Array;
12
+ /**
13
+ * K-PKE.KeyGen (FIPS 203 Algorithm 12) — deterministic.
14
+ *
15
+ * Slot map:
16
+ * pvec0 — current row of  (overwritten per row)
17
+ * pvec1 — ŝ (noise, persistent through dot products)
18
+ * pvec2 — ê (noise)
19
+ * pvec3 — t̂ = ·ŝ + ê (output)
20
+ */
21
+ export declare function indcpaKeypairDerand(kx: KyberExports, sx: Sha3Exports, params: KyberParams, d: Uint8Array): {
22
+ ekCpa: Uint8Array;
23
+ skCpa: Uint8Array;
24
+ };
25
+ /**
26
+ * K-PKE.Encrypt (FIPS 203 Algorithm 13) — deterministic.
27
+ *
28
+ * Slot map:
29
+ * pvec0 — current row of Â^T (transposed, overwritten per row)
30
+ * pvec1 — r̂ = NTT(r)
31
+ * pvec2 — e₁ (noise)
32
+ * pvec3 — u = invNTT(Â^T · r̂) + e₁
33
+ * pvec4 — t̂ (unpacked from ek)
34
+ * poly1 — e₂ (noise)
35
+ * poly2 — v = invNTT(t̂^T · r̂) + e₂ + msg
36
+ * poly3 — message polynomial
37
+ */
38
+ export declare function indcpaEncrypt(kx: KyberExports, sx: Sha3Exports, params: KyberParams, ek: Uint8Array, m: Uint8Array, coins: Uint8Array): Uint8Array;
39
+ /**
40
+ * K-PKE.Decrypt (FIPS 203 Algorithm 14).
41
+ *
42
+ * Slot map:
43
+ * pvec0 — û (decompressed from ct)
44
+ * pvec1 — ŝ (from sk)
45
+ * poly0 — v (decompressed from ct)
46
+ * poly1 — w = invNTT(ŝ^T · NTT(û))
47
+ * poly2 — m' = v - w
48
+ */
49
+ export declare function indcpaDecrypt(kx: KyberExports, params: KyberParams, skCpa: Uint8Array, ct: Uint8Array): Uint8Array;