peass-ng/PEASS-ng · error · InvalidOperationException

Threefish engine not initialised

Error message

Threefish engine not initialised

What it means

The internal ProcessBlock(ulong[], ulong[]) throws this InvalidOperationException when kw[blocksizeWords] == 0, i.e. the key-schedule extension word is still zero because Init() was never called (or was called with a null key, the documented way to mean 'not initialised'). Threefish requires a key and tweak to be set before any block can be processed; the parity/extension word doubles as the initialised flag.

Source

Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/BouncyCastle/crypto/engines/ThreefishEngine.cs:323

				WordToBytes(this.currentBlock[i >> 3], outBytes, outOff + i);
			}

			return blocksizeBytes;
		}

		/// <summary>
		/// Process a block of data represented as 64 bit words.
		/// </summary>
		/// <returns>the number of 8 byte words processed (which will be the same as the block size).</returns>
		/// <param name="inWords">a block sized buffer of words to process.</param>
		/// <param name="outWords">a block sized buffer of words to receive the output of the operation.</param>
		/// <exception cref="DataLengthException">if either the input or output is not block sized</exception>
		/// <exception cref="InvalidOperationException">if this engine is not initialised</exception>
		internal int ProcessBlock(ulong[] inWords, ulong[] outWords)
		{
			if (kw[blocksizeWords] == 0)
			{
				throw new InvalidOperationException("Threefish engine not initialised");
			}

			if (inWords.Length != blocksizeWords)
			{
				throw new DataLengthException("Input buffer too short");
			}
			if (outWords.Length != blocksizeWords)
			{
				throw new DataLengthException("Output buffer too short");
			}

			if (forEncryption)
			{
				cipher.EncryptBlock(inWords, outWords);
			}
			else
			{
				cipher.DecryptBlock(inWords, outWords);

View on GitHub (pinned to 53fb989abc)

Solutions

  1. Call engine.Init(forEncryption, new TweakableBlockCipherParameters(key, tweak, null)) — or the appropriate IBlockCipherParameters — before the first ProcessBlock.
  2. Check initialization state in your wrapper: track a bool set in Init and throw/guard before processing if it's false.
  3. If you reset with a null key, re-Init with a real key before the next ProcessBlock.
  4. Never assume a newly constructed ThreefishEngine is usable: construction and initialisation are separate steps.

Example fix

// before
var engine = new ThreefishEngine(256);
engine.ProcessBlock(input, 0, output, 0); // InvalidOperationException: not initialised
// after
var engine = new ThreefishEngine(256);
engine.Init(true, new TweakableBlockCipherParameters(new KeyParameter(key), tweak, null));
engine.ProcessBlock(input, 0, output, 0);
Defensive patterns

Strategy: validation

Validate before calling

// C#
if (!initialized)
    throw new InvalidOperationException("Call Init(forEncryption, cipherParameters) before ProcessBlock");
engine.Init(forEncryption, new TweakableBlockCipherParameters(new KeyParameter(key), tweak, null));

Type guard

bool IsCipherReady(IBlockCipher engine, Func<bool> initTracker) => engine != null && initTracker();

Try / catch

try
{
    engine.ProcessBlock(input, 0, output, 0);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("not initialised"))
{
    throw new CryptographyException("Threefish engine used before Init() — supply key and tweak parameters first", ex);
}

Prevention

When it happens

Trigger: Calling ProcessBlock(ulong[] inWords, ulong[] outWords) (directly or via the byte[] overload) before calling Init(true/false, keyParameters), or after Init was passed a null key — ThreefishEngine treats Init(forEncryption, null) as 'de-initialise'.

Common situations: Reusing a freshly constructed engine without wiring key parameters; resetting the cipher with a null key and then continuing to process blocks; a code path that constructs the engine lazily but processes eagerly; mixing engines where only one of several got Init called.

Related errors


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