ReadUint{16,32,64}Slice recurses on c[buffered:] without making progress
when the underlying Reader returns a partial Peek (buffered == 0) but no
error. An attacker-supplied wire prefix combined with a long destination
slice exhausts the goroutine stack on the destination chain.
Discovered by github.com/luxfi/warp/pulsar's FuzzPulseDeserialize
harness during the Mar-3 2026 PQ Consensus Architecture Freeze
(regression seed: testdata/fuzz/FuzzPulseDeserialize/ccdb090e0ca0007b).
Fix:
- Replace recursion with an iterative loop (O(1) stack)
- Detect zero-progress reads and return ErrZeroProgress
- Add Read{Uint16,Uint32,Uint64}SliceBounded length-prefix-aware
wrappers gated by MaxSliceLen() (default 1 MiB, configurable via
LUX_LATTICE_MAX_UINT64_SLICE_LEN env var)
- Regression tests for all three slice readers + happy path + bounded
rejection
The WriterTo and ReaderFrom standard interface should be sufficient for the serialization
of lattigo objects from their pointers. Other interfaces such as BinaryMarshaller should
be based on WriterTo. This is possible in an efficient way if the Writer and Reader interface
expose their internal buffer.