1# Build perl code that calculates the key schedule
2# The key schedule is a maze of twisty little bit operations,
3# all different. You'd go nuts doing it by hand.
4
5use strict;
6use warnings;
7
8# This key schedule specification is right out of RFC2144
9$_ = <<END;
10   z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
11   z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA]
12   z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]
13   zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB]
14   K1  = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]
15   K2  = S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6]
16   K3  = S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9]
17   K4  = S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC]
18   x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]
19   x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]
20   x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]
21   xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3]
22   K5  = S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8]
23   K6  = S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD]
24   K7  = S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3]
25   K8  = S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7]
26   z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
27   z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA]
28   z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]
29   zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB]
30   K9  = S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9]
31   K10 = S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC]
32   K11 = S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2]
33   K12 = S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6]
34   x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]
35   x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]
36   x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]
37   xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3]
38   K13 = S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3]
39   K14 = S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7]
40   K15 = S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8]
41   K16 = S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD]
42END
43
44my %table = (
45'x0x1x2x3' => '$s',
46'x4x5x6x7' => '$t',
47'x8x9xAxB' => '$u',
48'xCxDxExF' => '$v',
49'z0z1z2z3' => '$w',
50'z4z5z6z7' => '$x',
51'z8z9zAzB' => '$y',
52'zCzDzEzF' => '$z',
53'x0' => '$s>>24&255',
54'x1' => '$s>>16&255',
55'x2' => '$s>>8&255',
56'x3' => '$s&255',
57'x4' => '$t>>24&255',
58'x5' => '$t>>16&255',
59'x6' => '$t>>8&255',
60'x7' => '$t&255',
61'x8' => '$u>>24&255',
62'x9' => '$u>>16&255',
63'xA' => '$u>>8&255',
64'xB' => '$u&255',
65'xC' => '$v>>24&255',
66'xD' => '$v>>16&255',
67'xE' => '$v>>8&255',
68'xF' => '$v&255',
69'z0' => '$w>>24&255',
70'z1' => '$w>>16&255',
71'z2' => '$w>>8&255',
72'z3' => '$w&255',
73'z4' => '$x>>24&255',
74'z5' => '$x>>16&255',
75'z6' => '$x>>8&255',
76'z7' => '$x&255',
77'z8' => '$y>>24&255',
78'z9' => '$y>>16&255',
79'zA' => '$y>>8&255',
80'zB' => '$y&255',
81'zC' => '$z>>24&255',
82'zD' => '$z>>16&255',
83'zE' => '$z>>8&255',
84'zF' => '$z&255',
85);
86
87s/ //g;
88s/\n/;\n/g;
89s/S/\$s/g;
90s/K\d+=/push\@k,/g;
91s/((?:[xz][0-9A-F])+)/$table{$1}||$1/eg;
92print;
93
94