1 /** 2 * Serpent in x86-32 asm 3 * 4 * Copyright: 5 * (C) 1999-2007 Jack Lloyd 6 * (C) 2014-2015 Etienne Cimon 7 * 8 * License: 9 * Botan is released under the Simplified BSD License (see LICENSE.md) 10 */ 11 module botan.block.serp_x86_32; 12 13 import botan.constants; 14 static if (BOTAN_HAS_SERPENT_X86_32): 15 16 import botan.block.serpent; 17 import botan.utils.loadstor; 18 import botan.utils.asm_x86_32.asm_x86_32; 19 import botan.block.block_cipher; 20 import botan.utils.mem_ops; 21 22 /** 23 * Serpent implementation in x86-32 assembly 24 */ 25 final class Serpent_X86_32 : Serpent 26 { 27 public: 28 /* 29 * Serpent Encryption 30 */ 31 override void encryptN(const(ubyte)* input, ubyte* output, size_t blocks) 32 { 33 auto keys = this.getRoundKeys().ptr; 34 35 foreach (size_t i; 0 .. blocks) 36 { 37 botan_serpent_x86_32_encrypt(input, output, keys); 38 input += BLOCK_SIZE; 39 output += BLOCK_SIZE; 40 } 41 } 42 /* 43 * Serpent Decryption 44 */ 45 override void decryptN(const(ubyte)* input, ubyte* output, size_t blocks) 46 { 47 auto keys = this.getRoundKeys().ptr; 48 49 foreach (size_t i; 0 .. blocks) 50 { 51 botan_serpent_x86_32_decrypt(input, output, keys); 52 input += BLOCK_SIZE; 53 output += BLOCK_SIZE; 54 } 55 } 56 57 override @property size_t parallelism() const { return 1; } 58 override BlockCipher clone() const { return new Serpent_X86_32; } 59 protected: 60 /* 61 * Serpent Key Schedule 62 */ 63 override void keySchedule(const(ubyte)* key, size_t length) 64 { 65 SecureVector!uint W = SecureVector!uint(140); 66 foreach (size_t i; 0 .. (length / 4)) 67 W[i] = loadLittleEndian!uint(key, i); 68 W[length / 4] |= uint(1) << ((length%4)*8); 69 70 botan_serpent_x86_32_key_schedule(W.ptr); 71 this.setRoundKeys(*cast(uint[132]*) &W[8]); 72 } 73 74 } 75 76 /** 77 * Entry point for Serpent encryption in x86 asm 78 * Params: 79 * input = the input block 80 * output = the output block 81 * ks = the key schedule 82 */ 83 extern(C) 84 void botan_serpent_x86_32_encrypt(const(ubyte)* input, ubyte* output, in uint* ks ) pure 85 { 86 87 enum PUSHED = 4; 88 enum ASM = START_ASM ~ 89 "naked;\n" ~ 90 SPILL_REGS() ~ 91 ASSIGN(EBP, ARG(PUSHED, 1)) /* input block */ ~ 92 ASSIGN(EAX, ARRAY4(EBP, 0)) ~ 93 ASSIGN(EBX, ARRAY4(EBP, 1)) ~ 94 ASSIGN(ECX, ARRAY4(EBP, 2)) ~ 95 ASSIGN(EDX, ARRAY4(EBP, 3)) ~ 96 97 ASSIGN(EDI, ARG(PUSHED, 3)) ~ /* round keys */ 98 ZEROIZE(EBP) ~ 99 100 E_ROUND!SBOX_E1(EAX, EBX, ECX, EDX, EBP, 0 ) ~ 101 E_ROUND!SBOX_E2(EAX, EBX, ECX, EDX, EBP, 1 ) ~ 102 E_ROUND!SBOX_E3(EAX, EBX, ECX, EDX, EBP, 2 ) ~ 103 E_ROUND!SBOX_E4(EAX, EBX, ECX, EDX, EBP, 3 ) ~ 104 E_ROUND!SBOX_E5(EAX, EBX, ECX, EDX, EBP, 4 ) ~ 105 E_ROUND!SBOX_E6(EAX, EBX, ECX, EDX, EBP, 5 ) ~ 106 E_ROUND!SBOX_E7(EAX, EBX, ECX, EDX, EBP, 6 ) ~ 107 E_ROUND!SBOX_E8(EAX, EBX, ECX, EDX, EBP, 7 ) ~ 108 109 E_ROUND!SBOX_E1(EAX, EBX, ECX, EDX, EBP, 8 ) ~ 110 E_ROUND!SBOX_E2(EAX, EBX, ECX, EDX, EBP, 9 ) ~ 111 E_ROUND!SBOX_E3(EAX, EBX, ECX, EDX, EBP, 10 ) ~ 112 E_ROUND!SBOX_E4(EAX, EBX, ECX, EDX, EBP, 11 ) ~ 113 E_ROUND!SBOX_E5(EAX, EBX, ECX, EDX, EBP, 12 ) ~ 114 E_ROUND!SBOX_E6(EAX, EBX, ECX, EDX, EBP, 13 ) ~ 115 E_ROUND!SBOX_E7(EAX, EBX, ECX, EDX, EBP, 14 ) ~ 116 E_ROUND!SBOX_E8(EAX, EBX, ECX, EDX, EBP, 15 ) ~ 117 118 E_ROUND!SBOX_E1(EAX, EBX, ECX, EDX, EBP, 16 ) ~ 119 E_ROUND!SBOX_E2(EAX, EBX, ECX, EDX, EBP, 17 ) ~ 120 E_ROUND!SBOX_E3(EAX, EBX, ECX, EDX, EBP, 18 ) ~ 121 E_ROUND!SBOX_E4(EAX, EBX, ECX, EDX, EBP, 19 ) ~ 122 E_ROUND!SBOX_E5(EAX, EBX, ECX, EDX, EBP, 20 ) ~ 123 E_ROUND!SBOX_E6(EAX, EBX, ECX, EDX, EBP, 21 ) ~ 124 E_ROUND!SBOX_E7(EAX, EBX, ECX, EDX, EBP, 22 ) ~ 125 E_ROUND!SBOX_E8(EAX, EBX, ECX, EDX, EBP, 23 ) ~ 126 127 E_ROUND!SBOX_E1(EAX, EBX, ECX, EDX, EBP, 24 ) ~ 128 E_ROUND!SBOX_E2(EAX, EBX, ECX, EDX, EBP, 25 ) ~ 129 E_ROUND!SBOX_E3(EAX, EBX, ECX, EDX, EBP, 26 ) ~ 130 E_ROUND!SBOX_E4(EAX, EBX, ECX, EDX, EBP, 27 ) ~ 131 E_ROUND!SBOX_E5(EAX, EBX, ECX, EDX, EBP, 28 ) ~ 132 E_ROUND!SBOX_E6(EAX, EBX, ECX, EDX, EBP, 29 ) ~ 133 E_ROUND!SBOX_E7(EAX, EBX, ECX, EDX, EBP, 30 ) ~ 134 135 KEY_XOR(EAX, EBX, ECX, EDX, 31) ~ 136 SBOX_E8(EAX, EBX, ECX, EDX, EBP) ~ 137 KEY_XOR(EAX, EBX, ECX, EDX, 32) ~ 138 139 ASSIGN(EBP, ARG(PUSHED, 2)) /* output block */ ~ 140 ASSIGN(ARRAY4(EBP, 0), EAX) ~ 141 ASSIGN(ARRAY4(EBP, 1), EBX) ~ 142 ASSIGN(ARRAY4(EBP, 2), ECX) ~ 143 ASSIGN(ARRAY4(EBP, 3), EDX) ~ 144 RESTORE_REGS() ~ 145 "ret;\n" ~ 146 END_ASM; 147 mixin(ASM); 148 } 149 150 /** 151 * Entry point for Serpent decryption in x86 asm 152 * Params: 153 * input = the input block 154 * output = the output block 155 * ks = the key schedule 156 */ 157 extern(C) 158 void botan_serpent_x86_32_decrypt(const(ubyte)* input, ubyte* output, in uint* ks) pure 159 { 160 161 enum PUSHED = 4; 162 163 enum ASM = START_ASM ~ 164 "naked;" ~ 165 SPILL_REGS() ~ 166 ASSIGN(EBP, ARG(PUSHED, 1)) ~ /* input block */ 167 ASSIGN(EAX, ARRAY4(EBP, 0)) ~ 168 ASSIGN(EBX, ARRAY4(EBP, 1)) ~ 169 ASSIGN(ECX, ARRAY4(EBP, 2)) ~ 170 ASSIGN(EDX, ARRAY4(EBP, 3)) ~ 171 172 ASSIGN(EDI, ARG(PUSHED, 3)) ~ /* round keys */ 173 174 ZEROIZE(EBP) ~ 175 176 KEY_XOR(EAX, EBX, ECX, EDX, 32) ~ 177 SBOX_D8(EAX, EBX, ECX, EDX, EBP) ~ 178 KEY_XOR(EAX, EBX, ECX, EDX, 31) ~ 179 180 D_ROUND!SBOX_D7(EAX, EBX, ECX, EDX, EBP, 30) ~ 181 D_ROUND!SBOX_D6(EAX, EBX, ECX, EDX, EBP, 29) ~ 182 D_ROUND!SBOX_D5(EAX, EBX, ECX, EDX, EBP, 28) ~ 183 D_ROUND!SBOX_D4(EAX, EBX, ECX, EDX, EBP, 27) ~ 184 D_ROUND!SBOX_D3(EAX, EBX, ECX, EDX, EBP, 26) ~ 185 D_ROUND!SBOX_D2(EAX, EBX, ECX, EDX, EBP, 25) ~ 186 D_ROUND!SBOX_D1(EAX, EBX, ECX, EDX, EBP, 24) ~ 187 188 D_ROUND!SBOX_D8(EAX, EBX, ECX, EDX, EBP, 23) ~ 189 D_ROUND!SBOX_D7(EAX, EBX, ECX, EDX, EBP, 22) ~ 190 D_ROUND!SBOX_D6(EAX, EBX, ECX, EDX, EBP, 21) ~ 191 D_ROUND!SBOX_D5(EAX, EBX, ECX, EDX, EBP, 20) ~ 192 D_ROUND!SBOX_D4(EAX, EBX, ECX, EDX, EBP, 19) ~ 193 D_ROUND!SBOX_D3(EAX, EBX, ECX, EDX, EBP, 18) ~ 194 D_ROUND!SBOX_D2(EAX, EBX, ECX, EDX, EBP, 17) ~ 195 D_ROUND!SBOX_D1(EAX, EBX, ECX, EDX, EBP, 16) ~ 196 197 D_ROUND!SBOX_D8(EAX, EBX, ECX, EDX, EBP, 15) ~ 198 D_ROUND!SBOX_D7(EAX, EBX, ECX, EDX, EBP, 14) ~ 199 D_ROUND!SBOX_D6(EAX, EBX, ECX, EDX, EBP, 13) ~ 200 D_ROUND!SBOX_D5(EAX, EBX, ECX, EDX, EBP, 12) ~ 201 D_ROUND!SBOX_D4(EAX, EBX, ECX, EDX, EBP, 11) ~ 202 D_ROUND!SBOX_D3(EAX, EBX, ECX, EDX, EBP, 10) ~ 203 D_ROUND!SBOX_D2(EAX, EBX, ECX, EDX, EBP, 9) ~ 204 D_ROUND!SBOX_D1(EAX, EBX, ECX, EDX, EBP, 8) ~ 205 206 D_ROUND!SBOX_D8(EAX, EBX, ECX, EDX, EBP, 7) ~ 207 D_ROUND!SBOX_D7(EAX, EBX, ECX, EDX, EBP, 6) ~ 208 D_ROUND!SBOX_D6(EAX, EBX, ECX, EDX, EBP, 5) ~ 209 D_ROUND!SBOX_D5(EAX, EBX, ECX, EDX, EBP, 4) ~ 210 D_ROUND!SBOX_D4(EAX, EBX, ECX, EDX, EBP, 3) ~ 211 D_ROUND!SBOX_D3(EAX, EBX, ECX, EDX, EBP, 2) ~ 212 D_ROUND!SBOX_D2(EAX, EBX, ECX, EDX, EBP, 1) ~ 213 D_ROUND!SBOX_D1(EAX, EBX, ECX, EDX, EBP, 0) ~ 214 215 ASSIGN(EBP, ARG(PUSHED, 2)) ~ /* output block */ 216 ASSIGN(ARRAY4(EBP, 0), EAX) ~ 217 ASSIGN(ARRAY4(EBP, 1), EBX) ~ 218 ASSIGN(ARRAY4(EBP, 2), ECX) ~ 219 ASSIGN(ARRAY4(EBP, 3), EDX) ~ 220 RESTORE_REGS() ~ 221 "ret;\n" ~ 222 END_ASM; 223 mixin(ASM); 224 } 225 226 /** 227 * Entry point for Serpent key schedule in x86 asm 228 * Params: 229 * ks = holds the initial working key (padded), and is set to the 230 final key schedule 231 */ 232 extern(C) 233 void botan_serpent_x86_32_key_schedule(uint* ks) pure 234 { 235 string LOAD_AND_SBOX(alias SBOX)(ubyte MSG) { 236 return ASSIGN(EAX, ARRAY4(EDI, (4*MSG+ 8))) ~ 237 ASSIGN(EBX, ARRAY4(EDI, (4*MSG+ 9))) ~ 238 ASSIGN(ECX, ARRAY4(EDI, (4*MSG+10))) ~ 239 ASSIGN(EDX, ARRAY4(EDI, (4*MSG+11))) ~ 240 SBOX(EAX, EBX, ECX, EDX, EBP) ~ 241 ASSIGN(ARRAY4(EDI, (4*MSG+ 8)), EAX) ~ 242 ASSIGN(ARRAY4(EDI, (4*MSG+ 9)), EBX) ~ 243 ASSIGN(ARRAY4(EDI, (4*MSG+10)), ECX) ~ 244 ASSIGN(ARRAY4(EDI, (4*MSG+11)), EDX); 245 } 246 enum PUSHED = 4; 247 enum ASM = 248 START_ASM ~ 249 "naked;\n" ~ 250 SPILL_REGS() ~ 251 ASSIGN(EDI, ARG(PUSHED, 1)) ~ /* round keys */ 252 ASSIGN(ESI, IMM(8)) ~ 253 ADD_IMM(EDI, 32) ~ 254 255 START_LOOP("L_SERP_EXPANSION") ~ 256 ASSIGN(EAX, ARRAY4(EDI, -1)) ~ 257 ASSIGN(EBX, ARRAY4(EDI, -3)) ~ 258 ASSIGN(ECX, ARRAY4(EDI, -5)) ~ 259 ASSIGN(EDX, ARRAY4(EDI, -8)) ~ 260 261 ASSIGN(EBP, ESI) ~ 262 SUB_IMM(EBP, 8) ~ 263 XOR(EBP, IMM(0x9E3779B9)) ~ 264 XOR(EAX, EBX) ~ 265 XOR(ECX, EDX) ~ 266 XOR(EAX, EBP) ~ 267 XOR(EAX, ECX) ~ 268 269 ROTL_IMM(EAX, 11) ~ 270 271 ASSIGN(ARRAY4(EDI, 0), EAX) ~ 272 273 ADD_IMM(ESI, 1) ~ 274 ADD_IMM(EDI, 4) ~ 275 LOOP_UNTIL_EQ(ESI, 140, "L_SERP_EXPANSION") ~ 276 277 ASSIGN(EDI, ARG(PUSHED, 1)) ~ /* round keys */ 278 279 LOAD_AND_SBOX!SBOX_E4( 0 ) ~ 280 LOAD_AND_SBOX!SBOX_E3( 1 ) ~ 281 LOAD_AND_SBOX!SBOX_E2( 2 ) ~ 282 LOAD_AND_SBOX!SBOX_E1( 3 ) ~ 283 284 LOAD_AND_SBOX!SBOX_E8( 4 ) ~ 285 LOAD_AND_SBOX!SBOX_E7( 5 ) ~ 286 LOAD_AND_SBOX!SBOX_E6( 6 ) ~ 287 LOAD_AND_SBOX!SBOX_E5( 7 ) ~ 288 LOAD_AND_SBOX!SBOX_E4( 8 ) ~ 289 LOAD_AND_SBOX!SBOX_E3( 9 ) ~ 290 LOAD_AND_SBOX!SBOX_E2(10 ) ~ 291 LOAD_AND_SBOX!SBOX_E1(11 ) ~ 292 293 LOAD_AND_SBOX!SBOX_E8(12 ) ~ 294 LOAD_AND_SBOX!SBOX_E7(13 ) ~ 295 LOAD_AND_SBOX!SBOX_E6(14 ) ~ 296 LOAD_AND_SBOX!SBOX_E5(15 ) ~ 297 LOAD_AND_SBOX!SBOX_E4(16 ) ~ 298 LOAD_AND_SBOX!SBOX_E3(17 ) ~ 299 LOAD_AND_SBOX!SBOX_E2(18 ) ~ 300 LOAD_AND_SBOX!SBOX_E1(19 ) ~ 301 302 LOAD_AND_SBOX!SBOX_E8(20 ) ~ 303 LOAD_AND_SBOX!SBOX_E7(21 ) ~ 304 LOAD_AND_SBOX!SBOX_E6(22 ) ~ 305 LOAD_AND_SBOX!SBOX_E5(23 ) ~ 306 LOAD_AND_SBOX!SBOX_E4(24 ) ~ 307 LOAD_AND_SBOX!SBOX_E3(25 ) ~ 308 LOAD_AND_SBOX!SBOX_E2(26 ) ~ 309 LOAD_AND_SBOX!SBOX_E1(27 ) ~ 310 311 LOAD_AND_SBOX!SBOX_E8(28 ) ~ 312 LOAD_AND_SBOX!SBOX_E7(29 ) ~ 313 LOAD_AND_SBOX!SBOX_E6(30 ) ~ 314 LOAD_AND_SBOX!SBOX_E5(31 ) ~ 315 LOAD_AND_SBOX!SBOX_E4(32 ) ~ 316 317 RESTORE_REGS() ~ 318 "ret;\n"~ 319 END_ASM; 320 321 mixin(ASM); 322 } 323 324 string E_ROUND(alias SBOX)(string A, string B, string C, string D, string T, ubyte N) 325 { 326 return KEY_XOR(A, B, C, D, N) ~ 327 SBOX(A, B, C, D, T) ~ 328 TRANSFORM(A, B, C, D, T); 329 } 330 331 string D_ROUND(alias SBOX)(string A, string B, string C, string D, string T, ubyte N) 332 { 333 return I_TRANSFORM(A, B, C, D, T) ~ 334 SBOX(A, B, C, D, T) ~ 335 KEY_XOR(A, B, C, D, N); 336 } 337 338 string KEY_XOR(string A, string B, string C, string D, ubyte N) { 339 return XOR(A, ARRAY4(EDI, (4*N ))) ~ 340 XOR(B, ARRAY4(EDI, (4*N+1))) ~ 341 XOR(C, ARRAY4(EDI, (4*N+2))) ~ 342 XOR(D, ARRAY4(EDI, (4*N+3))); 343 } 344 345 string TRANSFORM(string A, string B, string C, string D, string T) { 346 return ROTL_IMM(A, 13) ~ 347 ROTL_IMM(C, 3) ~ 348 SHL2_3(T, A) ~ 349 XOR(B, A) ~ 350 XOR(D, C) ~ 351 XOR(B, C) ~ 352 XOR(D, T) ~ 353 ROTL_IMM(B, 1) ~ 354 ROTL_IMM(D, 7) ~ 355 ASSIGN(T, B) ~ 356 SHL_IMM(T, 7)~ 357 XOR(A, B) ~ 358 XOR(C, D) ~ 359 XOR(A, D) ~ 360 XOR(C, T) ~ 361 ROTL_IMM(A, 5) ~ 362 ROTL_IMM(C, 22); 363 } 364 365 string I_TRANSFORM(string A, string B, string C, string D, string T) { 366 return ROTR_IMM(C, 22) ~ 367 ROTR_IMM(A, 5) ~ 368 ASSIGN(T, B) ~ 369 SHL_IMM(T, 7)~ 370 XOR(A, B) ~ 371 XOR(C, D) ~ 372 XOR(A, D) ~ 373 XOR(C, T) ~ 374 ROTR_IMM(D, 7) ~ 375 ROTR_IMM(B, 1) ~ 376 SHL2_3(T, A) ~ 377 XOR(B, C) ~ 378 XOR(D, C) ~ 379 XOR(B, A) ~ 380 XOR(D, T) ~ 381 ROTR_IMM(C, 3) ~ 382 ROTR_IMM(A, 13); 383 } 384 string SBOX_E1(string A, string B, string C, string D, string T) 385 { 386 return XOR(D, A) ~ 387 ASSIGN(T, B) ~ 388 AND(B, D) ~ 389 XOR(T, C) ~ 390 XOR(B, A) ~ 391 OR(A, D) ~ 392 XOR(A, T) ~ 393 XOR(T, D) ~ 394 XOR(D, C) ~ 395 OR(C, B) ~ 396 XOR(C, T) ~ 397 NOT(T) ~ 398 OR(T, B) ~ 399 XOR(B, D) ~ 400 XOR(B, T) ~ 401 OR(D, A) ~ 402 XOR(B, D) ~ 403 XOR(T, D) ~ 404 ASSIGN(D, A) ~ 405 ASSIGN(A, B) ~ 406 ASSIGN(B, T); 407 } 408 string SBOX_E2(string A, string B, string C, string D, string T) 409 { 410 return NOT(A) ~ 411 NOT(C) ~ 412 ASSIGN(T, A) ~ 413 AND(A, B) ~ 414 XOR(C, A) ~ 415 OR(A, D) ~ 416 XOR(D, C) ~ 417 XOR(B, A) ~ 418 XOR(A, T) ~ 419 OR(T, B) ~ 420 XOR(B, D) ~ 421 OR(C, A) ~ 422 AND(C, T) ~ 423 XOR(A, B) ~ 424 AND(B, C) ~ 425 XOR(B, A) ~ 426 AND(A, C) ~ 427 XOR(T, A) ~ 428 ASSIGN(A, C) ~ 429 ASSIGN(C, D) ~ 430 ASSIGN(D, B) ~ 431 ASSIGN(B, T); 432 } 433 434 string SBOX_E3(string A, string B, string C, string D, string T) { 435 return ASSIGN(T, A) ~ 436 AND(A, C) ~ 437 XOR(A, D) ~ 438 XOR(C, B) ~ 439 XOR(C, A) ~ 440 OR(D, T) ~ 441 XOR(D, B) ~ 442 XOR(T, C) ~ 443 ASSIGN(B, D) ~ 444 OR(D, T) ~ 445 XOR(D, A) ~ 446 AND(A, B) ~ 447 XOR(T, A) ~ 448 XOR(B, D) ~ 449 XOR(B, T) ~ 450 NOT(T) ~ 451 ASSIGN(A, C) ~ 452 ASSIGN(C, B) ~ 453 ASSIGN(B, D) ~ 454 ASSIGN(D, T); 455 456 } 457 458 string SBOX_E4(string A, string B, string C, string D, string T) { 459 return ASSIGN(T, A) ~ 460 OR(A, D) ~ 461 XOR(D, B) ~ 462 AND(B, T) ~ 463 XOR(T, C) ~ 464 XOR(C, D) ~ 465 AND(D, A) ~ 466 OR(T, B) ~ 467 XOR(D, T) ~ 468 XOR(A, B) ~ 469 AND(T, A) ~ 470 XOR(B, D) ~ 471 XOR(T, C) ~ 472 OR(B, A) ~ 473 XOR(B, C) ~ 474 XOR(A, D) ~ 475 ASSIGN(C, B) ~ 476 OR(B, D) ~ 477 XOR(B, A) ~ 478 ASSIGN(A, B) ~ 479 ASSIGN(B, C) ~ 480 ASSIGN(C, D) ~ 481 ASSIGN(D, T); 482 } 483 484 string SBOX_E5(string A, string B, string C, string D, string T) { 485 return XOR(B, D) ~ 486 NOT(D) ~ 487 XOR(C, D) ~ 488 XOR(D, A) ~ 489 ASSIGN(T, B) ~ 490 AND(B, D) ~ 491 XOR(B, C) ~ 492 XOR(T, D) ~ 493 XOR(A, T) ~ 494 AND(C, T) ~ 495 XOR(C, A) ~ 496 AND(A, B) ~ 497 XOR(D, A) ~ 498 OR(T, B) ~ 499 XOR(T, A) ~ 500 OR(A, D) ~ 501 XOR(A, C) ~ 502 AND(C, D) ~ 503 NOT(A) ~ 504 XOR(T, C) ~ 505 ASSIGN(C, A) ~ 506 ASSIGN(A, B) ~ 507 ASSIGN(B, T); 508 } 509 510 string SBOX_E6(string A, string B, string C, string D, string T) { 511 return XOR(A, B) ~ 512 XOR(B, D) ~ 513 NOT(D) ~ 514 ASSIGN(T, B) ~ 515 AND(B, A) ~ 516 XOR(C, D) ~ 517 XOR(B, C) ~ 518 OR(C, T) ~ 519 XOR(T, D) ~ 520 AND(D, B) ~ 521 XOR(D, A) ~ 522 XOR(T, B) ~ 523 XOR(T, C) ~ 524 XOR(C, A) ~ 525 AND(A, D) ~ 526 NOT(C) ~ 527 XOR(A, T) ~ 528 OR(T, D) ~ 529 XOR(T, C) ~ 530 ASSIGN(C, A) ~ 531 ASSIGN(A, B) ~ 532 ASSIGN(B, D) ~ 533 ASSIGN(D, T); 534 } 535 536 string SBOX_E7(string A, string B, string C, string D, string T) { 537 return NOT(C) ~ 538 ASSIGN(T, D) ~ 539 AND(D, A) ~ 540 XOR(A, T) ~ 541 XOR(D, C) ~ 542 OR(C, T) ~ 543 XOR(B, D) ~ 544 XOR(C, A) ~ 545 OR(A, B) ~ 546 XOR(C, B) ~ 547 XOR(T, A) ~ 548 OR(A, D) ~ 549 XOR(A, C) ~ 550 XOR(T, D) ~ 551 XOR(T, A) ~ 552 NOT(D) ~ 553 AND(C, T) ~ 554 XOR(C, D) ~ 555 ASSIGN(D, C) ~ 556 ASSIGN(C, T); 557 } 558 559 string SBOX_E8(string A, string B, string C, string D, string T) { 560 return ASSIGN(T, B) ~ 561 OR(B, C) ~ 562 XOR(B, D) ~ 563 XOR(T, C) ~ 564 XOR(C, B) ~ 565 OR(D, T) ~ 566 AND(D, A) ~ 567 XOR(T, C) ~ 568 XOR(D, B) ~ 569 OR(B, T) ~ 570 XOR(B, A) ~ 571 OR(A, T) ~ 572 XOR(A, C) ~ 573 XOR(B, T) ~ 574 XOR(C, B) ~ 575 AND(B, A) ~ 576 XOR(B, T) ~ 577 NOT(C) ~ 578 OR(C, A) ~ 579 XOR(T, C) ~ 580 ASSIGN(C, B) ~ 581 ASSIGN(B, D) ~ 582 ASSIGN(D, A) ~ 583 ASSIGN(A, T); 584 } 585 586 string SBOX_D1(string A, string B, string C, string D, string T) { 587 return NOT(C) ~ 588 ASSIGN(T, B) ~ 589 OR(B, A) ~ 590 NOT(T) ~ 591 XOR(B, C) ~ 592 OR(C, T) ~ 593 XOR(B, D) ~ 594 XOR(A, T) ~ 595 XOR(C, A) ~ 596 AND(A, D) ~ 597 XOR(T, A) ~ 598 OR(A, B) ~ 599 XOR(A, C) ~ 600 XOR(D, T) ~ 601 XOR(C, B) ~ 602 XOR(D, A) ~ 603 XOR(D, B) ~ 604 AND(C, D) ~ 605 XOR(T, C) ~ 606 ASSIGN(C, B) ~ 607 ASSIGN(B, T); 608 } 609 610 string SBOX_D2(string A, string B, string C, string D, string T) { 611 return ASSIGN(T, B) ~ 612 XOR(B, D) ~ 613 AND(D, B) ~ 614 XOR(T, C) ~ 615 XOR(D, A) ~ 616 OR(A, B) ~ 617 XOR(C, D) ~ 618 XOR(A, T) ~ 619 OR(A, C) ~ 620 XOR(B, D) ~ 621 XOR(A, B) ~ 622 OR(B, D) ~ 623 XOR(B, A) ~ 624 NOT(T) ~ 625 XOR(T, B) ~ 626 OR(B, A) ~ 627 XOR(B, A) ~ 628 OR(B, T) ~ 629 XOR(D, B) ~ 630 ASSIGN(B, A) ~ 631 ASSIGN(A, T) ~ 632 ASSIGN(T, D) ~ 633 ASSIGN(D, C) ~ 634 ASSIGN(C, T); 635 } 636 637 string SBOX_D3(string A, string B, string C, string D, string T) { 638 return XOR(C, D) ~ 639 XOR(D, A) ~ 640 ASSIGN(T, D) ~ 641 AND(D, C) ~ 642 XOR(D, B) ~ 643 OR(B, C) ~ 644 XOR(B, T) ~ 645 AND(T, D) ~ 646 XOR(C, D) ~ 647 AND(T, A) ~ 648 XOR(T, C) ~ 649 AND(C, B) ~ 650 OR(C, A) ~ 651 NOT(D) ~ 652 XOR(C, D) ~ 653 XOR(A, D) ~ 654 AND(A, B) ~ 655 XOR(D, T) ~ 656 XOR(D, A) ~ 657 ASSIGN(A, B) ~ 658 ASSIGN(B, T); 659 } 660 661 string SBOX_D4(string A, string B, string C, string D, string T) { 662 return ASSIGN(T, C) ~ 663 XOR(C, B) ~ 664 XOR(A, C) ~ 665 AND(T, C) ~ 666 XOR(T, A) ~ 667 AND(A, B) ~ 668 XOR(B, D) ~ 669 OR(D, T) ~ 670 XOR(C, D) ~ 671 XOR(A, D) ~ 672 XOR(B, T) ~ 673 AND(D, C) ~ 674 XOR(D, B) ~ 675 XOR(B, A) ~ 676 OR(B, C) ~ 677 XOR(A, D) ~ 678 XOR(B, T) ~ 679 XOR(A, B) ~ 680 ASSIGN(T, A) ~ 681 ASSIGN(A, C) ~ 682 ASSIGN(C, D) ~ 683 ASSIGN(D, T); 684 685 } 686 687 string SBOX_D5(string A, string B, string C, string D, string T) { 688 return ASSIGN(T, C) ~ 689 AND(C, D) ~ 690 XOR(C, B) ~ 691 OR(B, D) ~ 692 AND(B, A) ~ 693 XOR(T, C) ~ 694 XOR(T, B) ~ 695 AND(B, C) ~ 696 NOT(A) ~ 697 XOR(D, T) ~ 698 XOR(B, D) ~ 699 AND(D, A) ~ 700 XOR(D, C) ~ 701 XOR(A, B) ~ 702 AND(C, A) ~ 703 XOR(D, A) ~ 704 XOR(C, T) ~ 705 OR(C, D) ~ 706 XOR(D, A) ~ 707 XOR(C, B) ~ 708 ASSIGN(B, D) ~ 709 ASSIGN(D, T); 710 } 711 712 string SBOX_D6(string A, string B, string C, string D, string T) { 713 return NOT(B) ~ 714 ASSIGN(T, D) ~ 715 XOR(C, B) ~ 716 OR(D, A) ~ 717 XOR(D, C) ~ 718 OR(C, B) ~ 719 AND(C, A) ~ 720 XOR(T, D) ~ 721 XOR(C, T) ~ 722 OR(T, A) ~ 723 XOR(T, B) ~ 724 AND(B, C) ~ 725 XOR(B, D) ~ 726 XOR(T, C) ~ 727 AND(D, T) ~ 728 XOR(T, B) ~ 729 XOR(D, T) ~ 730 NOT(T) ~ 731 XOR(D, A) ~ 732 ASSIGN(A, B) ~ 733 ASSIGN(B, T) ~ 734 ASSIGN(T, D) ~ 735 ASSIGN(D, C) ~ 736 ASSIGN(C, T); 737 } 738 739 string SBOX_D7(string A, string B, string C, string D, string T) { 740 return XOR(A, C) ~ 741 ASSIGN(T, C) ~ 742 AND(C, A) ~ 743 XOR(T, D) ~ 744 NOT(C) ~ 745 XOR(D, B) ~ 746 XOR(C, D) ~ 747 OR(T, A) ~ 748 XOR(A, C) ~ 749 XOR(D, T) ~ 750 XOR(T, B) ~ 751 AND(B, D) ~ 752 XOR(B, A) ~ 753 XOR(A, D) ~ 754 OR(A, C) ~ 755 XOR(D, B) ~ 756 XOR(T, A) ~ 757 ASSIGN(A, B) ~ 758 ASSIGN(B, C) ~ 759 ASSIGN(C, T); 760 } 761 762 string SBOX_D8(string A, string B, string C, string D, string T) { 763 return ASSIGN(T, C) ~ 764 XOR(C, A) ~ 765 AND(A, D) ~ 766 OR(T, D) ~ 767 NOT(C) ~ 768 XOR(D, B) ~ 769 OR(B, A) ~ 770 XOR(A, C) ~ 771 AND(C, T) ~ 772 AND(D, T) ~ 773 XOR(B, C) ~ 774 XOR(C, A) ~ 775 OR(A, C) ~ 776 XOR(T, B) ~ 777 XOR(A, D) ~ 778 XOR(D, T) ~ 779 OR(T, A) ~ 780 XOR(D, C) ~ 781 XOR(T, C) ~ 782 ASSIGN(C, B) ~ 783 ASSIGN(B, A) ~ 784 ASSIGN(A, D) ~ 785 ASSIGN(D, T); 786 }