package lafsession // replayWindow is a sliding bit-window anti-replay tracker for a single direction. type replayWindow struct { maxSeq uint64 size uint64 // bits bits []uint64 } func newReplayWindow(size uint64) *replayWindow { if size < 64 { size = 64 } words := (size + 63) / 64 return &replayWindow{ size: size, bits: make([]uint64, words), } } // accept returns true if seq is new and within window; marks it seen. func (w *replayWindow) accept(seq uint64) bool { if seq+w.size <= w.maxSeq { // too old return false } if seq > w.maxSeq { shift := seq - w.maxSeq if shift >= w.size { // clear entire window for i := range w.bits { w.bits[i] = 0 } } else { w.shift(shift) } w.maxSeq = seq } idx := w.maxSeq - seq word := idx / 64 bit := idx % 64 if word >= uint64(len(w.bits)) { return false } mask := uint64(1) << bit if w.bits[word]&mask != 0 { return false // already seen } w.bits[word] |= mask return true } func (w *replayWindow) shift(n uint64) { words := n / 64 bits := n % 64 if words > 0 { copy(w.bits[words:], w.bits) for i := uint64(0); i < words && i < uint64(len(w.bits)); i++ { w.bits[i] = 0 } // zero the tail that was shifted out conceptually for i := uint64(len(w.bits)); i > words; i-- { // already copied } if words < uint64(len(w.bits)) { for i := 0; i < int(words); i++ { w.bits[i] = 0 } } else { for i := range w.bits { w.bits[i] = 0 } return } } if bits == 0 { return } var carry uint64 for i := len(w.bits) - 1; i >= 0; i-- { newCarry := w.bits[i] >> (64 - bits) w.bits[i] = (w.bits[i] << bits) | carry carry = newCarry } }