From 9791a1e70979ee4ba832851912f0de20301343a8 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Tue, 29 Sep 2026 13:57:58 +0100 Subject: Move a link to a new epoch now and then, so keys that leak later open nothing past MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A sender offers the public half of a pair made for the next epoch (OFFER) until the receiver accepts with a half of its own (ACCEPT); their X25519 and the epoch's secret make the next one's, and the private halves go. The header's low four bits say a packet's epoch; epoch 0 is the nodes' static secret, as the keys were. The first epoch is offered in the run's first packet (it begins with the first answer when the receiver is not busy), then one an hour or GiB. One who later has both nodes' keys opens only epoch 0, and no record went there after an epoch began: test-link tries every packet sent under the static keys, with epochs a second long, loss, reordering, restarts and replays. The receiver writes the epoch it accepted in its memo (a place is 256 bytes now), so it goes on without an X25519 when it starts again; one that forgot is not heard from, and its senders, after 2 s and four probes unanswered, offer again in epoch 0 with no records until an epoch begins. Keys of four epochs are tried (accepted, now, before, zero), as two may share the four bits. An accept costs an X25519 on each side, 220 µs on this Pi: one of a sender with records costs a token (256 a second, 8 at once) and the next packet offers again when there is none; one of a sender with nothing else to send waits for none, one a second for it. The X25519 is made after the turn's answers, never between a packet and its answer. serve's report and M2's generator count keys, X25519s and epochs. --- research/experiments/019-idle-links/links.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'research/experiments') diff --git a/research/experiments/019-idle-links/links.c b/research/experiments/019-idle-links/links.c index 0378109..d6cc28b 100644 --- a/research/experiments/019-idle-links/links.c +++ b/research/experiments/019-idle-links/links.c @@ -370,11 +370,11 @@ static int run_all(char **argv) { fprintf(stderr, "{\"t\":%.1f,\"made\":%" PRIu64 ",\"stored\":%" PRIu64 "}\n", (double)(now - began) / 1e9, made, stored); } } - uint64_t again = 0, keyed = 0, secrets = 0; + uint64_t again = 0, keyed = 0, secrets = 0, epochs = 0; for (size_t k = 0; k < count; ++k) { PureLinkCounts c; pure_link_sender_counts(devices[k].sender, &c); - again += c.resent, keyed += c.keyed, secrets += c.secrets; + again += c.resent, keyed += c.keyed, secrets += c.secrets, epochs += c.epochs; } /* The p50 and p99 of the records made in each second: where the slow ones are. */ size_t seconds_made = (size_t)seconds + 1; @@ -404,7 +404,8 @@ static int run_all(char **argv) { latency_count ? latency[latency_count * 99 / 100] : 0, latency_count ? latency[latency_count - 1] : 0, longest * 100, gap * 100); for (size_t b = 0; b <= last; ++b) printf("%s%u", b ? "," : "", timeline[b]); - printf("],\"keyed\":%" PRIu64 ",\"secrets\":%" PRIu64 ",\"p50_ms_by_second_made\":[", keyed, secrets); + printf("],\"keyed\":%" PRIu64 ",\"secrets\":%" PRIu64 ",\"epochs\":%" PRIu64 ",\"p50_ms_by_second_made\":[", keyed, + secrets, epochs); for (size_t second = 0; second < seconds_made; ++second) printf("%s%.2f", second ? "," : "", p50_by_second[second]); printf("],\"p99_ms_by_second_made\":["); for (size_t second = 0; second < seconds_made; ++second) printf("%s%.2f", second ? "," : "", p99_by_second[second]); -- cgit v1.2.3