public void InitializeKey(byte[] key, int offset) { uint i, c, d, t, s, shifts; c = CipherUtil.GetIntLE(key, offset + 0); d = CipherUtil.GetIntLE(key, offset + 4); t = ((d >> 4) ^ c) & 0x0f0f0f0f; c ^= t; d ^= t << 4; t = (((c << (16 - (-2))) ^ c) & 0xcccc0000); c = c ^ t ^ (t >> (16 - (-2))); t = (((d << (16 - (-2))) ^ d) & 0xcccc0000); d = d ^ t ^ (t >> (16 - (-2))); t = ((d >> 1) ^ c) & 0x55555555; c ^= t; d ^= t << 1; t = ((c >> 8) ^ d) & 0x00ff00ff; d ^= t; c ^= t << 8; t = ((d >> 1) ^ c) & 0x55555555; c ^= t; d ^= t << 1; d = ((d & 0xff) << 16) | (d & 0xff00) | ((d >> 16) & 0xff) | ((c >> 4) & 0xf000000); c &= 0x0fffffff; shifts = 0x7efc; for (i = 0; i < 16; i++) { if ((shifts & 1) != 0) { c = ((c >> 2) | (c << 26)); d = ((d >> 2) | (d << 26)); } else { c = ((c >> 1) | (c << 27)); d = ((d >> 1) | (d << 27)); } shifts >>= 1; c &= 0x0fffffff; d &= 0x0fffffff; s = SKB[0, (c) & 0x3f] | SKB[1, ((c >> 6) & 0x03) | ((c >> 7) & 0x3c)] | SKB[2, ((c >> 13) & 0x0f) | ((c >> 14) & 0x30)] | SKB[3, ((c >> 20) & 0x01) | ((c >> 21) & 0x06) | ((c >> 22) & 0x38)]; t = SKB[4, (d) & 0x3f] | SKB[5, ((d >> 7) & 0x03) | ((d >> 8) & 0x3c)] | SKB[6, (d >> 15) & 0x3f] | SKB[7, ((d >> 21) & 0x0f) | ((d >> 22) & 0x30)]; _key[i * 2] = ((t << 16) | (s & 0xffff)); s = ((s >> 16) | (t & 0xffff0000)); _key[(i * 2) + 1] = (s << 4) | (s >> 28); } }
public void BlockDecrypt(byte[] input, int inOffset, byte[] output, int outOffset) { uint t; int i; uint[] lr = new uint[2]; lr[0] = CipherUtil.GetIntLE(input, inOffset); lr[1] = CipherUtil.GetIntLE(input, inOffset + 4); initPerm(lr); t = (lr[1] << 1) | (lr[1] >> 31); lr[1] = (lr[0] << 1) | (lr[0] >> 31); lr[0] = t; for (i = 30; i > 0; i -= 4) { desCipher1(lr, i); desCipher2(lr, i - 2); } lr[0] = (lr[0] >> 1) | (lr[0] << 31); lr[1] = (lr[1] >> 1) | (lr[1] << 31); finalPerm(lr); CipherUtil.PutIntLE(lr[0], output, outOffset); CipherUtil.PutIntLE(lr[1], output, outOffset + 4); }