peass-ng/PEASS-ng · error · InvalidOperationException
unsupported state size: only 512/1024 are allowed
Error message
unsupported state size: only 512/1024 are allowed
What it means
ShiftRows performs the AES-like row-shuffle on the internal state, which is sized 512 or 1024 bits (8 or 16 ulongs). The switch has cases only for those sizes; any other state size falls into the default and throws InvalidOperationException. In normal use the constructor guarantees a valid size, so this signals corrupted/internal misuse.
Source
Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/BouncyCastle/crypto/digests/DSTU7564Digest.cs:412
d = (c00 ^ c01) & 0xFF00FF00FF00FF00UL; c00 ^= d; c01 ^= d;
d = (c02 ^ c03) & 0xFF00FF00FF00FF00UL; c02 ^= d; c03 ^= d;
d = (c04 ^ c05) & 0xFF00FF00FF00FF00UL; c04 ^= d; c05 ^= d;
d = (c06 ^ c07) & 0xFF00FF00FF00FF00UL; c06 ^= d; c07 ^= d;
d = (c08 ^ c09) & 0xFF00FF00FF00FF00UL; c08 ^= d; c09 ^= d;
d = (c10 ^ c11) & 0xFF00FF00FF00FF00UL; c10 ^= d; c11 ^= d;
d = (c12 ^ c13) & 0xFF00FF00FF00FF00UL; c12 ^= d; c13 ^= d;
d = (c14 ^ c15) & 0xFF00FF00FF00FF00UL; c14 ^= d; c15 ^= d;
s[0] = c00; s[1] = c01; s[2] = c02; s[3] = c03;
s[4] = c04; s[5] = c05; s[6] = c06; s[7] = c07;
s[8] = c08; s[9] = c09; s[10] = c10; s[11] = c11;
s[12] = c12; s[13] = c13; s[14] = c14; s[15] = c15;
break;
}
default:
{
throw new InvalidOperationException("unsupported state size: only 512/1024 are allowed");
}
}
}
private void SubBytes(ulong[] s)
{
for (int i = 0; i < columns; ++i)
{
ulong u = s[i];
uint lo = (uint)u, hi = (uint)(u >> 32);
byte t0 = S0[lo & 0xFF];
byte t1 = S1[(lo >> 8) & 0xFF];
byte t2 = S2[(lo >> 16) & 0xFF];
byte t3 = S3[lo >> 24];
lo = (uint)t0 | ((uint)t1 << 8) | ((uint)t2 << 16) | ((uint)t3 << 24);
byte t4 = S0[hi & 0xFF];
byte t5 = S1[(hi >> 8) & 0xFF];
byte t6 = S2[(hi >> 16) & 0xFF];View on GitHub (pinned to 53fb989abc)
Solutions
- Only create Dstu7564Digest via its constructor with hashSizeBits of 256, 384, or 512; never hand-construct or deserialize digest instances.
- Use one digest instance per thread (IDigest instances are not thread-safe) and call Reset() between hashes.
- If seen in a modified build, restore the stock BouncyCastle source or verify the size passed to the constructor.
Example fix
// before var digest = Activator.CreateInstance(typeof(Dstu7564Digest)); // default/uninitialized state // after var digest = new Dstu7564Digest(512); // valid size, state arrays sized correctly
Defensive patterns
Strategy: try-catch
Validate before calling
// construct only through the constructor with a valid size
var digest = hashBits == 256 || hashBits == 384 || hashBits == 512
? new Dstu7564Digest(hashBits)
: new Dstu7564Digest(512); Type guard
static bool HasValidState(Dstu7564Digest d) => d != null; // size is fixed at construction; use only constructor-built instances
Try / catch
try { digest.BlockUpdate(data, 0, data.Length); }
catch (InvalidOperationException ex) { /* replace instance: var d = new Dstu7564Digest(512); */ } Prevention
- Never deserialize or reflect-construct digest instances
- One digest instance per thread
- Call Reset() between hashes on the same instance
When it happens
Trigger: ShiftRows invoked (via P or Q permutation rounds) on a state array that is neither 8 nor 16 ulongs long — practically only when a Dstu7564Digest instance was built with an invalid size bypassing the constructor check, via reflection/serialization of a hand-modified object, or a patched library.
Common situations: Deserializing a Dstu7564Digest instance from untrusted/partial data; custom subclasses or modified forks that change columns/rounds; state corruption from concurrent use of one digest instance across threads.
Related errors
- Hash size is not recommended. Use 256/384/512 instead
- invalid rate value
- attempt to absorb with odd length queue
- Keys > 32 are not supported
- Invalid digest length (required: 1 - 32)
AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02).
Data as JSON: /api/errors/b838156c37ea7cce.
Report an issue: GitHub.