quantum-resistant-rustykey 0.4.1 → 0.6.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.
- package/README.md +115 -125
- package/dist/index.mjs +2404 -0
- package/package.json +32 -38
- package/install/index.d.ts +0 -21
- package/install/index.js +0 -1877
- package/install/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,68 +1,69 @@
|
|
|
1
|
-
**Note**: 🚧 WORK IN PROGRESS...do not pnpm install 🚧
|
|
2
|
-
|
|
3
1
|
# Quantum-Resistant RustyKey®
|
|
4
2
|
|
|
5
|
-
A WebAssembly implementation of ML-KEM
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
3
|
+
A WebAssembly implementation of ML-KEM for both Node.js and web environments.
|
|
4
|
+
|
|
5
|
+
## Implementation status
|
|
6
|
+
|
|
7
|
+
- **ML-KEM-512**, **ML-KEM-768**, and **ML-KEM-1024** all use the same stack: [mlkem-native](https://github.com/pq-code-package/mlkem-native) (C) built with **Emscripten**, plus TypeScript adapted from Dmitry Chestnykh’s [mlkem-wasm](https://github.com/dchest/mlkem-wasm), vendored in this repo (no runtime npm dependency on `mlkem-wasm`).
|
|
8
|
+
- **PQClean** and **libsodium** are no longer part of this package’s build or runtime path.
|
|
9
|
+
|
|
10
|
+
## Security assurance and verification
|
|
11
|
+
|
|
12
|
+
This project relies on upstream `mlkem-native` for arithmetic/security properties.
|
|
13
|
+
The three parameter sets (512/768/1024) use the same implementation family and differ only by compile-time parameter selection.
|
|
14
|
+
|
|
15
|
+
### Upstream evidence
|
|
16
|
+
|
|
17
|
+
- `mlkem-native` security/formal-verification statements:
|
|
18
|
+
- [README.md](https://github.com/pq-code-package/mlkem-native/blob/main/README.md)
|
|
19
|
+
- [SOUNDNESS.md](https://github.com/pq-code-package/mlkem-native/blob/main/SOUNDNESS.md)
|
|
20
|
+
- [proofs/hol_light/README.md](https://github.com/pq-code-package/mlkem-native/blob/main/proofs/hol_light/README.md)
|
|
21
|
+
- [proofs/cbmc/README.md](https://github.com/pq-code-package/mlkem-native/blob/main/proofs/cbmc/README.md)
|
|
22
|
+
- Arithmetic implementation details in upstream source:
|
|
23
|
+
- Montgomery multiplication path in `mlk_fqmul()`:
|
|
24
|
+
- [mlkem/src/poly.c](https://github.com/pq-code-package/mlkem-native/blob/main/mlkem/src/poly.c)
|
|
25
|
+
- Barrett reduction path in `mlk_barrett_reduce()`:
|
|
26
|
+
- [mlkem/src/poly.c](https://github.com/pq-code-package/mlkem-native/blob/main/mlkem/src/poly.c)
|
|
27
|
+
- Generic Montgomery reduction helper:
|
|
28
|
+
- [mlkem/src/poly.h](https://github.com/pq-code-package/mlkem-native/blob/main/mlkem/src/poly.h)
|
|
29
|
+
|
|
30
|
+
### What this means for 512/768/1024
|
|
31
|
+
|
|
32
|
+
- Constant-time claims and proofs are provided upstream by `mlkem-native` (see links above).
|
|
33
|
+
- This package builds the same source for all three variants by changing only `MLK_CONFIG_PARAMETER_SET` in `wasm/Makefile`.
|
|
34
|
+
- Variant sizes/parameters are defined upstream in `mlkem/mlkem_native.h`.
|
|
35
|
+
|
|
36
|
+
### How users can independently verify
|
|
37
|
+
|
|
38
|
+
From the repository root:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# 1) Confirm the three variant builds only change parameter set.
|
|
42
|
+
rg "MLK_CONFIG_PARAMETER_SET=512|MLK_CONFIG_PARAMETER_SET=768|MLK_CONFIG_PARAMETER_SET=1024" wasm/Makefile
|
|
43
|
+
|
|
44
|
+
# 2) Confirm Montgomery and Barrett reduction functions exist in upstream source.
|
|
45
|
+
rg "mlk_fqmul|Montgomery multiplication|mlk_barrett_reduce|Barrett reduction" vendor/mlkem-native/mlkem/src/poly.c
|
|
46
|
+
rg "mlk_montgomery_reduce" vendor/mlkem-native/mlkem/src/poly.h
|
|
47
|
+
|
|
48
|
+
# 3) Confirm upstream constant-time/security documentation is present.
|
|
49
|
+
rg "constant-time|secret-dependent|HOL-Light|CBMC" vendor/mlkem-native/README.md vendor/mlkem-native/SOUNDNESS.md
|
|
50
|
+
|
|
51
|
+
# 4) (Optional) Rebuild the vendored wasm/modules from source.
|
|
52
|
+
pnpm build:vendor
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Notes:
|
|
56
|
+
- The upstream project documents scope/assumptions in `SOUNDNESS.md`; review this when making compliance assertions.
|
|
57
|
+
- This package uses ML-KEM-1024 (not "1028").
|
|
58
|
+
|
|
59
|
+
## Credits
|
|
60
|
+
|
|
61
|
+
- Core approach adapted from Dmitry Chestnykh's `mlkem-wasm`:
|
|
62
|
+
- https://github.com/dchest/mlkem-wasm
|
|
62
63
|
|
|
63
64
|
## Installation
|
|
64
65
|
|
|
65
|
-
|
|
66
|
+
Install via pnpm, npm or yarn:
|
|
66
67
|
|
|
67
68
|
```bash
|
|
68
69
|
pnpm install quantum-resistant-rustykey
|
|
@@ -74,7 +75,7 @@ yarn add quantum-resistant-rustykey
|
|
|
74
75
|
|
|
75
76
|
## Usage
|
|
76
77
|
|
|
77
|
-
### Node.js
|
|
78
|
+
### Node.js example
|
|
78
79
|
|
|
79
80
|
```typescript
|
|
80
81
|
import { loadMlKem1024, loadMlKem768, loadMlKem512 } from "quantum-resistant-rustykey";
|
|
@@ -93,13 +94,13 @@ async function main() {
|
|
|
93
94
|
|
|
94
95
|
// Encrypt a message
|
|
95
96
|
const message = "Hello, this is a secret message!";
|
|
96
|
-
|
|
97
|
+
const encrypt = mlkem.encrypt(keypair.get('public_key'))
|
|
97
98
|
const sharedSecret = encrypt.get('secret')
|
|
98
99
|
const encryptedMessage = await mlkem.encryptMessage(message, sharedSecret)
|
|
99
100
|
console.log("Encrypted message: ", encryptedMessage)
|
|
100
101
|
|
|
101
102
|
// Decrypt the message
|
|
102
|
-
|
|
103
|
+
const decryptedSharedSecret = mlkem.decrypt(encrypt.get('cyphertext'), keypair.get('private_key'))
|
|
103
104
|
const decryptedMessage = await mlkem.decryptMessage(encryptedMessage, decryptedSharedSecret)
|
|
104
105
|
console.log("Decrypted message: ", decryptedMessage)
|
|
105
106
|
} catch (error) {
|
|
@@ -110,39 +111,45 @@ async function main() {
|
|
|
110
111
|
main();
|
|
111
112
|
```
|
|
112
113
|
|
|
113
|
-
###
|
|
114
|
+
### Frontend example (Vite / browser)
|
|
114
115
|
|
|
115
|
-
|
|
116
|
+
```typescript
|
|
117
|
+
import { loadMlKem768 } from "quantum-resistant-rustykey";
|
|
116
118
|
|
|
117
|
-
|
|
118
|
-
- Never store private keys in localStorage or sessionStorage
|
|
119
|
-
- Use secure storage mechanisms like IndexedDB with encryption
|
|
120
|
-
- Consider using the Web Crypto API for additional security
|
|
119
|
+
const output = document.querySelector("#output");
|
|
121
120
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
- Consider using a key management service for production applications
|
|
121
|
+
async function run() {
|
|
122
|
+
const kem = await loadMlKem768();
|
|
123
|
+
const kp = kem.keypair();
|
|
126
124
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
- Implement proper error handling to prevent information leakage
|
|
125
|
+
const enc = kem.encrypt(kp.get("public_key"));
|
|
126
|
+
const sharedSecretA = await enc.get("secret");
|
|
127
|
+
const sharedSecretB = await kem.decrypt(enc.get("cyphertext"), kp.get("private_key"));
|
|
131
128
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
129
|
+
const encrypted = await kem.encryptMessage("hello from browser", sharedSecretA);
|
|
130
|
+
const decrypted = await kem.decryptMessage(encrypted, sharedSecretB);
|
|
131
|
+
|
|
132
|
+
output.textContent = decrypted;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
run().catch((err) => {
|
|
136
|
+
console.error(err);
|
|
137
|
+
output.textContent = "failed";
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Security note for web apps:
|
|
142
|
+
- never store private keys in `localStorage`/`sessionStorage`
|
|
143
|
+
- prefer HTTPS + short-lived keys
|
|
144
|
+
- use secure key storage strategy (e.g. IndexedDB + app-level protections)
|
|
136
145
|
|
|
137
146
|
## Building from Source
|
|
138
147
|
|
|
139
148
|
### Prerequisites
|
|
140
149
|
|
|
141
|
-
- Node.js >=
|
|
142
|
-
-
|
|
143
|
-
-
|
|
144
|
-
- Emscripten
|
|
145
|
-
- CMake
|
|
150
|
+
- Node.js >= 22 (LTS)
|
|
151
|
+
- pnpm (or npm)
|
|
152
|
+
- Emscripten **or** Docker — only needed if you run `pnpm build:vendor` to regenerate `src/vendor/mlkem*.js`
|
|
146
153
|
|
|
147
154
|
### Build Instructions
|
|
148
155
|
|
|
@@ -152,72 +159,55 @@ git clone https://github.com/antonymott/quantum-resistant-rustykey.git
|
|
|
152
159
|
cd quantum-resistant-rustykey
|
|
153
160
|
```
|
|
154
161
|
|
|
155
|
-
2.
|
|
162
|
+
2. Install dependencies:
|
|
156
163
|
```bash
|
|
157
|
-
|
|
164
|
+
pnpm i
|
|
158
165
|
```
|
|
159
166
|
|
|
160
|
-
3.
|
|
167
|
+
3. (Optional) Clone [mlkem-native](https://github.com/pq-code-package/mlkem-native) if you will regenerate vendored bundles:
|
|
161
168
|
```bash
|
|
162
|
-
|
|
169
|
+
git clone --depth 1 https://github.com/pq-code-package/mlkem-native.git vendor/mlkem-native
|
|
163
170
|
```
|
|
164
171
|
|
|
165
|
-
4.
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
The package supports two different environments:
|
|
172
|
+
4. (Optional) Rebuild `src/vendor/mlkem*.js` after changing `wasm/` or `mlkem-src/` (requires `emcc` or Docker):
|
|
173
|
+
```bash
|
|
174
|
+
pnpm build:vendor
|
|
175
|
+
```
|
|
170
176
|
|
|
171
|
-
|
|
172
|
-
- **Node.js Environment**: Set `sENVIRONMENT=node,worker` in CMakeLists.txt
|
|
177
|
+
5. Compile TypeScript to `dist/`:
|
|
173
178
|
|
|
174
179
|
```bash
|
|
175
|
-
pnpm
|
|
176
|
-
|
|
177
|
-
# Copy the WASM file to src directory
|
|
178
|
-
cp install/kyber_crystals_wasm_engine.wasm ./src/
|
|
180
|
+
pnpm build
|
|
179
181
|
```
|
|
180
182
|
|
|
181
|
-
The `sENVIRONMENT` option specifies which environments the WebAssembly module should be built for:
|
|
182
|
-
- `web`: Enables running in web browsers
|
|
183
|
-
- `worker`: Enables running in Web Workers
|
|
184
|
-
- `node`: Enables running in Node.js
|
|
185
183
|
|
|
186
|
-
|
|
187
|
-
|
|
184
|
+
## Testing
|
|
185
|
+
|
|
186
|
+
- Run `pnpm test` for ML-KEM-512 / 768 / 1024 round-trips.
|
|
187
|
+
|
|
188
|
+
## Browser example (local)
|
|
188
189
|
|
|
189
|
-
|
|
190
|
+
A Vite app under `examples/browser-demo` links this package from the workspace. From the repo root:
|
|
190
191
|
|
|
191
192
|
```bash
|
|
192
193
|
pnpm build
|
|
194
|
+
pnpm example:browser
|
|
193
195
|
```
|
|
194
196
|
|
|
195
|
-
|
|
196
|
-
## Testing
|
|
197
|
-
|
|
198
|
-
- Tested to work with Node.js v23.6.0
|
|
199
|
-
- For web testing, open `install/test.html` in a live server and check the console for encryption/decryption results of the three variants
|
|
197
|
+
See `examples/browser-demo/README.md` for details.
|
|
200
198
|
|
|
201
199
|
## Project Structure
|
|
202
200
|
|
|
203
|
-
|
|
204
|
-
stateDiagram-v2
|
|
205
|
-
[*] --> install
|
|
206
|
-
install --> [*]
|
|
207
|
-
install --> kyber_crystals_wasm_engine.js
|
|
208
|
-
kyber_crystals_wasm_engine.js --> kyber_crystals_wasm_engine.wasm
|
|
209
|
-
kyber_crystals_wasm_engine.wasm --> test.html
|
|
210
|
-
test.html --> [*]
|
|
211
|
-
```
|
|
201
|
+
ML-KEM logic comes from **mlkem-native** (C), compiled with **Emscripten** under `wasm/`, wrapped by TypeScript derived from [mlkem-wasm](https://github.com/dchest/mlkem-wasm) in `mlkem-src/`, then bundled into `src/vendor/mlkem*.js`.
|
|
212
202
|
|
|
213
203
|
## Publishing
|
|
214
204
|
|
|
215
|
-
The package is published from the `
|
|
205
|
+
The package is published from the npm package root (`dist/`). To publish a new version:
|
|
216
206
|
1. make a new branch locally from main
|
|
217
207
|
2. edit and test your changes
|
|
218
208
|
3. pnpm changeset
|
|
219
|
-
4.
|
|
220
|
-
5.
|
|
209
|
+
4. `pnpm lint && pnpm test && pnpm build`
|
|
210
|
+
5. merge to main; CI publishes when the version changed
|
|
221
211
|
|
|
222
212
|
## Security Considerations
|
|
223
213
|
|