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. 21 import Base 22 import bend-osdev-bytes@0.1.1.0/bytes.bend as B 23 import 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) 27 def 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) 62 def 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) 97 def 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) 132 def 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) 167 def 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) 202 def 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) 237 def 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) 272 def 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) 308 type LcCastTabs is Data: 309 LcCastTabs{s1: L.LcTab, s2: L.LcTab, s3: L.LcTab, s4: L.LcTab} 310 311 def 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) 315 type LcCastTy is Data: 316 LcCastF1{} 317 LcCastF2{} 318 LcCastF3{} 319 320 def 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) 338 def 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) 351 type LcCast5Rk is Data: 352 LcCast5Rk{ty: LcCastTy, km: U32, kr: U32, t: LcCastTabs} 353 354 def 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) 362 type LcCastKTabs is Data: 363 LcCastKTabs{s5: L.LcTab, s6: L.LcTab, s7: L.LcTab, s8: L.LcTab} 364 365 def 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 369 def 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 383 def 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 387 def 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) 393 def 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 398 def 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 = ...) 405 def 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 412 def 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) 417 def 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 420 def 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 423 def 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 426 def 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 430 type LcCastHalf is Data: 431 LcCastHalf{ks: List<&2, U32>, x: List<&2, U32>} 432 433 def 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 440 def cast.subkeys.rest(+t: LcCastKTabs, h: LcCastHalf) -> List<&2, U32>: 441 match h: 442 case LcCastHalf{ks, x3}: 443 ks 444 445 def 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 451 def cast.subkeys(+x: List<&2, U32>) -> List<&2, U32>: 452 +t = cast.ktables() 453 cast.subkeys.of(t, cast.half(t, x)) 454 455 def 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, ... 465 def cast5.ty(i: Nat) -> LcCastTy: 466 cast5.ty.of(Nat.mod(i, 3n)) 467 468 def 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 476 def 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 480 def 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) 492 type LcCast5Key is Data: 493 LcCast5Key{rks: List<&2, LcCast5Rk>} 494 495 def 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 499 def 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 509 def 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 514 def 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 519 def 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))