<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.1" />

SparkleEngine

public sealed class SparkleEngine : IAeadCipher
Sparkle v1.2, based on the current round 3 submission, https://sparkle-lwc.github.io/ .
using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Utilities; using System; using System.Runtime.CompilerServices; namespace Org.BouncyCastle.Crypto.Engines { public sealed class SparkleEngine : IAeadCipher { public enum SparkleParameters { SCHWAEMM128_128, SCHWAEMM256_128, SCHWAEMM192_192, SCHWAEMM256_256 } private enum State { Uninitialized, EncInit, EncAad, EncData, EncFinal, DecInit, DecAad, DecData, DecFinal } private static readonly uint[] RCON = new uint[8] { 3084996962, 3211876480, 951376470, 844003128, 3138487787, 1333558103, 3485442504, 3266521405 }; private string algorithmName; private readonly uint[] state; private readonly uint[] k; private readonly uint[] npub; private byte[] tag; private bool encrypted; private State m_state; private byte[] initialAssociatedText; private readonly int m_bufferSizeDecrypt; private readonly byte[] m_buf; private int m_bufPos; private readonly int SCHWAEMM_KEY_LEN; private readonly int SCHWAEMM_NONCE_LEN; private readonly int SPARKLE_STEPS_SLIM; private readonly int SPARKLE_STEPS_BIG; private readonly int KEY_BYTES; private readonly int KEY_WORDS; private readonly int TAG_WORDS; private readonly int TAG_BYTES; private readonly int STATE_WORDS; private readonly int RATE_WORDS; private readonly int RATE_BYTES; private readonly int CAP_MASK; private readonly uint _A0; private readonly uint _A1; private readonly uint _M2; private readonly uint _M3; public string AlgorithmName => algorithmName; public SparkleEngine(SparkleParameters sparkleParameters) { int num; int num2; int num3; switch (sparkleParameters) { case SparkleParameters.SCHWAEMM128_128: SCHWAEMM_KEY_LEN = 128; SCHWAEMM_NONCE_LEN = 128; num = 128; num2 = 256; num3 = 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; num = 128; num2 = 384; num3 = 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; num = 192; num2 = 384; num3 = 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; num = 256; num2 = 512; num3 = 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; TAG_WORDS = num >> 5; TAG_BYTES = num >> 3; STATE_WORDS = num2 >> 5; RATE_WORDS = SCHWAEMM_NONCE_LEN >> 5; RATE_BYTES = SCHWAEMM_NONCE_LEN >> 3; int num4 = num3 >> 6; int num5 = num3 >> 5; CAP_MASK = ((RATE_WORDS > num5) ? (num5 - 1) : (-1)); _A0 = (uint)(1 << num4 << 24); _A1 = (uint)((1 ^ (1 << num4)) << 24); _M2 = (uint)((2 ^ (1 << num4)) << 24); _M3 = (uint)((3 ^ (1 << num4)) << 24); state = new uint[STATE_WORDS]; k = new uint[KEY_WORDS]; npub = new uint[RATE_WORDS]; m_bufferSizeDecrypt = RATE_BYTES + TAG_BYTES; m_buf = new byte[m_bufferSizeDecrypt]; } public int GetKeyBytesSize() { return KEY_BYTES; } public int GetIVBytesSize() { return RATE_BYTES; } public void Init(bool forEncryption, ICipherParameters parameters) { AeadParameters aeadParameters = parameters as AeadParameters; KeyParameter keyParameter; byte[] array; if (aeadParameters != null) { keyParameter = aeadParameters.Key; array = aeadParameters.GetNonce(); initialAssociatedText = aeadParameters.GetAssociatedText(); int macSize = aeadParameters.MacSize; if (macSize != TAG_BYTES * 8) throw new ArgumentException("Invalid value for MAC size: " + macSize.ToString()); } else { ParametersWithIV parametersWithIV = parameters as ParametersWithIV; if (parametersWithIV == null) throw new ArgumentException("invalid parameters passed to Sparkle"); keyParameter = (parametersWithIV.Parameters as KeyParameter); array = parametersWithIV.GetIV(); initialAssociatedText = null; } if (keyParameter == null) throw new ArgumentException("Sparkle Init parameters must include a key"); int num = KEY_WORDS * 4; if (num != keyParameter.KeyLength) throw new ArgumentException(algorithmName + " requires exactly " + num.ToString() + " bytes of key"); int num2 = RATE_WORDS * 4; if (num2 != array.Length) throw new ArgumentException(algorithmName + " requires exactly " + num2.ToString() + " bytes of IV"); Pack.LE_To_UInt32(keyParameter.GetKey(), 0, k); Pack.LE_To_UInt32(array, 0, npub); m_state = (forEncryption ? State.EncInit : State.DecInit); Reset(); } public void ProcessAadByte(byte input) { CheckAad(); if (m_bufPos == RATE_BYTES) { ProcessBufferAad(m_buf, 0); m_bufPos = 0; } m_buf[m_bufPos++] = input; } public void ProcessAadBytes(byte[] inBytes, int inOff, int len) { Check.DataLength(inBytes, inOff, len, "input buffer too short"); if (len > 0) { CheckAad(); if (m_bufPos > 0) { int num = RATE_BYTES - m_bufPos; if (len <= num) { Array.Copy(inBytes, inOff, m_buf, m_bufPos, len); m_bufPos += len; return; } Array.Copy(inBytes, inOff, m_buf, m_bufPos, num); inOff += num; len -= num; ProcessBufferAad(m_buf, 0); } while (len > RATE_BYTES) { ProcessBufferAad(inBytes, inOff); inOff += RATE_BYTES; len -= RATE_BYTES; } Array.Copy(inBytes, inOff, m_buf, 0, len); m_bufPos = len; } } public int ProcessByte(byte input, byte[] outBytes, int outOff) { return ProcessBytes(new byte[1] { input }, 0, 1, outBytes, outOff); } public int ProcessBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int outOff) { Check.DataLength(inBytes, inOff, len, "input buffer too short"); bool num = CheckData(); int num2 = 0; if (num) { if (m_bufPos > 0) { int num3 = RATE_BYTES - m_bufPos; if (len <= num3) { Array.Copy(inBytes, inOff, m_buf, m_bufPos, len); m_bufPos += len; return 0; } Array.Copy(inBytes, inOff, m_buf, m_bufPos, num3); inOff += num3; len -= num3; ProcessBufferEncrypt(m_buf, 0, outBytes, outOff); num2 = RATE_BYTES; } while (len > RATE_BYTES) { ProcessBufferEncrypt(inBytes, inOff, outBytes, outOff + num2); inOff += RATE_BYTES; len -= RATE_BYTES; num2 += RATE_BYTES; } } else { int num4 = m_bufferSizeDecrypt - m_bufPos; if (len <= num4) { Array.Copy(inBytes, inOff, m_buf, m_bufPos, len); m_bufPos += len; return 0; } if (m_bufPos > RATE_BYTES) { ProcessBufferDecrypt(m_buf, 0, outBytes, outOff); m_bufPos -= RATE_BYTES; Array.Copy(m_buf, RATE_BYTES, m_buf, 0, m_bufPos); num2 = RATE_BYTES; num4 += RATE_BYTES; if (len <= num4) { Array.Copy(inBytes, inOff, m_buf, m_bufPos, len); m_bufPos += len; return num2; } } num4 = RATE_BYTES - m_bufPos; Array.Copy(inBytes, inOff, m_buf, m_bufPos, num4); inOff += num4; len -= num4; ProcessBufferDecrypt(m_buf, 0, outBytes, outOff + num2); num2 += RATE_BYTES; while (len > m_bufferSizeDecrypt) { ProcessBufferDecrypt(inBytes, inOff, outBytes, outOff + num2); inOff += RATE_BYTES; len -= RATE_BYTES; num2 += RATE_BYTES; } } Array.Copy(inBytes, inOff, m_buf, 0, len); m_bufPos = len; return num2; } public int DoFinal(byte[] outBytes, int outOff) { bool flag = CheckData(); int num; if (flag) num = m_bufPos + TAG_BYTES; else { if (m_bufPos < TAG_BYTES) throw new InvalidCipherTextException("data too short"); m_bufPos -= TAG_BYTES; num = m_bufPos; } Check.OutputLength(outBytes, outOff, num, "output buffer too short"); if (encrypted || m_bufPos > 0) { state[STATE_WORDS - 1] ^= ((m_bufPos < RATE_BYTES) ? _M2 : _M3); uint[] array = new uint[RATE_WORDS]; for (int i = 0; i < m_bufPos; i++) { array[i >> 2] |= (uint)(m_buf[i] << ((i & 3) << 3)); } if (m_bufPos < RATE_BYTES) { if (!flag) { int num2 = (m_bufPos & 3) << 3; array[m_bufPos >> 2] |= state[m_bufPos >> 2] >> num2 << num2; num2 = (m_bufPos >> 2) + 1; Array.Copy(state, num2, array, num2, RATE_WORDS - num2); } array[m_bufPos >> 2] ^= (uint)(128 << ((m_bufPos & 3) << 3)); } for (int j = 0; j < RATE_WORDS / 2; j++) { int num3 = j + RATE_WORDS / 2; uint num4 = state[j]; uint num5 = state[num3]; if (flag) { state[j] = (num5 ^ array[j] ^ state[RATE_WORDS + j]); state[num3] = (num4 ^ num5 ^ array[num3] ^ state[RATE_WORDS + (num3 & CAP_MASK)]); } else { state[j] = (num4 ^ num5 ^ array[j] ^ state[RATE_WORDS + j]); state[num3] = (num4 ^ array[num3] ^ state[RATE_WORDS + (num3 & CAP_MASK)]); } array[j] ^= num4; array[num3] ^= num5; } for (int k = 0; k < m_bufPos; k++) { outBytes[outOff++] = (byte)(array[k >> 2] >> ((k & 3) << 3)); } SparkleOpt(state, SPARKLE_STEPS_BIG); } for (int l = 0; l < KEY_WORDS; l++) { state[RATE_WORDS + l] ^= this.k[l]; } tag = new byte[TAG_BYTES]; Pack.UInt32_To_LE(state, RATE_WORDS, TAG_WORDS, tag, 0); if (flag) Array.Copy(tag, 0, outBytes, outOff, TAG_BYTES); else if (!Arrays.FixedTimeEquals(TAG_BYTES, tag, 0, m_buf, m_bufPos)) { throw new InvalidCipherTextException("mac check in " + AlgorithmName + " failed"); } Reset(!flag); return num; } public byte[] GetMac() { return tag; } public int GetUpdateOutputSize(int len) { int num = System.Math.Max(0, len) - 1; switch (m_state) { case State.DecInit: case State.DecAad: num = System.Math.Max(0, num - TAG_BYTES); break; case State.DecData: case State.DecFinal: num = System.Math.Max(0, num + m_bufPos - TAG_BYTES); break; case State.EncData: case State.EncFinal: num = System.Math.Max(0, num + m_bufPos); break; } return num - num % RATE_BYTES; } public int GetOutputSize(int len) { int num = System.Math.Max(0, len); switch (m_state) { case State.DecInit: case State.DecAad: return System.Math.Max(0, num - TAG_BYTES); case State.DecData: case State.DecFinal: return System.Math.Max(0, num + m_bufPos - TAG_BYTES); case State.EncData: case State.EncFinal: return num + m_bufPos + TAG_BYTES; default: return num + TAG_BYTES; } } public void Reset() { Reset(true); } private void CheckAad() { switch (m_state) { case State.EncAad: case State.DecAad: break; case State.DecInit: m_state = State.DecAad; break; case State.EncInit: m_state = State.EncAad; break; case State.EncFinal: throw new InvalidOperationException(AlgorithmName + " cannot be reused for encryption"); default: throw new InvalidOperationException(AlgorithmName + " needs to be initialized"); } } private bool CheckData() { switch (m_state) { case State.DecInit: case State.DecAad: FinishAad(State.DecData); return false; case State.EncInit: case State.EncAad: FinishAad(State.EncData); return true; case State.DecData: return false; case State.EncData: return true; case State.EncFinal: throw new InvalidOperationException(AlgorithmName + " cannot be reused for encryption"); default: throw new InvalidOperationException(AlgorithmName + " needs to be initialized"); } } private void FinishAad(State nextState) { State state = m_state; if (state == State.EncAad || state == State.DecAad) ProcessFinalAad(); m_bufPos = 0; m_state = nextState; } private void ProcessBufferAad(byte[] buffer, int bufOff) { for (int i = 0; i < RATE_WORDS / 2; i++) { int num = i + RATE_WORDS / 2; uint num2 = state[i]; uint num3 = state[num]; uint num4 = Pack.LE_To_UInt32(buffer, bufOff + i * 4); uint num5 = Pack.LE_To_UInt32(buffer, bufOff + num * 4); state[i] = (num3 ^ num4 ^ state[RATE_WORDS + i]); state[num] = (num2 ^ num3 ^ num5 ^ state[RATE_WORDS + (num & CAP_MASK)]); } SparkleOpt(state, SPARKLE_STEPS_SLIM); } private void ProcessBufferDecrypt(byte[] buffer, int bufOff, byte[] output, int outOff) { Check.OutputLength(output, outOff, RATE_BYTES, "output buffer too short"); for (int i = 0; i < RATE_WORDS / 2; i++) { int num = i + RATE_WORDS / 2; uint num2 = state[i]; uint num3 = state[num]; uint num4 = Pack.LE_To_UInt32(buffer, bufOff + i * 4); uint num5 = Pack.LE_To_UInt32(buffer, bufOff + num * 4); state[i] = (num2 ^ num3 ^ num4 ^ state[RATE_WORDS + i]); state[num] = (num2 ^ num5 ^ state[RATE_WORDS + (num & CAP_MASK)]); Pack.UInt32_To_LE(num4 ^ num2, output, outOff + i * 4); Pack.UInt32_To_LE(num5 ^ num3, output, outOff + num * 4); } SparkleOpt(state, SPARKLE_STEPS_SLIM); encrypted = true; } private void ProcessBufferEncrypt(byte[] buffer, int bufOff, byte[] output, int outOff) { Check.OutputLength(output, outOff, RATE_BYTES, "output buffer too short"); for (int i = 0; i < RATE_WORDS / 2; i++) { int num = i + RATE_WORDS / 2; uint num2 = state[i]; uint num3 = state[num]; uint num4 = Pack.LE_To_UInt32(buffer, bufOff + i * 4); uint num5 = Pack.LE_To_UInt32(buffer, bufOff + num * 4); state[i] = (num3 ^ num4 ^ state[RATE_WORDS + i]); state[num] = (num2 ^ num3 ^ num5 ^ state[RATE_WORDS + (num & CAP_MASK)]); Pack.UInt32_To_LE(num4 ^ num2, output, outOff + i * 4); Pack.UInt32_To_LE(num5 ^ num3, output, outOff + num * 4); } SparkleOpt(state, SPARKLE_STEPS_SLIM); encrypted = true; } private void ProcessFinalAad() { if (m_bufPos < RATE_BYTES) { state[STATE_WORDS - 1] ^= _A0; m_buf[m_bufPos] = 128; while (++m_bufPos < RATE_BYTES) { m_buf[m_bufPos] = 0; } } else state[STATE_WORDS - 1] ^= _A1; for (int i = 0; i < RATE_WORDS / 2; i++) { int num = i + RATE_WORDS / 2; uint num2 = state[i]; uint num3 = state[num]; uint num4 = Pack.LE_To_UInt32(m_buf, i * 4); uint num5 = Pack.LE_To_UInt32(m_buf, num * 4); state[i] = (num3 ^ num4 ^ state[RATE_WORDS + i]); state[num] = (num2 ^ num3 ^ num5 ^ state[RATE_WORDS + (num & CAP_MASK)]); } SparkleOpt(state, SPARKLE_STEPS_BIG); } private void Reset(bool clearMac) { if (clearMac) tag = null; Arrays.Clear(m_buf); m_bufPos = 0; encrypted = false; switch (m_state) { case State.DecAad: case State.DecData: case State.DecFinal: m_state = State.DecInit; break; case State.EncAad: case State.EncData: case State.EncFinal: m_state = State.EncFinal; return; default: throw new InvalidOperationException(AlgorithmName + " needs to be initialized"); case State.EncInit: case State.DecInit: break; } Array.Copy(npub, 0, state, 0, RATE_WORDS); Array.Copy(k, 0, state, RATE_WORDS, KEY_WORDS); SparkleOpt(state, SPARKLE_STEPS_BIG); if (initialAssociatedText != null) ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void ArxBox(uint rc, ref uint s00, ref uint s01) { s00 += Integers.RotateRight(s01, 31); s01 ^= Integers.RotateRight(s00, 24); s00 ^= rc; s00 += Integers.RotateRight(s01, 17); s01 ^= Integers.RotateRight(s00, 17); s00 ^= rc; s00 += s01; s01 ^= Integers.RotateRight(s00, 31); s00 ^= rc; s00 += Integers.RotateRight(s01, 24); s01 ^= Integers.RotateRight(s00, 16); s00 ^= rc; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static uint ELL(uint x) { return Integers.RotateRight(x, 16) ^ (x & 65535); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void SparkleOpt(uint[] state, int steps) { switch (state.LongLength) { case 8: SparkleOpt8(state, steps); break; case 12: SparkleOpt12(state, steps); break; case 16: SparkleOpt16(state, steps); break; default: throw new InvalidOperationException(); } } internal static void SparkleOpt8(uint[] state, int steps) { uint s = state[0]; uint s2 = state[1]; uint s3 = state[2]; uint s4 = state[3]; uint s5 = state[4]; uint s6 = state[5]; uint s7 = state[6]; uint s8 = state[7]; for (int i = 0; i < steps; i++) { s2 ^= RCON[i & 7]; s4 = (uint)((int)s4 ^ i); ArxBox(RCON[0], ref s, ref s2); ArxBox(RCON[1], ref s3, ref s4); ArxBox(RCON[2], ref s5, ref s6); ArxBox(RCON[3], ref s7, ref s8); uint num = ELL(s ^ s3); uint num2 = ELL(s2 ^ s4); uint num3 = s ^ s5; uint num4 = s2 ^ s6; uint num5 = s3 ^ s7; uint num6 = s4 ^ s8; s5 = s; s6 = s2; s7 = s3; s8 = s4; s = (num5 ^ num2); s2 = (num6 ^ num); s3 = (num3 ^ num2); s4 = (num4 ^ num); } state[0] = s; state[1] = s2; state[2] = s3; state[3] = s4; state[4] = s5; state[5] = s6; state[6] = s7; state[7] = s8; } internal static void SparkleOpt12(uint[] state, int steps) { uint s = state[0]; uint s2 = state[1]; uint s3 = state[2]; uint s4 = state[3]; uint s5 = state[4]; uint s6 = state[5]; uint s7 = state[6]; uint s8 = state[7]; uint s9 = state[8]; uint s10 = state[9]; uint s11 = state[10]; uint s12 = state[11]; for (int i = 0; i < steps; i++) { s2 ^= RCON[i & 7]; s4 = (uint)((int)s4 ^ i); ArxBox(RCON[0], ref s, ref s2); ArxBox(RCON[1], ref s3, ref s4); ArxBox(RCON[2], ref s5, ref s6); ArxBox(RCON[3], ref s7, ref s8); ArxBox(RCON[4], ref s9, ref s10); ArxBox(RCON[5], ref s11, ref s12); uint num = ELL(s ^ s3 ^ s5); uint num2 = ELL(s2 ^ s4 ^ s6); uint num3 = s ^ s7; uint num4 = s2 ^ s8; uint num5 = s3 ^ s9; uint num6 = s4 ^ s10; uint num7 = s5 ^ s11; uint num8 = s6 ^ s12; s7 = s; s8 = s2; s9 = s3; s10 = s4; s11 = s5; s12 = s6; s = (num5 ^ num2); s2 = (num6 ^ num); s3 = (num7 ^ num2); s4 = (num8 ^ num); s5 = (num3 ^ num2); s6 = (num4 ^ num); } state[0] = s; state[1] = s2; state[2] = s3; state[3] = s4; state[4] = s5; state[5] = s6; state[6] = s7; state[7] = s8; state[8] = s9; state[9] = s10; state[10] = s11; state[11] = s12; } internal static void SparkleOpt16(uint[] state, int steps) { uint s = state[0]; uint s2 = state[1]; uint s3 = state[2]; uint s4 = state[3]; uint s5 = state[4]; uint s6 = state[5]; uint s7 = state[6]; uint s8 = state[7]; uint s9 = state[8]; uint s10 = state[9]; uint s11 = state[10]; uint s12 = state[11]; uint s13 = state[12]; uint s14 = state[13]; uint s15 = state[14]; uint s16 = state[15]; int num = 0; while (num < steps) { s2 ^= RCON[num & 7]; s4 = (uint)((int)s4 ^ num++); ArxBox(RCON[0], ref s, ref s2); ArxBox(RCON[1], ref s3, ref s4); ArxBox(RCON[2], ref s5, ref s6); ArxBox(RCON[3], ref s7, ref s8); ArxBox(RCON[4], ref s9, ref s10); ArxBox(RCON[5], ref s11, ref s12); ArxBox(RCON[6], ref s13, ref s14); ArxBox(RCON[7], ref s15, ref s16); uint num3 = ELL(s ^ s3 ^ s5 ^ s7); uint num4 = ELL(s2 ^ s4 ^ s6 ^ s8); uint num5 = s9; uint num6 = s10; s9 = (s3 ^ s11 ^ num4); s10 = (s4 ^ s12 ^ num3); s11 = (s5 ^ s13 ^ num4); s12 = (s6 ^ s14 ^ num3); s13 = (s7 ^ s15 ^ num4); s14 = (s8 ^ s16 ^ num3); s15 = (s ^ num5 ^ num4); s16 = (s2 ^ num6 ^ num3); s10 ^= RCON[num & 7]; s12 = (uint)((int)s12 ^ num++); ArxBox(RCON[0], ref s9, ref s10); ArxBox(RCON[1], ref s11, ref s12); ArxBox(RCON[2], ref s13, ref s14); ArxBox(RCON[3], ref s15, ref s16); ArxBox(RCON[4], ref s, ref s2); ArxBox(RCON[5], ref s3, ref s4); ArxBox(RCON[6], ref s5, ref s6); ArxBox(RCON[7], ref s7, ref s8); uint num8 = ELL(s9 ^ s11 ^ s13 ^ s15); uint num9 = ELL(s10 ^ s12 ^ s14 ^ s16); uint num10 = s; uint num11 = s2; s = (s3 ^ s11 ^ num9); s2 = (s4 ^ s12 ^ num8); s3 = (s5 ^ s13 ^ num9); s4 = (s6 ^ s14 ^ num8); s5 = (s7 ^ s15 ^ num9); s6 = (s8 ^ s16 ^ num8); s7 = (num10 ^ s9 ^ num9); s8 = (num11 ^ s10 ^ num8); } state[0] = s; state[1] = s2; state[2] = s3; state[3] = s4; state[4] = s5; state[5] = s6; state[6] = s7; state[7] = s8; state[8] = s9; state[9] = s10; state[10] = s11; state[11] = s12; state[12] = s13; state[13] = s14; state[14] = s15; state[15] = s16; } } }