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 SetKey(byte[] Key, byte[] Iv) { if (Key != null) { if (Key.Length == 32) { m_wrkState[0] = IntUtils.BytesToLe32(m_dstCode, 0); m_wrkState[1] = IntUtils.BytesToLe32(Key, 0); m_wrkState[2] = IntUtils.BytesToLe32(Key, 4); m_wrkState[3] = IntUtils.BytesToLe32(Key, 8); m_wrkState[4] = IntUtils.BytesToLe32(Key, 12); m_wrkState[5] = IntUtils.BytesToLe32(m_dstCode, 4); m_wrkState[6] = IntUtils.BytesToLe32(Iv, 0); m_wrkState[7] = IntUtils.BytesToLe32(Iv, 4); m_wrkState[8] = IntUtils.BytesToLe32(m_dstCode, 8); m_wrkState[9] = IntUtils.BytesToLe32(Key, 16); m_wrkState[10] = IntUtils.BytesToLe32(Key, 20); m_wrkState[11] = IntUtils.BytesToLe32(Key, 24); m_wrkState[12] = IntUtils.BytesToLe32(Key, 28); m_wrkState[13] = IntUtils.BytesToLe32(m_dstCode, 12); } else { m_wrkState[0] = IntUtils.BytesToLe32(m_dstCode, 0); m_wrkState[1] = IntUtils.BytesToLe32(Key, 0); m_wrkState[2] = IntUtils.BytesToLe32(Key, 4); m_wrkState[3] = IntUtils.BytesToLe32(Key, 8); m_wrkState[4] = IntUtils.BytesToLe32(Key, 12); m_wrkState[5] = IntUtils.BytesToLe32(m_dstCode, 4); m_wrkState[6] = IntUtils.BytesToLe32(Iv, 0); m_wrkState[7] = IntUtils.BytesToLe32(Iv, 4); m_wrkState[8] = IntUtils.BytesToLe32(m_dstCode, 8); m_wrkState[9] = IntUtils.BytesToLe32(Key, 0); m_wrkState[10] = IntUtils.BytesToLe32(Key, 4); m_wrkState[11] = IntUtils.BytesToLe32(Key, 8); m_wrkState[12] = IntUtils.BytesToLe32(Key, 12); m_wrkState[13] = IntUtils.BytesToLe32(m_dstCode, 12); } } }
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 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 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); }