peass-ng/PEASS-ng · error · ArgumentException
Threefish tweak must be bytes
Error message
Threefish tweak must be bytes
What it means
An argument validation in ThreefishEngine.Init: when a tweak byte array is supplied its length must equal TWEAK_SIZE_BYTES (16, i.e. two 64-bit words); any other length is rejected because the tweak schedule is built from exactly two words. The message interpolates the required size, so it reads with a missing number only when the constant is elided in formatting.
Source
Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/BouncyCastle/crypto/engines/ThreefishEngine.cs:198
if (keyBytes != null)
{
if (keyBytes.Length != this.blocksizeBytes)
{
throw new ArgumentException("Threefish key must be same size as block (" + blocksizeBytes
+ " bytes)");
}
keyWords = new ulong[blocksizeWords];
for (int i = 0; i < keyWords.Length; i++)
{
keyWords[i] = BytesToWord(keyBytes, i * 8);
}
}
if (tweakBytes != null)
{
if (tweakBytes.Length != TWEAK_SIZE_BYTES)
{
throw new ArgumentException("Threefish tweak must be " + TWEAK_SIZE_BYTES + " bytes");
}
tweakWords = new ulong[] { BytesToWord(tweakBytes, 0), BytesToWord(tweakBytes, 8) };
}
Init(forEncryption, keyWords, tweakWords);
}
/// <summary>
/// Initialise the engine, specifying the key and tweak directly.
/// </summary>
/// <param name="forEncryption">the cipher mode.</param>
/// <param name="key">the words of the key, or <code>null</code> to use the current key.</param>
/// <param name="tweak">the 2 word (128 bit) tweak, or <code>null</code> to use the current tweak.</param>
internal void Init(bool forEncryption, ulong[] key, ulong[] tweak)
{
this.forEncryption = forEncryption;
if (key != null)
{
SetKey(key);View on GitHub (pinned to 53fb989abc)
Solutions
- Supply exactly 16 bytes of tweak material
- If the tweak source is longer/shorter, derive 16 bytes via SHA-256 truncation or a dedicated KDF
- Construct tweak as two 8-byte little-endian words when building it manually
Example fix
// before byte[] tweak = new byte[8]; engine.Init(true, new ParametersWithTweak(new KeyParameter(key), tweak)); // after byte[] tweak = new byte[16]; engine.Init(true, new ParametersWithTweak(new KeyParameter(key), tweak));
Defensive patterns
Strategy: validation
Validate before calling
const int TweakSizeBytes = 16;
if (tweak == null || tweak.Length != TweakSizeBytes)
throw new ArgumentException("Threefish tweak must be exactly 16 bytes");
engine.Init(forEncryption, new ParametersWithTweak(new KeyParameter(key), tweak)); Type guard
bool IsValidThreefishTweak(byte[] tweak) => tweak != null && tweak.Length == 16;
Try / catch
try { engine.Init(forEnc, new ParametersWithTweak(keyParam, tweak)); }
catch (ArgumentException) { /* normalize tweak to 16 bytes and retry once */ } Prevention
- Remember the Threefish tweak is 128 bits (two 64-bit words)
- Hash/truncate external tweak sources to exactly 16 bytes
- Reuse a single helper to build ParametersWithTweak consistently
When it happens
Trigger: Calling Init with ParametersWithTweak whose tweak array is not 16 bytes (e.g. 8-byte counter, 32-byte tweak, null-padded value).
Common situations: Feeding an AES-GCM-style 12-byte IV as a Threefish tweak; hashing a tweak to 32 bytes instead of 16; forgetting that Threefish's tweak is 128 bits.
Related errors
- Tweak must be words.
- Invalid blocksize - Threefish is defined with block size of
- Invalid parameter passed to Threefish init -
- Threefish key must be same size as block (
- Output buffer too short
AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02).
Data as JSON: /api/errors/37cf0b5fceb4a322.
Report an issue: GitHub.