/// <remarks> /// Apply the linear transformation to the register set /// </remarks> private void LinearTransform(ref uint R0, ref uint R1, ref uint R2, ref uint R3) { uint x0 = IntUtils.RotateLeft(R0, 13); uint x2 = IntUtils.RotateLeft(R2, 3); uint x1 = R1 ^ x0 ^ x2; uint x3 = R3 ^ x2 ^ x0 << 3; R1 = IntUtils.RotateLeft(x1, 1); R3 = IntUtils.RotateLeft(x3, 7); R0 = IntUtils.RotateLeft(x0 ^ R1 ^ R3, 5); R2 = IntUtils.RotateLeft(x2 ^ R3 ^ (R1 << 7), 22); }
/// <remarks> /// Apply the linear transformation to the register set /// </remarks> private void LinearTransform(ref UInt32 R0, ref UInt32 R1, ref UInt32 R2, ref UInt32 R3) { UInt32 x0 = IntUtils.RotateLeft(R0, 13); UInt32 x2 = IntUtils.RotateLeft(R2, 3); UInt32 x1 = R1 ^ x0 ^ x2; UInt32 x3 = R3 ^ x2 ^ x0 << 3; R1 = IntUtils.RotateLeft(x1, 1); R3 = IntUtils.RotateLeft(x3, 7); R0 = IntUtils.RotateLeft(x0 ^ R1 ^ R3, 5); R2 = IntUtils.RotateLeft(x2 ^ R3 ^ (R1 << 7), 22); }
private void Transform(byte[] Output, int OutOffset, uint[] Counter) { int ctr = 0; uint X0 = m_wrkState[ctr]; uint X1 = m_wrkState[++ctr]; uint X2 = m_wrkState[++ctr]; uint X3 = m_wrkState[++ctr]; uint X4 = m_wrkState[++ctr]; uint X5 = m_wrkState[++ctr]; uint X6 = m_wrkState[++ctr]; uint X7 = m_wrkState[++ctr]; uint X8 = Counter[0]; uint X9 = Counter[1]; uint X10 = m_wrkState[++ctr]; uint X11 = m_wrkState[++ctr]; uint X12 = m_wrkState[++ctr]; uint X13 = m_wrkState[++ctr]; uint X14 = m_wrkState[++ctr]; uint X15 = m_wrkState[++ctr]; ctr = Rounds; while (ctr != 0) { X4 ^= IntUtils.RotateLeft(X0 + X12, 7); X8 ^= IntUtils.RotateLeft(X4 + X0, 9); X12 ^= IntUtils.RotateLeft(X8 + X4, 13); X0 ^= IntUtils.RotateLeft(X12 + X8, 18); X9 ^= IntUtils.RotateLeft(X5 + X1, 7); X13 ^= IntUtils.RotateLeft(X9 + X5, 9); X1 ^= IntUtils.RotateLeft(X13 + X9, 13); X5 ^= IntUtils.RotateLeft(X1 + X13, 18); X14 ^= IntUtils.RotateLeft(X10 + X6, 7); X2 ^= IntUtils.RotateLeft(X14 + X10, 9); X6 ^= IntUtils.RotateLeft(X2 + X14, 13); X10 ^= IntUtils.RotateLeft(X6 + X2, 18); X3 ^= IntUtils.RotateLeft(X15 + X11, 7); X7 ^= IntUtils.RotateLeft(X3 + X15, 9); X11 ^= IntUtils.RotateLeft(X7 + X3, 13); X15 ^= IntUtils.RotateLeft(X11 + X7, 18); X1 ^= IntUtils.RotateLeft(X0 + X3, 7); X2 ^= IntUtils.RotateLeft(X1 + X0, 9); X3 ^= IntUtils.RotateLeft(X2 + X1, 13); X0 ^= IntUtils.RotateLeft(X3 + X2, 18); X6 ^= IntUtils.RotateLeft(X5 + X4, 7); X7 ^= IntUtils.RotateLeft(X6 + X5, 9); X4 ^= IntUtils.RotateLeft(X7 + X6, 13); X5 ^= IntUtils.RotateLeft(X4 + X7, 18); X11 ^= IntUtils.RotateLeft(X10 + X9, 7); X8 ^= IntUtils.RotateLeft(X11 + X10, 9); X9 ^= IntUtils.RotateLeft(X8 + X11, 13); X10 ^= IntUtils.RotateLeft(X9 + X8, 18); X12 ^= IntUtils.RotateLeft(X15 + X14, 7); X13 ^= IntUtils.RotateLeft(X12 + X15, 9); X14 ^= IntUtils.RotateLeft(X13 + X12, 13); X15 ^= IntUtils.RotateLeft(X14 + X13, 18); ctr -= 2; } IntUtils.Le32ToBytes(X0 + m_wrkState[ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X1 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X2 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X3 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X4 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X5 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X6 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X7 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X8 + Counter[0], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X9 + Counter[1], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X10 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X11 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X12 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X13 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X14 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X15 + m_wrkState[++ctr], Output, OutOffset); }
private void Transform(byte[] Output, int OutOffset, uint[] Counter) { int ctr = 0; uint X0 = m_wrkState[ctr]; uint X1 = m_wrkState[++ctr]; uint X2 = m_wrkState[++ctr]; uint X3 = m_wrkState[++ctr]; uint X4 = m_wrkState[++ctr]; uint X5 = m_wrkState[++ctr]; uint X6 = m_wrkState[++ctr]; uint X7 = m_wrkState[++ctr]; uint X8 = m_wrkState[++ctr]; uint X9 = m_wrkState[++ctr]; uint X10 = m_wrkState[++ctr]; uint X11 = m_wrkState[++ctr]; uint X12 = Counter[0]; uint X13 = Counter[1]; uint X14 = m_wrkState[++ctr]; uint X15 = m_wrkState[++ctr]; ctr = Rounds; while (ctr != 0) { X0 += X4; X12 = IntUtils.RotateLeft(X12 ^ X0, 16); X8 += X12; X4 = IntUtils.RotateLeft(X4 ^ X8, 12); X0 += X4; X12 = IntUtils.RotateLeft(X12 ^ X0, 8); X8 += X12; X4 = IntUtils.RotateLeft(X4 ^ X8, 7); X1 += X5; X13 = IntUtils.RotateLeft(X13 ^ X1, 16); X9 += X13; X5 = IntUtils.RotateLeft(X5 ^ X9, 12); X1 += X5; X13 = IntUtils.RotateLeft(X13 ^ X1, 8); X9 += X13; X5 = IntUtils.RotateLeft(X5 ^ X9, 7); X2 += X6; X14 = IntUtils.RotateLeft(X14 ^ X2, 16); X10 += X14; X6 = IntUtils.RotateLeft(X6 ^ X10, 12); X2 += X6; X14 = IntUtils.RotateLeft(X14 ^ X2, 8); X10 += X14; X6 = IntUtils.RotateLeft(X6 ^ X10, 7); X3 += X7; X15 = IntUtils.RotateLeft(X15 ^ X3, 16); X11 += X15; X7 = IntUtils.RotateLeft(X7 ^ X11, 12); X3 += X7; X15 = IntUtils.RotateLeft(X15 ^ X3, 8); X11 += X15; X7 = IntUtils.RotateLeft(X7 ^ X11, 7); X0 += X5; X15 = IntUtils.RotateLeft(X15 ^ X0, 16); X10 += X15; X5 = IntUtils.RotateLeft(X5 ^ X10, 12); X0 += X5; X15 = IntUtils.RotateLeft(X15 ^ X0, 8); X10 += X15; X5 = IntUtils.RotateLeft(X5 ^ X10, 7); X1 += X6; X12 = IntUtils.RotateLeft(X12 ^ X1, 16); X11 += X12; X6 = IntUtils.RotateLeft(X6 ^ X11, 12); X1 += X6; X12 = IntUtils.RotateLeft(X12 ^ X1, 8); X11 += X12; X6 = IntUtils.RotateLeft(X6 ^ X11, 7); X2 += X7; X13 = IntUtils.RotateLeft(X13 ^ X2, 16); X8 += X13; X7 = IntUtils.RotateLeft(X7 ^ X8, 12); X2 += X7; X13 = IntUtils.RotateLeft(X13 ^ X2, 8); X8 += X13; X7 = IntUtils.RotateLeft(X7 ^ X8, 7); X3 += X4; X14 = IntUtils.RotateLeft(X14 ^ X3, 16); X9 += X14; X4 = IntUtils.RotateLeft(X4 ^ X9, 12); X3 += X4; X14 = IntUtils.RotateLeft(X14 ^ X3, 8); X9 += X14; X4 = IntUtils.RotateLeft(X4 ^ X9, 7); ctr -= 2; } IntUtils.Le32ToBytes(X0 + m_wrkState[ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X1 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X2 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X3 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X4 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X5 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X6 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X7 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X8 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X9 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X10 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X11 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X12 + Counter[0], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X13 + Counter[1], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X14 + m_wrkState[++ctr], Output, OutOffset); OutOffset += 4; IntUtils.Le32ToBytes(X15 + m_wrkState[++ctr], Output, OutOffset); }
private uint[] StandardExpand(byte[] Key) { int cnt = 0; int index = 0; int padSize = Key.Length < 32 ? 16 : Key.Length / 2; uint[] tmpKey = new uint[padSize]; int offset = 0; // CHANGE: 512 key gets 8 extra rounds m_rndCount = (Key.Length == 64) ? 40 : ROUNDS32; int keySize = 4 * (m_rndCount + 1); // step 1: reverse copy key to temp array for (offset = Key.Length; offset > 0; offset -= 4) { tmpKey[index++] = IntUtils.BytesToBe32(Key, offset - 4); } // pad small key if (index < 8) { tmpKey[index] = 1; } // initialize the key uint[] expKey = new uint[keySize]; if (padSize == 16) { // 32 byte key // step 2: rotate k into w(k) ints for (int i = 8; i < 16; i++) { tmpKey[i] = IntUtils.RotateLeft((uint)(tmpKey[i - 8] ^ tmpKey[i - 5] ^ tmpKey[i - 3] ^ tmpKey[i - 1] ^ PHI ^ (i - 8)), 11); } // copy to expanded key Array.Copy(tmpKey, 8, expKey, 0, 8); // step 3: calculate remainder of rounds with rotating primitive for (int i = 8; i < keySize; i++) { expKey[i] = IntUtils.RotateLeft((uint)(expKey[i - 8] ^ expKey[i - 5] ^ expKey[i - 3] ^ expKey[i - 1] ^ PHI ^ i), 11); } } else { // *extended*: 64 byte key // step 3: rotate k into w(k) ints, with extended polynominal // Wp := (Wp-16 ^ Wp-13 ^ Wp-11 ^ Wp-10 ^ Wp-8 ^ Wp-5 ^ Wp-3 ^ Wp-1 ^ PHI ^ i) <<< 11 for (int i = 16; i < 32; i++) { tmpKey[i] = IntUtils.RotateLeft((uint)(tmpKey[i - 16] ^ tmpKey[i - 13] ^ tmpKey[i - 11] ^ tmpKey[i - 10] ^ tmpKey[i - 8] ^ tmpKey[i - 5] ^ tmpKey[i - 3] ^ tmpKey[i - 1] ^ PHI ^ (i - 16)), 11); } // copy to expanded key Array.Copy(tmpKey, 16, expKey, 0, 16); // step 3: calculate remainder of rounds with rotating primitive for (int i = 16; i < keySize; i++) { expKey[i] = IntUtils.RotateLeft((uint)(expKey[i - 16] ^ expKey[i - 13] ^ expKey[i - 11] ^ expKey[i - 10] ^ expKey[i - 8] ^ expKey[i - 5] ^ expKey[i - 3] ^ expKey[i - 1] ^ PHI ^ i), 11); } } // step 4: create the working keys by processing with the Sbox and IP while (cnt < keySize - 4) { Sb3(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4; Sb2(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4; Sb1(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4; Sb0(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4; Sb7(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4; Sb6(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4; Sb5(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4; Sb4(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); cnt += 4; } // last round Sb3(ref expKey[cnt], ref expKey[cnt + 1], ref expKey[cnt + 2], ref expKey[cnt + 3]); return(expKey); }
private UInt32[] ExpandKey(byte[] Key) { int cnt = 0; int index = 0; int padSize = Key.Length < 32 ? 16 : Key.Length / 2; UInt32[] Wp = new UInt32[padSize]; int offset = 0; // less than 512 is default rounds if (Key.Length < 64) { _dfnRounds = ROUNDS32; } int keySize = 4 * (_dfnRounds + 1); // step 1: reverse copy key to temp array for (offset = Key.Length; offset > 0; offset -= 4) { Wp[index++] = IntUtils.BytesToBe32(Key, offset - 4); } // pad small key if (index < 8) { Wp[index] = 1; } // initialize the key UInt32[] Wk = new UInt32[keySize]; if (padSize == 16) { // 32 byte key // step 2: rotate k into w(k) ints for (int i = 8; i < 16; i++) { Wp[i] = IntUtils.RotateLeft((UInt32)(Wp[i - 8] ^ Wp[i - 5] ^ Wp[i - 3] ^ Wp[i - 1] ^ PHI ^ (i - 8)), 11); } // copy to expanded key Array.Copy(Wp, 8, Wk, 0, 8); // step 3: calculate remainder of rounds with rotating primitive for (int i = 8; i < keySize; i++) { Wk[i] = IntUtils.RotateLeft((UInt32)(Wk[i - 8] ^ Wk[i - 5] ^ Wk[i - 3] ^ Wk[i - 1] ^ PHI ^ i), 11); } } else { // *extended*: 64 byte key // step 3: rotate k into w(k) ints, with extended polynominal // Wp := (Wp-16 ^ Wp-13 ^ Wp-11 ^ Wp-10 ^ Wp-8 ^ Wp-5 ^ Wp-3 ^ Wp-1 ^ PHI ^ i) <<< 11 for (int i = 16; i < 32; i++) { Wp[i] = IntUtils.RotateLeft((UInt32)(Wp[i - 16] ^ Wp[i - 13] ^ Wp[i - 11] ^ Wp[i - 10] ^ Wp[i - 8] ^ Wp[i - 5] ^ Wp[i - 3] ^ Wp[i - 1] ^ PHI ^ (i - 16)), 11); } // copy to expanded key Array.Copy(Wp, 16, Wk, 0, 16); // step 3: calculate remainder of rounds with rotating primitive for (int i = 16; i < keySize; i++) { Wk[i] = IntUtils.RotateLeft((UInt32)(Wk[i - 16] ^ Wk[i - 13] ^ Wk[i - 11] ^ Wk[i - 10] ^ Wk[i - 8] ^ Wk[i - 5] ^ Wk[i - 3] ^ Wk[i - 1] ^ PHI ^ i), 11); } } // step 4: create the working keys by processing with the Sbox and IP while (cnt < keySize - 4) { Sb3(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4; Sb2(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4; Sb1(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4; Sb0(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4; Sb7(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4; Sb6(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4; Sb5(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4; Sb4(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); cnt += 4; } // last round Sb3(ref Wk[cnt], ref Wk[cnt + 1], ref Wk[cnt + 2], ref Wk[cnt + 3]); return(Wk); }