cast5.bend

bend-osdev-legacy-ciphers@0.1.0.0 · 522 lines · 44 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 legacy-ciphers.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.0.0/bytes.bend as B
23import bend-osdev-legacy-ciphers@0.1.0.0/legacy_ciphers.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))