Intuitively, one might expect that if we write a block of zeros (all bytes set to 0x00) and read it back, the result should be exactly the XOR mask. However, this is true only in one special case.

Scrambler Model

The scrambler can be modeled as having two components:


XOR model

where:

  • input — the data being written; for a zero block, all bytes are 0x00
  • A — a fixed XOR mask that remains constant for the page (the underlying “clean” key)
  • LFSR(seed) — a pseudorandom bit sequence generated by a linear-feedback shift register (LFSR) initialized with a specific seed

When a zero block is written (input = 0x00), the value observed on readback is therefore not necessarily the pure mask A. The LFSR-generated sequence is mixed into the result as well:

The Special Case

If the seed is 0x0000, and the LFSR is a standard linear implementation with no constant feedback term, then an all-zero state remains all zero:

LFSR(0x0000) → 0x00, 0x00, 0x00, ...

In this special case, the zero block does reveal the pure XOR mask:

output = A XOR 0x00 = A  ✓

This is precisely why the zero-block method can appear to work perfectly in some cases.

However, once a non-zero seed is used, the LFSR produces a non-zero sequence, and the same method no longer recovers A directly. Instead, it produces a seed-dependent combination of A and the LFSR output.

For example:

A        = 0xA5
LFSR(7)  = 0x3C
output   = 0x00 XOR 0xA5 XOR 0x3C = 0x99

It may appear that A = 0x99, but in fact A = 0xA5.