cast5.bend
bend-osdev-cast5@0.1.0.0 · 522 lines · 0 definitions
1# CAST-128 (RFC 2144, The CAST-128 Encryption Algorithm, 1997), also called
2# CAST5: a 64-bit block cipher with keys of 40 to 128 bits in 8-bit steps.
3# This file also holds the S-boxes S1 .. S4 and round functions that
4# CAST-256 (cast6.bend) shares.
5#
6# The block is two big-endian halves L, R; each round is the Feistel round
7# (L, R) -> (R, L xor f_i(R)) and the output is (R16, L16). Rounds 1, 4, 7,
8# 10, 13, 16 use f type 1, rounds 2, 5, ... type 2, rounds 3, 6, ... type 3:
9# type 1: I = (Km + D) <<< Kr, f = ((S1[Ia] xor S2[Ib]) - S3[Ic]) + S4[Id]
10# type 2: I = (Km xor D) <<< Kr, f = ((S1[Ia] - S2[Ib]) + S3[Ic]) xor S4[Id]
11# type 3: I = (Km - D) <<< Kr, f = ((S1[Ia] + S2[Ib]) xor S3[Ic]) - S4[Id]
12# (Ia the most significant byte of I). Keys of up to 80 bits use 12 rounds,
13# longer ones 16 (2.5); a shorter key is zero-padded to 128 bits. The key
14# schedule (2.4) computes K1 .. K32 with S5 .. S8; round i uses Km_i = K_i and
15# Kr_i = the low 5 bits of K_(16+i).
16#
17# The rounds are cipher-core.bend's Feistel rounds over f, followed by the
18# exchange of the halves, so decryption (the exchange, then the rounds undone
19# last to first: RFC 2144's decryption) undoes encryption for every key and
20# block, whatever the S-boxes hold.
21import Base
22import bend-osdev-bytes@0.1.1.0/bytes.bend as B
23import bend-osdev-cipher-core@0.1.0.0/cipher_core.bend as L
24
25# BEGIN GENERATED by gen/tables.py: tables
26# S1 (RFC 2144, Appendix A)
27def cast.s1.list() -> List<&2, U32>:
28 [821772500, 2678128395, 1810681135, 1059425402, 505495343, 2617265619, 1610868032, 3483355465,
29 3218386727, 2294005173, 3791863952, 2563806837, 1852023008, 365126098, 3269944861, 584384398,
30 677919599, 3229601881, 4280515016, 2002735330, 1136869587, 3744433750, 2289869850, 2731719981,
31 2714362070, 879511577, 1639411079, 575934255, 717107937, 2857637483, 576097850, 2731753936,
32 1725645000, 2810460463, 5111599, 767152862, 2543075244, 1251459544, 1383482551, 3052681127,
33 3089939183, 3612463449, 1878520045, 1510570527, 2189125840, 2431448366, 582008916, 3163445557,
34 1265446783, 1354458274, 3529918736, 3202711853, 3073581712, 3912963487, 3029263377, 1275016285,
35 4249207360, 2905708351, 3304509486, 1442611557, 3585198765, 2712415662, 2731849581, 3248163920,
36 2283946226, 208555832, 2766454743, 1331405426, 1447828783, 3315356441, 3108627284, 2957404670,
37 2981538698, 3339933917, 1669711173, 286233437, 1465092821, 1782121619, 3862771680, 710211251,
38 980974943, 1651941557, 430374111, 2051154026, 704238805, 4128970897, 3144820574, 2857402727,
39 948965521, 3333752299, 2227686284, 718756367, 2269778983, 2731643755, 718440111, 2857816721,
40 3616097120, 1113355533, 2478022182, 410092745, 1811985197, 1944238868, 2696854588, 1415722873,
41 1682284203, 1060277122, 1998114690, 1503841958, 82706478, 2315155686, 1068173648, 845149890,
42 2167947013, 1768146376, 1993038550, 3566826697, 3390574031, 940016341, 3355073782, 2328040721,
43 904371731, 1205506512, 4094660742, 2816623006, 825647681, 85914773, 2857843460, 1249926541,
44 1417871568, 3287612, 3211054559, 3126306446, 1975924523, 1353700161, 2814456437, 2438597621,
45 1800716203, 722146342, 2873936343, 1151126914, 4160483941, 2877670899, 458611604, 2866078500,
46 3483680063, 770352098, 2652916994, 3367839148, 3940505011, 3585973912, 3809620402, 718646636,
47 2504206814, 2914927912, 3631288169, 2857486607, 2860018678, 575749918, 2857478043, 718488780,
48 2069512688, 3548183469, 453416197, 1106044049, 3032691430, 52586708, 3378514636, 3459808877,
49 3211506028, 1785789304, 218356169, 3571399134, 3759170522, 1194783844, 1523787992, 3007827094,
50 1975193539, 2555452411, 1341901877, 3045838698, 3776907964, 3217423946, 2802510864, 2889438986,
51 1057244207, 1636348243, 3761863214, 1462225785, 2632663439, 481089165, 718503062, 24497053,
52 3332243209, 3344655856, 3655024856, 3960371065, 1195698900, 2971415156, 3710176158, 2115785917,
53 4027663609, 3525578417, 2524296189, 2745972565, 3564906415, 1372086093, 1452307862, 2780501478,
54 1476592880, 3389271281, 18495466, 2378148571, 901398090, 891748256, 3279637769, 3157290713,
55 2560960102, 1447622437, 4284372637, 216884176, 2086908623, 1879786977, 3588903153, 2242455666,
56 2938092967, 3559082096, 2810645491, 758861177, 1121993112, 215018983, 642190776, 4169236812,
57 1196255959, 2081185372, 3508738393, 941322904, 4124243163, 2877523539, 1848581667, 2205260958,
58 3180453958, 2589345134, 3694731276, 550028657, 2519456284, 3789985535, 2973870856, 2093648313,
59 443148163, 46942275, 2734146937, 1117713533, 1115362972, 1523183689, 3717140224, 1551984063]
60
61# S2 (RFC 2144, Appendix A)
62def cast.s2.list() -> List<&2, U32>:
63 [522195092, 4010518363, 1776537470, 960447360, 4267822970, 4005896314, 1435016340, 1929119313,
64 2913464185, 1310552629, 3579470798, 3724818106, 2579771631, 1594623892, 417127293, 2715217907,
65 2696228731, 1508390405, 3994398868, 3925858569, 3695444102, 4019471449, 3129199795, 3770928635,
66 3520741761, 990456497, 4187484609, 2783367035, 21106139, 3840405339, 631373633, 3783325702,
67 532942976, 396095098, 3548038825, 4267192484, 2564721535, 2011709262, 2039648873, 620404603,
68 3776170075, 2898526339, 3612357925, 4159332703, 1645490516, 223693667, 1567101217, 3362177881,
69 1029951347, 3470931136, 3570957959, 1550265121, 119497089, 972513919, 907948164, 3840628539,
70 1613718692, 3594177948, 465323573, 2659255085, 654439692, 2575596212, 2699288441, 3127702412,
71 277098644, 624404830, 4100943870, 2717858591, 546110314, 2403699828, 3655377447, 1321679412,
72 4236791657, 1045293279, 4010672264, 895050893, 2319792268, 494945126, 1914543101, 2777056443,
73 3894764339, 2219737618, 311263384, 4275257268, 3458730721, 669096869, 3584475730, 3835122877,
74 3319158237, 3949359204, 2005142349, 2713102337, 2228954793, 3769984788, 569394103, 3855636576,
75 1425027204, 108000370, 2736431443, 3671869269, 3043122623, 1750473702, 2211081108, 762237499,
76 3972989403, 2798899386, 3061857628, 2943854345, 867476300, 964413654, 1591880597, 1594774276,
77 2179821409, 552026980, 3026064248, 3726140315, 2283577634, 3110545105, 2152310760, 582474363,
78 1582640421, 1383256631, 2043843868, 3322775884, 1217180674, 463797851, 2763038571, 480777679,
79 2718707717, 2289164131, 3118346187, 214354409, 200212307, 3810608407, 3025414197, 2674075964,
80 3997296425, 1847405948, 1342460550, 510035443, 4080271814, 815934613, 833030224, 1620250387,
81 1945732119, 2703661145, 3966000196, 1388869545, 3456054182, 2687178561, 2092620194, 562037615,
82 1356438536, 3409922145, 3261847397, 1688467115, 2150901366, 631725691, 3840332284, 549916902,
83 3455104640, 394546491, 837744717, 2114462948, 751520235, 2221554606, 2415360136, 3999097078,
84 2063029875, 803036379, 2702586305, 821456707, 3019566164, 360699898, 4018502092, 3511869016,
85 3677355358, 2402471449, 812317050, 49299192, 2570164949, 3259169295, 2816732080, 3331213574,
86 3101303564, 2156015656, 3705598920, 3546263921, 143268808, 3200304480, 1638124008, 3165189453,
87 3341807610, 578956953, 2193977524, 3638120073, 2333881532, 807278310, 658237817, 2969561766,
88 1641658566, 11683945, 3086995007, 148645947, 1138423386, 4158756760, 1981396783, 2401016740,
89 3699783584, 380097457, 2680394679, 2803068651, 3334260286, 441530178, 4016580796, 1375954390,
90 761952171, 891809099, 2183123478, 157052462, 3683840763, 1592404427, 341349109, 2438483839,
91 1417898363, 644327628, 2233032776, 2353769706, 2201510100, 220455161, 1815641738, 182899273,
92 2995019788, 3627381533, 3702638151, 2890684138, 1052606899, 588164016, 1681439879, 4038439418,
93 2405343923, 4229449282, 167996282, 1336969661, 1688053129, 2739224926, 1543734051, 1046297529,
94 1138201970, 2121126012, 115334942, 1819067631, 1902159161, 1941945968, 2206692869, 1159982321]
95
96# S3 (RFC 2144, Appendix A)
97def cast.s3.list() -> List<&2, U32>:
98 [2381300288, 637164959, 3952098751, 3893414151, 1197506559, 916448331, 2350892612, 2932787856,
99 3199334847, 4009478890, 3905886544, 1373570990, 2450425862, 4037870920, 3778841987, 2456817877,
100 286293407, 124026297, 3001279700, 1028597854, 3115296800, 4208886496, 2691114635, 2188540206,
101 1430237888, 1218109995, 3572471700, 308166588, 570424558, 2187009021, 2455094765, 307733056,
102 1310360322, 3135275007, 1384269543, 2388071438, 863238079, 2359263624, 2801553128, 3380786597,
103 2831162807, 1470087780, 1728663345, 4072488799, 1090516929, 532123132, 2389430977, 1132193179,
104 2578464191, 3051079243, 1670234342, 1434557849, 2711078940, 1241591150, 3314043432, 3435360113,
105 3091448339, 1812415473, 2198440252, 267246943, 796911696, 3619716990, 38830015, 1526438404,
106 2806502096, 374413614, 2943401790, 1489179520, 1603809326, 1920779204, 168801282, 260042626,
107 2358705581, 1563175598, 2397674057, 1356499128, 2217211040, 514611088, 2037363785, 2186468373,
108 4022173083, 2792511869, 2913485016, 1173701892, 4200428547, 3896427269, 1334932762, 2455136706,
109 602925377, 2835607854, 1613172210, 41346230, 2499634548, 2457437618, 2188827595, 41386358,
110 4172255629, 1313404830, 2405527007, 3801973774, 2217704835, 873260488, 2528884354, 2478092616,
111 4012915883, 2555359016, 2006953883, 2463913485, 575479328, 2218240648, 2099895446, 660001756,
112 2341502190, 3038761536, 3888151779, 3848713377, 3286851934, 1022894237, 1620365795, 3449594689,
113 1551255054, 15374395, 3570825345, 4249311020, 4151111129, 3181912732, 310226346, 1133119310,
114 530038928, 136043402, 2476768958, 3107506709, 2544909567, 1036173560, 2367337196, 1681395281,
115 1758231547, 3641649032, 306774401, 1575354324, 3716085866, 1990386196, 3114533736, 2455606671,
116 1262092282, 3124342505, 2768229131, 4210529083, 1833535011, 423410938, 660763973, 2187129978,
117 1639812000, 3508421329, 3467445492, 310289298, 272797111, 2188552562, 2456863912, 310240523,
118 677093832, 1013118031, 901835429, 3892695601, 1116285435, 3036471170, 1337354835, 243122523,
119 520626091, 277223598, 4244441197, 4194248841, 1766575121, 594173102, 316590669, 742362309,
120 3536858622, 4176435350, 3838792410, 2501204839, 1229605004, 3115755532, 1552908988, 2312334149,
121 979407927, 3959474601, 1148277331, 176638793, 3614686272, 2083809052, 40992502, 1340822838,
122 2731552767, 3535757508, 3560899520, 1354035053, 122129617, 7215240, 2732932949, 3118912700,
123 2718203926, 2539075635, 3609230695, 3725561661, 1928887091, 2882293555, 1988674909, 2063640240,
124 2491088897, 1459647954, 4189817080, 2302804382, 1113892351, 2237858528, 1927010603, 4002880361,
125 1856122846, 1594404395, 2944033133, 3855189863, 3474975698, 1643104450, 4054590833, 3431086530,
126 1730235576, 2984608721, 3084664418, 2131803598, 4178205752, 267404349, 1617849798, 1616132681,
127 1462223176, 736725533, 2327058232, 551665188, 2945899023, 1749386277, 2575514597, 1611482493,
128 674206544, 2201269090, 3642560800, 728599968, 1680547377, 2620414464, 1388111496, 453204106,
129 4156223445, 1094905244, 2754698257, 2201108165, 3757000246, 2704524545, 3922940700, 3996465027]
130
131# S4 (RFC 2144, Appendix A)
132def cast.s4.list() -> List<&2, U32>:
133 [2645754912, 532081118, 2814278639, 3530793624, 1246723035, 1689095255, 2236679235, 4194438865,
134 2116582143, 3859789411, 157234593, 2045505824, 4245003587, 1687664561, 4083425123, 605965023,
135 672431967, 1336064205, 3376611392, 214114848, 4258466608, 3232053071, 489488601, 605322005,
136 3998028058, 264917351, 1912574028, 756637694, 436560991, 202637054, 135989450, 85393697,
137 2152923392, 3896401662, 2895836408, 2145855233, 3535335007, 115294817, 3147733898, 1922296357,
138 3464822751, 4117858305, 1037454084, 2725193275, 2127856640, 1417604070, 1148013728, 1827919605,
139 642362335, 2929772533, 909348033, 1346338451, 3547799649, 297154785, 1917849091, 4161712827,
140 2883604526, 3968694238, 1469521537, 3780077382, 3375584256, 1763717519, 136166297, 4290970789,
141 1295325189, 2134727907, 2798151366, 1566297257, 3672928234, 2677174161, 2672173615, 965822077,
142 2780786062, 289653839, 1133871874, 3491843819, 35685304, 1068898316, 418943774, 672553190,
143 642281022, 2346158704, 1954014401, 3037126780, 4079815205, 2030668546, 3840588673, 672283427,
144 1776201016, 359975446, 3750173538, 555499703, 2769985273, 1324923, 69110472, 152125443,
145 3176785106, 3822147285, 1340634837, 798073664, 1434183902, 15393959, 216384236, 1303690150,
146 3881221631, 3711134124, 3960975413, 106373927, 2578434224, 1455997841, 1801814300, 1578393881,
147 1854262133, 3188178946, 3258078583, 2302670060, 1539295533, 3505142565, 3078625975, 2372746020,
148 549938159, 3278284284, 2620926080, 181285381, 2865321098, 3970029511, 68876850, 488006234,
149 1728155692, 2608167508, 836007927, 2435231793, 919367643, 3339422534, 3655756360, 1457871481,
150 40520939, 1380155135, 797931188, 234455205, 2255801827, 3990488299, 397000196, 739833055,
151 3077865373, 2871719860, 4022553888, 772369276, 390177364, 3853951029, 557662966, 740064294,
152 1640166671, 1699928825, 3535942136, 622006121, 3625353122, 68743880, 1742502, 219489963,
153 1664179233, 1577743084, 1236991741, 410585305, 2366487942, 823226535, 1050371084, 3426619607,
154 3586839478, 212779912, 4147118561, 1819446015, 1911218849, 530248558, 3486241071, 3252585495,
155 2886188651, 3410272728, 2342195030, 20547779, 2982490058, 3032363469, 3631753222, 312714466,
156 1870521650, 1493008054, 3491686656, 615382978, 4103671749, 2534517445, 1932181, 2196105170,
157 278426614, 6369430, 3274544417, 2913018367, 697336853, 2143000447, 2946413531, 701099306,
158 1558357093, 2805003052, 3500818408, 2321334417, 3567135975, 216290473, 3591032198, 23009561,
159 1996984579, 3735042806, 2024298078, 3739440863, 569400510, 2339758983, 3016033873, 3097871343,
160 3639523026, 3844324983, 3256173865, 795471839, 2951117563, 4101031090, 4091603803, 3603732598,
161 971261452, 534414648, 428311343, 3389027175, 2844869880, 694888862, 1227866773, 2456207019,
162 3043454569, 2614353370, 3749578031, 3676663836, 459166190, 4132644070, 1794958188, 51825668,
163 2252611902, 3084671440, 2036672799, 3436641603, 1099053433, 2469121526, 3059204941, 1323291266,
164 2061838604, 1018778475, 2233344254, 2553501054, 334295216, 3556750194, 1065731521, 183467730]
165
166# S5 (RFC 2144, Appendix A)
167def cast.s5.list() -> List<&2, U32>:
168 [2127105028, 745436345, 2601412319, 2788391185, 3093987327, 500390133, 1155374404, 389092991,
169 150729210, 3891597772, 3523549952, 1935325696, 716645080, 946045387, 2901812282, 1774124410,
170 3869435775, 4039581901, 3293136918, 3438657920, 948246080, 363898952, 3867875531, 1286266623,
171 1598556673, 68334250, 630723836, 1104211938, 1312863373, 613332731, 2377784574, 1101634306,
172 441780740, 3129959883, 1917973735, 2510624549, 3238456535, 2544211978, 3308894634, 1299840618,
173 4076074851, 1756332096, 3977027158, 297047435, 3790297736, 2265573040, 3621810518, 1311375015,
174 1667687725, 47300608, 3299642885, 2474112369, 201668394, 1468347890, 576830978, 3594690761,
175 3742605952, 1958042578, 1747032512, 3558991340, 1408974056, 3366841779, 682131401, 1033214337,
176 1545599232, 4265137049, 206503691, 103024618, 2855227313, 1337551222, 2428998917, 2963842932,
177 4015366655, 3852247746, 2796956967, 3865723491, 3747938335, 247794022, 3755824572, 702416469,
178 2434691994, 397379957, 851939612, 2314769512, 218229120, 1380406772, 62274761, 214451378,
179 3170103466, 2276210409, 3845813286, 28563499, 446592073, 1693330814, 3453727194, 29968656,
180 3093872512, 220656637, 2470637031, 77972100, 1667708854, 1358280214, 4064765667, 2395616961,
181 325977563, 4277240721, 4220025399, 3605526484, 3355147721, 811859167, 3069544926, 3962126810,
182 652502677, 3075892249, 4132761541, 3498924215, 1217549313, 3250244479, 3858715919, 3053989961,
183 1538642152, 2279026266, 2875879137, 574252750, 3324769229, 2651358713, 1758150215, 141295887,
184 2719868960, 3515574750, 4093007735, 4194485238, 1082055363, 3417560400, 395511885, 2966884026,
185 179534037, 3646028556, 3738688086, 1092926436, 2496269142, 257381841, 3772900718, 1636087230,
186 1477059743, 2499234752, 3811018894, 2675660129, 3285975680, 90732309, 1684827095, 1150307763,
187 1723134115, 3237045386, 1769919919, 1240018934, 815675215, 750138730, 2239792499, 1234303040,
188 1995484674, 138143821, 675421338, 1145607174, 1936608440, 3238603024, 2345230278, 2105974004,
189 323969391, 779555213, 3004902369, 2861610098, 1017501463, 2098600890, 2628620304, 2940611490,
190 2682542546, 1171473753, 3656571411, 3687208071, 4091869518, 393037935, 159126506, 1662887367,
191 1147106178, 391545844, 3452332695, 1891500680, 3016609650, 1851642611, 546529401, 1167818917,
192 3194020571, 2848076033, 3953471836, 575554290, 475796850, 4134673196, 450035699, 2351251534,
193 844027695, 1080539133, 86184846, 1554234488, 3692025454, 1972511363, 2018339607, 1491841390,
194 1141460869, 1061690759, 4244549243, 2008416118, 2351104703, 2868147542, 1598468138, 722020353,
195 1027143159, 212344630, 1387219594, 1725294528, 3745187956, 2500153616, 458938280, 4129215917,
196 1828119673, 544571780, 3503225445, 2297937496, 1241802790, 267843827, 2694610800, 1397140384,
197 1558801448, 3782667683, 1806446719, 929573330, 2234912681, 400817706, 616011623, 4121520928,
198 3603768725, 1761550015, 1968522284, 4053731006, 4192232858, 4005120285, 872482584, 3140537016,
199 3894607381, 2287405443, 1963876937, 3663887957, 1584857000, 2975024454, 1833426440, 4025083860]
200
201# S6 (RFC 2144, Appendix A)
202def cast.s6.list() -> List<&2, U32>:
203 [4143615901, 749497569, 1285769319, 3795025788, 2514159847, 23610292, 3974978748, 844452780,
204 3214870880, 3751928557, 2213566365, 1676510905, 448177848, 3730751033, 4086298418, 2307502392,
205 871450977, 3222878141, 4110862042, 3831651966, 2735270553, 1310974780, 2043402188, 1218528103,
206 2736035353, 4274605013, 2702448458, 3936360550, 2693061421, 162023535, 2827510090, 687910808,
207 23484817, 3784910947, 3371371616, 779677500, 3503626546, 3473927188, 4157212626, 3500679282,
208 4248902014, 2466621104, 3899384794, 1958663117, 925738300, 1283408968, 3669349440, 1840910019,
209 137959847, 2679828185, 1239142320, 1315376211, 1547541505, 1690155329, 739140458, 3128809933,
210 3933172616, 3876308834, 905091803, 1548541325, 4040461708, 3095483362, 144808038, 451078856,
211 676114313, 2861728291, 2469707347, 993665471, 373509091, 2599041286, 4025009006, 4170239449,
212 2149739950, 3275793571, 3749616649, 2794760199, 1534877388, 572371878, 2590613551, 1753320020,
213 3467782511, 1405125690, 4270405205, 633333386, 3026356924, 3475123903, 632057672, 2846462855,
214 1404951397, 3882875879, 3915906424, 195638627, 2385783745, 3902872553, 1233155085, 3355999740,
215 2380578713, 2702246304, 2144565621, 3663341248, 3894384975, 2502479241, 4248018925, 3094885567,
216 1594115437, 572884632, 3385116731, 767645374, 1331858858, 1475698373, 3793881790, 3532746431,
217 1321687957, 619889600, 1121017241, 3440213920, 2070816767, 2833025776, 1933951238, 4095615791,
218 890643334, 3874130214, 859025556, 360630002, 925594799, 1764062180, 3920222280, 4078305929,
219 979562269, 2810700344, 4087740022, 1949714515, 546639971, 1165388173, 3069891591, 1495988560,
220 922170659, 1291546247, 2107952832, 1813327274, 3406010024, 3306028637, 4241950635, 153207855,
221 2313154747, 1608695416, 1150242611, 1967526857, 721801357, 1220138373, 3691287617, 3356069787,
222 2112743302, 3281662835, 1111556101, 1778980689, 250857638, 2298507990, 673216130, 2846488510,
223 3207751581, 3562756981, 3008625920, 3417367384, 2198807050, 529510932, 3547516680, 3426503187,
224 2364944742, 102533054, 2294910856, 1617093527, 1204784762, 3066581635, 1019391227, 1069574518,
225 1317995090, 1691889997, 3661132003, 510022745, 3238594800, 1362108837, 1817929911, 2184153760,
226 805817662, 1953603311, 3699844737, 120799444, 2118332377, 207536705, 2282301548, 4120041617,
227 145305846, 2508124933, 3086745533, 3261524335, 1877257368, 2977164480, 3160454186, 2503252186,
228 4221677074, 759945014, 254147243, 2767453419, 3801518371, 629083197, 2471014217, 907280572,
229 3900796746, 940896768, 2751021123, 2625262786, 3161476951, 3661752313, 3260732218, 1425318020,
230 2977912069, 1496677566, 3988592072, 2140652971, 3126511541, 3069632175, 977771578, 1392695845,
231 1698528874, 1411812681, 1369733098, 1343739227, 3620887944, 1142123638, 67414216, 3102056737,
232 3088749194, 1626167401, 2546293654, 3941374235, 697522451, 33404913, 143560186, 2595682037,
233 994885535, 1247667115, 3859094837, 2699155541, 3547024625, 4114935275, 2968073508, 3199963069,
234 2732024527, 1237921620, 951448369, 1898488916, 1211705605, 2790989240, 2233243581, 3598044975]
235
236# S7 (RFC 2144, Appendix A)
237def cast.s7.list() -> List<&2, U32>:
238 [2246066201, 858518887, 1714274303, 3485882003, 713916271, 2879113490, 3730835617, 539548191,
239 36158695, 1298409750, 419087104, 1358007170, 749914897, 2989680476, 1261868530, 2995193822,
240 2690628854, 3443622377, 3780124940, 3796824509, 2976433025, 4259637129, 1551479000, 512490819,
241 1296650241, 951993153, 2436689437, 2460458047, 144139966, 3136204276, 310820559, 3068840729,
242 643875328, 1969602020, 1680088954, 2185813161, 3283332454, 672358534, 198762408, 896343282,
243 276269502, 3014846926, 84060815, 197145886, 376173866, 3943890818, 3813173521, 3545068822,
244 1316698879, 1598252827, 2633424951, 1233235075, 859989710, 2358460855, 3503838400, 3409603720,
245 1203513385, 1193654839, 2792018475, 2060853022, 207403770, 1144516871, 3068631394, 1121114134,
246 177607304, 3785736302, 326409831, 1929119770, 2983279095, 4183308101, 3474579288, 3200513878,
247 3228482096, 119610148, 1170376745, 3378393471, 3163473169, 951863017, 3337026068, 3135789130,
248 2907618374, 1183797387, 2015970143, 4045674555, 2182986399, 2952138740, 3928772205, 384012900,
249 2454997643, 10178499, 2879818989, 2596892536, 111523738, 2995089006, 451689641, 3196290696,
250 235406569, 1441906262, 3890558523, 3013735005, 4158569349, 1644036924, 376726067, 1006849064,
251 3664579700, 2041234796, 1021632941, 1374734338, 2566452058, 371631263, 4007144233, 490221539,
252 206551450, 3140638584, 1053219195, 1853335209, 3412429660, 3562156231, 735133835, 1623211703,
253 3104214392, 2738312436, 4096837757, 3366392578, 3110964274, 3956598718, 3196820781, 2038037254,
254 3877786376, 2339753847, 300912036, 3766732888, 2372630639, 1516443558, 4200396704, 1574567987,
255 4069441456, 4122592016, 2699739776, 146372218, 2748961456, 2043888151, 35287437, 2596680554,
256 655490400, 1132482787, 110692520, 1031794116, 2188192751, 1324057718, 1217253157, 919197030,
257 686247489, 3261139658, 1028237775, 3135486431, 3059715558, 2460921700, 986174950, 2661811465,
258 4062904701, 2752986992, 3709736643, 367056889, 1353824391, 731860949, 1650113154, 1778481506,
259 784341916, 357075625, 3608602432, 1074092588, 2480052770, 3811426202, 92751289, 877911070,
260 3600361838, 1231880047, 480201094, 3756190983, 3094495953, 434011822, 87971354, 363687820,
261 1717726236, 1901380172, 3926403882, 2481662265, 400339184, 1490350766, 2661455099, 1389319756,
262 2558787174, 784598401, 1983468483, 30828846, 3550527752, 2716276238, 3841122214, 1765724805,
263 1955612312, 1277890269, 1333098070, 1564029816, 2704417615, 1026694237, 3287671188, 1260819201,
264 3349086767, 1016692350, 1582273796, 1073413053, 1995943182, 694588404, 1025494639, 3323872702,
265 3551898420, 4146854327, 453260480, 1316140391, 1435673405, 3038941953, 3486689407, 1622062951,
266 403978347, 817677117, 950059133, 4246079218, 3278066075, 1486738320, 1417279718, 481875527,
267 2549965225, 3933690356, 760697757, 1452955855, 3897451437, 1177426808, 1702951038, 4085348628,
268 2447005172, 1084371187, 3516436277, 3068336338, 1073369276, 1027665953, 3284188590, 1230553676,
269 1368340146, 2226246512, 267243139, 2274220762, 4070734279, 2497715176, 2423353163, 2504755875]
270
271# S8 (RFC 2144, Appendix A)
272def cast.s8.list() -> List<&2, U32>:
273 [3793104909, 3151888380, 2817252029, 895778965, 2005530807, 3871412763, 237245952, 86829237,
274 296341424, 3851759377, 3974600970, 2475086196, 709006108, 1994621201, 2972577594, 937287164,
275 3734691505, 168608556, 3189338153, 2225080640, 3139713551, 3033610191, 3025041904, 77524477,
276 185966941, 1208824168, 2344345178, 1721625922, 3354191921, 1066374631, 1927223579, 1971335949,
277 2483503697, 1551748602, 2881383779, 2856329572, 3003241482, 48746954, 1398218158, 2050065058,
278 313056748, 4255789917, 393167848, 1912293076, 940740642, 3465845460, 3091687853, 2522601570,
279 2197016661, 1727764327, 364383054, 492521376, 1291706479, 3264136376, 1474851438, 1685747964,
280 2575719748, 1619776915, 1814040067, 970743798, 1561002147, 2925768690, 2123093554, 1880132620,
281 3151188041, 697884420, 2550985770, 2607674513, 2659114323, 110200136, 1489731079, 997519150,
282 1378877361, 3527870668, 478029773, 2766872923, 1022481122, 431258168, 1112503832, 897933369,
283 2635587303, 669726182, 3383752315, 918222264, 163866573, 3246985393, 3776823163, 114105080,
284 1903216136, 761148244, 3571337562, 1690750982, 3166750252, 1037045171, 1888456500, 2010454850,
285 642736655, 616092351, 365016990, 1185228132, 4174898510, 1043824992, 2023083429, 2241598885,
286 3863320456, 3279669087, 3674716684, 108438443, 2132974366, 830746235, 606445527, 4173263986,
287 2204105912, 1844756978, 2532684181, 4245352700, 2969441100, 3796921661, 1335562986, 4061524517,
288 2720232303, 2679424040, 634407289, 885462008, 3294724487, 3933892248, 2094100220, 339117932,
289 4048830727, 3202280980, 1458155303, 2689246273, 1022871705, 2464987878, 3714515309, 353796843,
290 2822958815, 4256850100, 4052777845, 551748367, 618185374, 3778635579, 4020649912, 1904685140,
291 3069366075, 2670879810, 3407193292, 2954511620, 4058283405, 2219449317, 3135758300, 1120655984,
292 3447565834, 1474845562, 3577699062, 550456716, 3466908712, 2043752612, 881257467, 869518812,
293 2005220179, 938474677, 3305539448, 3850417126, 1315485940, 3318264702, 226533026, 965733244,
294 321539988, 1136104718, 804158748, 573969341, 3708209826, 937399083, 3290727049, 2901666755,
295 1461057207, 4013193437, 4066861423, 3242773476, 2421326174, 1581322155, 3028952165, 786071460,
296 3900391652, 3918438532, 1485433313, 4023619836, 3708277595, 3678951060, 953673138, 1467089153,
297 1930354364, 1533292819, 2492563023, 1346121658, 1685000834, 1965281866, 3765933717, 4190206607,
298 2052792609, 3515332758, 690371149, 3125873887, 2180283551, 2903598061, 3933952357, 436236910,
299 289419410, 14314871, 1242357089, 2904507907, 1616633776, 2666382180, 585885352, 3471299210,
300 2699507360, 1432659641, 277164553, 3354103607, 770115018, 2303809295, 3741942315, 3177781868,
301 2853364978, 2269453327, 3774259834, 987383833, 1290892879, 225909803, 1741533526, 890078084,
302 1496906255, 1111072499, 916028167, 243534141, 1252605537, 2204162171, 531204876, 290011180,
303 3916834213, 102027703, 237315147, 209093447, 1486785922, 220223953, 2758195998, 4175039106,
304 82940208, 3127791296, 2569425252, 518464269, 1353887104, 3941492737, 2377294467, 3935040926]
305# END GENERATED: tables
306
307# S1 .. S4, the round functions' S-boxes (internal; CAST-256 uses them too)
308type LcCastTabs is Data:
309 LcCastTabs{s1: L.LcTab, s2: L.LcTab, s3: L.LcTab, s4: L.LcTab}
310
311def cast.tables() -> LcCastTabs:
312 LcCastTabs{L.lc.tab(8n, cast.s1.list()), L.lc.tab(8n, cast.s2.list()), L.lc.tab(8n, cast.s3.list()), L.lc.tab(8n, cast.s4.list())}
313
314# The round function's type (internal)
315type LcCastTy is Data:
316 LcCastF1{}
317 LcCastF2{}
318 LcCastF3{}
319
320def cast.lookup(+t: LcCastTabs, +i: U32, n: Nat) -> U32:
321 match t:
322 case LcCastTabs{s1, s2, s3, s4}:
323 match n:
324 case 0n:
325 L.lc.tab.get(8n, s1, L.lc.byte(i, 3n))
326 case 1n+n1:
327 match n1:
328 case 0n:
329 L.lc.tab.get(8n, s2, L.lc.byte(i, 2n))
330 case 1n+n2:
331 match n2:
332 case 0n:
333 L.lc.tab.get(8n, s3, L.lc.byte(i, 1n))
334 case 1n+n3:
335 L.lc.tab.get(8n, s4, L.lc.byte(i, 0n))
336
337# f of type ty on data d, with masking key km and rotation kr (0 to 31)
338def cast.f(ty: LcCastTy, +t: LcCastTabs, d: U32, km: U32, +kr: U32) -> U32:
339 match ty:
340 case LcCastF1{}:
341 +i = L.lc.rotl(U32.add(km, d), U32.to_nat(kr))
342 U32.add(U32.sub(U32.xor(cast.lookup(t, i, 0n), cast.lookup(t, i, 1n)), cast.lookup(t, i, 2n)), cast.lookup(t, i, 3n))
343 case LcCastF2{}:
344 +i = L.lc.rotl(U32.xor(km, d), U32.to_nat(kr))
345 U32.xor(U32.add(U32.sub(cast.lookup(t, i, 0n), cast.lookup(t, i, 1n)), cast.lookup(t, i, 2n)), cast.lookup(t, i, 3n))
346 case LcCastF3{}:
347 +i = L.lc.rotl(U32.sub(km, d), U32.to_nat(kr))
348 U32.sub(U32.xor(U32.add(cast.lookup(t, i, 0n), cast.lookup(t, i, 1n)), cast.lookup(t, i, 2n)), cast.lookup(t, i, 3n))
349
350# A round key (internal)
351type LcCast5Rk is Data:
352 LcCast5Rk{ty: LcCastTy, km: U32, kr: U32, t: LcCastTabs}
353
354def cast5.f(k: LcCast5Rk, d: U32) -> U32:
355 match k:
356 case LcCast5Rk{ty, km, kr, t}:
357 cast.f(ty, t, d, km, kr)
358
359# The key schedule (RFC 2144, 2.4.1)
360
361# S5 .. S8 (internal)
362type LcCastKTabs is Data:
363 LcCastKTabs{s5: L.LcTab, s6: L.LcTab, s7: L.LcTab, s8: L.LcTab}
364
365def cast.ktables() -> LcCastKTabs:
366 LcCastKTabs{L.lc.tab(8n, cast.s5.list()), L.lc.tab(8n, cast.s6.list()), L.lc.tab(8n, cast.s7.list()), L.lc.tab(8n, cast.s8.list())}
367
368# S_j[byte i of a], j = 5 to 8
369def cast.ks(+t: LcCastKTabs, j: Nat, +a: List<&2, U32>, +i: Nat) -> U32:
370 match t:
371 case LcCastKTabs{s5, s6, s7, s8}:
372 match j:
373 case 5n:
374 L.lc.tab.get(8n, s5, L.lc.at(a, i))
375 case 6n:
376 L.lc.tab.get(8n, s6, L.lc.at(a, i))
377 case 7n:
378 L.lc.tab.get(8n, s7, L.lc.at(a, i))
379 case _:
380 L.lc.tab.get(8n, s8, L.lc.at(a, i))
381
382# the big-endian word of bytes i .. i + 3 of a
383def cast.w(+a: List<&2, U32>, +i: Nat) -> U32:
384 L.lc.be(L.lc.at(a, i), L.lc.at(a, Nat.add(i, 1n)), L.lc.at(a, Nat.add(i, 2n)), L.lc.at(a, Nat.add(i, 3n)))
385
386# a word's four bytes, most significant first, in front of rest
387def cast.bytes(+w: U32, rest: List<&2, U32>) -> List<&2, U32>:
388 Con{L.lc.byte(w, 3n), Con{L.lc.byte(w, 2n), Con{L.lc.byte(w, 1n), Con{L.lc.byte(w, 0n), rest}}}}
389
390# a word of z (or x) from a word of x (or z): w ^ S5[a] ^ S6[b] ^ S7[c] ^
391# S8[d] ^ Sj[e], bytes a .. d of the half being built so far (cur) and e of
392# the other (src)
393def cast.mix(+t: LcCastKTabs, +w: U32, +cur: List<&2, U32>, ia: Nat, ib: Nat, ic: Nat, id: Nat, +src: List<&2, U32>, j: Nat, ie: Nat) -> U32:
394 U32.xor(U32.xor(U32.xor(w, cast.ks(t, 5n, cur, ia)), U32.xor(cast.ks(t, 6n, cur, ib), cast.ks(t, 7n, cur, ic))), U32.xor(cast.ks(t, 8n, cur, id), cast.ks(t, j, src, ie)))
395
396# z from x (the four lines z0z1z2z3 = ... of 2.4.1); the bytes of z built so
397# far are the cur argument of the later words
398def cast.z(+t: LcCastKTabs, +x: List<&2, U32>) -> List<&2, U32>:
399 +z0 = cast.bytes(cast.mix(t, cast.w(x, 0n), x, 13n, 15n, 12n, 14n, x, 7n, 8n), Nil{})
400 +z1 = B.append(z0, cast.bytes(cast.mix(t, cast.w(x, 8n), z0, 0n, 2n, 1n, 3n, x, 8n, 10n), Nil{}))
401 +z2 = B.append(z1, cast.bytes(cast.mix(t, cast.w(x, 12n), z1, 7n, 6n, 5n, 4n, x, 5n, 9n), Nil{}))
402 B.append(z2, cast.bytes(cast.mix(t, cast.w(x, 4n), z2, 10n, 9n, 11n, 8n, x, 6n, 11n), Nil{}))
403
404# x from z (the four lines x0x1x2x3 = ...)
405def cast.x(+t: LcCastKTabs, +z: List<&2, U32>) -> List<&2, U32>:
406 +x0 = cast.bytes(cast.mix(t, cast.w(z, 8n), z, 5n, 7n, 4n, 6n, z, 7n, 0n), Nil{})
407 +x1 = B.append(x0, cast.bytes(cast.mix(t, cast.w(z, 0n), x0, 0n, 2n, 1n, 3n, z, 8n, 2n), Nil{}))
408 +x2 = B.append(x1, cast.bytes(cast.mix(t, cast.w(z, 4n), x1, 7n, 6n, 5n, 4n, z, 5n, 1n), Nil{}))
409 B.append(x2, cast.bytes(cast.mix(t, cast.w(z, 12n), x2, 10n, 9n, 11n, 8n, z, 6n, 3n), Nil{}))
410
411# a subkey: S5[a] ^ S6[b] ^ S7[c] ^ S8[d] ^ Sj[e] on the bytes of v
412def cast.sub(+t: LcCastKTabs, +v: List<&2, U32>, ia: Nat, ib: Nat, ic: Nat, id: Nat, j: Nat, ie: Nat) -> U32:
413 U32.xor(U32.xor(U32.xor(cast.ks(t, 5n, v, ia), cast.ks(t, 6n, v, ib)), U32.xor(cast.ks(t, 7n, v, ic), cast.ks(t, 8n, v, id))), cast.ks(t, j, v, ie))
414
415# the four subkey sets of 2.4.1 (K1 .. K4, K5 .. K8, K9 .. K12, K13 .. K16;
416# then again for K17 .. K32)
417def cast.set1(+t: LcCastKTabs, +z: List<&2, U32>) -> List<&2, U32>:
418 [cast.sub(t, z, 8n, 9n, 7n, 6n, 5n, 2n), cast.sub(t, z, 10n, 11n, 5n, 4n, 6n, 6n), cast.sub(t, z, 12n, 13n, 3n, 2n, 7n, 9n), cast.sub(t, z, 14n, 15n, 1n, 0n, 8n, 12n)]
419
420def cast.set2(+t: LcCastKTabs, +x: List<&2, U32>) -> List<&2, U32>:
421 [cast.sub(t, x, 3n, 2n, 12n, 13n, 5n, 8n), cast.sub(t, x, 1n, 0n, 14n, 15n, 6n, 13n), cast.sub(t, x, 7n, 6n, 8n, 9n, 7n, 3n), cast.sub(t, x, 5n, 4n, 10n, 11n, 8n, 7n)]
422
423def cast.set3(+t: LcCastKTabs, +z: List<&2, U32>) -> List<&2, U32>:
424 [cast.sub(t, z, 3n, 2n, 12n, 13n, 5n, 9n), cast.sub(t, z, 1n, 0n, 14n, 15n, 6n, 12n), cast.sub(t, z, 7n, 6n, 8n, 9n, 7n, 2n), cast.sub(t, z, 5n, 4n, 10n, 11n, 8n, 6n)]
425
426def cast.set4(+t: LcCastKTabs, +x: List<&2, U32>) -> List<&2, U32>:
427 [cast.sub(t, x, 8n, 9n, 7n, 6n, 5n, 3n), cast.sub(t, x, 10n, 11n, 5n, 4n, 6n, 7n), cast.sub(t, x, 12n, 13n, 3n, 2n, 7n, 8n), cast.sub(t, x, 14n, 15n, 1n, 0n, 8n, 13n)]
428
429# sixteen subkeys from x, and the x after them
430type LcCastHalf is Data:
431 LcCastHalf{ks: List<&2, U32>, x: List<&2, U32>}
432
433def cast.half(+t: LcCastKTabs, +x: List<&2, U32>) -> LcCastHalf:
434 +z1 = cast.z(t, x)
435 +x1 = cast.x(t, z1)
436 +z2 = cast.z(t, x1)
437 +x2 = cast.x(t, z2)
438 LcCastHalf{B.append(cast.set1(t, z1), B.append(cast.set2(t, x1), B.append(cast.set3(t, z2), cast.set4(t, x2)))), x2}
439
440def cast.subkeys.rest(+t: LcCastKTabs, h: LcCastHalf) -> List<&2, U32>:
441 match h:
442 case LcCastHalf{ks, x3}:
443 ks
444
445def cast.subkeys.of(+t: LcCastKTabs, h: LcCastHalf) -> List<&2, U32>:
446 match h:
447 case LcCastHalf{ks, +x2}:
448 B.append(ks, cast.subkeys.rest(t, cast.half(t, x2)))
449
450# K1 .. K32 of a 16-byte (padded) key
451def cast.subkeys(+x: List<&2, U32>) -> List<&2, U32>:
452 +t = cast.ktables()
453 cast.subkeys.of(t, cast.half(t, x))
454
455def cast5.ty.of(m: Nat) -> LcCastTy:
456 match m:
457 case 0n:
458 LcCastF1{}
459 case 1n:
460 LcCastF2{}
461 case _:
462 LcCastF3{}
463
464# the round type of round i (0-based): 1, 2, 3, 1, 2, 3, ...
465def cast5.ty(i: Nat) -> LcCastTy:
466 cast5.ty.of(Nat.mod(i, 3n))
467
468def cast5.rounds.pick(short: Bool) -> Nat:
469 match short:
470 case True{}:
471 12n
472 case False{}:
473 16n
474
475# the number of rounds for a key of n bytes: 12 up to 80 bits, else 16
476def cast5.rounds(n: Nat) -> Nat:
477 cast5.rounds.pick(Nat.is_le(n, 10n))
478
479# the round keys of n rounds from round i, Km from kms and Kr from krs
480def cast5.rks(n: Nat, +i: Nat, +t: LcCastTabs, kms: List<&2, U32>, krs: List<&2, U32>) -> List<&2, LcCast5Rk>:
481 match n:
482 case 0n:
483 Nil{}
484 case 1n+p:
485 match kms krs:
486 case Con{km, kt} Con{kr, rt}:
487 Con{LcCast5Rk{cast5.ty(i), km, U32.and(31, kr), t}, cast5.rks(p, Nat.add(i, 1n), t, kt, rt)}
488 case _ _:
489 Nil{}
490
491# A CAST-128 key: the round keys (opaque; built by LcCast5.key)
492type LcCast5Key is Data:
493 LcCast5Key{rks: List<&2, LcCast5Rk>}
494
495def cast5.key(+n: Nat, +xs: List<&2, U32>) -> LcCast5Key:
496 +ks = cast.subkeys(B.append(xs, B.zeros(Nat.sub(16n, n))))
497 LcCast5Key{cast5.rks(cast5.rounds(n), 0n, cast.tables(), ks, B.drop(16n, ks))}
498
499def cast5.key.pick(ok: Bool, +n: Nat, +xs: List<&2, U32>) -> Result<&2, &2, L.LcError, LcCast5Key>:
500 match ok:
501 case True{}:
502 Done{cast5.key(n, xs)}
503 case False{}:
504 Fail{L.LcBadKeyLength{n}}
505
506# The cipher
507
508# a key of 5 to 16 bytes (40 to 128 bits); up to 10 bytes, 12 rounds
509def LcCast5.key(o: B.Octets) -> Result<&2, &2, L.LcError, LcCast5Key>:
510 +xs = B.Octets.to_list(o)
511 +n = B.len(xs)
512 cast5.key.pick(Bool.and(Nat.is_le(5n, n), Nat.is_le(n, 16n)), n, xs)
513
514def LcCast5.encrypt(k: LcCast5Key, b: L.LcBlock64) -> L.LcBlock64:
515 match k:
516 case LcCast5Key{rks}:
517 L.lc.swap(L.lc.fe.run(~LcCast5Rk, ~cast5.f, rks, b))
518
519def LcCast5.decrypt(k: LcCast5Key, b: L.LcBlock64) -> L.LcBlock64:
520 match k:
521 case LcCast5Key{rks}:
522 L.lc.fe.unrun(~LcCast5Rk, ~cast5.f, rks, L.lc.swap(b))