peass-ng/PEASS-ng · error · InvalidOperationException
invalid rate value
Error message
invalid rate value
What it means
InitSponge computes the sponge rate as 1600 - 2*bitLength and requires it to be positive, below 1600, and 64-bit aligned. A rate violating this invariant leaves the Keccak permutation operating on inconsistent parameters, so InitSponge throws InvalidOperationException.
Source
Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/BouncyCastle/crypto/digests/KeccakDigest.cs:139
switch (bitLength)
{
case 128:
case 224:
case 256:
case 288:
case 384:
case 512:
InitSponge(1600 - (bitLength << 1));
break;
default:
throw new ArgumentException("must be one of 128, 224, 256, 288, 384, or 512.", "bitLength");
}
}
private void InitSponge(int rate)
{
if (rate <= 0 || rate >= 1600 || (rate & 63) != 0)
throw new InvalidOperationException("invalid rate value");
this.rate = rate;
Array.Clear(state, 0, state.Length);
Arrays.Fill(this.dataQueue, (byte)0);
this.bitsInQueue = 0;
this.squeezing = false;
this.fixedOutputLength = (1600 - rate) >> 1;
}
protected void Absorb(byte data)
{
if ((bitsInQueue & 7) != 0)
throw new InvalidOperationException("attempt to absorb with odd length queue");
if (squeezing)
throw new InvalidOperationException("attempt to absorb while squeezing");
dataQueue[bitsInQueue >> 3] = data;
if ((bitsInQueue += 8) == rate)View on GitHub (pinned to 53fb989abc)
Solutions
- Use only standard Keccak bit lengths (128/224/256/288/384/512) so the computed rate is always valid.
- If subclassing, ensure bitLength yields 1600 - 2*bitLength in (0, 1600) and 64-byte aligned.
- Fix any modified library code so Init's allow-list runs before InitSponge.
Example fix
// before
class CustomKeccak : KeccakDigest { public CustomKeccak() : base(800) { } } // rate = 0
// after
class CustomKeccak : KeccakDigest { public CustomKeccak() : base(256) { } } // rate = 1088 Defensive patterns
Strategy: validation
Validate before calling
int rate = 1600 - (bitLength << 1);
if (rate <= 0 || rate >= 1600 || (rate & 63) != 0)
throw new ArgumentOutOfRangeException(nameof(bitLength), "bitLength yields invalid sponge rate");
var keccak = new KeccakDigest(bitLength); Type guard
static bool HasValidRate(int bitLength) { int r = 1600 - (bitLength << 1); return r > 0 && r < 1600 && (r & 63) == 0; } Try / catch
try { k.BlockUpdate(data, 0, len); }
catch (InvalidOperationException ex) { /* recreate with standard bitLength */ } Prevention
- Stick to standard Keccak lengths so rate is always valid
- Verify rate math when subclassing KeccakDigest
- Reject non-standard bitLengths at configuration time
When it happens
Trigger: InitSponge(rate) called (from Init/constructor paths) with a bitLength that yields rate <= 0, rate >= 1600, or a rate not divisible by 64 — e.g. bitLength >= 800 or a bitLength producing a non-aligned rate. Only reachable if Init's case switch was bypassed or a subclass passes odd bitLengths.
Common situations: Subclassing KeccakDigest with a custom fixedBitLength not in the supported set; forks that relaxed the constructor check; bitLength of 0 or negative from config defaults.
Related errors
- attempt to absorb with odd length queue
- unsupported state size: only 512/1024 are allowed
- must be one of 128, 224, 256, 288, 384, or 512.
- 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/8b4af47937e09ce3.
Report an issue: GitHub.