@lanitlabs/pqc-lnqc714 1.0.0 → 1.0.1
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 +119 -0
- package/package.json +5 -1
package/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# @lanitlabs/pqc-lnqc714
|
|
2
|
+
|
|
3
|
+
**Post-Quantum Key Encapsulation Mechanism (KEM)** — LPN-based key agreement with LDPC error correction.
|
|
4
|
+
Constant-time Rust/WASM engine targeting browsers, Node.js, and Edge runtimes.
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
npm install @lanitlabs/pqc-lnqc714
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
LNQC-714 is a KEM whose security reduces to the hardness of the fixed-weight **Learning Parity with Noise (LPN)** problem over GF(2). A **Low-Density Parity-Check (LDPC)** code with a Gallager bit-flipping decoder absorbs the sparse LPN noise, achieving 0% decryption failure at the security parameters:
|
|
13
|
+
|
|
14
|
+
| Parameter | Value |
|
|
15
|
+
|---|---|
|
|
16
|
+
| LPN dimension | `n = 512` |
|
|
17
|
+
| LPN samples | `m = 512` |
|
|
18
|
+
| Noise weight | `w = 4` |
|
|
19
|
+
| LDPC codeword | 2048 bits |
|
|
20
|
+
| LDPC data | 256 bits |
|
|
21
|
+
| Decoder | Gallager bit-flipping (50 iters) |
|
|
22
|
+
| Public key | 262 656 bytes |
|
|
23
|
+
| Ciphertext | 1 050 624 bytes |
|
|
24
|
+
|
|
25
|
+
All operations execute in **constant-time binary matrix algebra modulo 2** — no data-dependent branching, no rejection sampling, no modular arithmetic. This provides architectural immunity to cache-timing and power-analysis side-channel attacks.
|
|
26
|
+
|
|
27
|
+
## API
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import LNQC from '@lanitlabs/pqc-lnqc714';
|
|
31
|
+
|
|
32
|
+
// ── Key Generation ──────────────────────────────────────────
|
|
33
|
+
const keys = LNQC.keyGen();
|
|
34
|
+
// keys.publicKeyA: Uint8Array (512 × 512 bits, row-major)
|
|
35
|
+
// keys.publicKeyT: Uint8Array (512 bits)
|
|
36
|
+
// keys.privateKey: Uint8Array (512 bits)
|
|
37
|
+
|
|
38
|
+
// ── Encapsulation ───────────────────────────────────────────
|
|
39
|
+
const msg = LNQC.randomBits(256); // 256-bit shared secret
|
|
40
|
+
const ct = LNQC.encapsulate(
|
|
41
|
+
keys.publicKeyA,
|
|
42
|
+
keys.publicKeyT,
|
|
43
|
+
msg,
|
|
44
|
+
);
|
|
45
|
+
// ct.u: Uint8Array (2048 × 512 bits)
|
|
46
|
+
// ct.v: Uint8Array (2048 bits)
|
|
47
|
+
// ct.byteLength: number
|
|
48
|
+
|
|
49
|
+
// ── Decapsulation ───────────────────────────────────────────
|
|
50
|
+
const recovered = LNQC.decapsulate(
|
|
51
|
+
keys.privateKey,
|
|
52
|
+
ct.u,
|
|
53
|
+
ct.v,
|
|
54
|
+
);
|
|
55
|
+
// recovered equals `msg` (LDPC decoder corrects LPN noise)
|
|
56
|
+
|
|
57
|
+
// ── Constant-Time Verification ──────────────────────────────
|
|
58
|
+
const match = LNQC.constantTimeVerify(secretA, secretB);
|
|
59
|
+
// Returns true/false in constant time (subtle::ConstantTimeEq)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Parameter getters
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
LNQC.getNCols() // 512
|
|
66
|
+
LNQC.getMRows() // 512
|
|
67
|
+
LNQC.getNoiseWeight() // 4
|
|
68
|
+
LNQC.getLdpcDataBits() // 256
|
|
69
|
+
LNQC.getLdpcCodewordBits() // 2048
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Architecture
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
┌──────────────────────────────────────────────────────────┐
|
|
76
|
+
│ JS/TS (consumer) │
|
|
77
|
+
│ import LNQC from '@lanitlabs/pqc-lnqc714' │
|
|
78
|
+
└─────────────────────┬────────────────────────────────────┘
|
|
79
|
+
│
|
|
80
|
+
┌─────────────────────▼────────────────────────────────────┐
|
|
81
|
+
│ dist/index.js (dynamic loader) │
|
|
82
|
+
│ Node.js → pkg/node/pqc_lnqc714.js │
|
|
83
|
+
│ Browser → pkg/browser/pqc_lnqc714.js │
|
|
84
|
+
└─────────────────────┬────────────────────────────────────┘
|
|
85
|
+
│ wasm-bindgen
|
|
86
|
+
┌─────────────────────▼────────────────────────────────────┐
|
|
87
|
+
│ Rust/WASM (src/crypto.rs) │
|
|
88
|
+
│ • Secure RNG via getrandom (os.urandom) │
|
|
89
|
+
│ • Regular LDPC construction (col_weight=15) │
|
|
90
|
+
│ • Gallager bit-flipping decoder │
|
|
91
|
+
│ • Sparse R_indices optimization │
|
|
92
|
+
│ • subtle::ConstantTimeEq for verification │
|
|
93
|
+
└──────────────────────────────────────────────────────────┘
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Security
|
|
97
|
+
|
|
98
|
+
- **LPN hardness**: No known sub-exponential quantum algorithm.
|
|
99
|
+
- **CSPRNG**: All keys, noise vectors, and ephemeral randomness use `getrandom` (OS entropy / `crypto.getRandomValues`). **No** insecure PRNG (PCG, xorshift) is used for security-critical data.
|
|
100
|
+
- **Constant-time**: The `subtle` crate guards token comparison against timing side-channels.
|
|
101
|
+
- **LDPC protection**: Regular column-weight-15 parity-check matrix eliminates single-check failure modes.
|
|
102
|
+
|
|
103
|
+
## Development
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Build WASM targets
|
|
107
|
+
wasm-pack build --target bundler --out-dir pkg/browser --release
|
|
108
|
+
wasm-pack build --target nodejs --out-dir pkg/node --release
|
|
109
|
+
|
|
110
|
+
# Test (native)
|
|
111
|
+
cargo test --release
|
|
112
|
+
|
|
113
|
+
# Publish
|
|
114
|
+
npm publish --access public
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## License
|
|
118
|
+
|
|
119
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lanitlabs/pqc-lnqc714",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/lanitlabs/pqc-lnqc714"
|
|
7
|
+
},
|
|
4
8
|
"description": "Post-Quantum KEM — LPN-based key encapsulation with LDPC error correction. Constant-time Rust/WASM engine.",
|
|
5
9
|
"license": "MIT",
|
|
6
10
|
"main": "./dist/index.js",
|