18e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrompackage org.bouncycastle.crypto.engines; 28e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 38e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstromimport org.bouncycastle.crypto.BlockCipher; 48e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstromimport org.bouncycastle.crypto.CipherParameters; 58e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstromimport org.bouncycastle.crypto.DataLengthException; 68e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstromimport org.bouncycastle.crypto.params.KeyParameter; 78e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 88e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom/** 98e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * A class that provides Twofish encryption operations. 108e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * 118e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * This Java implementation is based on the Java reference 128e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * implementation provided by Bruce Schneier and developed 138e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * by Raif S. Naffah. 148e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom */ 158e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrompublic final class TwofishEngine 168e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom implements BlockCipher 178e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom{ 188e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final byte[][] P = { 198e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { // p0 208e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xA9, (byte) 0x67, (byte) 0xB3, (byte) 0xE8, 218e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x04, (byte) 0xFD, (byte) 0xA3, (byte) 0x76, 228e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x9A, (byte) 0x92, (byte) 0x80, (byte) 0x78, 238e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xE4, (byte) 0xDD, (byte) 0xD1, (byte) 0x38, 248e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x0D, (byte) 0xC6, (byte) 0x35, (byte) 0x98, 258e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x18, (byte) 0xF7, (byte) 0xEC, (byte) 0x6C, 268e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x43, (byte) 0x75, (byte) 0x37, (byte) 0x26, 278e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xFA, (byte) 0x13, (byte) 0x94, (byte) 0x48, 288e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xF2, (byte) 0xD0, (byte) 0x8B, (byte) 0x30, 298e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x84, (byte) 0x54, (byte) 0xDF, (byte) 0x23, 308e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x19, (byte) 0x5B, (byte) 0x3D, (byte) 0x59, 318e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xF3, (byte) 0xAE, (byte) 0xA2, (byte) 0x82, 328e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x63, (byte) 0x01, (byte) 0x83, (byte) 0x2E, 338e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xD9, (byte) 0x51, (byte) 0x9B, (byte) 0x7C, 348e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xA6, (byte) 0xEB, (byte) 0xA5, (byte) 0xBE, 358e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x16, (byte) 0x0C, (byte) 0xE3, (byte) 0x61, 368e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xC0, (byte) 0x8C, (byte) 0x3A, (byte) 0xF5, 378e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x73, (byte) 0x2C, (byte) 0x25, (byte) 0x0B, 388e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xBB, (byte) 0x4E, (byte) 0x89, (byte) 0x6B, 398e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x53, (byte) 0x6A, (byte) 0xB4, (byte) 0xF1, 408e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xE1, (byte) 0xE6, (byte) 0xBD, (byte) 0x45, 418e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xE2, (byte) 0xF4, (byte) 0xB6, (byte) 0x66, 428e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xCC, (byte) 0x95, (byte) 0x03, (byte) 0x56, 438e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xD4, (byte) 0x1C, (byte) 0x1E, (byte) 0xD7, 448e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xFB, (byte) 0xC3, (byte) 0x8E, (byte) 0xB5, 458e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xE9, (byte) 0xCF, (byte) 0xBF, (byte) 0xBA, 468e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xEA, (byte) 0x77, (byte) 0x39, (byte) 0xAF, 478e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x33, (byte) 0xC9, (byte) 0x62, (byte) 0x71, 488e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x81, (byte) 0x79, (byte) 0x09, (byte) 0xAD, 498e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x24, (byte) 0xCD, (byte) 0xF9, (byte) 0xD8, 508e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xE5, (byte) 0xC5, (byte) 0xB9, (byte) 0x4D, 518e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x44, (byte) 0x08, (byte) 0x86, (byte) 0xE7, 528e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xA1, (byte) 0x1D, (byte) 0xAA, (byte) 0xED, 538e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x06, (byte) 0x70, (byte) 0xB2, (byte) 0xD2, 548e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x41, (byte) 0x7B, (byte) 0xA0, (byte) 0x11, 558e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x31, (byte) 0xC2, (byte) 0x27, (byte) 0x90, 568e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x20, (byte) 0xF6, (byte) 0x60, (byte) 0xFF, 578e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x96, (byte) 0x5C, (byte) 0xB1, (byte) 0xAB, 588e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x9E, (byte) 0x9C, (byte) 0x52, (byte) 0x1B, 598e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x5F, (byte) 0x93, (byte) 0x0A, (byte) 0xEF, 608e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x91, (byte) 0x85, (byte) 0x49, (byte) 0xEE, 618e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x2D, (byte) 0x4F, (byte) 0x8F, (byte) 0x3B, 628e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x47, (byte) 0x87, (byte) 0x6D, (byte) 0x46, 638e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xD6, (byte) 0x3E, (byte) 0x69, (byte) 0x64, 648e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x2A, (byte) 0xCE, (byte) 0xCB, (byte) 0x2F, 658e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xFC, (byte) 0x97, (byte) 0x05, (byte) 0x7A, 668e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xAC, (byte) 0x7F, (byte) 0xD5, (byte) 0x1A, 678e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x4B, (byte) 0x0E, (byte) 0xA7, (byte) 0x5A, 688e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x28, (byte) 0x14, (byte) 0x3F, (byte) 0x29, 698e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x88, (byte) 0x3C, (byte) 0x4C, (byte) 0x02, 708e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xB8, (byte) 0xDA, (byte) 0xB0, (byte) 0x17, 718e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x55, (byte) 0x1F, (byte) 0x8A, (byte) 0x7D, 728e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x57, (byte) 0xC7, (byte) 0x8D, (byte) 0x74, 738e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xB7, (byte) 0xC4, (byte) 0x9F, (byte) 0x72, 748e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x7E, (byte) 0x15, (byte) 0x22, (byte) 0x12, 758e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x58, (byte) 0x07, (byte) 0x99, (byte) 0x34, 768e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x6E, (byte) 0x50, (byte) 0xDE, (byte) 0x68, 778e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x65, (byte) 0xBC, (byte) 0xDB, (byte) 0xF8, 788e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xC8, (byte) 0xA8, (byte) 0x2B, (byte) 0x40, 798e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xDC, (byte) 0xFE, (byte) 0x32, (byte) 0xA4, 808e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xCA, (byte) 0x10, (byte) 0x21, (byte) 0xF0, 818e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xD3, (byte) 0x5D, (byte) 0x0F, (byte) 0x00, 828e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x6F, (byte) 0x9D, (byte) 0x36, (byte) 0x42, 838e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x4A, (byte) 0x5E, (byte) 0xC1, (byte) 0xE0 }, 848e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { // p1 858e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x75, (byte) 0xF3, (byte) 0xC6, (byte) 0xF4, 868e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xDB, (byte) 0x7B, (byte) 0xFB, (byte) 0xC8, 878e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x4A, (byte) 0xD3, (byte) 0xE6, (byte) 0x6B, 888e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x45, (byte) 0x7D, (byte) 0xE8, (byte) 0x4B, 898e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xD6, (byte) 0x32, (byte) 0xD8, (byte) 0xFD, 908e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x37, (byte) 0x71, (byte) 0xF1, (byte) 0xE1, 918e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x30, (byte) 0x0F, (byte) 0xF8, (byte) 0x1B, 928e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x87, (byte) 0xFA, (byte) 0x06, (byte) 0x3F, 938e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x5E, (byte) 0xBA, (byte) 0xAE, (byte) 0x5B, 948e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x8A, (byte) 0x00, (byte) 0xBC, (byte) 0x9D, 958e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x6D, (byte) 0xC1, (byte) 0xB1, (byte) 0x0E, 968e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x80, (byte) 0x5D, (byte) 0xD2, (byte) 0xD5, 978e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xA0, (byte) 0x84, (byte) 0x07, (byte) 0x14, 988e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xB5, (byte) 0x90, (byte) 0x2C, (byte) 0xA3, 998e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xB2, (byte) 0x73, (byte) 0x4C, (byte) 0x54, 1008e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x92, (byte) 0x74, (byte) 0x36, (byte) 0x51, 1018e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x38, (byte) 0xB0, (byte) 0xBD, (byte) 0x5A, 1028e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xFC, (byte) 0x60, (byte) 0x62, (byte) 0x96, 1038e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x6C, (byte) 0x42, (byte) 0xF7, (byte) 0x10, 1048e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x7C, (byte) 0x28, (byte) 0x27, (byte) 0x8C, 1058e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x13, (byte) 0x95, (byte) 0x9C, (byte) 0xC7, 1068e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x24, (byte) 0x46, (byte) 0x3B, (byte) 0x70, 1078e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xCA, (byte) 0xE3, (byte) 0x85, (byte) 0xCB, 1088e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x11, (byte) 0xD0, (byte) 0x93, (byte) 0xB8, 1098e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xA6, (byte) 0x83, (byte) 0x20, (byte) 0xFF, 1108e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x9F, (byte) 0x77, (byte) 0xC3, (byte) 0xCC, 1118e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x03, (byte) 0x6F, (byte) 0x08, (byte) 0xBF, 1128e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x40, (byte) 0xE7, (byte) 0x2B, (byte) 0xE2, 1138e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x79, (byte) 0x0C, (byte) 0xAA, (byte) 0x82, 1148e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x41, (byte) 0x3A, (byte) 0xEA, (byte) 0xB9, 1158e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xE4, (byte) 0x9A, (byte) 0xA4, (byte) 0x97, 1168e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x7E, (byte) 0xDA, (byte) 0x7A, (byte) 0x17, 1178e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x66, (byte) 0x94, (byte) 0xA1, (byte) 0x1D, 1188e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x3D, (byte) 0xF0, (byte) 0xDE, (byte) 0xB3, 1198e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x0B, (byte) 0x72, (byte) 0xA7, (byte) 0x1C, 1208e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xEF, (byte) 0xD1, (byte) 0x53, (byte) 0x3E, 1218e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x8F, (byte) 0x33, (byte) 0x26, (byte) 0x5F, 1228e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xEC, (byte) 0x76, (byte) 0x2A, (byte) 0x49, 1238e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x81, (byte) 0x88, (byte) 0xEE, (byte) 0x21, 1248e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xC4, (byte) 0x1A, (byte) 0xEB, (byte) 0xD9, 1258e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xC5, (byte) 0x39, (byte) 0x99, (byte) 0xCD, 1268e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xAD, (byte) 0x31, (byte) 0x8B, (byte) 0x01, 1278e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x18, (byte) 0x23, (byte) 0xDD, (byte) 0x1F, 1288e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x4E, (byte) 0x2D, (byte) 0xF9, (byte) 0x48, 1298e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x4F, (byte) 0xF2, (byte) 0x65, (byte) 0x8E, 1308e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x78, (byte) 0x5C, (byte) 0x58, (byte) 0x19, 1318e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x8D, (byte) 0xE5, (byte) 0x98, (byte) 0x57, 1328e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x67, (byte) 0x7F, (byte) 0x05, (byte) 0x64, 1338e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xAF, (byte) 0x63, (byte) 0xB6, (byte) 0xFE, 1348e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xF5, (byte) 0xB7, (byte) 0x3C, (byte) 0xA5, 1358e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xCE, (byte) 0xE9, (byte) 0x68, (byte) 0x44, 1368e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xE0, (byte) 0x4D, (byte) 0x43, (byte) 0x69, 1378e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x29, (byte) 0x2E, (byte) 0xAC, (byte) 0x15, 1388e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x59, (byte) 0xA8, (byte) 0x0A, (byte) 0x9E, 1398e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x6E, (byte) 0x47, (byte) 0xDF, (byte) 0x34, 1408e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x35, (byte) 0x6A, (byte) 0xCF, (byte) 0xDC, 1418e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x22, (byte) 0xC9, (byte) 0xC0, (byte) 0x9B, 1428e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x89, (byte) 0xD4, (byte) 0xED, (byte) 0xAB, 1438e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x12, (byte) 0xA2, (byte) 0x0D, (byte) 0x52, 1448e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xBB, (byte) 0x02, (byte) 0x2F, (byte) 0xA9, 1458e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0xD7, (byte) 0x61, (byte) 0x1E, (byte) 0xB4, 1468e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x50, (byte) 0x04, (byte) 0xF6, (byte) 0xC2, 1478e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x16, (byte) 0x25, (byte) 0x86, (byte) 0x56, 1488e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (byte) 0x55, (byte) 0x09, (byte) 0xBE, (byte) 0x91 } 1498e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom }; 1508e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 1518e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom /** 1528e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * Define the fixed p0/p1 permutations used in keyed S-box lookup. 1538e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * By changing the following constant definitions, the S-boxes will 1548e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * automatically get changed in the Twofish engine. 1558e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom */ 1568e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_00 = 1; 1578e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_01 = 0; 1588e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_02 = 0; 1598e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_03 = P_01 ^ 1; 1608e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_04 = 1; 1618e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 1628e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_10 = 0; 1638e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_11 = 0; 1648e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_12 = 1; 1658e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_13 = P_11 ^ 1; 1668e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_14 = 0; 1678e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 1688e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_20 = 1; 1698e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_21 = 1; 1708e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_22 = 0; 1718e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_23 = P_21 ^ 1; 1728e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_24 = 0; 1738e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 1748e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_30 = 0; 1758e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_31 = 1; 1768e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_32 = 1; 1778e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_33 = P_31 ^ 1; 1788e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int P_34 = 1; 1798e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 1808e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom /* Primitive polynomial for GF(256) */ 1818e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int GF256_FDBK = 0x169; 1828e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int GF256_FDBK_2 = GF256_FDBK / 2; 1838e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int GF256_FDBK_4 = GF256_FDBK / 4; 1848e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 1858e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int RS_GF_FDBK = 0x14D; // field generator 1868e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 1878e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom //==================================== 1888e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom // Useful constants 1898e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom //==================================== 1908e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 1918e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int ROUNDS = 16; 1928e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int MAX_ROUNDS = 16; // bytes = 128 bits 1938e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int BLOCK_SIZE = 16; // bytes = 128 bits 1948e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int MAX_KEY_BITS = 256; 1958e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 1968e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int INPUT_WHITEN=0; 1978e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int OUTPUT_WHITEN=INPUT_WHITEN+BLOCK_SIZE/4; // 4 1988e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int ROUND_SUBKEYS=OUTPUT_WHITEN+BLOCK_SIZE/4;// 8 1998e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2008e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int TOTAL_SUBKEYS=ROUND_SUBKEYS+2*MAX_ROUNDS;// 40 2018e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2028e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int SK_STEP = 0x02020202; 2038e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int SK_BUMP = 0x01010101; 2048e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private static final int SK_ROTL = 9; 2058e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2068e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private boolean encrypting = false; 2078e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2088e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int[] gMDS0 = new int[MAX_KEY_BITS]; 2098e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int[] gMDS1 = new int[MAX_KEY_BITS]; 2108e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int[] gMDS2 = new int[MAX_KEY_BITS]; 2118e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int[] gMDS3 = new int[MAX_KEY_BITS]; 2128e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2138e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom /** 2148e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * gSubKeys[] and gSBox[] are eventually used in the 2158e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * encryption and decryption methods. 2168e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom */ 2178e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int[] gSubKeys; 2188e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int[] gSBox; 2198e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2208e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int k64Cnt = 0; 2218e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2228e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private byte[] workingKey = null; 2238e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2248e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom public TwofishEngine() 2258e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 2268e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom // calculate the MDS matrix 2278e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int[] m1 = new int[2]; 2288e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int[] mX = new int[2]; 2298e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int[] mY = new int[2]; 2308e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int j; 2318e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2328e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom for (int i=0; i< MAX_KEY_BITS ; i++) 2338e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 2348e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom j = P[0][i] & 0xff; 2358e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom m1[0] = j; 2368e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom mX[0] = Mx_X(j) & 0xff; 2378e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom mY[0] = Mx_Y(j) & 0xff; 2388e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2398e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom j = P[1][i] & 0xff; 2408e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom m1[1] = j; 2418e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom mX[1] = Mx_X(j) & 0xff; 2428e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom mY[1] = Mx_Y(j) & 0xff; 2438e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2448e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gMDS0[i] = m1[P_00] | mX[P_00] << 8 | 2458e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom mY[P_00] << 16 | mY[P_00] << 24; 2468e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2478e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gMDS1[i] = mY[P_10] | mY[P_10] << 8 | 2488e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom mX[P_10] << 16 | m1[P_10] << 24; 2498e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2508e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gMDS2[i] = mX[P_20] | mY[P_20] << 8 | 2518e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom m1[P_20] << 16 | mY[P_20] << 24; 2528e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2538e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gMDS3[i] = mX[P_30] | m1[P_30] << 8 | 2548e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom mY[P_30] << 16 | mX[P_30] << 24; 2558e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 2568e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 2578e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2588e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom /** 2598e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * initialise a Twofish cipher. 2608e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * 2618e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * @param encrypting whether or not we are for encryption. 2628e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * @param params the parameters required to set up the cipher. 2638e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * @exception IllegalArgumentException if the params argument is 2648e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * inappropriate. 2658e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom */ 2668e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom public void init( 2678e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom boolean encrypting, 2688e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom CipherParameters params) 2698e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 2708e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom if (params instanceof KeyParameter) 2718e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 2728e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom this.encrypting = encrypting; 2738e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom this.workingKey = ((KeyParameter)params).getKey(); 2748e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom this.k64Cnt = (this.workingKey.length / 8); // pre-padded ? 2758e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom setKey(this.workingKey); 2768e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2778e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return; 2788e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 2798e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2808e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom throw new IllegalArgumentException("invalid parameter passed to Twofish init - " + params.getClass().getName()); 2818e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 2828e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2838e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom public String getAlgorithmName() 2848e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 2858e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return "Twofish"; 2868e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 2878e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2888e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom public int processBlock( 2898e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom byte[] in, 2908e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int inOff, 2918e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom byte[] out, 2928e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int outOff) 2938e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 2948e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom if (workingKey == null) 2958e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 2968e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom throw new IllegalStateException("Twofish not initialised"); 2978e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 2988e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 2998e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom if ((inOff + BLOCK_SIZE) > in.length) 3008e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 3018e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom throw new DataLengthException("input buffer too short"); 3028e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 3038e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3048e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom if ((outOff + BLOCK_SIZE) > out.length) 3058e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 3068e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom throw new DataLengthException("output buffer too short"); 3078e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 3088e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3098e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom if (encrypting) 3108e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 3118e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom encryptBlock(in, inOff, out, outOff); 3128e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 3138e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom else 3148e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 3158e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom decryptBlock(in, inOff, out, outOff); 3168e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 3178e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3188e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return BLOCK_SIZE; 3198e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 3208e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3218e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom public void reset() 3228e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 3238e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom if (this.workingKey != null) 3248e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 3258e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom setKey(this.workingKey); 3268e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 3278e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 3288e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3298e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom public int getBlockSize() 3308e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 3318e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return BLOCK_SIZE; 3328e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 3338e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3348e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom //================================== 3358e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom // Private Implementation 3368e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom //================================== 3378e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3388e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private void setKey(byte[] key) 3398e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 3408e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int[] k32e = new int[MAX_KEY_BITS/64]; // 4 3418e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int[] k32o = new int[MAX_KEY_BITS/64]; // 4 3428e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3438e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int[] sBoxKeys = new int[MAX_KEY_BITS/64]; // 4 3448e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSubKeys = new int[TOTAL_SUBKEYS]; 3458e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3468e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom if (k64Cnt < 1) 3478e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 3488e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom throw new IllegalArgumentException("Key size less than 64 bits"); 3498e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 3508e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3518e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom if (k64Cnt > 4) 3528e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 3538e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom throw new IllegalArgumentException("Key size larger than 256 bits"); 3548e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 3558e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3568e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom /* 3578e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * k64Cnt is the number of 8 byte blocks (64 chunks) 3588e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * that are in the input key. The input key is a 3598e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * maximum of 32 bytes (256 bits), so the range 3608e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * for k64Cnt is 1..4 3618e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom */ 3628e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom for (int i=0; i<k64Cnt ; i++) 3638e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 3648e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int p = i* 8; 3658e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3668e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom k32e[i] = BytesTo32Bits(key, p); 3678e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom k32o[i] = BytesTo32Bits(key, p+4); 3688e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3698e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom sBoxKeys[k64Cnt-1-i] = RS_MDS_Encode(k32e[i], k32o[i]); 3708e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 3718e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3728e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int q,A,B; 3738e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom for (int i=0; i < TOTAL_SUBKEYS / 2 ; i++) 3748e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 3758e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom q = i*SK_STEP; 3768e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom A = F32(q, k32e); 3778e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom B = F32(q+SK_BUMP, k32o); 3788e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom B = B << 8 | B >>> 24; 3798e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom A += B; 3808e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSubKeys[i*2] = A; 3818e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom A += B; 3828e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSubKeys[i*2 + 1] = A << SK_ROTL | A >>> (32-SK_ROTL); 3838e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 3848e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 3858e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom /* 3868e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * fully expand the table for speed 3878e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom */ 3888e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int k0 = sBoxKeys[0]; 3898e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int k1 = sBoxKeys[1]; 3908e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int k2 = sBoxKeys[2]; 3918e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int k3 = sBoxKeys[3]; 3928e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int b0, b1, b2, b3; 3938e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox = new int[4*MAX_KEY_BITS]; 3948e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom for (int i=0; i<MAX_KEY_BITS; i++) 3958e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 3968e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b0 = b1 = b2 = b3 = i; 3978e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom switch (k64Cnt & 3) 3988e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 3998e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom case 1: 4008e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox[i*2] = gMDS0[(P[P_01][b0] & 0xff) ^ b0(k0)]; 4018e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox[i*2+1] = gMDS1[(P[P_11][b1] & 0xff) ^ b1(k0)]; 4028e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox[i*2+0x200] = gMDS2[(P[P_21][b2] & 0xff) ^ b2(k0)]; 4038e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox[i*2+0x201] = gMDS3[(P[P_31][b3] & 0xff) ^ b3(k0)]; 4048e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom break; 4054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom case 0: // 256 bits of key 4068e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b0 = (P[P_04][b0] & 0xff) ^ b0(k3); 4078e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b1 = (P[P_14][b1] & 0xff) ^ b1(k3); 4088e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b2 = (P[P_24][b2] & 0xff) ^ b2(k3); 4098e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b3 = (P[P_34][b3] & 0xff) ^ b3(k3); 4104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // fall through, having pre-processed b[0]..b[3] with k32[3] 4114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom case 3: // 192 bits of key 4128e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b0 = (P[P_03][b0] & 0xff) ^ b0(k2); 4138e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b1 = (P[P_13][b1] & 0xff) ^ b1(k2); 4148e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b2 = (P[P_23][b2] & 0xff) ^ b2(k2); 4158e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b3 = (P[P_33][b3] & 0xff) ^ b3(k2); 4164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // fall through, having pre-processed b[0]..b[3] with k32[2] 4174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom case 2: // 128 bits of key 4188e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox[i*2] = gMDS0[(P[P_01] 4198e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom [(P[P_02][b0] & 0xff) ^ b0(k1)] & 0xff) ^ b0(k0)]; 4208e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox[i*2+1] = gMDS1[(P[P_11] 4218e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom [(P[P_12][b1] & 0xff) ^ b1(k1)] & 0xff) ^ b1(k0)]; 4228e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox[i*2+0x200] = gMDS2[(P[P_21] 4238e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom [(P[P_22][b2] & 0xff) ^ b2(k1)] & 0xff) ^ b2(k0)]; 4248e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox[i*2+0x201] = gMDS3[(P[P_31] 4258e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom [(P[P_32][b3] & 0xff) ^ b3(k1)] & 0xff) ^ b3(k0)]; 4268e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom break; 4278e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 4288e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 4298e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 4308e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom /* 4318e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * the function exits having setup the gSBox with the 4328e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * input key material. 4338e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom */ 4348e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 4358e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 4368e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom /** 4378e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * Encrypt the given input starting at the given offset and place 4388e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * the result in the provided buffer starting at the given offset. 4398e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * The input will be an exact multiple of our blocksize. 4408e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * 4418e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * encryptBlock uses the pre-calculated gSBox[] and subKey[] 4428e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * arrays. 4438e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom */ 4448e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private void encryptBlock( 4458e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom byte[] src, 4468e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int srcIndex, 4478e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom byte[] dst, 4488e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int dstIndex) 4498e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 4508e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int x0 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[INPUT_WHITEN]; 4518e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int x1 = BytesTo32Bits(src, srcIndex + 4) ^ gSubKeys[INPUT_WHITEN + 1]; 4528e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int x2 = BytesTo32Bits(src, srcIndex + 8) ^ gSubKeys[INPUT_WHITEN + 2]; 4538e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int x3 = BytesTo32Bits(src, srcIndex + 12) ^ gSubKeys[INPUT_WHITEN + 3]; 4548e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 4558e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int k = ROUND_SUBKEYS; 4568e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int t0, t1; 4578e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom for (int r = 0; r < ROUNDS; r +=2) 4588e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 4598e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom t0 = Fe32_0(x0); 4608e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom t1 = Fe32_3(x1); 4618e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom x2 ^= t0 + t1 + gSubKeys[k++]; 4628e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom x2 = x2 >>>1 | x2 << 31; 4638e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom x3 = (x3 << 1 | x3 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]); 4648e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 4658e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom t0 = Fe32_0(x2); 4668e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom t1 = Fe32_3(x3); 4678e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom x0 ^= t0 + t1 + gSubKeys[k++]; 4688e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom x0 = x0 >>>1 | x0 << 31; 4698e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom x1 = (x1 << 1 | x1 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]); 4708e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 4718e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 4728e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom Bits32ToBytes(x2 ^ gSubKeys[OUTPUT_WHITEN], dst, dstIndex); 4738e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom Bits32ToBytes(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], dst, dstIndex + 4); 4748e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom Bits32ToBytes(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], dst, dstIndex + 8); 4758e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom Bits32ToBytes(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], dst, dstIndex + 12); 4768e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 4778e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 4788e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom /** 4798e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * Decrypt the given input starting at the given offset and place 4808e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * the result in the provided buffer starting at the given offset. 4818e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * The input will be an exact multiple of our blocksize. 4828e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom */ 4838e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private void decryptBlock( 4848e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom byte[] src, 4858e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int srcIndex, 4868e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom byte[] dst, 4878e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int dstIndex) 4888e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 4898e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int x2 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[OUTPUT_WHITEN]; 4908e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int x3 = BytesTo32Bits(src, srcIndex+4) ^ gSubKeys[OUTPUT_WHITEN + 1]; 4918e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int x0 = BytesTo32Bits(src, srcIndex+8) ^ gSubKeys[OUTPUT_WHITEN + 2]; 4928e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int x1 = BytesTo32Bits(src, srcIndex+12) ^ gSubKeys[OUTPUT_WHITEN + 3]; 4938e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 4948e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int k = ROUND_SUBKEYS + 2 * ROUNDS -1 ; 4958e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int t0, t1; 4968e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom for (int r = 0; r< ROUNDS ; r +=2) 4978e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 4988e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom t0 = Fe32_0(x2); 4998e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom t1 = Fe32_3(x3); 5008e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom x1 ^= t0 + 2*t1 + gSubKeys[k--]; 5018e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom x0 = (x0 << 1 | x0 >>> 31) ^ (t0 + t1 + gSubKeys[k--]); 5028e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom x1 = x1 >>>1 | x1 << 31; 5038e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 5048e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom t0 = Fe32_0(x0); 5058e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom t1 = Fe32_3(x1); 5068e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom x3 ^= t0 + 2*t1 + gSubKeys[k--]; 5078e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom x2 = (x2 << 1 | x2 >>> 31) ^ (t0 + t1 + gSubKeys[k--]); 5088e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom x3 = x3 >>>1 | x3 << 31; 5098e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 5108e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 5118e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom Bits32ToBytes(x0 ^ gSubKeys[INPUT_WHITEN], dst, dstIndex); 5128e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom Bits32ToBytes(x1 ^ gSubKeys[INPUT_WHITEN + 1], dst, dstIndex + 4); 5138e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom Bits32ToBytes(x2 ^ gSubKeys[INPUT_WHITEN + 2], dst, dstIndex + 8); 5148e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom Bits32ToBytes(x3 ^ gSubKeys[INPUT_WHITEN + 3], dst, dstIndex + 12); 5158e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 5168e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 5178e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom /* 5188e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * TODO: This can be optimised and made cleaner by combining 5198e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * the functionality in this function and applying it appropriately 5208e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * to the creation of the subkeys during key setup. 5218e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom */ 5228e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int F32(int x, int[] k32) 5238e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 5248e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int b0 = b0(x); 5258e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int b1 = b1(x); 5268e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int b2 = b2(x); 5278e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int b3 = b3(x); 5288e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int k0 = k32[0]; 5298e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int k1 = k32[1]; 5308e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int k2 = k32[2]; 5318e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int k3 = k32[3]; 5328e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 5338e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int result = 0; 5348e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom switch (k64Cnt & 3) 5358e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 5368e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom case 1: 5378e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom result = gMDS0[(P[P_01][b0] & 0xff) ^ b0(k0)] ^ 5388e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gMDS1[(P[P_11][b1] & 0xff) ^ b1(k0)] ^ 5398e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gMDS2[(P[P_21][b2] & 0xff) ^ b2(k0)] ^ 5408e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gMDS3[(P[P_31][b3] & 0xff) ^ b3(k0)]; 5418e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom break; 5428e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom case 0: /* 256 bits of key */ 5438e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b0 = (P[P_04][b0] & 0xff) ^ b0(k3); 5448e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b1 = (P[P_14][b1] & 0xff) ^ b1(k3); 5458e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b2 = (P[P_24][b2] & 0xff) ^ b2(k3); 5468e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b3 = (P[P_34][b3] & 0xff) ^ b3(k3); 5478e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom case 3: 5488e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b0 = (P[P_03][b0] & 0xff) ^ b0(k2); 5498e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b1 = (P[P_13][b1] & 0xff) ^ b1(k2); 5508e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b2 = (P[P_23][b2] & 0xff) ^ b2(k2); 5518e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b3 = (P[P_33][b3] & 0xff) ^ b3(k2); 5528e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom case 2: 5538e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom result = 5548e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gMDS0[(P[P_01][(P[P_02][b0]&0xff)^b0(k1)]&0xff)^b0(k0)] ^ 5558e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gMDS1[(P[P_11][(P[P_12][b1]&0xff)^b1(k1)]&0xff)^b1(k0)] ^ 5568e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gMDS2[(P[P_21][(P[P_22][b2]&0xff)^b2(k1)]&0xff)^b2(k0)] ^ 5578e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gMDS3[(P[P_31][(P[P_32][b3]&0xff)^b3(k1)]&0xff)^b3(k0)]; 5588e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom break; 5598e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 5608e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return result; 5618e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 5628e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 5638e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom /** 5648e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * Use (12, 8) Reed-Solomon code over GF(256) to produce 5658e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * a key S-box 32-bit entity from 2 key material 32-bit 5668e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * entities. 5678e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * 5688e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * @param k0 first 32-bit entity 5698e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * @param k1 second 32-bit entity 5708e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * @return Remainder polynomial generated using RS code 5718e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom */ 5728e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int RS_MDS_Encode(int k0, int k1) 5738e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 5748e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int r = k1; 5758e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom for (int i = 0 ; i < 4 ; i++) // shift 1 byte at a time 5768e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 5778e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom r = RS_rem(r); 5788e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 5798e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom r ^= k0; 5808e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom for (int i=0 ; i < 4 ; i++) 5818e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 5828e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom r = RS_rem(r); 5838e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 5848e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 5858e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return r; 5868e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 5878e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 5888e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom /** 5898e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * Reed-Solomon code parameters: (12,8) reversible code:<p> 5908e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * <pre> 5918e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * g(x) = x^4 + (a+1/a)x^3 + ax^2 + (a+1/a)x + 1 5928e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * </pre> 5938e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom * where a = primitive root of field generator 0x14D 5948e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom */ 5958e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int RS_rem(int x) 5968e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 5978e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int b = (x >>> 24) & 0xff; 5988e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int g2 = ((b << 1) ^ 5998e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom ((b & 0x80) != 0 ? RS_GF_FDBK : 0)) & 0xff; 6008e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom int g3 = ((b >>> 1) ^ 6018e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom ((b & 0x01) != 0 ? (RS_GF_FDBK >>> 1) : 0)) ^ g2 ; 6028e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return ((x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b); 6038e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 6048e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 6058e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int LFSR1(int x) 6068e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 6078e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return (x >> 1) ^ 6088e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (((x & 0x01) != 0) ? GF256_FDBK_2 : 0); 6098e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 6108e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 6118e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int LFSR2(int x) 6128e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 6138e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return (x >> 2) ^ 6148e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (((x & 0x02) != 0) ? GF256_FDBK_2 : 0) ^ 6158e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom (((x & 0x01) != 0) ? GF256_FDBK_4 : 0); 6168e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 6178e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 6188e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int Mx_X(int x) 6198e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 6208e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return x ^ LFSR2(x); 6218e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } // 5B 6228e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 6238e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int Mx_Y(int x) 6248e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 6258e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return x ^ LFSR1(x) ^ LFSR2(x); 6268e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } // EF 6278e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 6288e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int b0(int x) 6298e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 6308e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return x & 0xff; 6318e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 6328e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 6338e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int b1(int x) 6348e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 6358e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return (x >>> 8) & 0xff; 6368e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 6378e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 6388e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int b2(int x) 6398e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 6408e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return (x >>> 16) & 0xff; 6418e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 6428e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 6438e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int b3(int x) 6448e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 6458e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return (x >>> 24) & 0xff; 6468e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 6478e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 6488e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int Fe32_0(int x) 6498e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 6508e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return gSBox[ 0x000 + 2*(x & 0xff) ] ^ 6518e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox[ 0x001 + 2*((x >>> 8) & 0xff) ] ^ 6528e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox[ 0x200 + 2*((x >>> 16) & 0xff) ] ^ 6538e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox[ 0x201 + 2*((x >>> 24) & 0xff) ]; 6548e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 6558e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 6568e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int Fe32_3(int x) 6578e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 6588e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return gSBox[ 0x000 + 2*((x >>> 24) & 0xff) ] ^ 6598e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox[ 0x001 + 2*(x & 0xff) ] ^ 6608e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox[ 0x200 + 2*((x >>> 8) & 0xff) ] ^ 6618e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom gSBox[ 0x201 + 2*((x >>> 16) & 0xff) ]; 6628e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 6638e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 6648e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private int BytesTo32Bits(byte[] b, int p) 6658e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 6668e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return ((b[p] & 0xff)) | 6678e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom ((b[p+1] & 0xff) << 8) | 6688e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom ((b[p+2] & 0xff) << 16) | 6698e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom ((b[p+3] & 0xff) << 24); 6708e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 6718e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom 6728e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom private void Bits32ToBytes(int in, byte[] b, int offset) 6738e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom { 6748e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b[offset] = (byte)in; 6758e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b[offset + 1] = (byte)(in >> 8); 6768e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b[offset + 2] = (byte)(in >> 16); 6778e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom b[offset + 3] = (byte)(in >> 24); 6788e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 6798e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom} 680