@@ -276,6 +276,10 @@ func (c *eea) reset(offset uint64) {
276276 c .used = n * uint64 (c .bucketSize )
277277}
278278
279+ // fastForward advances the ZUC cipher state to handle a given offset
280+ // without having to process each intermediate byte. This optimization
281+ // leverages precomputed states stored in buckets to move the cipher
282+ // state forward efficiently.
279283func (c * eea ) fastForward (offset uint64 ) {
280284 // fast forward, check and adjust state if needed
281285 var n uint64
@@ -291,21 +295,27 @@ func (c *eea) fastForward(offset uint64) {
291295 }
292296}
293297
294- // seek sets the offset for the next XORKeyStream operation.
295- //
296- // If the offset is less than the current offset, the state will be reset to the initial state.
297- // If the offset is equal to the current offset, the function behaves the same as XORKeyStream.
298- // If the offset is greater than the current offset, the function will forward the state to the offset.
299- // Note: This method is not thread-safe.
298+ // seek advances the internal state of the ZUC stream cipher to a given offset in the
299+ // key stream. It efficiently positions the cipher state to allow encryption or decryption
300+ // starting from the specified byte offset.
300301func (c * eea ) seek (offset uint64 ) {
302+ // 1. fast forward to the nearest precomputed state
301303 c .fastForward (offset )
304+
305+ // 2. check if need to reset and backward, regardless of bucketSize
302306 if offset < c .used {
303307 c .reset (offset )
304308 }
309+
310+ // 3. if offset equals to c.used, nothing to do
305311 if offset == c .used {
306312 return
307313 }
314+
315+ // 4. offset > used, need to forward
308316 gap := offset - c .used
317+
318+ // 5. gap <= c.xLen, consume remaining key bytes, adjust buffer and return
309319 if gap <= uint64 (c .xLen ) {
310320 // offset is within the remaining key bytes
311321 c .xLen -= int (gap )
@@ -316,14 +326,15 @@ func (c *eea) seek(offset uint64) {
316326 }
317327 return
318328 }
319- // consumed all remaining key bytes first
329+
330+ // 6. gap > c.xLen, consume remaining key bytes first
320331 if c .xLen > 0 {
321332 c .used += uint64 (c .xLen )
322333 gap -= uint64 (c .xLen )
323334 c .xLen = 0
324335 }
325336
326- // forward the state to the offset
337+ // 7. for the remaining gap, generate and discard key bytes in chunks
327338 nextBucketOffset := c .bucketSize * len (c .states )
328339 stepLen := uint64 (RoundBytes )
329340 var keyStream [RoundWords ]uint32
@@ -337,6 +348,8 @@ func (c *eea) seek(offset uint64) {
337348 }
338349 }
339350
351+ // 8. finally consume remaining gap < RoundBytes
352+ // and save remaining key bytes if any
340353 if gap > 0 {
341354 var keyBytes [RoundBytes ]byte
342355 genKeyStreamRev32 (keyBytes [:], & c .zucState32 )
0 commit comments