private static int do_cast_setkey(ref CAST5_context c, byte[] key) { int i; uint[] x = new uint[4]; uint[] z = new uint[4]; uint[] k = new uint[16]; x[0] = (uint)(key[0] << 24) | (uint)(key[1] << 16) | (uint)(key[2] << 8) | key[3]; x[1] = (uint)(key[4] << 24) | (uint)(key[5] << 16) | (uint)(key[6] << 8) | key[7]; x[2] = (uint)(key[8] << 24) | (uint)(key[9] << 16) | (uint)(key[10] << 8) | key[11]; x[3] = (uint)(key[12] << 24) | (uint)(key[13] << 16) | (uint)(key[14] << 8) | key[15]; key_schedule(x, z, k); for (i = 0; i < 16; i++) { c.Km[i] = k[i]; } key_schedule(x, z, k); for (i = 0; i < 16; i++) { c.Kr[i] = (byte)(k[i] & 0x1f); } x.Initialize(); z.Initialize(); k.Initialize(); return(0); }
private static byte[] decrypt_block(ref CAST5_context c, byte[] inbuf) { byte[] outbuf = do_decrypt_block(ref c, inbuf); burn_stack(20 + 4 * outbuf.Length); return(outbuf); }
private static CAST5_context cast_setkey(byte[] key) { CAST5_context c = new CAST5_context(); c.Km = new uint[16]; c.Kr = new byte[16]; do_cast_setkey(ref c, key); burn_stack(96 + 7 * key.Length); return(c); }
private static byte[] do_encrypt_block(ref CAST5_context c, byte[] inbuf) { byte[] outbuf = new byte[8]; uint l, r, t; uint[] Km; byte[] Kr; Km = c.Km; Kr = c.Kr; /* (L0,R0) <-- (m1...m64). (Split the plaintext into left and * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.) */ l = (uint)(inbuf[0] << 24) | (uint)(inbuf[1] << 16) | (uint)(inbuf[2] << 8) | (uint)inbuf[3]; r = (uint)inbuf[4] << 24 | (uint)(inbuf[5] << 16) | (uint)(inbuf[6] << 8) | (uint)inbuf[7]; /* (16 rounds) for i from 1 to 16, compute Li and Ri as follows: * Li = Ri-1; * Ri = Li-1 ^ f(Ri-1,Kmi,Kri), where f is defined in Section 2.2 * Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1. * Rounds 2, 5, 8, 11, and 14 use f function Type 2. * Rounds 3, 6, 9, 12, and 15 use f function Type 3. */ t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]); t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]); t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]); /* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and * concatenate to form the ciphertext.) */ outbuf[0] = (byte)((r >> 24) & 0xff); outbuf[1] = (byte)((r >> 16) & 0xff); outbuf[2] = (byte)((r >> 8) & 0xff); outbuf[3] = (byte)(r & 0xff); outbuf[4] = (byte)((l >> 24) & 0xff); outbuf[5] = (byte)((l >> 16) & 0xff); outbuf[6] = (byte)((l >> 8) & 0xff); outbuf[7] = (byte)(l & 0xff); return(outbuf); }
private static byte[] do_decrypt_block(ref CAST5_context c, byte[] inbuf) { byte[] outbuf = new byte[8]; uint l, r, t; uint[] Km; byte[] Kr; Km = c.Km; Kr = c.Kr; l = (uint)(inbuf[0] << 24) | (uint)(inbuf[1] << 16) | (uint)(inbuf[2] << 8) | (uint)inbuf[3]; r = (uint)(inbuf[4] << 24) | (uint)(inbuf[5] << 16) | (uint)(inbuf[6] << 8) | (uint)inbuf[7]; t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]); t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]); t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]); t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); outbuf[0] = (byte)((r >> 24) & 0xff); outbuf[1] = (byte)((r >> 16) & 0xff); outbuf[2] = (byte)((r >> 8) & 0xff); outbuf[3] = (byte)(r & 0xff); outbuf[4] = (byte)((l >> 24) & 0xff); outbuf[5] = (byte)((l >> 16) & 0xff); outbuf[6] = (byte)((l >> 8) & 0xff); outbuf[7] = (byte)(l & 0xff); return(outbuf); }
private static byte[] encrypt_block(ref CAST5_context c, byte[] inbuf) { byte[] outbuf = do_encrypt_block(ref c, inbuf); burn_stack(20+4*outbuf.Length); return outbuf; }
private static byte[] do_encrypt_block(ref CAST5_context c, byte[] inbuf) { byte[] outbuf = new byte[8]; uint l, r, t; uint[] Km; byte[] Kr; Km = c.Km; Kr = c.Kr; /* (L0,R0) <-- (m1...m64). (Split the plaintext into left and * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.) */ l = (uint)(inbuf[0] << 24) | (uint)(inbuf[1] << 16) | (uint)(inbuf[2] << 8) | (uint)inbuf[3]; r = (uint)inbuf[4] << 24 | (uint)(inbuf[5] << 16) | (uint)(inbuf[6] << 8) | (uint)inbuf[7]; /* (16 rounds) for i from 1 to 16, compute Li and Ri as follows: * Li = Ri-1; * Ri = Li-1 ^ f(Ri-1,Kmi,Kri), where f is defined in Section 2.2 * Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1. * Rounds 2, 5, 8, 11, and 14 use f function Type 2. * Rounds 3, 6, 9, 12, and 15 use f function Type 3. */ t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]); t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]); t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]); t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]); t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]); t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]); t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]); t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]); t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]); t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]); t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]); t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]); t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]); /* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and * concatenate to form the ciphertext.) */ outbuf[0] = (byte)((r >> 24) & 0xff); outbuf[1] = (byte)((r >> 16) & 0xff); outbuf[2] = (byte)((r >> 8) & 0xff); outbuf[3] = (byte)( r & 0xff); outbuf[4] = (byte)((l >> 24) & 0xff); outbuf[5] = (byte)((l >> 16) & 0xff); outbuf[6] = (byte)((l >> 8) & 0xff); outbuf[7] = (byte)( l & 0xff); return outbuf; }
private static byte[] do_decrypt_block(ref CAST5_context c, byte[] inbuf) { byte[] outbuf = new byte[8]; uint l, r, t; uint[] Km; byte[] Kr; Km = c.Km; Kr = c.Kr; l = (uint)(inbuf[0] << 24) | (uint)(inbuf[1] << 16) | (uint)(inbuf[2] << 8) | (uint)inbuf[3]; r = (uint)(inbuf[4] << 24) | (uint)(inbuf[5] << 16) | (uint)(inbuf[6] << 8) | (uint)inbuf[7]; t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]); t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]); t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]); t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]); t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]); t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]); t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]); t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]); t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]); t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]); t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]); t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]); t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]); outbuf[0] = (byte)((r >> 24) & 0xff); outbuf[1] = (byte)((r >> 16) & 0xff); outbuf[2] = (byte)((r >> 8) & 0xff); outbuf[3] = (byte)( r & 0xff); outbuf[4] = (byte)((l >> 24) & 0xff); outbuf[5] = (byte)((l >> 16) & 0xff); outbuf[6] = (byte)((l >> 8) & 0xff); outbuf[7] = (byte)( l & 0xff); return outbuf; }
private static int do_cast_setkey(ref CAST5_context c, byte[] key) { int i; uint[] x = new uint[4]; uint[] z = new uint[4]; uint[] k = new uint[16]; x[0] = (uint)(key[0] << 24) | (uint)(key[1] << 16) | (uint)(key[2] << 8) | key[3]; x[1] = (uint)(key[4] << 24) | (uint)(key[5] << 16) | (uint)(key[6] << 8) | key[7]; x[2] = (uint)(key[8] << 24) | (uint)(key[9] << 16) | (uint)(key[10] << 8) | key[11]; x[3] = (uint)(key[12] << 24) | (uint)(key[13] << 16) | (uint)(key[14] << 8) | key[15]; key_schedule(x, z, k); for(i=0; i < 16; i++) c.Km[i] = k[i]; key_schedule(x, z, k); for(i=0; i < 16; i++) c.Kr[i] = (byte)(k[i] & 0x1f); x.Initialize(); z.Initialize(); k.Initialize(); return 0; }
private static CAST5_context cast_setkey(byte[] key) { CAST5_context c = new CAST5_context(); c.Km = new uint[16]; c.Kr = new byte[16]; do_cast_setkey(ref c, key); burn_stack(96+7*key.Length); return c; }
public static bool selftest() { CAST5_context c = new CAST5_context(); //int i; // simple selftest byte[] key = {0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78, 0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A}; byte[] simple_plaintext = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; byte[] simple_ciphertext = {0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2}; c = cast_setkey(key); byte[] encrypted = encrypt_block(ref c, simple_plaintext); for (int i=0; i<encrypted.Length; i++) if (simple_ciphertext[i] != encrypted[i]) return false; // strong selftest as in RFC 2144 byte[] a = new byte[16]; byte[] b = new byte[16]; byte[] aL = {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78}; byte[] aR = {0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A}; byte[] bL = {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78}; byte[] bR = {0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A}; byte[] verify_a = {0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6,0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92}; byte[] verify_b = {0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71,0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E}; for (int i=0; i < 1000000; i++) { Array.Copy(bL, b, 8); Array.Copy(bR, 0, b, 8, 8); c = cast_setkey(b); aL = encrypt_block(ref c, aL); aR = encrypt_block(ref c, aR); Array.Copy(aL, a, 8); Array.Copy(aR, 0, a, 8, 8); c = cast_setkey(a); bL = encrypt_block(ref c, bL); bR = encrypt_block(ref c, bR); } Array.Copy(bL, b, 8); Array.Copy(bR, 0, b, 8, 8); Array.Copy(aL, a, 8); Array.Copy(aR, 0, a, 8, 8); for (int i=0; i<a.Length; i++) if (a[i] != verify_a[i]) return false; for (int i=0; i<b.Length; i++) if (b[i] != verify_b[i]) return false; return true; }
/// <summary> /// Default constructor - initializes all fields to default values /// </summary> public CAST5Transform(CAST5 baseClass, bool isEncryption) : base(baseClass, isEncryption, baseClass.IV) { this.baseClass = baseClass; this.encrypt = isEncryption; c = cast_setkey(baseClass.Key); }
public static bool selftest() { CAST5_context c = new CAST5_context(); //int i; // simple selftest byte[] key = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A }; byte[] simple_plaintext = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; byte[] simple_ciphertext = { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 }; c = cast_setkey(key); byte[] encrypted = encrypt_block(ref c, simple_plaintext); for (int i = 0; i < encrypted.Length; i++) { if (simple_ciphertext[i] != encrypted[i]) { return(false); } } // strong selftest as in RFC 2144 byte[] a = new byte[16]; byte[] b = new byte[16]; byte[] aL = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78 }; byte[] aR = { 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A }; byte[] bL = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78 }; byte[] bR = { 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A }; byte[] verify_a = { 0xEE, 0xA9, 0xD0, 0xA2, 0x49, 0xFD, 0x3B, 0xA6, 0xB3, 0x43, 0x6F, 0xB8, 0x9D, 0x6D, 0xCA, 0x92 }; byte[] verify_b = { 0xB2, 0xC9, 0x5E, 0xB0, 0x0C, 0x31, 0xAD, 0x71, 0x80, 0xAC, 0x05, 0xB8, 0xE8, 0x3D, 0x69, 0x6E }; for (int i = 0; i < 1000000; i++) { Array.Copy(bL, b, 8); Array.Copy(bR, 0, b, 8, 8); c = cast_setkey(b); aL = encrypt_block(ref c, aL); aR = encrypt_block(ref c, aR); Array.Copy(aL, a, 8); Array.Copy(aR, 0, a, 8, 8); c = cast_setkey(a); bL = encrypt_block(ref c, bL); bR = encrypt_block(ref c, bR); } Array.Copy(bL, b, 8); Array.Copy(bR, 0, b, 8, 8); Array.Copy(aL, a, 8); Array.Copy(aR, 0, a, 8, 8); for (int i = 0; i < a.Length; i++) { if (a[i] != verify_a[i]) { return(false); } } for (int i = 0; i < b.Length; i++) { if (b[i] != verify_b[i]) { return(false); } } return(true); }