feat: RS erasure-coded handshake chunking for PQ key exchange#30
Merged
disentangle-network merged 5 commits intomasterfrom Mar 8, 2026
Merged
feat: RS erasure-coded handshake chunking for PQ key exchange#30disentangle-network merged 5 commits intomasterfrom
disentangle-network merged 5 commits intomasterfrom
Conversation
Add RS erasure-coded chunk header types for oversized PQ handshakes. The 8-byte ChunkHeader carries handshake_id, noise message number, chunk index, total chunks, and data shard count for reconstruction.
Add Reed-Solomon encoding for oversized handshake messages (PQ handshakes ~9KB). Messages exceeding 1200 bytes are automatically split into k+m chunks where k=ceil(payload/1200) and m=3 parity. Any k of k+m chunks arriving suffices for reconstruction. Send paths modified: handleOutbound (initiator), ixHandshakeStage1 (responder direct + relay), and ErrAlreadySeen cached resend. Non-PQ handshakes below threshold bypass chunking entirely.
Add ReassemblyManager for reconstructing chunked handshake messages. Chunks are buffered by (handshakeID, noiseMsgNum) key and RS-decoded when k shards arrive. Buffers are bounded (256 max) and expired (5s timeout) for DoS mitigation. HandleIncoming dispatches chunked packets to reassembly and re-injects completed messages.
RS encode now prepends a 4-byte big-endian length prefix before splitting into shards, allowing the decoder to strip RS padding that was corrupting protobuf unmarshal. Updated all unit tests to account for the +4 byte prefix in data shard count calculations. Rewrote TestGoodHandshakePQ to use router-based assertTunnel approach since chunked handshakes produce multiple UDP packets. All unit tests, reassembly tests, PQ e2e test, and non-PQ e2e tests pass -- backward compatibility confirmed.
Use assert.LessOrEqual instead of assert.True for comparison, and assert.Empty instead of assert.Len(0) per golangci-lint testifylint rules.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
HandshakeIXPSK0Chunkedmessage subtype with 8-byte chunk header for reassembly metadataArchitecture
The chunking layer sits between Noise (untouched) and UDP:
Key files:
header/header.go:HandshakeIXPSK0Chunkedsubtype,ChunkHeaderstructrs_chunking.go:rsEncode,rsDecode,needsChunking, send helpersrs_reassembly.go:ReassemblyManager,HandleChunkhandshake_manager.go: Integration inHandleIncomingandhandleOutboundhandshake_ix.go: Chunked send inixHandshakeStage1(responder path)Test plan
TestGoodHandshakePQverifies full chunked handshake completes and bidirectional tunnel worksgo build,go vet, full test suiteCloses #28