pynltp 1.2.0__tar.gz

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.
pynltp-1.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Amandeep Bains
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,20 @@
1
+ include LICENSE
2
+ include README.md
3
+ include pyproject.toml
4
+ recursive-include pynltp *.py
5
+ recursive-include nltp *.py
6
+ recursive-include necklink *.py
7
+ prune arduino
8
+ prune assets
9
+ prune backup
10
+ prune csrc
11
+ prune deliverables
12
+ prune docs
13
+ prune esp32
14
+ prune examples
15
+ prune experiments
16
+ prune java
17
+ prune js
18
+ prune results
19
+ prune scripts
20
+ prune tests
pynltp-1.2.0/PKG-INFO ADDED
@@ -0,0 +1,392 @@
1
+ Metadata-Version: 2.4
2
+ Name: pynltp
3
+ Version: 1.2.0
4
+ Summary: NLTP v1.2: loss-resilient ChaCha20-Poly1305 encrypted UDP file & telemetry transport with GF(2^8) Cauchy FEC and 4G CGNAT traversal
5
+ Author: Amandeep Singh Bains
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/indian-aman/necklink
8
+ Project-URL: Repository, https://github.com/indian-aman/necklink
9
+ Project-URL: Releases, https://github.com/indian-aman/necklink/releases
10
+ Project-URL: Issues, https://github.com/indian-aman/necklink/issues
11
+ Project-URL: Documentation, https://github.com/indian-aman/necklink#readme
12
+ Keywords: nltp,pynltp,necklink,udp,fec,cauchy,galois-field,telemetry,marine,iot,esp32,stun,cgnat,nat-traversal,chacha20-poly1305
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Intended Audience :: Telecommunications Industry
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: C
19
+ Classifier: Programming Language :: Java
20
+ Classifier: Programming Language :: JavaScript
21
+ Classifier: Programming Language :: Python :: 3
22
+ Classifier: Programming Language :: Python :: 3.9
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Programming Language :: Python :: 3.11
25
+ Classifier: Programming Language :: Python :: 3.12
26
+ Classifier: Topic :: Internet
27
+ Classifier: Topic :: System :: Networking
28
+ Requires-Python: >=3.9
29
+ Description-Content-Type: text/markdown
30
+ License-File: LICENSE
31
+ Requires-Dist: numpy>=1.24
32
+ Requires-Dist: cryptography>=41.0
33
+ Provides-Extra: quic
34
+ Requires-Dist: aioquic>=1.0; extra == "quic"
35
+ Provides-Extra: torch
36
+ Requires-Dist: torch>=2.0; extra == "torch"
37
+ Provides-Extra: dev
38
+ Requires-Dist: pytest>=7.0; extra == "dev"
39
+ Requires-Dist: aioquic>=1.0; extra == "dev"
40
+ Dynamic: license-file
41
+
42
+ <div align="center">
43
+
44
+ # NLTP (`necklink` v1.2.0)
45
+
46
+ **Loss-resilient, two-way UDP file and telemetry transport for wireless, marine radio, `4G`/`5G` CGNAT, and satellite links — in Python, JavaScript / TypeScript, Java, zero-heap ANSI C99, and Arduino / `ESP32`.**
47
+
48
+ [![Release](https://img.shields.io/badge/release-v1.2.0-0EA5E9?style=flat-square)](https://github.com/indian-aman/necklink/releases/tag/v1.2.0)
49
+ [![Python](https://img.shields.io/badge/python-3.9%2B-3776AB?style=flat-square&logo=python&logoColor=white)](docs/INSTALL_AND_PYPI.md)
50
+ [![JavaScript / TS](https://img.shields.io/badge/JavaScript%20%2F%20TS-ESM%20%2B%20CJS%20%2B%20WebRTC-F7DF1E?style=flat-square&logo=javascript&logoColor=black)](js/)
51
+ [![Java](https://img.shields.io/badge/Java-11%2B%20%7C%20Android-ED8B00?style=flat-square&logo=openjdk&logoColor=white)](java/)
52
+ [![ANSI C99](https://img.shields.io/badge/C99-zero--heap%20%7C%20zero--float-00599C?style=flat-square&logo=c&logoColor=white)](csrc/)
53
+ [![Arduino / ESP32](https://img.shields.io/badge/Arduino%20%2F%20ESP32-library%20v1.2.0-00979D?style=flat-square&logo=arduino&logoColor=white)](https://github.com/indian-aman/necklink/releases/download/v1.2.0/NLTP-Arduino-1.2.0.zip)
54
+ [![4-Language Interop](https://img.shields.io/badge/Py%E2%86%94C%E2%86%94JS%E2%86%94Java%20interop-210%2F210%20passed-10B981?style=flat-square)](scripts/multilang_interop_test.py)
55
+ [![ESP32 Radio](https://img.shields.io/badge/ESP32%20encrypted%20radio-48%2F48%20verified-10B981?style=flat-square)](results/esp32_espnow_vs_nltp.json)
56
+ [![License: MIT](https://img.shields.io/badge/license-MIT-F59E0B?style=flat-square)](LICENSE)
57
+
58
+ [**30-Second Quick Start**](#-30-second-quick-start) ·
59
+ [**JavaScript / TypeScript**](#2-javascript--typescript-nodejs--browser--webrtc) ·
60
+ [**Java 11+ / Android**](#3-java-11--android-ionecklinknltp) ·
61
+ [**Arduino / ESP32**](#4-arduino-ide--platformio-esp32) ·
62
+ [**4G/5G CGNAT Relay**](#5-traverse-4g5g-carrier-cgnat-in-3-commands) ·
63
+ [**Benchmarks**](#-post-upgrade-benchmarks--hardware-verification) ·
64
+ [**NLTP vs. ESP-NOW**](#3-nltp-v12-vs-esp-now-on-esp32-hardware)
65
+
66
+ </div>
67
+
68
+ <p align="center">
69
+ <img src="https://raw.githubusercontent.com/indian-aman/necklink/main/assets/nltp_v12_benchmarks.png" alt="NLTP v1.2 Multi-Protocol & ESP32 Hardware Benchmarks" width="100%">
70
+ </p>
71
+
72
+ ---
73
+
74
+ ## Why NLTP?
75
+
76
+ Standard `TCP` and `QUIC` stall on bursty wireless fades, while raw microcontroller protocols like `ESP-NOW` cannot cross routers/SIM cards or reassemble multi-kilobyte files when chunks drop. **NLTP v1.2** bridges embedded hardware, mobile/web gateways, and cloud/shore software with a single encrypted, FEC-protected UDP wire format:
77
+
78
+ - **Survives `20%` Packet Loss & Bursty Fades**: Systematic `GF(2^8)` Cauchy forward error correction (8-shard generations + incremental Gauss-Jordan decoding) reconstructs lost packets without waiting for round-trip retransmission timeouts.
79
+ - **1-RTT Bottleneck Pacing**: Adaptive BBR-style delivery-rate and packet-train probing learns link capacity in a single round trip without overflowing router queues.
80
+ - **One Wire Format Across 5 Platforms (`ESP32` / C99 ↔ Python ↔ JavaScript/TS ↔ Java)**: Zero-malloc ANSI C99 (`~65 KB` RAM on `ESP32`) talks two-way (`tx` + `rx` on one UDP port) directly to Python, Node.js/Browser, and Java/Android endpoints, verified by `ChaCha20-Poly1305` (256-bit AEAD), `RFC 6479` replay protection, and end-to-end `SHA-256` receipts (`210/210` cross-language pairings verified).
81
+ - **Built-In NAT & Carrier CGNAT Traversal**: `RFC 5389` STUN discovery, low-TTL (`TTL=2`) direct UDP hole-punching, keepalives, and automatic 3-second fallback to a zero-knowledge 1-port UDP relay (`NLTPRelayHub`).
82
+
83
+ ```mermaid
84
+ flowchart LR
85
+ A["ESP32 / C99 Node (Zero-Heap, ~65 KB RAM)"] <-->|"Wi-Fi / Marine Radio / Satellite"| B["Direct UDP + Cauchy FEC + ChaCha20-Poly1305"]
86
+ B <--> C["Python · Node.js / TS · Java / Android Shore & Cloud"]
87
+ A <-->|"4G/5G SIM Behind CGNAT"| D["STUN P2P Punch or 1-Port NLTPRelayHub (Zero Keys)"]
88
+ D <--> C
89
+ ```
90
+
91
+ ---
92
+
93
+ ## ⚡ 30-Second Quick Start
94
+
95
+ ### 1. Python (`pynltp` — `import nltp` / `import pynltp` + `nltp` CLI)
96
+
97
+ Install on Windows, Linux, or macOS via `pip`:
98
+
99
+ ```bash
100
+ pip install pynltp
101
+ # Or directly from GitHub:
102
+ pip install git+https://github.com/indian-aman/necklink.git
103
+ ```
104
+
105
+ Send an out-of-line urgent command (`send_reflex`) and a `SHA-256`-verified encrypted file in 10 lines:
106
+
107
+ ```python
108
+ from nltp import NLTPServer, NLTPClient, generate_nltp_key
109
+
110
+ key = generate_nltp_key() # 256-bit ChaCha20-Poly1305 key
111
+
112
+ with NLTPServer(("0.0.0.0", 9000), save_dir="./inbox", psk=key) as srv:
113
+ with NLTPClient(("127.0.0.1", 9000), psk=key, max_tx_kbps=10_000) as cli:
114
+ cli.send_reflex("ESTOP_CHECK") # Bypasses file queue (0 HOL blocking)
115
+ receipt = cli.send_file("mission_log.bin") # Cauchy FEC + SHA-256 verified
116
+ assert receipt["verified_sha256"] is True
117
+ ```
118
+
119
+ Or run directly from the terminal:
120
+
121
+ ```bash
122
+ nltp gen-key
123
+ nltp stun
124
+ nltp serve --host 0.0.0.0 --port 9000 --psk "<KEY>" --save-dir ./inbox
125
+ nltp send-file --host <SERVER_IP> --port 9000 --psk "<KEY>" --file firmware.bin
126
+ ```
127
+
128
+ ---
129
+
130
+ ### 2. JavaScript & TypeScript (Node.js / Browser / WebRTC)
131
+
132
+ Zero external dependencies (`ESM` + `CommonJS` + `.d.ts` TypeScript types + `nltp/core` for WebRTC / WebTransport):
133
+
134
+ ```bash
135
+ npm install https://github.com/indian-aman/necklink/releases/download/v1.2.0/nltp-js-1.2.0.tgz
136
+ ```
137
+
138
+ ```javascript
139
+ import { NLTPServer, NLTPClient, generateNltpKey } from 'nltp';
140
+
141
+ const key = generateNltpKey();
142
+ const srv = await NLTPServer.listen({ host: '0.0.0.0', port: 9000, psk: key, saveDir: './inbox' });
143
+ const cli = await NLTPClient.connect({ host: '127.0.0.1', port: 9000, psk: key, maxTxKbps: 10_000 });
144
+
145
+ await cli.sendReflex('ESTOP_CHECK');
146
+ const receipt = await cli.sendFile('mission_log.bin');
147
+ console.log('Verified SHA-256:', receipt.verifiedSha256);
148
+
149
+ await cli.close();
150
+ await srv.close();
151
+ ```
152
+
153
+ ---
154
+
155
+ ### 3. Java 11+ & Android (`io.necklink:nltp`)
156
+
157
+ Zero external dependencies — includes portable constant-time `RFC 8439` `ChaCha20-Poly1305` and non-blocking NIO `DatagramChannel` (`--release 11`). Download **[`nltp-java-1.2.0.jar`](https://github.com/indian-aman/necklink/releases/download/v1.2.0/nltp-java-1.2.0.jar)** or build via Maven/Gradle (`java/`):
158
+
159
+ ```java
160
+ import io.necklink.nltp.*;
161
+ import java.nio.charset.StandardCharsets;
162
+ import java.nio.file.Paths;
163
+
164
+ String key = NLTPWire.generateNltpKey();
165
+ try (NLTPServer srv = NLTPServer.builder().bind("0.0.0.0", 9000).psk(key).saveDir(Paths.get("./inbox")).build();
166
+ NLTPClient cli = NLTPClient.builder().server("127.0.0.1", 9000).psk(key).maxTxKbps(10_000.0).build()) {
167
+ cli.sendReflex("ESTOP_CHECK".getBytes(StandardCharsets.UTF_8));
168
+ TransferReceipt receipt = cli.sendFile(Paths.get("mission_log.bin"), 60_000L);
169
+ assert receipt.verifiedSha256();
170
+ }
171
+ ```
172
+
173
+ ---
174
+
175
+ ### 4. Arduino IDE & PlatformIO (`ESP32`)
176
+
177
+ - **Arduino IDE (1-Click `.ZIP`)**: Download **[`NLTP-Arduino-1.2.0.zip`](https://github.com/indian-aman/necklink/releases/download/v1.2.0/NLTP-Arduino-1.2.0.zip)** → **Sketch → Include Library → Add .ZIP Library...** → open **File → Examples → NLTP** (`ESP32_Encrypted_Receiver`, `ESP32_Marine_Buoy_Sender`, or `ESP32_Relay_CGNAT_Node`).
178
+ - **PlatformIO (`platformio.ini`)**:
179
+ ```ini
180
+ lib_deps =
181
+ https://github.com/indian-aman/necklink/releases/download/v1.2.0/NLTP-Arduino-1.2.0.zip
182
+ ```
183
+
184
+ Minimal two-way encrypted `ESP32` sketch (`#include <NLTP.h>`):
185
+
186
+ ```cpp
187
+ #include <WiFi.h>
188
+ #include <NLTP.h>
189
+
190
+ NLTPWiFiNode nltp;
191
+ uint8_t telemetryBatch[2048];
192
+
193
+ void setup() {
194
+ WiFi.begin("YOUR_WIFI", "YOUR_PASS");
195
+ while (WiFi.status() != WL_CONNECTED) delay(250);
196
+
197
+ nltp.begin(9700, "shared-256bit-key-or-passphrase");
198
+ nltp.setPeer(IPAddress(192, 168, 1, 100), 9700); // Python laptop / shore server
199
+ }
200
+
201
+ void loop() {
202
+ nltp.poll(); // Drives both TX pacing & RX FEC decoding
203
+
204
+ if (nltp.hasReceivedFile() && nltp.isReceivedShaOk()) {
205
+ // Handle command/config received from Python server (nltp.receivedData(), nltp.receivedLength())
206
+ nltp.clearReceived();
207
+ nltp.sendBytes(telemetryBatch, sizeof(telemetryBatch), "buoy_batch.bin");
208
+ }
209
+ }
210
+ ```
211
+
212
+ ---
213
+
214
+ ### 5. Traverse `4G`/`5G` Carrier CGNAT in 3 Commands
215
+
216
+ When both sender and receiver sit behind carrier NAT/firewalls with no public IP or port forwarding, run `nltp relay` on any tiny 1-port VPS (holds **zero keys**, sees only `ChaCha20-Poly1305` ciphertext):
217
+
218
+ ```bash
219
+ # 1. Public 1-port relay VM:
220
+ nltp relay --host 0.0.0.0 --port 9000
221
+
222
+ # 2. Shore receiver behind Office NAT:
223
+ nltp serve --relay <RELAY_IP>:9000 --room buoy-01 --psk "<KEY>" --save-dir ./inbox
224
+
225
+ # 3. Field / buoy sender behind 4G SIM CGNAT (Python or ESP32 beginRelay()):
226
+ nltp send-file --relay <RELAY_IP>:9000 --room buoy-01 --psk "<KEY>" --file sensor_batch.bin
227
+ ```
228
+
229
+ ---
230
+
231
+ ### 6. Portable Zero-Heap ANSI C99 Core (`csrc/`)
232
+
233
+ Compiles cleanly under `-std=c99 -Wall -Wextra -pedantic -Werror` with **zero `malloc`** and **zero floating-point operations**:
234
+
235
+ ```bash
236
+ make -C csrc all test
237
+ python scripts/c_interop_test.py
238
+ ```
239
+
240
+ Direct STUN hole-punching with automatic 3-second relay fallback from the C CLI:
241
+
242
+ ```bash
243
+ ./csrc/build/nltp_cli recv 0.0.0.0 0 ./out.bin \
244
+ --psk "<KEY>" --stun stun.cloudflare.com:3478 --punch --relay <RELAY_IP>:9000 --room buoy-01
245
+
246
+ ./csrc/build/nltp_cli send 0.0.0.0 0 ./firmware.bin \
247
+ --psk "<KEY>" --stun stun.cloudflare.com:3478 --punch --relay <RELAY_IP>:9000 --room buoy-01
248
+ ```
249
+
250
+ ---
251
+
252
+ ## 📊 Post-Upgrade Benchmarks & Hardware Verification
253
+
254
+ All results below reflect the final **v1.2.0** codebase measured on `Linux 6.18` network namespaces (`tc netem` + `tbf`, symmetric loss/rate limits in both directions, `iptables` wire-byte accounting including dropped packets) and real `ESP32-D0WDQ6` hardware.
255
+
256
+ ### 1. `1 MB` File / Firmware Transfer vs. 8 Competing Protocols
257
+
258
+ Median completion time across 3 runs (wire bytes ÷ file size in parentheses):
259
+
260
+ | Emulated Link (Symmetric) | **`NLTP v1.2`** | `TCP BBR` | `QUIC` (`ngtcp2`) | `KCP` (`w128`) | `kcptun` (`FEC`) | `UDT4` | `SRT` |
261
+ | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
262
+ | **Clean** (`20 Mbit`, `20 ms`, `0%`) | `0.58 s` (`1.23x`) | **`0.51 s` (`1.04x`)** | `0.57 s` (`1.05x`) | `0.60 s` (`1.54x`) | `0.74 s` (`2.25x`) | `0.95 s` (`1.15x`) | `0.87 s` (`1.15x`) |
263
+ | **Light Loss** (`20 Mbit`, `40 ms`, `2%`) | **`0.60 s` (`1.20x`)** | `0.65 s` (`1.07x`) | `0.67 s` (`1.07x`) | `0.85 s` (`1.25x`) | `0.81 s` (`1.62x`) | `3.02 s` (`1.07x`) | `1.37 s` (`1.05x`) |
264
+ | **Moderate Loss** (`10 Mbit`, `100 ms`, `5%`) | **`1.28 s` (`1.30x`)** | `1.49 s` (`1.12x`) | `1.57 s` (`1.07x`) | `1.74 s` (`1.45x`) | `1.52 s` (`1.75x`) | `9.98 s` (`1.19x`) | `6.49 s` (`1.24x`) |
265
+ | **Heavy Loss** (`5 Mbit`, `200 ms`, `10%`) | **`2.78 s` (`1.41x`)** | `3.45 s` (`1.15x`) | `4.42 s` (`1.16x`) | `4.08 s` (`1.61x`) | `3.15 s` (`1.72x`) | `26.47 s` (`1.37x`) | `14.73 s` *(1/3)* |
266
+ | **Severe Loss** (`2 Mbit`, `300 ms`, `20%`) | **`6.36 s` (`1.54x`)** | `8.31 s` (`1.32x`) | `11.87 s` (`1.26x`) | `8.98 s` (`2.11x`) | `9.38 s` (`2.25x`) | `FAIL (0/3)` | `FAIL (0/3)` |
267
+ | **Bursty Fades** (`10 Mbit`, `100 ms`, `10%` burst) | **`1.84 s` (`1.49x`)** | `13.10 s` *(2/3)* | `3.48 s` (`CUBIC`) | `2.16 s` (`1.63x`) | `2.07 s` (`1.71x`) | `9.55 s` (`1.34x`) | `4.11 s` *(2/3)* |
268
+
269
+ *(Note: `TCP CUBIC` degraded from `1.80 s` at `2%` loss to `42.50 s` at `10%` loss and `FAIL 0/3` at `20%` loss; `KCP w1024` overflowed router queues on `1 MB`, taking `6.22–70.48 s` and `3.1–6.2x` wire bytes.)*
270
+
271
+ ---
272
+
273
+ ### 2. Satellite, `10 MB` Bursty Fades, Jitter, Reordering & `64 KB` Transfers
274
+
275
+ | Scenario | Payload | **`NLTP v1.2`** | `TCP BBR` | `QUIC` (`ngtcp2`) | `KCP` (`fast`) | `kcptun` (`FEC`) |
276
+ | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
277
+ | **GEO Satellite** (`2 Mbit`, `600 ms`, `3%`) | `64 KB` | **`0.91 s` (enc) / `1.02 s`** | `2.77 s` | `2.67 s` | `1.12 s` (`3.25x`) | `1.57 s` (`3.10x`) |
278
+ | **GEO Satellite** (`2 Mbit`, `600 ms`, `3%`) | `1 MB` | **`6.05 s` (`1.23x`)** | `8.85 s` | `7.29 s` | `8.56 s` (`1.68x`) | `7.32 s` (`1.67x`) |
279
+ | **Large Bursty Fades** (`10 Mbit`, `100 ms`, `10%` burst) | `10 MB` | **`13.79 s` (`3/3` ok)** | `10.86 s` *(1/3 ok)* | `11.25 s` *(1/3 ok)* | — | `21.00 s` (`3/3` ok) |
280
+ | **Large Steady Loss** (`10 Mbit`, `100 ms`, `5%`) | `10 MB` | `11.28 s` (`1.28x`) | **`9.81 s` (`1.10x`)** | `9.85 s` (`1.11x`) | — | `14.41 s` (`1.78x`) |
281
+ | **Large Clean Link** (`20 Mbit`, `20 ms`, `0%`) | `10 MB` | `5.64 s` (`1.24x`) | **`4.45 s` (`1.04x`)** | `4.78 s` (`1.05x`) | — | `7.13 s` (`2.31x`) |
282
+ | **Packet Reordering** (`10 Mbit`, `60 ms`, `2%`, `10%` reorder) | `1 MB` | `1.19 s` (`1.20x`) | **`1.12 s` (`1.08x`)** | `1.22 s` (`1.05x`) | `1.42 s` (`1.32x`) | `1.62 s` (`1.91x`) |
283
+ | **Heavy Jitter** (`10 Mbit`, `100 ± 20 ms`, `5%`) | `1 MB` | `3.28 s` (`3/3` ok) | `2.60 s` | `1.52 s` | `2.36 s` | **`1.39 s`** |
284
+ | **Short Transfers (`0–20%` loss)** | `64 KB` | `0.08–1.42 s` (**`0.17 s` warm @ 5%**) | `0.09–3.27 s` | `0.17–2.73 s` | **`0.05–0.77 s`** | `0.06–1.37 s` |
285
+
286
+ ---
287
+
288
+ ### 3. `NLTP v1.2` vs. `ESP-NOW` on `ESP32` Hardware
289
+
290
+ Measured side-by-side on `ESP32-D0WDQ6` (`2.4 GHz` Ch 11, `-47 dBm`, `ESP-NOW v2.0`, 5 runs/cell; [`results/esp32_espnow_vs_nltp.json`](results/esp32_espnow_vs_nltp.json)). **NLTP v1.2** and **TCP** cross **2 Wi-Fi hops (`ESP32 ↔ Router ↔ PC`)** with end-to-end `SHA-256` receipt verification; **ESP-NOW** is **1-hop RF air-time** with IEEE 802.11 hardware `ACK` frames (`100%` ACKed, without receiver-side reassembly overhead):
291
+
292
+ #### A. Speeds by Payload Size (Clean `-47 dBm` RF)
293
+
294
+ | Protocol / Mode on `ESP32` | **`250 B`** | **`1.47 KB`** | **`4 KB`** | **`16 KB`** | **`60 KB`** |
295
+ | :--- | :--- | :--- | :--- | :--- | :--- |
296
+ | **ESP-NOW v1 Default** *(1 Mbps PHY)* | **`0.60 Mbps`** (`73 KB/s`, `3.4 ms`) | `0.53 Mbps` (`65 KB/s`, `22.2 ms`) | `0.53 Mbps` (`64 KB/s`, `62.3 ms`) | `0.47 Mbps` (`57 KB/s`, `279 ms`) | `0.55 Mbps` (`67 KB/s`, `901 ms`) |
297
+ | **ESP-NOW v2 Default** *(1 Mbps PHY)* | **`0.60 Mbps`** (`74 KB/s`, `3.3 ms`) | `0.45 Mbps` (`55 KB/s`, `26.3 ms`) | `0.50 Mbps` (`61 KB/s`, `65.4 ms`) | `0.44 Mbps` (`54 KB/s`, `299 ms`) | `0.38 Mbps` (`47 KB/s`, `1282 ms`) |
298
+ | **NLTP v1.2 Plain** *(`ESP32 → PC`)* | `0.20 Mbps` (`24 KB/s`, `10.3 ms`) | `0.66 Mbps` (`80 KB/s`, `17.9 ms`) | `0.92 Mbps` (`112 KB/s`, `35.7 ms`) | `1.44 Mbps` (`176 KB/s`, `91.0 ms`) | `2.53 Mbps` (`309 KB/s`, `194 ms`) |
299
+ | **NLTP v1.2 Encrypted** *(`ESP32 → PC`)* | `0.24 Mbps` (`29 KB/s`, `8.4 ms`) | **`0.78 Mbps`** (`95 KB/s`, `15.1 ms`) | **`1.86 Mbps`** (`226 KB/s`, `17.7 ms`) | **`2.67 Mbps`** (`326 KB/s`, `49.0 ms`) | `2.57 Mbps` (`314 KB/s`, `191 ms`) |
300
+ | **NLTP v1.2 Encrypted** *(`PC → ESP32`)* | `0.14 Mbps` (`17 KB/s`, `14.8 ms`) | **`0.80 Mbps`** (`98 KB/s`, `14.7 ms`) | `1.78 Mbps` (`217 KB/s`, `18.5 ms`) | `2.16 Mbps` (`263 KB/s`, `60.8 ms`) | **`3.04 Mbps`** (`371 KB/s`, `162 ms`) |
301
+ | **TCP** *(`PC → ESP32` lwIP)* | `0.07 Mbps` (`9 KB/s`, `27.9 ms`) | `0.38 Mbps` (`47 KB/s`, `30.6 ms`) | `0.71 Mbps` (`86 KB/s`, `46.4 ms`) | `1.60 Mbps` (`195 KB/s`, `82.1 ms`) | `2.33 Mbps` (`284 KB/s`, `211 ms`) |
302
+ | **ESP-NOW v1 Tuned `MCS7`** *(1-hop)* | **`3.25 Mbps`** (`394 KB/s`, `0.6 ms`) | `5.22 Mbps` (`637 KB/s`, `2.3 ms`) | `5.40 Mbps` (`659 KB/s`, `6.1 ms`) | `5.41 Mbps` (`660 KB/s`, `24.3 ms`) | `5.79 Mbps` (`707 KB/s`, `84.9 ms`) |
303
+ | **ESP-NOW v2 Tuned `MCS7`** *(1-hop)* | `2.01 Mbps` (`246 KB/s`, `1.0 ms`) | **`11.24 Mbps`** (`1.37 MB/s`, `1.1 ms`) | **`19.26 Mbps`** (`2.35 MB/s`, `1.7 ms`) | **`23.52 Mbps`** (`2.87 MB/s`, `5.6 ms`) | **`25.82 Mbps`** (`3.15 MB/s`, `19.0 ms`) |
304
+
305
+ #### B. Speeds by Link Condition (`58–60 KB` Verified File Transfer on `ESP32`, `48/48` Encrypted)
306
+
307
+ | Link Condition | **`NLTP v1.2` (Encrypted)** | **ESP-NOW Default** *(1 Mbps)* | **ESP-NOW Tuned `MCS7`** *(72 Mbps)* | **`TCP`** *(lwIP)* |
308
+ | :--- | :--- | :--- | :--- | :--- |
309
+ | **Clean Desk Wi-Fi** (`0%` loss) | `2.57–3.04 Mbps` (`0.16–0.19 s`) | `0.38–0.55 Mbps` (`0.90–1.28 s`) | **`5.79–25.82 Mbps` (`0.02–0.08 s`)** | `2.33 Mbps` (`0.21 s`) |
310
+ | **Far Wi-Fi** (`5 Mbit`, `5%` loss) | **`1.90–1.98 Mbps` (`0.24–0.25 s`, `12/12` ok)** | `FAIL` *(missing chunks, no FEC)* | `FAIL` *(weak `-72 dBm` range + no FEC)* | Degrades sharply |
311
+ | **Weak 4G** (`2 Mbit`, `9–13%` loss) | **`0.56–0.75 Mbps` (`0.63–0.85 s`, `12/12` ok)** | *Cannot cross 4G / routers* | *Cannot cross 4G / routers* | Stalls on fades |
312
+ | **Marine Radio** (`1 Mbit`, `6–18%` loss) | **`0.31–0.53 Mbps` (`0.89–1.53 s`, `12/12` ok)** | *Cannot cross IP radio* | *Cannot cross IP radio* | Stalls on fades |
313
+ | **Severe Loss** (`1 Mbit`, `20.8%` loss) | **`0.17–0.28 Mbps` (`1.68–2.80 s`, `12/12` ok)** | `FAIL` *(0% intact file delivery)* | `FAIL` *(0% intact file delivery)* | Times out |
314
+
315
+ #### C. `ESP-NOW` vs. `NLTP v1.2` Capability Matrix
316
+
317
+ | Feature | **ESP-NOW** (Espressif) | **NLTP v1.2** (`necklink`) |
318
+ | :--- | :--- | :--- |
319
+ | **Network Layer & Direction** | Layer 2 raw 802.11 action frames; **two-way** | Layer 4/7 over **UDP/IP** (or byte callback); **two-way** (`tx`+`rx` on one port) |
320
+ | **Internet / 4G / Satellite** | **No** — local 2.4 GHz hop only (~100–400 m; cannot cross routers or SIMs) | **Yes** — works over Wi-Fi routers, `4G`/`5G` CGNAT, satellite, and marine IP radios |
321
+ | **Direct Laptop / Cloud Link** | **No** — ESP-to-ESP only (needs an extra USB bridge ESP32 on PC) | **Yes** — `ESP32` talks directly to any Python laptop or Linux cloud server |
322
+ | **Payload Size & Loss Recovery** | `250 B` (v1) / `1,470 B` (v2) per packet; **no file chunking or FEC** | **Multi-MB files & batches**; `GF(2^8)` Cauchy FEC + `SHA-256` survives **`20%` loss** |
323
+ | **Encryption & Peer Limit** | `AES-128 CCMP`, capped at **6–17 encrypted peers** (`20` total MAC peers) | **`ChaCha20-Poly1305` (256-bit)** + `RFC 6479` replay window; **no peer-table cap** |
324
+ | **Deep-Sleep Coin-Cell Use** | **Wins (`~1–3 ms` wake-and-tx, no Wi-Fi router handshake)** | Higher power — requires an active Wi-Fi / cellular IP session (`~65 KB` RAM) |
325
+
326
+ ---
327
+
328
+ ### 4. Cross-Language (`Python ↔ C99 ↔ JavaScript ↔ Java`) & Dual-NAT / CGNAT Verification
329
+
330
+ - **`210/210` 4-Language Wire & Encryption Interoperability ([`scripts/multilang_interop_test.py`](scripts/multilang_interop_test.py) / [`results/multilang_interop_test.json`](results/multilang_interop_test.json))**:
331
+ - **`192/192` Full 4×4 Directional Matrix**: Every `sender → receiver` pair across **Python**, **ANSI C99**, **JavaScript (Node.js ESM/CJS)**, and **Java (JDK 11+ NIO)** across plaintext, 256-bit Base64 keys, and passphrases at `0%` and `15%` packet loss (`1 KB` short `k=1` generation and `64 KB` multi-generation FEC).
332
+ - **`8/8` `256 KB` Lossy Cross-Language Stress**: Heterogeneous encrypted multi-window streams (`py↔js`, `js↔java`, `java↔c`, `c↔py`) at `15%` packet loss.
333
+ - **`6/6` Cross-Language Zero-Knowledge `NLTPRelayHub`**: Python, JavaScript, and Java relay hubs forwarding encrypted `64 KB` streams across heterogeneous language pairs at `10%` loss.
334
+ - **`4/4` Cross-Language Urgent `send_reflex`**: Out-of-line encrypted `ESTOP` delivery across `Python ↔ JS` and `Python ↔ Java`.
335
+ - **`9/9` C99 + `9/9` JS + `7/7` Java Security & FEC Self-Tests**: Verified cross-SDK key derivation parity, bit-flipped packet rejection + `GF(2^8)` erasure recovery, `RFC 6479` replay rejection, wrong-key rejection, and plaintext-downgrade rejection.
336
+ - **`18/18` Dual-NAT & Symmetric-CGNAT Suite ([`scripts/virtual_nat_test.py`](scripts/virtual_nat_test.py))**: `1 MB` encrypted transfers across two separate Linux NAT routers (`40 ms` RTT + `5%` loss on each last mile):
337
+ - Direct STUN + low-TTL UDP hole-punching (`C↔C` and `C↔Python`): **`9/9` direct P2P** (`1.22–2.26 s`).
338
+ - Zero-knowledge `NLTPRelayHub`: **`3/3`** (`1.31–2.19 s`).
339
+ - Symmetric CGNAT (`MASQUERADE --random-fully`): automatic 3-second fallback to `NLTPRelayHub` completed in **`1.80 s`**.
340
+ - `4 s` UDP NAT expiry across an `8 s` idle gap: **`1 s` keepalives** preserved the mapping (`1.59 s` second file).
341
+
342
+ ---
343
+
344
+ ## 🎯 When to Use NLTP — and When Not To
345
+
346
+ > [!TIP]
347
+ > **Reach for NLTP v1.2 when:**
348
+ > - Moving **files, sensor batches, logs, images, configs, or OTA firmware (`2 KB – 10 MB`)** across lossy (`2–20%`), bursty-fade, marine radio, `4G`/`5G` cellular-edge, or satellite links.
349
+ > - Connecting **`ESP32` / C99 embedded hardware directly to Python laptops or cloud servers**, including behind carrier CGNAT (`NLTPRelayHub` / STUN), or sending zero-head-of-line urgent commands (`send_reflex("ESTOP")`).
350
+
351
+ > [!NOTE]
352
+ > **Stick with standard tools when:**
353
+ > - **Clean wired/Wi-Fi links or large (`>= 10 MB`) steady-loss transfers**: Kernel `TCP BBR` and C `QUIC` (`ngtcp2`) are `12–27%` faster and use fewer wire bytes (`1.04–1.32x` vs NLTP's `1.20–1.64x` parity overhead).
354
+ > - **Coin-cell / deep-sleep `<= 250 B` sensor pings with no router**: Local `ESP-NOW` wakes and fires in `1–3 ms` without Wi-Fi association (pair `ESP-NOW` leaf sensors with an `NLTP` gateway for the best of both).
355
+ > - **Tiny (`<= 64 KB`) isolated messages on private IP links**: `KCP` fast mode is slightly faster on most cells (`0.05–0.77 s`), though at `2.15–2.61x` wire-byte cost under heavy loss.
356
+
357
+ ---
358
+
359
+ ## 🗂️ Repository Layout
360
+
361
+ | Path | Contents |
362
+ | :--- | :--- |
363
+ | [`necklink/`](necklink/) & [`nltp/`](nltp/) | Python package & `import nltp` alias (`NLTPServer`, `NLTPClient`, `NLTPRelayHub`, STUN/hole-punch, `ChaCha20-Poly1305` AEAD, `nltp` CLI) |
364
+ | [`js/`](js/) | Zero-dependency JavaScript / TypeScript SDK (`ESM` + `CommonJS` + `.d.ts` + Browser/WebRTC `NLTPEndpoint` + Node UDP `NLTPServer`/`NLTPClient`/`NLTPRelayHub` + `nltp-js` CLI) |
365
+ | [`java/`](java/) | Zero-dependency Pure Java 11+ / Android SDK (`io.necklink:nltp`, Maven `pom.xml` + Gradle, portable `ChaCha20-Poly1305`, NIO UDP + `NLTPCli` executable JAR) |
366
+ | [`arduino/NLTP/`](arduino/NLTP/) | Drop-in Arduino IDE (`.zip`) & PlatformIO library (`#include <NLTP.h>`) with 3 ready-to-flash `ESP32` `.ino` sketches |
367
+ | [`examples/`](examples/) | Runnable Python (`examples/python/`), JavaScript (`examples/javascript/`), and Java (`examples/java/`) examples |
368
+ | [`csrc/`](csrc/) | Portable zero-heap, zero-float ANSI C99 core (`nltp_core.{h,c}`, `nltp_net.{h,c}`, `nltp_sha256.{h,c}`, `nltp_wire.h`), POSIX CLI, and `9/9` security self-test |
369
+ | [`esp32/`](esp32/) | PlatformIO `ESP32` hardware firmware (`Arduino-ESP32`), verified bidirectional over encrypted Wi-Fi and emulated radio profiles |
370
+ | [`scripts/`](scripts/) | Live field-trial kit ([`field_test.py`](scripts/field_test.py)), `210/210` 4-language interop ([`multilang_interop_test.py`](scripts/multilang_interop_test.py)), `72/72` C↔Python interop, `18/18` dual-NAT suite, and `netem` harnesses |
371
+ | [`tests/`](tests/) | `pytest` unit and integration suite (`20` tests) |
372
+ | [`docs/`](docs/) | Installation & PyPI publishing guide ([`INSTALL_AND_PYPI.md`](docs/INSTALL_AND_PYPI.md)) and GitHub Actions CI workflow ([`github-ci.yml`](docs/github-ci.yml)) |
373
+
374
+ ---
375
+
376
+ ## 🚤 Run Your Own Live Radio / Marine Field Trial
377
+
378
+ Benchmark NLTP side-by-side against kernel `TCP` between any two reachable hosts over a real vessel, buoy, radio, or cellular link:
379
+
380
+ ```bash
381
+ # Shore / receiver host:
382
+ python scripts/field_test.py server --port 9700 --psk "<KEY>"
383
+
384
+ # Vessel / field host:
385
+ python scripts/field_test.py client --host <SHORE_IP> --port 9700 --psk "<KEY>" --sizes 64k,256k,1m --runs 5
386
+ ```
387
+
388
+ ---
389
+
390
+ ## License
391
+
392
+ Released under the [MIT License](LICENSE).