A replay attack occurs when an attacker captures a valid encrypted packet and retransmits it. Even though the attacker cannot read or modify the payload (AEAD protects it), they can re-deliver it — causing the server to process the same request twice.
Why a counter isn't enough
The naive approach is to require strictly increasing sequence numbers. If the last accepted sequence number was 100, reject anything ≤ 100. This works for perfectly ordered traffic but breaks for legitimate out-of-order delivery over lossy networks.
KSP's solution: a 1024-bit sliding window bitmap. This allows accepting packets that arrive slightly out of order while still detecting replays.
The Algorithm
Maintain two pieces of state per direction:
highest_seq: the highest accepted sequence number- A 1024-bit bitmap representing sequence numbers
[highest_seq - 1023, highest_seq]
On each incoming frame:
- If
seq > highest_seq: Accept. Advance the window. Set the bit for seq. - If
seq ≤ highest_seq - 1024: Reject. Too old — outside the window. - If
seqis within the window: Check the bitmap. If the bit is already set: Reject (replay). If clear: Accept and set the bit.
Silent discard
When a replay is detected, the frame is discarded silently. No error response is sent. This is deliberate: sending an error message on every rejected replay would let an attacker probe the replay window to learn what sequence numbers have been seen. Silence is the correct behavior.