summary refs log tree commit diff
path: root/crypto/src/crypto/engines
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/crypto/engines')
-rw-r--r--crypto/src/crypto/engines/ElephantEngine.cs71
-rw-r--r--crypto/src/crypto/engines/ISAPEngine.cs14
-rw-r--r--crypto/src/crypto/engines/PhotonBeetleEngine.cs44
-rw-r--r--crypto/src/crypto/engines/SparkleEngine.cs188
-rw-r--r--crypto/src/crypto/engines/XoodyakEngine.cs95
5 files changed, 186 insertions, 226 deletions
diff --git a/crypto/src/crypto/engines/ElephantEngine.cs b/crypto/src/crypto/engines/ElephantEngine.cs
index 4e0e3216d..89d2ca6be 100644
--- a/crypto/src/crypto/engines/ElephantEngine.cs
+++ b/crypto/src/crypto/engines/ElephantEngine.cs
@@ -1,8 +1,10 @@
 using System;
+using System.Drawing;
 using System.IO;
 
 using Org.BouncyCastle.Crypto.Modes;
 using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math.Raw;
 using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Crypto.Engines
@@ -13,6 +15,7 @@ namespace Org.BouncyCastle.Crypto.Engines
      * Specification: https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/elephant-spec-final.pdf
      */
     public class ElephantEngine
+        // TODO IAeadCipher only
         : IAeadBlockCipher
     {
         public enum ElephantParameters
@@ -22,7 +25,7 @@ namespace Org.BouncyCastle.Crypto.Engines
             elephant200
         }
 
-        private bool forEncryption;
+        private bool forEncryption = true; // Safe output sizes before initialization
         private readonly string algorithmName;
         private ElephantParameters parameters;
         private int BLOCK_SIZE;
@@ -226,28 +229,20 @@ namespace Org.BouncyCastle.Crypto.Engines
         {
             switch (parameters)
             {
-                case ElephantParameters.elephant160:
-                    output[BLOCK_SIZE - 1] = (byte)((((input[0] & 0xFF) << 3) | ((input[0] & 0xFF) >> 5)) ^
-                        ((input[3] & 0xFF) << 7) ^ ((input[13] & 0xFF) >> 7));
-                    break;
-                case ElephantParameters.elephant176:
-                    output[BLOCK_SIZE - 1] = (byte)(rotl(input[0]) ^ ((input[3] & 0xFF) << 7) ^ ((input[19] & 0xFF) >> 7));
-                    break;
-                case ElephantParameters.elephant200:
-                    output[BLOCK_SIZE - 1] = (byte)(rotl(input[0]) ^ rotl(input[2]) ^ (input[13] << 1));
-                    break;
+            case ElephantParameters.elephant160:
+                output[BLOCK_SIZE - 1] = (byte)((((input[0] & 0xFF) << 3) | ((input[0] & 0xFF) >> 5)) ^
+                    ((input[3] & 0xFF) << 7) ^ ((input[13] & 0xFF) >> 7));
+                break;
+            case ElephantParameters.elephant176:
+                output[BLOCK_SIZE - 1] = (byte)(rotl(input[0]) ^ ((input[3] & 0xFF) << 7) ^ ((input[19] & 0xFF) >> 7));
+                break;
+            case ElephantParameters.elephant200:
+                output[BLOCK_SIZE - 1] = (byte)(rotl(input[0]) ^ rotl(input[2]) ^ (input[13] << 1));
+                break;
             }
             Array.Copy(input, 1, output, 0, BLOCK_SIZE - 1);
         }
 
-        private void xor_block(byte[] state, byte[] block, int bOff, int size)
-        {
-            for (int i = 0; i < size; ++i)
-            {
-                state[i] ^= block[i + bOff];
-            }
-        }
-
         // Write the ith assocated data block to "output".
         // The nonce is prepended and padding is added as required.
         // adlen is the length of the associated data in bytes
@@ -412,14 +407,13 @@ namespace Org.BouncyCastle.Crypto.Engines
                     // Compute ciphertext block
                     Array.Copy(npub, 0, buffer, 0, CRYPTO_NPUBBYTES);
                     Arrays.Fill(buffer, CRYPTO_NPUBBYTES, BLOCK_SIZE, (byte)0);
-                    xor_block(buffer, current_mask, 0, BLOCK_SIZE);
-                    xor_block(buffer, next_mask, 0, BLOCK_SIZE);
+                    Bytes.XorTo(BLOCK_SIZE, current_mask, buffer);
+                    Bytes.XorTo(BLOCK_SIZE, next_mask, buffer);
                     permutation(buffer);
-                    xor_block(buffer, current_mask, 0, BLOCK_SIZE);
-                    xor_block(buffer, next_mask, 0, BLOCK_SIZE);
+                    Bytes.XorTo(BLOCK_SIZE, current_mask, buffer);
+                    Bytes.XorTo(BLOCK_SIZE, next_mask, buffer);
                     int r_size = (i == nblocks_m - 1) ? mlen - offset : BLOCK_SIZE;
-                    xor_block(buffer, m, offset, r_size);
-                    Array.Copy(buffer, 0, output, offset + outOff, r_size);
+                    Bytes.Xor(r_size, m, offset, buffer, 0, output, outOff + offset);
                 }
                 if (i > 0 && i <= nblocks_c)
                 {
@@ -432,21 +426,21 @@ namespace Org.BouncyCastle.Crypto.Engines
                     {
                         get_c_block(buffer, m, 0, mlen, i - 1);
                     }
-                    xor_block(buffer, previous_mask, 0, BLOCK_SIZE);
-                    xor_block(buffer, next_mask, 0, BLOCK_SIZE);
+                    Bytes.XorTo(BLOCK_SIZE, previous_mask, buffer);
+                    Bytes.XorTo(BLOCK_SIZE, next_mask, buffer);
                     permutation(buffer);
-                    xor_block(buffer, previous_mask, 0, BLOCK_SIZE);
-                    xor_block(buffer, next_mask, 0, BLOCK_SIZE);
-                    xor_block(tag_buffer, buffer, 0, BLOCK_SIZE);
+                    Bytes.XorTo(BLOCK_SIZE, previous_mask, buffer);
+                    Bytes.XorTo(BLOCK_SIZE, next_mask, buffer);
+                    Bytes.XorTo(BLOCK_SIZE, buffer, tag_buffer);
                 }
                 // If there is any AD left, compute tag for AD block
                 if (i + 1 < nblocks_ad)
                 {
                     get_ad_block(buffer, ad, adlen, npub, i + 1);
-                    xor_block(buffer, next_mask, 0, BLOCK_SIZE);
+                    Bytes.XorTo(BLOCK_SIZE, next_mask, buffer);
                     permutation(buffer);
-                    xor_block(buffer, next_mask, 0, BLOCK_SIZE);
-                    xor_block(tag_buffer, buffer, 0, BLOCK_SIZE);
+                    Bytes.XorTo(BLOCK_SIZE, next_mask, buffer);
+                    Bytes.XorTo(BLOCK_SIZE, buffer, tag_buffer);
                 }
                 // Cyclically shift the mask buffers
                 // Value of next_mask will be computed in the next iteration
@@ -458,9 +452,9 @@ namespace Org.BouncyCastle.Crypto.Engines
             }
             outOff += mlen;
             tag = new byte[CRYPTO_ABYTES];
-            xor_block(tag_buffer, expanded_key, 0, BLOCK_SIZE);
+            Bytes.XorTo(BLOCK_SIZE, expanded_key, tag_buffer);
             permutation(tag_buffer);
-            xor_block(tag_buffer, expanded_key, 0, BLOCK_SIZE);
+            Bytes.XorTo(BLOCK_SIZE, expanded_key, tag_buffer);
             if (forEncryption)
             {
                 Array.Copy(tag_buffer, 0, tag, 0, CRYPTO_ABYTES);
@@ -483,11 +477,13 @@ namespace Org.BouncyCastle.Crypto.Engines
 
         public int GetUpdateOutputSize(int len)
         {
+            // TODO
             return len;
         }
 
         public int GetOutputSize(int len)
         {
+            // TODO
             return len + CRYPTO_ABYTES;
         }
 
@@ -514,13 +510,13 @@ namespace Org.BouncyCastle.Crypto.Engines
 
         public int ProcessByte(byte input, Span<byte> output)
         {
-            message.Write(new byte[]{ input });
+            message.WriteByte(input);
             return 0;
         }
 
         public int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output)
         {
-            message.Write(input.ToArray());
+            message.Write(input);
             return 0;
         }
 
@@ -558,4 +554,3 @@ namespace Org.BouncyCastle.Crypto.Engines
         }
     }
 }
-
diff --git a/crypto/src/crypto/engines/ISAPEngine.cs b/crypto/src/crypto/engines/ISAPEngine.cs
index 7ef629d1b..17c679439 100644
--- a/crypto/src/crypto/engines/ISAPEngine.cs
+++ b/crypto/src/crypto/engines/ISAPEngine.cs
@@ -35,7 +35,7 @@ namespace Org.BouncyCastle.Crypto.Engines
         private const int ISAP_STATE_SZ = 40;
 
         private string algorithmName;
-        private bool forEncryption;
+        private bool forEncryption = true; // Safe output sizes before initialization
         private bool initialised;
         private byte[] mac;
         private MemoryStream aadData = new MemoryStream();
@@ -112,7 +112,7 @@ namespace Org.BouncyCastle.Crypto.Engines
             protected ulong ISAP_IV1_64;
             protected ulong ISAP_IV2_64;
             protected ulong ISAP_IV3_64;
-            protected ulong x0, x1, x2, x3, x4, t0, t1, t2, t3, t4;
+            protected ulong x0, x1, x2, x3, x4;
 
             public override void init(byte[] k, byte[] npub, int ISAP_rH, int ISAP_rH_SZ)
             {
@@ -248,11 +248,11 @@ namespace Org.BouncyCastle.Crypto.Engines
 #endif
             protected void ROUND(ulong C)
             {
-                t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C));
-                t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3));
-                t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4);
-                t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4));
-                t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1);
+                ulong t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C));
+                ulong t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3));
+                ulong t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4);
+                ulong t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4));
+                ulong t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1);
                 x0 = t0 ^ Longs.RotateRight(t0, 19) ^ Longs.RotateRight(t0, 28);
                 x1 = t1 ^ Longs.RotateRight(t1, 39) ^ Longs.RotateRight(t1, 61);
                 x2 = ~(t2 ^ Longs.RotateRight(t2, 1) ^ Longs.RotateRight(t2, 6));
diff --git a/crypto/src/crypto/engines/PhotonBeetleEngine.cs b/crypto/src/crypto/engines/PhotonBeetleEngine.cs
index e593bb6f5..5d96213a1 100644
--- a/crypto/src/crypto/engines/PhotonBeetleEngine.cs
+++ b/crypto/src/crypto/engines/PhotonBeetleEngine.cs
@@ -14,7 +14,8 @@ namespace Org.BouncyCastle.Crypto.Engines
      * Photon-Beetle with reference to C Reference Impl from: https://github.com/PHOTON-Beetle/Software
      * </p>
      */
-    public class PhotonBeetleEngine
+    public sealed class PhotonBeetleEngine
+        // TODO IAeadCipher only
         : IAeadBlockCipher
     {
         public enum PhotonBeetleParameters
@@ -24,7 +25,7 @@ namespace Org.BouncyCastle.Crypto.Engines
         }
 
         private bool input_empty;
-        private bool forEncryption;
+        private bool forEncryption = true; // Safe output sizes before initialization
         private bool initialised;
         private byte[] K;
         private byte[] N;
@@ -94,6 +95,7 @@ namespace Org.BouncyCastle.Crypto.Engines
 
         public string AlgorithmName => "Photon-Beetle AEAD";
 
+        // TODO
         public IBlockCipher UnderlyingCipher => throw new NotImplementedException();
 
         public byte[] GetMac()
@@ -103,37 +105,33 @@ namespace Org.BouncyCastle.Crypto.Engines
 
         public int GetOutputSize(int len)
         {
+            // TODO
             return len + TAG_INBYTES;
         }
 
         public int GetUpdateOutputSize(int len)
         {
+            // TODO
             return len;
         }
 
         public void Init(bool forEncryption, ICipherParameters parameters)
         {
             this.forEncryption = forEncryption;
-            if (!(parameters is ParametersWithIV param))
-            {
+
+            if (!(parameters is ParametersWithIV ivParams))
                 throw new ArgumentException("Photon-Beetle AEAD init parameters must include an IV");
-            }
-            ParametersWithIV ivParams = param;
+
             N = ivParams.GetIV();
             if (N == null || N.Length != CRYPTO_NPUBBYTES)
-            {
                 throw new ArgumentException("Photon-Beetle AEAD requires exactly 16 bytes of IV");
-            }
-            if (!(ivParams.Parameters is KeyParameter))
-            {
+
+            if (!(ivParams.Parameters is KeyParameter key))
                 throw new ArgumentException("Photon-Beetle AEAD init parameters must include a key");
-            }
-            KeyParameter key = (KeyParameter)ivParams.Parameters;
+
             K = key.GetKey();
             if (K.Length != CRYPTO_KEYBYTES)
-            {
                 throw new ArgumentException("Photon-Beetle AEAD key must be 128 bits long");
-            }
 
             state = new byte[STATE_INBYTES];
             state_2d = new byte[D][];
@@ -148,7 +146,7 @@ namespace Org.BouncyCastle.Crypto.Engines
 
         public void ProcessAadByte(byte input)
         {
-            aadData.Write(new byte[] { input }, 0, 1);
+            aadData.WriteByte(input);
         }
 
         public void ProcessAadBytes(byte[] inBytes, int inOff, int len)
@@ -300,19 +298,11 @@ namespace Org.BouncyCastle.Crypto.Engines
             }
             if (forEncryption)
             {
-                XOR(plaintext, inOff, DBlen_inbytes);
+                Bytes.XorTo(DBlen_inbytes, plaintext, inOff, state, 0);
             }
             else
             {
-                XOR(ciphertext, inOff, DBlen_inbytes);
-            }
-        }
-
-        void XOR(byte[] in_right, int rOff, int iolen_inbytes)
-        {
-            for (int i = 0; i < iolen_inbytes; i++)
-            {
-                state[i] ^= in_right[rOff++];
+                Bytes.XorTo(DBlen_inbytes, ciphertext, inOff, state, 0);
             }
         }
 
@@ -344,11 +334,11 @@ namespace Org.BouncyCastle.Crypto.Engines
                 for (i = 0; i < Dlen_inblocks - 1; i++)
                 {
                     PHOTON_Permutation();
-                    XOR(A, i * RATE_INBYTES, RATE_INBYTES);
+                    Bytes.XorTo(RATE_INBYTES, A, i * RATE_INBYTES, state, 0);
                 }
                 PHOTON_Permutation();
                 LastDBlocklen = adlen - i * RATE_INBYTES;
-                XOR(A, i * RATE_INBYTES, LastDBlocklen);
+                Bytes.XorTo(LastDBlocklen, A, i * RATE_INBYTES, state, 0);
                 if (LastDBlocklen < RATE_INBYTES)
                 {
                     state[LastDBlocklen] ^= 0x01; // ozs
diff --git a/crypto/src/crypto/engines/SparkleEngine.cs b/crypto/src/crypto/engines/SparkleEngine.cs
index 63e400d4c..7d8c28f8e 100644
--- a/crypto/src/crypto/engines/SparkleEngine.cs
+++ b/crypto/src/crypto/engines/SparkleEngine.cs
@@ -14,7 +14,8 @@ namespace Org.BouncyCastle.Crypto.Engines
     /// Specification:
     /// https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/sparkle-spec-final.pdf .
     /// </remarks>
-    public class SparkleEngine
+    public sealed class SparkleEngine
+        // TODO IAeadCipher only
         : IAeadBlockCipher
     {
         public enum SparkleParameters
@@ -24,8 +25,9 @@ namespace Org.BouncyCastle.Crypto.Engines
             SCHWAEMM192_192,
             SCHWAEMM256_256
         }
+
         private string algorithmName;
-        private bool forEncryption;
+        private bool forEncryption = true; // Safe output sizes before initialization
         private readonly uint[] state;
         private readonly uint[] k;
         private readonly uint[] npub;
@@ -60,48 +62,48 @@ namespace Org.BouncyCastle.Crypto.Engines
             int SPARKLE_CAPACITY;
             switch (sparkleParameters)
             {
-                case SparkleParameters.SCHWAEMM128_128:
-                    SCHWAEMM_KEY_LEN = 128;
-                    SCHWAEMM_NONCE_LEN = 128;
-                    SCHWAEMM_TAG_LEN = 128;
-                    SPARKLE_STATE = 256;
-                    SPARKLE_CAPACITY = 128;
-                    SPARKLE_STEPS_SLIM = 7;
-                    SPARKLE_STEPS_BIG = 10;
-                    algorithmName = "SCHWAEMM128-128";
-                    break;
-                case SparkleParameters.SCHWAEMM256_128:
-                    SCHWAEMM_KEY_LEN = 128;
-                    SCHWAEMM_NONCE_LEN = 256;
-                    SCHWAEMM_TAG_LEN = 128;
-                    SPARKLE_STATE = 384;
-                    SPARKLE_CAPACITY = 128;
-                    SPARKLE_STEPS_SLIM = 7;
-                    SPARKLE_STEPS_BIG = 11;
-                    algorithmName = "SCHWAEMM256-128";
-                    break;
-                case SparkleParameters.SCHWAEMM192_192:
-                    SCHWAEMM_KEY_LEN = 192;
-                    SCHWAEMM_NONCE_LEN = 192;
-                    SCHWAEMM_TAG_LEN = 192;
-                    SPARKLE_STATE = 384;
-                    SPARKLE_CAPACITY = 192;
-                    SPARKLE_STEPS_SLIM = 7;
-                    SPARKLE_STEPS_BIG = 11;
-                    algorithmName = "SCHWAEMM192-192";
-                    break;
-                case SparkleParameters.SCHWAEMM256_256:
-                    SCHWAEMM_KEY_LEN = 256;
-                    SCHWAEMM_NONCE_LEN = 256;
-                    SCHWAEMM_TAG_LEN = 256;
-                    SPARKLE_STATE = 512;
-                    SPARKLE_CAPACITY = 256;
-                    SPARKLE_STEPS_SLIM = 8;
-                    SPARKLE_STEPS_BIG = 12;
-                    algorithmName = "SCHWAEMM256-256";
-                    break;
-                default:
-                    throw new ArgumentException("Invalid definition of SCHWAEMM instance");
+            case SparkleParameters.SCHWAEMM128_128:
+                SCHWAEMM_KEY_LEN = 128;
+                SCHWAEMM_NONCE_LEN = 128;
+                SCHWAEMM_TAG_LEN = 128;
+                SPARKLE_STATE = 256;
+                SPARKLE_CAPACITY = 128;
+                SPARKLE_STEPS_SLIM = 7;
+                SPARKLE_STEPS_BIG = 10;
+                algorithmName = "SCHWAEMM128-128";
+                break;
+            case SparkleParameters.SCHWAEMM256_128:
+                SCHWAEMM_KEY_LEN = 128;
+                SCHWAEMM_NONCE_LEN = 256;
+                SCHWAEMM_TAG_LEN = 128;
+                SPARKLE_STATE = 384;
+                SPARKLE_CAPACITY = 128;
+                SPARKLE_STEPS_SLIM = 7;
+                SPARKLE_STEPS_BIG = 11;
+                algorithmName = "SCHWAEMM256-128";
+                break;
+            case SparkleParameters.SCHWAEMM192_192:
+                SCHWAEMM_KEY_LEN = 192;
+                SCHWAEMM_NONCE_LEN = 192;
+                SCHWAEMM_TAG_LEN = 192;
+                SPARKLE_STATE = 384;
+                SPARKLE_CAPACITY = 192;
+                SPARKLE_STEPS_SLIM = 7;
+                SPARKLE_STEPS_BIG = 11;
+                algorithmName = "SCHWAEMM192-192";
+                break;
+            case SparkleParameters.SCHWAEMM256_256:
+                SCHWAEMM_KEY_LEN = 256;
+                SCHWAEMM_NONCE_LEN = 256;
+                SCHWAEMM_TAG_LEN = 256;
+                SPARKLE_STATE = 512;
+                SPARKLE_CAPACITY = 256;
+                SPARKLE_STEPS_SLIM = 8;
+                SPARKLE_STEPS_BIG = 12;
+                algorithmName = "SCHWAEMM256-256";
+                break;
+            default:
+                throw new ArgumentException("Invalid definition of SCHWAEMM instance");
             }
             KEY_WORDS = SCHWAEMM_KEY_LEN >> 5;
             KEY_BYTES = SCHWAEMM_KEY_LEN >> 3;
@@ -124,14 +126,9 @@ namespace Org.BouncyCastle.Crypto.Engines
             initialised = false;
         }
 
-        private uint ROT(uint x, int n)
-        {
-            return (((x) >> n) | ((x) << (32 - n)));
-        }
-
         private uint ELL(uint x)
         {
-            return ROT(((x) ^ ((x) << 16)), 16);
+            return Integers.RotateRight(x ^ (x << 16), 16);
         }
 
         private static readonly uint[] RCON = {0xB7E15162, 0xBF715880, 0x38B4DA56, 0x324E7738, 0xBB1185EB, 0x4F7C7B57,
@@ -149,17 +146,17 @@ namespace Org.BouncyCastle.Crypto.Engines
                 for (j = 0; j < 2 * brans; j += 2)
                 {
                     rc = RCON[j >> 1];
-                    state[j] += ROT(state[j + 1], 31);
-                    state[j + 1] ^= ROT(state[j], 24);
+                    state[j] += Integers.RotateRight(state[j + 1], 31);
+                    state[j + 1] ^= Integers.RotateRight(state[j], 24);
                     state[j] ^= rc;
-                    state[j] += ROT(state[j + 1], 17);
-                    state[j + 1] ^= ROT(state[j], 17);
+                    state[j] += Integers.RotateRight(state[j + 1], 17);
+                    state[j + 1] ^= Integers.RotateRight(state[j], 17);
                     state[j] ^= rc;
                     state[j] += state[j + 1];
-                    state[j + 1] ^= ROT(state[j], 31);
+                    state[j + 1] ^= Integers.RotateRight(state[j], 31);
                     state[j] ^= rc;
-                    state[j] += ROT(state[j + 1], 24);
-                    state[j + 1] ^= ROT(state[j], 16);
+                    state[j] += Integers.RotateRight(state[j + 1], 24);
+                    state[j + 1] ^= Integers.RotateRight(state[j], 16);
                     state[j] ^= rc;
                 }
                 // Linear layer
@@ -308,31 +305,22 @@ namespace Org.BouncyCastle.Crypto.Engines
         public void Init(bool forEncryption, ICipherParameters param)
         {
             this.forEncryption = forEncryption;
-            if (!(param is ParametersWithIV))
-            {
+            if (!(param is ParametersWithIV ivParams))
                 throw new ArgumentException(algorithmName + " init parameters must include an IV");
-            }
 
-            ParametersWithIV ivParams = (ParametersWithIV)param;
             byte[] iv = ivParams.GetIV();
-
             if (iv == null || iv.Length != SCHWAEMM_NONCE_LEN >> 3)
-            {
                 throw new ArgumentException(algorithmName + " requires exactly 16 bytes of IV");
-            }
+
             Pack.LE_To_UInt32(iv, 0, npub, 0, RATE_WORDS);
 
-            if (!(ivParams.Parameters is KeyParameter))
-            {
+            if (!(ivParams.Parameters is KeyParameter key))
                 throw new ArgumentException(algorithmName + " init parameters must include a key");
-            }
 
-            KeyParameter key = (KeyParameter)ivParams.Parameters;
             byte[] key8 = key.GetKey();
             if (key8.Length != SCHWAEMM_KEY_LEN >> 3)
-            {
                 throw new ArgumentException(algorithmName + " key must be 128 bits long");
-            }
+
             Pack.LE_To_UInt32(key8, 0, k, 0, KEY_WORDS);
             initialised = true;
             reset(false);
@@ -345,9 +333,9 @@ namespace Org.BouncyCastle.Crypto.Engines
                 throw new ArgumentException(algorithmName + ": AAD cannot be added after reading a full block(" +
                     GetBlockSize() + " bytes) of input for " + (forEncryption ? "encryption" : "decryption"));
             }
-            aadData.Write(new byte[] { input }, 0, 1);
-        }
 
+            aadData.WriteByte(input);
+        }
 
         public void ProcessAadBytes(byte[] input, int inOff, int len)
         {
@@ -356,61 +344,53 @@ namespace Org.BouncyCastle.Crypto.Engines
                 throw new ArgumentException(algorithmName + ": AAD cannot be added after reading a full block(" +
                     GetBlockSize() + " bytes) of input for " + (forEncryption ? "encryption" : "decryption"));
             }
-            if (inOff + len > input.Length)
-            {
-                throw new DataLengthException(algorithmName + " input buffer too short");
-            }
+
+            Check.DataLength(input, inOff, len, "input buffer too short");
+
             aadData.Write(input, inOff, len);
         }
 
-
         public int ProcessByte(byte input, byte[] output, int outOff)
         {
-            return ProcessBytes(new byte[] { input }, 0, 1, output, outOff);
+            return ProcessBytes(new byte[]{ input }, 0, 1, output, outOff);
         }
 
-
         public int ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff)
         {
             if (!initialised)
-            {
                 throw new ArgumentException(algorithmName + " Need call init function before encryption/decryption");
-            }
-            if (inOff + len > input.Length)
-            {
-                throw new DataLengthException(algorithmName + " input buffer too short");
-            }
+
+            Check.DataLength(input, inOff, len, "input buffer too short");
+
             message.Write(input, inOff, len);
+
+            int msgLen = Convert.ToInt32(message.Length);
+
             len = 0;
-            if ((forEncryption && (int)message.Length > GetBlockSize()) ||
-                (!forEncryption && (int)message.Length - TAG_BYTES > GetBlockSize()))
+            if ((forEncryption && msgLen > GetBlockSize()) ||
+                (!forEncryption && msgLen - TAG_BYTES > GetBlockSize()))
             {
-                len = ((int)message.Length - (forEncryption ? 0 : TAG_BYTES));
-                if (len / RATE_BYTES * RATE_BYTES + outOff > output.Length)
-                {
-                    throw new OutputLengthException(algorithmName + " output buffer is too short");
-                }
+                len = msgLen - (forEncryption ? 0 : TAG_BYTES);
+                Check.OutputLength(output, outOff, len / RATE_BYTES * RATE_BYTES, "output buffer is too short");
                 byte[] m = message.GetBuffer();
                 ProcessAssocData(state);
                 if (len != 0)
                 {
                     len = ProcessPlainText(state, output, m, 0, len);
                 }
-                int mlen = (int)message.Length;
                 message.SetLength(0);
-                message.Write(m, len, mlen - len);
+                // TODO Sketchy writing back to the buffer after setting length to 0
+                message.Write(m, len, msgLen - len);
             }
             return len;
         }
 
-
         public int DoFinal(byte[] output, int outOff)
         {
             if (!initialised)
-            {
-                throw new ArgumentException(algorithmName + " needs call init function before dofinal");
-            }
-            int inlen = (int)message.Length - (forEncryption ? 0 : TAG_BYTES);
+                throw new ArgumentException(algorithmName + " needs to call Init before DoFinal");
+
+            int inlen = Convert.ToInt32(message.Length) - (forEncryption ? 0 : TAG_BYTES);
             if ((forEncryption && inlen + TAG_BYTES + outOff > output.Length) ||
                 (!forEncryption && inlen + outOff > output.Length))
             {
@@ -495,25 +475,23 @@ namespace Org.BouncyCastle.Crypto.Engines
             return tag;
         }
 
-
         public int GetUpdateOutputSize(int len)
         {
+            // TODO
             return len;
         }
 
-
         public int GetOutputSize(int len)
         {
+            // TODO
             return len + TAG_BYTES;
         }
 
-
         public void Reset()
         {
             if (!initialised)
-            {
-                throw new ArgumentException(algorithmName + " needs call init function before reset");
-            }
+                throw new ArgumentException(algorithmName + " needs to call Init before Reset");
+
             reset(true);
         }
 
diff --git a/crypto/src/crypto/engines/XoodyakEngine.cs b/crypto/src/crypto/engines/XoodyakEngine.cs
index e0263272e..2eb563525 100644
--- a/crypto/src/crypto/engines/XoodyakEngine.cs
+++ b/crypto/src/crypto/engines/XoodyakEngine.cs
@@ -13,11 +13,23 @@ namespace Org.BouncyCastle.Crypto.Engines
     * <p>
     * Xoodyak with reference to C Reference Impl from: https://github.com/XKCP/XKCP
     * </p>
-*/
+    */
     public sealed class XoodyakEngine
+        // TODO IAeadCipher only
         : IAeadBlockCipher
     {
-        private bool forEncryption;
+        private enum MODE
+        {
+            ModeHash,
+            ModeKeyed
+        }
+
+        private const int Rkin = 44;
+
+        private static readonly uint[] RC = { 0x00000058U, 0x00000038U, 0x000003C0U, 0x000000D0U, 0x00000120U,
+            0x00000014U, 0x00000060U, 0x0000002CU, 0x00000380U, 0x000000F0U, 0x000001A0U, 0x00000012U };
+
+        private bool forEncryption = true; // Safe output sizes before initialization
         private byte[] state;
         private int phase;
         private MODE mode;
@@ -33,49 +45,36 @@ namespace Org.BouncyCastle.Crypto.Engines
         private const int NCOLUMS = 4;
         private const int MAXROUNDS = 12;
         private const int TAGLEN = 16;
-        const int Rkin = 44;
         private byte[] tag;
-        private readonly uint[] RC = {0x00000058, 0x00000038, 0x000003C0, 0x000000D0, 0x00000120, 0x00000014, 0x00000060,
-        0x0000002C, 0x00000380, 0x000000F0, 0x000001A0, 0x00000012};
         private bool aadFinished;
         private bool encrypted;
         private bool initialised = false;
-        public string AlgorithmName => "Xoodak AEAD";
-
-        public IBlockCipher UnderlyingCipher => throw new NotImplementedException();
 
         private MemoryStream aadData = new MemoryStream();
         private MemoryStream message = new MemoryStream();
 
-        enum MODE
-        {
-            ModeHash,
-            ModeKeyed
-        }
+        public string AlgorithmName => "Xoodak AEAD";
+
+        public IBlockCipher UnderlyingCipher => throw new NotImplementedException();
 
-        public void Init(bool forEncryption, ICipherParameters param)
+        public void Init(bool forEncryption, ICipherParameters parameters)
         {
             this.forEncryption = forEncryption;
-            if (!(param is ParametersWithIV))
-            {
+
+            if (!(parameters is ParametersWithIV ivParams))
                 throw new ArgumentException("Xoodyak init parameters must include an IV");
-            }
-            ParametersWithIV ivParams = (ParametersWithIV)param;
+
             iv = ivParams.GetIV();
             if (iv == null || iv.Length != 16)
-            {
                 throw new ArgumentException("Xoodyak requires exactly 16 bytes of IV");
-            }
-            if (!(ivParams.Parameters is KeyParameter))
-            {
+
+            if (!(ivParams.Parameters is KeyParameter key))
                 throw new ArgumentException("Xoodyak init parameters must include a key");
-            }
-            KeyParameter key = (KeyParameter)ivParams.Parameters;
+
             K = key.GetKey();
             if (K.Length != 16)
-            {
                 throw new ArgumentException("Xoodyak key must be 128 bits long");
-            }
+
             state = new byte[48];
             tag = new byte[TAGLEN];
             initialised = true;
@@ -89,9 +88,9 @@ namespace Org.BouncyCastle.Crypto.Engines
                 throw new ArgumentException("AAD cannot be added after reading a full block(" + GetBlockSize() +
                     " bytes) of input for " + (forEncryption ? "encryption" : "decryption"));
             }
-            aadData.Write(new byte[] { input }, 0, 1);
-        }
 
+            aadData.WriteByte(input);
+        }
 
         public void ProcessAadBytes(byte[] input, int inOff, int len)
         {
@@ -100,17 +99,15 @@ namespace Org.BouncyCastle.Crypto.Engines
                 throw new ArgumentException("AAD cannot be added after reading a full block(" + GetBlockSize() +
                     " bytes) of input for " + (forEncryption ? "encryption" : "decryption"));
             }
-            if ((inOff + len) > input.Length)
-            {
-                throw new DataLengthException("input buffer too short");
-            }
+
+            Check.DataLength(input, inOff, len, "input buffer too short");
+
             aadData.Write(input, inOff, len);
         }
 
-
-        public int ProcessByte(byte input, byte[] output, int outOff)
+        public int ProcessByte(byte input, byte[] outBytes, int outOff)
         {
-            return ProcessBytes(new byte[] { input }, 0, 1, output, outOff);
+            return ProcessBytes(new byte[]{ input }, 0, 1, outBytes, outOff);
         }
 
         private void processAAD()
@@ -123,7 +120,7 @@ namespace Org.BouncyCastle.Crypto.Engines
             }
         }
 
-        public int ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff)
+        public int ProcessBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int outOff)
         {
             if (!initialised)
                 throw new ArgumentException("Need to call Init before encryption/decryption");
@@ -131,17 +128,17 @@ namespace Org.BouncyCastle.Crypto.Engines
             if (mode != MODE.ModeKeyed)
                 throw new ArgumentException("Xoodyak has not been initialised");
 
-            Check.DataLength(input, inOff, len, "input buffer too short");
+            Check.DataLength(inBytes, inOff, len, "input buffer too short");
 
-            message.Write(input, inOff, len);
+            message.Write(inBytes, inOff, len);
             int blockLen = (int)message.Length - (forEncryption ? 0 : TAGLEN);
             if (blockLen >= GetBlockSize())
             {
                 byte[] blocks = message.GetBuffer();
                 len = blockLen / GetBlockSize() * GetBlockSize();
-                Check.OutputLength(output, outOff, len, "output buffer is too short");
+                Check.OutputLength(outBytes, outOff, len, "output buffer is too short");
                 processAAD();
-                encrypt(blocks, 0, len, output, outOff);
+                encrypt(blocks, 0, len, outBytes, outOff);
                 int messageLen = (int)message.Length;
                 message.SetLength(0);
                 message.Write(blocks, len, messageLen - len);
@@ -186,15 +183,15 @@ namespace Org.BouncyCastle.Crypto.Engines
         }
 
 
-        public int DoFinal(byte[] output, int outOff)
+        public int DoFinal(byte[] outBytes, int outOff)
         {
             if (!initialised)
                 throw new ArgumentException("Need to call Init before encryption/decryption");
 
             byte[] blocks = message.GetBuffer();
             int len = (int)message.Length;
-            if ((forEncryption && len + TAGLEN + outOff > output.Length) ||
-                (!forEncryption && len - TAGLEN + outOff > output.Length))
+            if ((forEncryption && len + TAGLEN + outOff > outBytes.Length) ||
+                (!forEncryption && len - TAGLEN + outOff > outBytes.Length))
             {
                 throw new OutputLengthException("output buffer too short");
             }
@@ -202,18 +199,18 @@ namespace Org.BouncyCastle.Crypto.Engines
             int rv = 0;
             if (forEncryption)
             {
-                encrypt(blocks, 0, len, output, outOff);
+                encrypt(blocks, 0, len, outBytes, outOff);
                 outOff += len;
                 tag = new byte[TAGLEN];
                 Up(tag, TAGLEN, 0x40);
-                Array.Copy(tag, 0, output, outOff, TAGLEN);
+                Array.Copy(tag, 0, outBytes, outOff, TAGLEN);
                 rv = len + TAGLEN;
             }
             else
             {
                 int inOff = len - TAGLEN;
                 rv = inOff;
-                encrypt(blocks, 0, inOff, output, outOff);
+                encrypt(blocks, 0, inOff, outBytes, outOff);
                 tag = new byte[TAGLEN];
                 Up(tag, TAGLEN, 0x40);
 
@@ -231,11 +228,13 @@ namespace Org.BouncyCastle.Crypto.Engines
 
         public int GetUpdateOutputSize(int len)
         {
+            // TODO
             return len;
         }
 
         public int GetOutputSize(int len)
         {
+            // TODO
             return len + TAGLEN;
         }
 
@@ -427,8 +426,6 @@ namespace Org.BouncyCastle.Crypto.Engines
             rv.AsSpan(0, len).CopyTo(output);
             return rv.Length;
         }
-
 #endif
-
     }
-}
\ No newline at end of file
+}