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
@@ -0,0 +1,160 @@
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/kem.ts
23
+ //
24
+ // ML-KEM KEM layer β€” Fujisaki-Okamoto transform.
25
+ // FIPS 203 Algorithms 15, 16, 17 (ML-KEM internal).
26
+ import { indcpaKeypairDerand, indcpaEncrypt, indcpaDecrypt, sha3_256Hash, sha3_512Hash, shake256Hash, } from './indcpa.js';
27
+ import { wipe } from '../utils.js';
28
+ /**
29
+ * ML-KEM.KeyGen_internal (FIPS 203 Algorithm 15).
30
+ *
31
+ * dk = skCpa || ek || H(ek) || z
32
+ */
33
+ export function kemKeypairDerand(kx, sx, params, d, z) {
34
+ // indcpaKeypairDerand handles its own sigma wipe
35
+ const { ekCpa, skCpa } = indcpaKeypairDerand(kx, sx, params, d);
36
+ const h = sha3_256Hash(sx, ekCpa);
37
+ try {
38
+ const dk = new Uint8Array(params.dkBytes);
39
+ dk.set(skCpa, 0);
40
+ dk.set(ekCpa, params.skCpaBytes);
41
+ dk.set(h, params.skCpaBytes + params.ekBytes);
42
+ dk.set(z, params.skCpaBytes + params.ekBytes + 32);
43
+ return {
44
+ encapsulationKey: ekCpa,
45
+ decapsulationKey: dk,
46
+ };
47
+ }
48
+ finally {
49
+ wipe(skCpa);
50
+ wipe(h);
51
+ }
52
+ }
53
+ /**
54
+ * ML-KEM.Encaps_internal (FIPS 203 Algorithm 16).
55
+ *
56
+ * (K, r) = G(m || H(ek)), c = K-PKE.Encrypt(ek, m, r)
57
+ */
58
+ export function kemEncapsulateDerand(kx, sx, params, ek, m) {
59
+ const h = sha3_256Hash(sx, ek);
60
+ let gInput;
61
+ let gOut;
62
+ let r;
63
+ try {
64
+ gInput = new Uint8Array(64);
65
+ gInput.set(m, 0);
66
+ gInput.set(h, 32);
67
+ gOut = sha3_512Hash(sx, gInput);
68
+ const K = gOut.slice(0, 32);
69
+ r = gOut.slice(32, 64);
70
+ const c = indcpaEncrypt(kx, sx, params, ek, m, r);
71
+ return { ciphertext: c, sharedSecret: K };
72
+ }
73
+ finally {
74
+ if (gInput)
75
+ wipe(gInput);
76
+ if (gOut)
77
+ wipe(gOut);
78
+ if (r)
79
+ wipe(r);
80
+ }
81
+ }
82
+ /**
83
+ * ML-KEM.Decaps_internal (FIPS 203 Algorithm 17).
84
+ *
85
+ * Constant-time: uses ct_verify and ct_cmov from kyber WASM.
86
+ * MUST NOT branch on secret data in JS β€” all comparison via WASM primitives.
87
+ */
88
+ export function kemDecapsulate(kx, sx, params, dk, c) {
89
+ const { skCpaBytes, ekBytes, ctBytes } = params;
90
+ // Parse dk: skCpa || ek || H(ek) || z
91
+ const skCpa = dk.slice(0, skCpaBytes);
92
+ const ek = dk.slice(skCpaBytes, skCpaBytes + ekBytes);
93
+ const h = dk.slice(skCpaBytes + ekBytes, skCpaBytes + ekBytes + 32);
94
+ const z = dk.slice(skCpaBytes + ekBytes + 32, skCpaBytes + ekBytes + 64);
95
+ let mPrime;
96
+ let gInput;
97
+ let gOut;
98
+ let kPrime;
99
+ let rPrime;
100
+ let jInput;
101
+ let kBar;
102
+ let cPrime;
103
+ try {
104
+ // Decrypt
105
+ mPrime = indcpaDecrypt(kx, params, skCpa, c);
106
+ // G(m' || H(ek)) β†’ (K', r')
107
+ gInput = new Uint8Array(64);
108
+ gInput.set(mPrime, 0);
109
+ gInput.set(h, 32);
110
+ gOut = sha3_512Hash(sx, gInput);
111
+ kPrime = gOut.slice(0, 32);
112
+ rPrime = gOut.slice(32, 64);
113
+ // J(z || c) β†’ KΜ„ [implicit rejection value]
114
+ jInput = new Uint8Array(32 + ctBytes);
115
+ jInput.set(z, 0);
116
+ jInput.set(c, 32);
117
+ kBar = shake256Hash(sx, jInput, 32);
118
+ // Re-encrypt c' = K-PKE.Encrypt(ek, m', r') β€” indcpaEncrypt handles its own prfInput wipe
119
+ cPrime = indcpaEncrypt(kx, sx, params, ek, mPrime, rPrime);
120
+ // Constant-time comparison and conditional select via kyber WASM
121
+ const kyberMem = new Uint8Array(kx.memory.buffer);
122
+ const ctOff = kx.getCtOffset();
123
+ const ctPrimeOff = kx.getCtPrimeOffset();
124
+ // Write c and c' into named kyber memory regions
125
+ kyberMem.set(c, ctOff);
126
+ kyberMem.set(cPrime, ctPrimeOff);
127
+ // Write K' and KΜ„ into poly slots (512B each, 32B needed)
128
+ const kPrimeOff = kx.getPolySlot0();
129
+ const kBarOff = kx.getPolySlot1();
130
+ kyberMem.set(kPrime, kPrimeOff);
131
+ kyberMem.set(kBar, kBarOff);
132
+ // fail = 0 if c == c', non-zero if different
133
+ const fail = kx.ct_verify(ctOff, ctPrimeOff, ctBytes);
134
+ // If fail != 0 (mismatch): K' ← KΜ„
135
+ kx.ct_cmov(kPrimeOff, kBarOff, 32, fail);
136
+ return kyberMem.slice(kPrimeOff, kPrimeOff + 32);
137
+ }
138
+ finally {
139
+ if (mPrime)
140
+ wipe(mPrime);
141
+ if (gInput)
142
+ wipe(gInput);
143
+ if (gOut)
144
+ wipe(gOut);
145
+ if (kPrime)
146
+ wipe(kPrime);
147
+ if (rPrime)
148
+ wipe(rPrime);
149
+ if (jInput)
150
+ wipe(jInput);
151
+ if (kBar)
152
+ wipe(kBar);
153
+ if (cPrime)
154
+ wipe(cPrime);
155
+ wipe(skCpa);
156
+ wipe(ek);
157
+ wipe(h);
158
+ wipe(z);
159
+ }
160
+ }
@@ -0,0 +1,14 @@
1
+ export interface KyberParams {
2
+ k: number;
3
+ eta1: number;
4
+ eta2: number;
5
+ du: number;
6
+ dv: number;
7
+ ekBytes: number;
8
+ dkBytes: number;
9
+ ctBytes: number;
10
+ skCpaBytes: number;
11
+ }
12
+ export declare const MLKEM512: KyberParams;
13
+ export declare const MLKEM768: KyberParams;
14
+ export declare const MLKEM1024: KyberParams;
@@ -0,0 +1,37 @@
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/params.ts
23
+ //
24
+ // ML-KEM (FIPS 203) parameter set configurations.
25
+ // FIPS 203 Table 2 β€” Parameter sets for ML-KEM.
26
+ export const MLKEM512 = {
27
+ k: 2, eta1: 3, eta2: 2, du: 10, dv: 4,
28
+ ekBytes: 800, dkBytes: 1632, ctBytes: 768, skCpaBytes: 768,
29
+ };
30
+ export const MLKEM768 = {
31
+ k: 3, eta1: 2, eta2: 2, du: 10, dv: 4,
32
+ ekBytes: 1184, dkBytes: 2400, ctBytes: 1088, skCpaBytes: 1152,
33
+ };
34
+ export const MLKEM1024 = {
35
+ k: 4, eta1: 2, eta2: 2, du: 11, dv: 5,
36
+ ekBytes: 1568, dkBytes: 3168, ctBytes: 1568, skCpaBytes: 1536,
37
+ };
@@ -0,0 +1,13 @@
1
+ import type { CipherSuite } from '../stream/types.js';
2
+ import type { KyberKeyPair, KyberEncapsulation } from './types.js';
3
+ import type { KyberParams } from './params.js';
4
+ interface MlKemLike {
5
+ readonly params: KyberParams;
6
+ encapsulate(ek: Uint8Array): KyberEncapsulation;
7
+ decapsulate(dk: Uint8Array, c: Uint8Array): Uint8Array;
8
+ keygen(): KyberKeyPair;
9
+ }
10
+ export declare function KyberSuite(kem: MlKemLike, inner: CipherSuite): CipherSuite & {
11
+ keygen(): KyberKeyPair;
12
+ };
13
+ export {};
@@ -0,0 +1,93 @@
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/suite.ts
23
+ //
24
+ // KyberSuite β€” wraps a MlKemBase + inner CipherSuite into a unified CipherSuite.
25
+ // Provides hybrid KEM + symmetric AEAD for use with SealStream / OpenStream / Seal.
26
+ import { concat } from '../utils.js';
27
+ import { HKDF_SHA256 } from '../sha2/index.js';
28
+ // KEM selector per parameter set (bits 4-5 of formatEnum)
29
+ const KEM_NIBBLE = {
30
+ 2: 0x10, // ML-KEM-512 (k=2)
31
+ 3: 0x20, // ML-KEM-768 (k=3)
32
+ 4: 0x30, // ML-KEM-1024 (k=4)
33
+ };
34
+ const KEM_LABEL = {
35
+ 2: 'mlkem512',
36
+ 3: 'mlkem768',
37
+ 4: 'mlkem1024',
38
+ };
39
+ export function KyberSuite(kem, inner) {
40
+ const p = kem.params;
41
+ const kemNibble = KEM_NIBBLE[p.k];
42
+ if (!kemNibble)
43
+ throw new Error(`unsupported ML-KEM k=${p.k}`);
44
+ const kemLabel = KEM_LABEL[p.k];
45
+ const infoBytes = new TextEncoder().encode(inner.hkdfInfo);
46
+ return {
47
+ formatEnum: kemNibble | inner.formatEnum,
48
+ formatName: `${kemLabel}+${inner.formatName}`,
49
+ hkdfInfo: inner.hkdfInfo,
50
+ keySize: p.ekBytes,
51
+ decKeySize: p.dkBytes,
52
+ kemCtSize: p.ctBytes,
53
+ tagSize: inner.tagSize,
54
+ padded: inner.padded,
55
+ wasmModules: [...inner.wasmModules, 'kyber', 'sha3'],
56
+ deriveKeys(key, nonce, kemCt) {
57
+ let sharedSecret;
58
+ let outKemCt;
59
+ let ctForInfo;
60
+ if (kemCt === undefined) {
61
+ // encrypt path: key = ek β€” encapsulate to produce shared secret + ct
62
+ const result = kem.encapsulate(key);
63
+ sharedSecret = result.sharedSecret;
64
+ outKemCt = result.ciphertext;
65
+ ctForInfo = outKemCt;
66
+ }
67
+ else {
68
+ // decrypt path: key = dk β€” decapsulate to recover shared secret
69
+ sharedSecret = kem.decapsulate(key, kemCt);
70
+ ctForInfo = kemCt;
71
+ }
72
+ // Bind kemCt into HKDF info for defense in depth (KEM ciphertext binding)
73
+ const info = concat(infoBytes, ctForInfo);
74
+ const hkdf = new HKDF_SHA256();
75
+ const derived = hkdf.derive(sharedSecret, nonce, info, inner.keySize);
76
+ hkdf.dispose();
77
+ sharedSecret.fill(0);
78
+ // Delegate actual per-cipher key derivation to the inner suite
79
+ const innerKeys = inner.deriveKeys(derived, nonce);
80
+ derived.fill(0);
81
+ return outKemCt
82
+ ? { bytes: innerKeys.bytes, kemCiphertext: outKemCt }
83
+ : innerKeys;
84
+ },
85
+ sealChunk: inner.sealChunk.bind(inner),
86
+ openChunk: inner.openChunk.bind(inner),
87
+ wipeKeys: inner.wipeKeys.bind(inner),
88
+ createPoolWorker: inner.createPoolWorker.bind(inner),
89
+ keygen() {
90
+ return kem.keygen();
91
+ },
92
+ };
93
+ }
@@ -0,0 +1,98 @@
1
+ export interface KyberExports {
2
+ memory: WebAssembly.Memory;
3
+ getModuleId: () => number;
4
+ getMemoryPages: () => number;
5
+ getPolySlotBase: () => number;
6
+ getPolySlotSize: () => number;
7
+ getPolySlot0: () => number;
8
+ getPolySlot1: () => number;
9
+ getPolySlot2: () => number;
10
+ getPolySlot3: () => number;
11
+ getPolySlot4: () => number;
12
+ getPolySlot5: () => number;
13
+ getPolySlot6: () => number;
14
+ getPolySlot7: () => number;
15
+ getPolySlot8: () => number;
16
+ getPolySlot9: () => number;
17
+ getPolyvecSlotBase: () => number;
18
+ getPolyvecSlotSize: () => number;
19
+ getPolyvecSlot0: () => number;
20
+ getPolyvecSlot1: () => number;
21
+ getPolyvecSlot2: () => number;
22
+ getPolyvecSlot3: () => number;
23
+ getPolyvecSlot4: () => number;
24
+ getPolyvecSlot5: () => number;
25
+ getPolyvecSlot6: () => number;
26
+ getPolyvecSlot7: () => number;
27
+ getSeedOffset: () => number;
28
+ getMsgOffset: () => number;
29
+ getPkOffset: () => number;
30
+ getSkOffset: () => number;
31
+ getCtOffset: () => number;
32
+ getCtPrimeOffset: () => number;
33
+ getXofPrfOffset: () => number;
34
+ wipeBuffers: () => void;
35
+ montgomery_reduce: (a: number) => number;
36
+ barrett_reduce: (a: number) => number;
37
+ fqmul: (a: number, b: number) => number;
38
+ getZetasOffset: () => number;
39
+ getZeta: (i: number) => number;
40
+ ntt: (polyOffset: number) => void;
41
+ invntt: (polyOffset: number) => void;
42
+ basemul: (rOffset: number, aOffset: number, bOffset: number, zetaIdx: number) => void;
43
+ poly_tobytes: (rOffset: number, polyOffset: number) => void;
44
+ poly_frombytes: (polyOffset: number, aOffset: number) => void;
45
+ poly_compress: (rOffset: number, polyOffset: number, dv: number) => void;
46
+ poly_decompress: (polyOffset: number, aOffset: number, dv: number) => void;
47
+ poly_frommsg: (polyOffset: number, msgOffset: number) => void;
48
+ poly_tomsg: (msgOffset: number, polyOffset: number) => void;
49
+ poly_add: (rOffset: number, aOffset: number, bOffset: number) => void;
50
+ poly_sub: (rOffset: number, aOffset: number, bOffset: number) => void;
51
+ poly_reduce: (polyOffset: number) => void;
52
+ poly_tomont: (polyOffset: number) => void;
53
+ poly_ntt: (polyOffset: number) => void;
54
+ poly_invntt: (polyOffset: number) => void;
55
+ poly_basemul_montgomery: (rOffset: number, aOffset: number, bOffset: number) => void;
56
+ poly_getnoise: (polyOffset: number, bufOffset: number, eta: number) => void;
57
+ polyvec_tobytes: (rOffset: number, pvOffset: number, k: number) => void;
58
+ polyvec_frombytes: (pvOffset: number, aOffset: number, k: number) => void;
59
+ polyvec_compress: (rOffset: number, pvOffset: number, k: number, du: number) => void;
60
+ polyvec_decompress: (pvOffset: number, aOffset: number, k: number, du: number) => void;
61
+ polyvec_ntt: (pvOffset: number, k: number) => void;
62
+ polyvec_invntt: (pvOffset: number, k: number) => void;
63
+ polyvec_reduce: (pvOffset: number, k: number) => void;
64
+ polyvec_add: (rOffset: number, aOffset: number, bOffset: number, k: number) => void;
65
+ polyvec_basemul_acc_montgomery: (rOffset: number, aOffset: number, bOffset: number, k: number) => void;
66
+ rej_uniform: (polyOffset: number, ctrStart: number, bufOffset: number, buflen: number) => number;
67
+ ct_verify: (aOffset: number, bOffset: number, len: number) => number;
68
+ ct_cmov: (rOffset: number, xOffset: number, len: number, b: number) => void;
69
+ }
70
+ export interface Sha3Exports {
71
+ memory: WebAssembly.Memory;
72
+ getInputOffset: () => number;
73
+ getOutOffset: () => number;
74
+ getStateOffset: () => number;
75
+ sha3_224Init: () => void;
76
+ sha3_256Init: () => void;
77
+ sha3_384Init: () => void;
78
+ sha3_512Init: () => void;
79
+ shake128Init: () => void;
80
+ shake256Init: () => void;
81
+ keccakAbsorb: (len: number) => void;
82
+ sha3_224Final: () => void;
83
+ sha3_256Final: () => void;
84
+ sha3_384Final: () => void;
85
+ sha3_512Final: () => void;
86
+ shakeFinal: (outLen: number) => void;
87
+ shakePad: () => void;
88
+ shakeSqueezeBlock: () => void;
89
+ wipeBuffers: () => void;
90
+ }
91
+ export interface KyberKeyPair {
92
+ encapsulationKey: Uint8Array;
93
+ decapsulationKey: Uint8Array;
94
+ }
95
+ export interface KyberEncapsulation {
96
+ ciphertext: Uint8Array;
97
+ sharedSecret: Uint8Array;
98
+ }
@@ -0,0 +1,25 @@
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/types.ts
23
+ //
24
+ // ML-KEM type definitions: WASM export interfaces and KEM API types.
25
+ export {};
@@ -0,0 +1,19 @@
1
+ import type { KyberExports, Sha3Exports } from './types.js';
2
+ import type { KyberParams } from './params.js';
3
+ /**
4
+ * Encapsulation key check β€” FIPS 203 Β§7.2 (EncapsulationKeyCheck).
5
+ *
6
+ * 1. Length check: ek.length == params.ekBytes
7
+ * 2. ByteDecode₁₂ β†’ ByteEncode₁₂ round-trip check on the polyvec portion.
8
+ * Any coefficient β‰₯ q stored modulo 2^12 survives frombytes, but tobytes
9
+ * re-encodes it differently β€” so the round-trip fails iff any coeff was β‰₯ q.
10
+ */
11
+ export declare function checkEncapsulationKey(kx: KyberExports, params: KyberParams, ek: Uint8Array): boolean;
12
+ /**
13
+ * Decapsulation key check β€” FIPS 203 Β§7.3 (DecapsulationKeyCheck).
14
+ *
15
+ * 1. Length check: dk.length == params.dkBytes
16
+ * 2. Extract embedded ek and H(ek), verify SHA3-256(ek) matches stored H
17
+ * 3. Also run checkEncapsulationKey on the embedded ek
18
+ */
19
+ export declare function checkDecapsulationKey(kx: KyberExports, sx: Sha3Exports, params: KyberParams, dk: Uint8Array): boolean;
@@ -0,0 +1,68 @@
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/validate.ts
23
+ //
24
+ // ML-KEM key validation β€” FIPS 203 Β§7.2 and Β§7.3.
25
+ import { sha3_256Hash } from './indcpa.js';
26
+ import { constantTimeEqual } from '../utils.js';
27
+ /**
28
+ * Encapsulation key check β€” FIPS 203 Β§7.2 (EncapsulationKeyCheck).
29
+ *
30
+ * 1. Length check: ek.length == params.ekBytes
31
+ * 2. ByteDecode₁₂ β†’ ByteEncode₁₂ round-trip check on the polyvec portion.
32
+ * Any coefficient β‰₯ q stored modulo 2^12 survives frombytes, but tobytes
33
+ * re-encodes it differently β€” so the round-trip fails iff any coeff was β‰₯ q.
34
+ */
35
+ export function checkEncapsulationKey(kx, params, ek) {
36
+ if (ek.length !== params.ekBytes)
37
+ return false;
38
+ const { k } = params;
39
+ const kyberMem = new Uint8Array(kx.memory.buffer);
40
+ const pkOff = kx.getPkOffset();
41
+ const skOff = kx.getSkOffset();
42
+ const pvecOff = kx.getPolyvecSlot0();
43
+ // Write the polyvec portion of ek into PK buffer, decode, re-encode
44
+ kyberMem.set(ek.subarray(0, k * 384), pkOff);
45
+ kx.polyvec_frombytes(pvecOff, pkOff, k);
46
+ kx.polyvec_tobytes(skOff, pvecOff, k);
47
+ // orig is at pkOff (written above); reEnc is at skOff (polyvec_tobytes output)
48
+ const mismatch = kx.ct_verify(pkOff, skOff, k * 384);
49
+ return mismatch === 0;
50
+ }
51
+ /**
52
+ * Decapsulation key check β€” FIPS 203 Β§7.3 (DecapsulationKeyCheck).
53
+ *
54
+ * 1. Length check: dk.length == params.dkBytes
55
+ * 2. Extract embedded ek and H(ek), verify SHA3-256(ek) matches stored H
56
+ * 3. Also run checkEncapsulationKey on the embedded ek
57
+ */
58
+ export function checkDecapsulationKey(kx, sx, params, dk) {
59
+ if (dk.length !== params.dkBytes)
60
+ return false;
61
+ const { skCpaBytes, ekBytes } = params;
62
+ const ek = dk.slice(skCpaBytes, skCpaBytes + ekBytes);
63
+ const h = dk.slice(skCpaBytes + ekBytes, skCpaBytes + ekBytes + 32);
64
+ const hComputed = sha3_256Hash(sx, ek);
65
+ if (!constantTimeEqual(hComputed, h))
66
+ return false;
67
+ return checkEncapsulationKey(kx, params, ek);
68
+ }
Binary file
package/dist/loader.d.ts CHANGED
@@ -1,4 +1,19 @@
1
- import type { Module } from './init.js';
2
- export declare function loadEmbedded(thunk: () => Promise<string>): Promise<WebAssembly.Instance>;
3
- export declare function loadStreaming(_mod: Module, baseUrl: URL | string, filename: string): Promise<WebAssembly.Instance>;
4
- export declare function loadManual(binary: Uint8Array | ArrayBuffer): Promise<WebAssembly.Instance>;
1
+ import type { WasmSource } from './wasm-source.js';
2
+ /**
3
+ * Decode a gzip+base64 embedded WASM string to raw bytes.
4
+ * Guards against missing DecompressionStream (Node <18, non-browser runtimes).
5
+ * Exported for pool worker launchers that decode blobs before spawning threads.
6
+ */
7
+ export declare function decodeWasm(b64: string): Promise<Uint8Array>;
8
+ /**
9
+ * Compile a WASM source to a Module without instantiating.
10
+ * Used by pool infrastructure to send compiled modules to workers.
11
+ */
12
+ export declare function compileWasm(source: WasmSource): Promise<WebAssembly.Module>;
13
+ /**
14
+ * Load a WASM module from any accepted source type.
15
+ * The loading strategy is inferred from the argument type β€” no mode string.
16
+ *
17
+ * Throws `TypeError` for null, numeric, or unrecognised inputs.
18
+ */
19
+ export declare function loadWasm(source: WasmSource): Promise<WebAssembly.Instance>;