peass-ng/PEASS-ng · error · ArgumentException
must be in the range 1 to 7
Error message
must be in the range 1 to 7
What it means
KeccakDigest.AbsorbBits(int, int) throws ArgumentException when the `bits` parameter is outside 1..7. AbsorbBits exists to absorb a sub-byte (partial byte) quantity; absorbing 0 or 8+ bits makes no sense — 8 bits go through the byte Absorb path. Called from the partial-byte DoFinal path.
Source
Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/BouncyCastle/crypto/digests/KeccakDigest.cs:204
count += available;
KeccakAbsorb(dataQueue, 0);
}
int remaining;
while ((remaining = (len - count)) >= rateBytes)
{
KeccakAbsorb(data, off + count);
count += rateBytes;
}
Array.Copy(data, off + count, dataQueue, 0, remaining);
this.bitsInQueue = remaining << 3;
}
protected void AbsorbBits(int data, int bits)
{
if (bits < 1 || bits > 7)
throw new ArgumentException("must be in the range 1 to 7", "bits");
if ((bitsInQueue & 7) != 0)
throw new InvalidOperationException("attempt to absorb with odd length queue");
if (squeezing)
throw new InvalidOperationException("attempt to absorb while squeezing");
int mask = (1 << bits) - 1;
dataQueue[bitsInQueue >> 3] = (byte)(data & mask);
// NOTE: After this, bitsInQueue is no longer a multiple of 8, so no more absorbs will work
bitsInQueue += bits;
}
private void PadAndSwitchToSqueezingPhase()
{
Debug.Assert(bitsInQueue < rate);
dataQueue[bitsInQueue >> 3] |= (byte)(1 << (bitsInQueue & 7));
View on GitHub (pinned to 53fb989abc)
Solutions
- Clamp/validate partialBits to 1..7 before calling; when no partial bits remain, use the plain DoFinal overload.
- Use plain DoFinal(output, outOff) when input is byte-aligned.
- Guard bit-count math so trailing bits are computed as (totalBits % 8) and skipped when 0.
Example fix
// before
int partialBits = totalBits % 8; // can be 0
digest.DoFinal(outBytes, 0, partialByte, partialBits); // throws when 0
// after
if (totalBits % 8 == 0)
digest.DoFinal(outBytes, 0);
else
digest.DoFinal(outBytes, 0, partialByte, totalBits % 8); Defensive patterns
Strategy: validation
Validate before calling
if (partialBits < 1 || partialBits > 7)
throw new ArgumentOutOfRangeException(nameof(partialBits), "must be in the range 1 to 7");
digest.DoFinal(output, outOff, partialByte, partialBits); Type guard
bool IsValidPartialBits(int bits) => bits >= 1 && bits <= 7;
Try / catch
try { digest.DoFinal(outBuf, 0, partialByte, partialBits); } catch (ArgumentException ex) when (ex.ParamName == "bits") { digest.DoFinal(outBuf, 0); // byte-aligned fallback } Prevention
- Compute partialBits as totalBits % 8 and use the plain DoFinal when it is 0.
- Add parameter range assertions at API boundaries.
- Prefer byte-aligned hashing; reserve AbsorbBits for protocols that genuinely need bit granularity.
When it happens
Trigger: Passing partialBits = 0 or partialBits > 7 to the extended DoFinal(output, outOff, partialByte, partialBits) overload, which forwards to AbsorbBits.
Common situations: Generic hashing wrappers computing partialBits from a bit-length count where the count is byte-aligned (yields 0) or mis-clamped; ported code from APIs that allow 0 partial bits.
Related errors
- BLAKE2b digest bit length must be a multiple of 8 and not gr
- Invalid digest length (required: 1 - 64)
- BLAKE2s digest bit length must be a multiple of 8 and not gr
- must be one of 128, 224, 256, 288, 384, or 512.
- attempt to absorb while squeezing
AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02).
Data as JSON: /api/errors/9abb2572596933c7.
Report an issue: GitHub.