From 6d276be51ba89b04a60bb16b5179c015ad202c7c Mon Sep 17 00:00:00 2001 From: eunhhu Date: Sun, 27 Sep 2026 19:17:02 +0100 Subject: Seal in one session a wire, authenticated by the sender's key (088) A sealed request cost three X25519 operations (about 0.5 ms), so sealed sends drained at half the plain rate. A wire now keeps one HPKE context, encapsulated at its first seal, and seals each request as the context's next number (a failed seal or a restart starts a new session); the header carries the session's encapsulated key and the number, so a receiver opens a session once per connection thread (16 remembered, the least used replaced) and each seal by its number, also after it restarts, unasked. A sender with a key of its own seals in HPKE auth mode and names that key in the header; a receiver started with --sender NAME=KEY takes deliveries only from the senders it names, each sealed with its key (403 sender otherwise). The body is now the ciphertext and its tag. Sealed sends, sender authenticated, drain at 461-464k a second against 462-470k plain and 207-234k sealed a request at a time (Raspberry Pi 5). The check adds: a wire's requests share one session numbered from 0; a changed number or sender key does not open; a receiver restarted naming its sender opens the same session again; another node claiming that sender's name with its own key is refused and applies nothing. --- .../2026-09-27-sessions-linux-aarch64.jsonl | 9 +++++++++ research/experiments/014-sealed-sends/drain.py | 14 ++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 research/experiments/014-sealed-sends/2026-09-27-sessions-linux-aarch64.jsonl (limited to 'research/experiments') diff --git a/research/experiments/014-sealed-sends/2026-09-27-sessions-linux-aarch64.jsonl b/research/experiments/014-sealed-sends/2026-09-27-sessions-linux-aarch64.jsonl new file mode 100644 index 0000000..55c4f0c --- /dev/null +++ b/research/experiments/014-sealed-sends/2026-09-27-sessions-linux-aarch64.jsonl @@ -0,0 +1,9 @@ +{"round": 0, "variant": "plain", "sends": 20000, "sends_per_second": 462162, "receiver_requests": 85, "delivery_attempts": 80} +{"round": 0, "variant": "sealed", "sends": 20000, "sends_per_second": 461190, "receiver_requests": 85, "delivery_attempts": 80} +{"round": 0, "variant": "baseline", "sends": 20000, "sends_per_second": 207310, "receiver_requests": 90, "delivery_attempts": 80} +{"round": 1, "variant": "sealed", "sends": 20000, "sends_per_second": 463529, "receiver_requests": 85, "delivery_attempts": 80} +{"round": 1, "variant": "baseline", "sends": 20000, "sends_per_second": 233662, "receiver_requests": 89, "delivery_attempts": 80} +{"round": 1, "variant": "plain", "sends": 20000, "sends_per_second": 468355, "receiver_requests": 85, "delivery_attempts": 80} +{"round": 2, "variant": "baseline", "sends": 20000, "sends_per_second": 233342, "receiver_requests": 89, "delivery_attempts": 80} +{"round": 2, "variant": "plain", "sends": 20000, "sends_per_second": 470174, "receiver_requests": 85, "delivery_attempts": 80} +{"round": 2, "variant": "sealed", "sends": 20000, "sends_per_second": 463747, "receiver_requests": 85, "delivery_attempts": 80} diff --git a/research/experiments/014-sealed-sends/drain.py b/research/experiments/014-sealed-sends/drain.py index 1a2819e..b40e820 100644 --- a/research/experiments/014-sealed-sends/drain.py +++ b/research/experiments/014-sealed-sends/drain.py @@ -4,10 +4,11 @@ A sender app (tests/check.py's LINK_SENDER) takes --sends orders from eight clients while its receiver is stopped (SIGSTOP), so the sends pile up in the sender's store; the receiver is then continued and timed until it has -applied them all. Runs plain and sealed (--seal to the receiver's --key) in -alternating order per round, and a --baseline pure-serve (plain only) when -given. Both servers on cores 0-2. Then the AEADs and X25519 on one core -(openssl speed). Prints one JSON line per run. +applied them all. Runs plain and sealed (--seal to the receiver's --key, +the sender sealing with its own --key) in rotated order per round, and a +--baseline pure-serve (plain, or sealed with --baseline-sealed) when given, +with its pure-crypto.so beside it. Both servers on cores 0-2. Then the +AEADs and X25519 on one core (openssl speed). Prints one JSON line per run. """ import argparse import json @@ -53,7 +54,7 @@ def run(work, binary, sends, sealed): key = ['--key', work / 'key' / 'receiver.key'] if sealed else [] receiver, started = start([binary, '--module', work / 'receiver.pmod', '--store', work / 'b', *key]) os.kill(receiver.pid, signal.SIGSTOP) - seal = ['--seal', f'ordered={started["public_key"]}'] if sealed else [] + seal = ['--seal', f'ordered={started["public_key"]}', '--key', work / 'key' / 'sender.key'] if sealed else [] sender, sender_started = start([binary, '--module', work / 'sender.pmod', '--store', work / 'a', '--send', f'ordered=http://127.0.0.1:{started["port"]}/inputs/order', *seal]) @@ -100,6 +101,7 @@ def main(): parser.add_argument('--aup', type=Path, default=ROOT.parent / 'aup' / 'build' / 'aup') parser.add_argument('--binary', type=Path, default=ROOT / 'build' / 'pure-serve') parser.add_argument('--baseline', type=Path, help='an earlier pure-serve, run plain') + parser.add_argument('--baseline-sealed', action='store_true', help='run the baseline sealed instead') parser.add_argument('--sends', type=int, default=20000) parser.add_argument('--rounds', type=int, default=3) args = parser.parse_args() @@ -111,7 +113,7 @@ def main(): for round_ in range(args.rounds): variants = [('plain', args.binary, False), ('sealed', args.binary, True)] if args.baseline: - variants.append(('baseline', args.baseline.resolve(), False)) + variants.append(('baseline', args.baseline.resolve(), args.baseline_sealed)) shift = round_ % len(variants) for name, binary, sealed in variants[shift:] + variants[:shift]: result = run(work, binary, args.sends, sealed) -- cgit v1.2.3