private void Encrypt16(byte[] Input, int InOffset, byte[] Output, int OutOffset) { int LRD = _expKey.Length - 1; int keyCtr = 0; UInt32 X0 = IntUtils.BytesToLe32(Input, InOffset) ^ _expKey[keyCtr]; UInt32 X1 = IntUtils.BytesToLe32(Input, InOffset + 4) ^ _expKey[++keyCtr]; UInt32 X2 = IntUtils.BytesToLe32(Input, InOffset + 8) ^ _expKey[++keyCtr]; UInt32 X3 = IntUtils.BytesToLe32(Input, InOffset + 12) ^ _expKey[++keyCtr]; UInt32 T0, T1; keyCtr = 7; do { T0 = Fe0(X0); T1 = Fe3(X1); X2 ^= T0 + T1 + _expKey[++keyCtr]; X2 = (X2 >> 1) | X2 << 31; X3 = (X3 << 1 | (X3 >> 31)) ^ (T0 + 2 * T1 + _expKey[++keyCtr]); T0 = Fe0(X2); T1 = Fe3(X3); X0 ^= T0 + T1 + _expKey[++keyCtr]; X0 = (X0 >> 1) | X0 << 31; X1 = (X1 << 1 | (X1 >> 31)) ^ (T0 + 2 * T1 + _expKey[++keyCtr]); } while (keyCtr != LRD); keyCtr = 4; IntUtils.Le32ToBytes(X2 ^ _expKey[keyCtr], Output, OutOffset); IntUtils.Le32ToBytes(X3 ^ _expKey[++keyCtr], Output, OutOffset + 4); IntUtils.Le32ToBytes(X0 ^ _expKey[++keyCtr], Output, OutOffset + 8); IntUtils.Le32ToBytes(X1 ^ _expKey[++keyCtr], Output, OutOffset + 12); }
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 UInt32[] ExpandKey(byte[] Key) { int k64Cnt = Key.Length / 8; int kmLen = k64Cnt > 4 ? 8 : 4; int keyCtr = 0; UInt32 A, B, Q; UInt32 Y0, Y1, Y2, Y3; UInt32[] eKm = new UInt32[kmLen]; UInt32[] oKm = new UInt32[kmLen]; byte[] sbKey = new byte[Key.Length == 64 ? 32 : 16]; UInt32[] wK = new UInt32[_dfnRounds * 2 + 8]; for (int i = 0; i < k64Cnt; i++) { // round key material eKm[i] = IntUtils.BytesToLe32(Key, keyCtr); keyCtr += 4; oKm[i] = IntUtils.BytesToLe32(Key, keyCtr); keyCtr += 4; // sbox key material IntUtils.Le32ToBytes(MDSEncode(eKm[i], oKm[i]), sbKey, ((k64Cnt * 4) - 4) - (i * 4)); } keyCtr = 0; while (keyCtr < KEY_BITS) { // create the expanded key if (keyCtr < (wK.Length / 2)) { Q = (uint)keyCtr * SK_STEP; A = Mix(Q, eKm, k64Cnt); B = Mix(Q + SK_BUMP, oKm, k64Cnt); B = B << 8 | (UInt32)(B >> 24); A += B; wK[keyCtr * 2] = A; A += B; wK[keyCtr * 2 + 1] = A << SK_ROTL | (UInt32)(A >> (32 - SK_ROTL)); } Y0 = Y1 = Y2 = Y3 = (uint)keyCtr; // 512 key if (Key.Length == 64) { Y0 = (uint)(byte)Q1[Y0] ^ sbKey[28]; Y1 = (uint)(byte)Q0[Y1] ^ sbKey[29]; Y2 = (uint)(byte)Q0[Y2] ^ sbKey[30]; Y3 = (uint)(byte)Q1[Y3] ^ sbKey[31]; Y0 = (uint)(byte)Q1[Y0] ^ sbKey[24]; Y1 = (uint)(byte)Q1[Y1] ^ sbKey[25]; Y2 = (uint)(byte)Q0[Y2] ^ sbKey[26]; Y3 = (uint)(byte)Q0[Y3] ^ sbKey[27]; Y0 = (uint)(byte)Q0[Y0] ^ sbKey[20]; Y1 = (uint)(byte)Q1[Y1] ^ sbKey[21]; Y2 = (uint)(byte)Q1[Y2] ^ sbKey[22]; Y3 = (uint)(byte)Q0[Y3] ^ sbKey[23]; Y0 = (uint)(byte)Q0[Y0] ^ sbKey[16]; Y1 = (uint)(byte)Q0[Y1] ^ sbKey[17]; Y2 = (uint)(byte)Q1[Y2] ^ sbKey[18]; Y3 = (uint)(byte)Q1[Y3] ^ sbKey[19]; } // 256 key if (Key.Length > 24) { Y0 = (uint)(byte)Q1[Y0] ^ sbKey[12]; Y1 = (uint)(byte)Q0[Y1] ^ sbKey[13]; Y2 = (uint)(byte)Q0[Y2] ^ sbKey[14]; Y3 = (uint)(byte)Q1[Y3] ^ sbKey[15]; } // 192 key if (Key.Length > 16) { Y0 = (uint)(byte)Q1[Y0] ^ sbKey[8]; Y1 = (uint)(byte)Q1[Y1] ^ sbKey[9]; Y2 = (uint)(byte)Q0[Y2] ^ sbKey[10]; Y3 = (uint)(byte)Q0[Y3] ^ sbKey[11]; } // sbox members as MDS matrix multiplies _sprBox[keyCtr * 2] = MDS0[(byte)Q0[(byte)Q0[Y0] ^ sbKey[4]] ^ sbKey[0]]; _sprBox[keyCtr * 2 + 1] = MDS1[(byte)Q0[Q1[Y1] ^ sbKey[5]] ^ sbKey[1]]; _sprBox[(keyCtr * 2) + 0x200] = MDS2[(byte)Q1[(byte)Q0[Y2] ^ sbKey[6]] ^ sbKey[2]]; _sprBox[keyCtr++ *2 + 0x201] = MDS3[(byte)Q1[(byte)Q1[Y3] ^ sbKey[7]] ^ sbKey[3]]; } // key processed _isInitialized = true; return(wK); }
private void Encrypt16(byte[] Input, int InOffset, byte[] Output, int OutOffset) { int LRD = m_expKey.Length - 5; int keyCtr = -1; // input round uint R0 = IntUtils.BytesToLe32(Input, InOffset); uint R1 = IntUtils.BytesToLe32(Input, InOffset + 4); uint R2 = IntUtils.BytesToLe32(Input, InOffset + 8); uint R3 = IntUtils.BytesToLe32(Input, InOffset + 12); // process 8 round blocks do { R0 ^= m_expKey[++keyCtr]; R1 ^= m_expKey[++keyCtr]; R2 ^= m_expKey[++keyCtr]; R3 ^= m_expKey[++keyCtr]; Sb0(ref R0, ref R1, ref R2, ref R3); LinearTransform(ref R0, ref R1, ref R2, ref R3); R0 ^= m_expKey[++keyCtr]; R1 ^= m_expKey[++keyCtr]; R2 ^= m_expKey[++keyCtr]; R3 ^= m_expKey[++keyCtr]; Sb1(ref R0, ref R1, ref R2, ref R3); LinearTransform(ref R0, ref R1, ref R2, ref R3); R0 ^= m_expKey[++keyCtr]; R1 ^= m_expKey[++keyCtr]; R2 ^= m_expKey[++keyCtr]; R3 ^= m_expKey[++keyCtr]; Sb2(ref R0, ref R1, ref R2, ref R3); LinearTransform(ref R0, ref R1, ref R2, ref R3);; R0 ^= m_expKey[++keyCtr]; R1 ^= m_expKey[++keyCtr]; R2 ^= m_expKey[++keyCtr]; R3 ^= m_expKey[++keyCtr]; Sb3(ref R0, ref R1, ref R2, ref R3); LinearTransform(ref R0, ref R1, ref R2, ref R3); R0 ^= m_expKey[++keyCtr]; R1 ^= m_expKey[++keyCtr]; R2 ^= m_expKey[++keyCtr]; R3 ^= m_expKey[++keyCtr]; Sb4(ref R0, ref R1, ref R2, ref R3); LinearTransform(ref R0, ref R1, ref R2, ref R3); R0 ^= m_expKey[++keyCtr]; R1 ^= m_expKey[++keyCtr]; R2 ^= m_expKey[++keyCtr]; R3 ^= m_expKey[++keyCtr]; Sb5(ref R0, ref R1, ref R2, ref R3); LinearTransform(ref R0, ref R1, ref R2, ref R3); R0 ^= m_expKey[++keyCtr]; R1 ^= m_expKey[++keyCtr]; R2 ^= m_expKey[++keyCtr]; R3 ^= m_expKey[++keyCtr]; Sb6(ref R0, ref R1, ref R2, ref R3); LinearTransform(ref R0, ref R1, ref R2, ref R3); R0 ^= m_expKey[++keyCtr]; R1 ^= m_expKey[++keyCtr]; R2 ^= m_expKey[++keyCtr]; R3 ^= m_expKey[++keyCtr]; Sb7(ref R0, ref R1, ref R2, ref R3); // skip on last block if (keyCtr != LRD) { LinearTransform(ref R0, ref R1, ref R2, ref R3); } }while (keyCtr != LRD); // last round IntUtils.Le32ToBytes(m_expKey[++keyCtr] ^ R0, Output, OutOffset); IntUtils.Le32ToBytes(m_expKey[++keyCtr] ^ R1, Output, OutOffset + 4); IntUtils.Le32ToBytes(m_expKey[++keyCtr] ^ R2, Output, OutOffset + 8); IntUtils.Le32ToBytes(m_expKey[++keyCtr] ^ R3, Output, OutOffset + 12); }
private void Decrypt16(byte[] Input, int InOffset, byte[] Output, int OutOffset) { int LRD = 4; int keyCtr = m_expKey.Length; // input round uint R3 = m_expKey[--keyCtr] ^ IntUtils.BytesToLe32(Input, InOffset + 12); uint R2 = m_expKey[--keyCtr] ^ IntUtils.BytesToLe32(Input, InOffset + 8); uint R1 = m_expKey[--keyCtr] ^ IntUtils.BytesToLe32(Input, InOffset + 4); uint R0 = m_expKey[--keyCtr] ^ IntUtils.BytesToLe32(Input, InOffset); // process 8 round blocks do { Ib7(ref R0, ref R1, ref R2, ref R3); R3 ^= m_expKey[--keyCtr]; R2 ^= m_expKey[--keyCtr]; R1 ^= m_expKey[--keyCtr]; R0 ^= m_expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); Ib6(ref R0, ref R1, ref R2, ref R3); R3 ^= m_expKey[--keyCtr]; R2 ^= m_expKey[--keyCtr]; R1 ^= m_expKey[--keyCtr]; R0 ^= m_expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); Ib5(ref R0, ref R1, ref R2, ref R3); R3 ^= m_expKey[--keyCtr]; R2 ^= m_expKey[--keyCtr]; R1 ^= m_expKey[--keyCtr]; R0 ^= m_expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); Ib4(ref R0, ref R1, ref R2, ref R3); R3 ^= m_expKey[--keyCtr]; R2 ^= m_expKey[--keyCtr]; R1 ^= m_expKey[--keyCtr]; R0 ^= m_expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); Ib3(ref R0, ref R1, ref R2, ref R3); R3 ^= m_expKey[--keyCtr]; R2 ^= m_expKey[--keyCtr]; R1 ^= m_expKey[--keyCtr]; R0 ^= m_expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); Ib2(ref R0, ref R1, ref R2, ref R3); R3 ^= m_expKey[--keyCtr]; R2 ^= m_expKey[--keyCtr]; R1 ^= m_expKey[--keyCtr]; R0 ^= m_expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); Ib1(ref R0, ref R1, ref R2, ref R3); R3 ^= m_expKey[--keyCtr]; R2 ^= m_expKey[--keyCtr]; R1 ^= m_expKey[--keyCtr]; R0 ^= m_expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); Ib0(ref R0, ref R1, ref R2, ref R3); // skip on last block if (keyCtr != LRD) { R3 ^= m_expKey[--keyCtr]; R2 ^= m_expKey[--keyCtr]; R1 ^= m_expKey[--keyCtr]; R0 ^= m_expKey[--keyCtr]; InverseTransform(ref R0, ref R1, ref R2, ref R3); } }while (keyCtr != LRD); // last round IntUtils.Le32ToBytes(R3 ^ m_expKey[--keyCtr], Output, OutOffset + 12); IntUtils.Le32ToBytes(R2 ^ m_expKey[--keyCtr], Output, OutOffset + 8); IntUtils.Le32ToBytes(R1 ^ m_expKey[--keyCtr], Output, OutOffset + 4); IntUtils.Le32ToBytes(R0 ^ m_expKey[--keyCtr], Output, OutOffset); }