peass-ng/PEASS-ng · error · MemoableResetException

Incompatible parameters in provided SkeinEngine.

Error message

Incompatible parameters in provided SkeinEngine.

What it means

SkeinEngine.Reset(IMemoable) restores state from another SkeinEngine. Because Skein's internal state depends on block size and output size, the library throws MemoableResetException('Incompatible parameters in provided SkeinEngine.') when either differs between the two engines.

Source

Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/BouncyCastle/crypto/digests/SkeinEngine.cs:578

            if ((existing == null) || (existing.Length != data.Length))
            {
                existing = new Parameter[data.Length];
            }
            Array.Copy(data, 0, existing, 0, existing.Length);
            return existing;
        }

        public IMemoable Copy()
        {
            return new SkeinEngine(this);
        }

        public void Reset(IMemoable other)
        {
            SkeinEngine s = (SkeinEngine)other;
            if ((BlockSize != s.BlockSize) || (outputSizeBytes != s.outputSizeBytes))
            {
                throw new MemoableResetException("Incompatible parameters in provided SkeinEngine.");
            }
            CopyIn(s);
        }

        public int OutputSize
        {
            get { return outputSizeBytes; }
        }

        public int BlockSize
        {
            get { return threefish.GetBlockSize (); }
        }

        /// <summary>
        /// Initialises the Skein engine with the provided parameters. See <see cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> for
        /// details on the parameterisation of the Skein hash function.
        /// </summary>

View on GitHub (pinned to 53fb989abc)

Solutions

  1. Only reset from engines created with the same blockSizeBits and outputSizeBits.
  2. Create a new SkeinEngine/SkeinDigest with the other's parameters instead of resetting.
  3. Key cached engines by (blockSize, outputSize) so lookups never cross configurations.

Example fix

// before
engine.Reset(otherEngine); // may have different params
// after
if (engine.BlockSize == otherEngine.BlockSize)
{
    engine.Reset(otherEngine);
}
else
{
    engine = new SkeinEngine(otherEngine.BlockSize, otherEngine.OutputSize * 8);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (engine.BlockSize != otherEngine.BlockSize || engine.OutputSize != otherEngine.OutputSize) throw new InvalidOperationException("Incompatible Skein parameters");

Type guard

bool CanResetFrom(SkeinEngine target, SkeinEngine other) => target.BlockSize == other.BlockSize && target.OutputSize == other.OutputSize;

Try / catch

try { engine.Reset(other); }
catch (MemoableResetException) { engine = new SkeinEngine(other.BlockSize, other.OutputSize * 8); engine.Reset(other); }

Prevention

When it happens

Trigger: Calling Reset(otherEngine) where other was created as new SkeinEngine(512, 256) but this as new SkeinEngine(1024, 256), or output sizes differ.

Common situations: Digest pooling/caching with mixed Skein parameter sets; reusing a cached engine after the application changed Skein configuration.

Related errors


AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02). Data as JSON: /api/errors/dcf628ba66af06fe. Report an issue: GitHub.