.globl twofish_128_key_schedule @ void twofish_128_key_schedule(unsigned char key[160], unsigned char sbox[4096])
.globl twofish_192_key_schedule @ void twofish_192_key_schedule(unsigned char key[160], unsigned char sbox[4096])
.globl twofish_256_key_schedule @ void twofish_256_key_schedule(unsigned char key[160], unsigned char sbox[4096])
.globl twofish_encrypt          @ void twofish_encrypt(unsigned char buffer[16], const unsigned char key[160], const unsigned char sbox[4096])
.globl twofish_decrypt          @ void twofish_decrypt(unsigned char buffer[16], const unsigned char key[160], const unsigned char sbox[4096])

.section .text,"ax",%progbits

.balign 64

rs:  .long          0, 2751636481,   84149506, 2701566211,  168299012, 2919935493,  252448518, 2869865223,  336598024, 2954014729,  286527754, 3038164235,  504897036, 3122313741,  454826766, 3206463247
     .long  673196048, 2351074321,  757345554, 2301004051,  573055508, 2250933781,  657205014, 2200863511, 1009794072, 2553452569,  959723802, 2637602075,  909653532, 2453312029,  859583262, 2537461535
     .long 1346392096, 4098028577, 1430541602, 4047958307, 1514691108, 4266327589, 1598840614, 4216257319, 1146111016, 3763527721, 1096040746, 3847677227, 1314410028, 3931826733, 1264339758, 4015976239
     .long 2019588144, 3697466417, 2103737650, 3647396147, 1919447604, 3597325877, 2003597110, 3547255607, 1819307064, 3362965561, 1769236794, 3447115067, 1719166524, 3262825021, 1669096254, 3346974527
     .long 2692784192,   75629633, 2776933698,   25559363, 2861083204,  243928645, 2945232710,  193858375, 3029382216,  278007881, 2979311946,  362157387, 3197681228,  446306893, 3147610958,  530456399
     .long 2292222032,  748825681, 2376371538,  698755411, 2192081492,  648685141, 2276230998,  598614871, 2628820056,  951203929, 2578749786, 1035353435, 2528679516,  851063389, 2478609246,  935212895
     .long 4039176288, 1422021729, 4123325794, 1371951459, 4207475300, 1590320741, 4291624806, 1540250471, 3838895208, 1087520873, 3788824938, 1171670379, 4007194220, 1255819885, 3957123950, 1339969391
     .long 3638614128, 2095217777, 3722763634, 2045147507, 3538473588, 1995077237, 3622623094, 1945006967, 3438333048, 1760716921, 3388262778, 1844866427, 3338192508, 1660576381, 3288122238, 1744725887
     .long  223153536, 2840570241,  139004034, 2890640515,  121964420, 2739381125,   37814918, 2789451399,  425531784, 3177168265,  475602058, 3093018763,  324342668, 3075979149,  374412942, 2991829647
     .long  627910032, 2171568529,  543760530, 2221638803,  795160468, 2338818965,  711010966, 2388889239,  830288280, 2508166553,  880358554, 2424017051,  997538716, 2675416989, 1047608990, 2591267487
     .long 1561157024, 4178573729, 1477007522, 4228644003, 1459967908, 4077384613, 1375818406, 4127454887, 1226656168, 3978292649, 1276726442, 3894143147, 1125467052, 3877103533, 1175537326, 3792954031
     .long 1965913520, 3509572017, 1881764018, 3559642291, 2133163956, 3676822453, 2049014454, 3726892727, 1631412664, 3309290937, 1681482938, 3225141435, 1798663100, 3476541373, 1848733374, 3392391871
     .long 2915937728,  164563393, 2831788226,  214633667, 2814748612,   63374277, 2730599110,  113444551, 3118315976,  501161417, 3168386250,  417011915, 3017126860,  399972301, 3067197134,  315822799
     .long 2246936016,  569319889, 2162786514,  619390163, 2414186452,  736570325, 2330036950,  786640599, 2449314264,  905917913, 2499384538,  821768411, 2616564700, 1073168349, 2666634974,  989018847
     .long 4253941216, 1502566881, 4169791714, 1552637155, 4152752100, 1401377765, 4068602598, 1451448039, 3919440360, 1302285801, 3969510634, 1218136299, 3818251244, 1201096685, 3868321518, 1116947183
     .long 3584939504, 1907323377, 3500790002, 1957393651, 3752189940, 2074573813, 3668040438, 2124644087, 3250438648, 1707042297, 3300508922, 1622892795, 3417689084, 1874292733, 3467759358, 1790143231
     .long          0, 1436636836, 2853153797, 4289657505,  421401866, 1287603118, 3004283151, 3870355371,  842803732, 1738374320, 2553513489, 3448950965,  723664670, 2122541498, 2167247643, 3565995455
     .long 1685607464,  836305548, 3463968813, 2614537865, 2103853346,  684136326, 3614043431, 2194193283, 1447329340,   65349784, 4232827449, 2850718877, 1331325750,  452672914, 3847604019, 2968818071
     .long 3371214928, 2639396596, 1660879957,  928928497, 3522084186, 2219830270, 2078347615,  775964667, 4207706692, 2943210720, 1354968641,   90339557, 3822229326, 3061039594, 1239235403,  477916655
     .long 2894658680, 4180257500,  109531261, 1395001049, 3046566258, 3761749974,  530138487, 1245189075, 2662651500, 3407184072,  884701801, 1629105357, 2276115302, 3523974594,  765816675, 2013542855
     .long 3719110048, 2282507012, 2007151013,  570681089, 3300067498, 2433900046, 1857856687,  991818251, 4019271604, 3123732752, 1168022449,  272616725, 4136575678, 2737730586, 1551929019,  153212959
     .long 3117762952, 3967033132,  333112717, 1182511913, 2697682050, 4117367334,  180678791, 1600497187, 2347328412, 3729274168,  568774553, 1950849341, 2465691286, 3344310322,  955832979, 1834585143
     .long  358462960, 1090315092, 3209828853, 3941814097,  205758714, 1508046430, 2790001919, 4092418651,  660709348, 1925237056, 2372809697, 3637470533, 1048546030, 1809767498, 2490377963, 3251728463
     .long 1898308056,  612677500, 3676982749, 2391481209, 1748759762, 1033544310, 3258210519, 2543128179, 1125764044,  381197672, 3910559689, 3166122349, 1510465222,  262572130, 4027085507, 2779325543
     .long 4145494541, 2729864361, 1561892360,  146391212, 3993579271, 3148380579, 1141277442,  296211878, 3307933721, 2424981181, 1864678428,  981854904, 3694462227, 2308199351, 1983555862,  597426098
     .long 2473553445, 3335403649,  962642464, 1824625796, 2322692911, 3754962315,  545183530, 1977581966, 2706588721, 4109505173,  190638132, 1593687696, 3092074811, 3991668639,  306380094, 1206102938
     .long 1072140893, 1783022841, 2515025496, 3226036476,  653887319, 1935200755, 2364943186, 3646389750,  232503369, 1484451565, 2815693900, 4067771112,  348499267, 1097137127, 3200909638, 3949680610
     .long 1537197685,  238981329, 4052773488, 2754690260, 1115804543,  388007387, 3901652858, 3173984734, 1772350561, 1006811845, 3282845796, 2517440192, 1891498347,  622637007, 3669120366, 2400388042
     .long  716842925, 2132504841, 2159381416, 3574914316,  866398887, 1711629315, 2578161314, 3423258630,  411438521, 1294424861, 2995364284, 3878221592,   26745011, 1413041687, 2878846134, 4265009682
     .long 1321366405,  459482401, 3838697344, 2976680228, 1474061967,   41758763, 4258515594, 2826083374, 2097043857,  694095669, 3606181268, 2203099952, 1709198491,  809572927, 3488604318, 2588849722
     .long 3796537341, 3085687129, 1212490744,  501511516, 4216625911, 2935344211, 1364932338,   83517526, 3497436649, 2245522253, 2054752748,  802709320, 3379081443, 2630477383, 1667701990,  918964802
     .long 2251480021, 3549662577,  742225872, 2040275316, 2670513887, 3398277243,  891511514, 1619145854, 3020878273, 3786385253,  503406020, 1268779872, 2903565515, 4172395119,  119490766, 1388191338
     .long          0, 2281472597, 1135954346, 3293170687, 2250740249,   31133772, 3314736051, 1114528230, 1095657778, 3333614439,   50012312, 2231870157, 3345611563, 1083537790, 2229056129,   52441300
     .long 2191315556,   90198065, 3240729550, 1188370843,   79380605, 2202518056, 1192102359, 3237120898, 3285367638, 1143879939, 2154296060,  127627433, 1173694799, 3255413530,  104882405, 2176639664
     .long 1232464328, 3465112477,  180396130, 2369528375, 3478289361, 1219426692, 2363961979,  186363950,  138117370, 2412184239, 1267648848, 3430042373, 2384204515,  165712054, 3450428233, 1247140124
     .long 3421060012, 1276492281, 2287759878,  262205523, 1305389493, 3392285664,  242999327, 2307351114, 2326221470,  224121035, 3373407028, 1324259681,  209764487, 2340176594, 1328908589, 3368618872
     .long 2464849885,  353770888, 3512718967, 1453544482,  348982724, 2469498769, 1467499630, 3498362427, 3550803695, 1415083194, 2417082181,  401423632, 1434674422, 3531597475,  372649308, 2445979401
     .long  276188601, 2542456812, 1405289491, 3560932934, 2521948064,  296574453, 3588527626, 1377309791, 1362633867, 3603211998,  311258401, 2507272052, 3609179794, 1357067463, 2494234424,  324435309
     .long 3684660757, 1550054464, 2552905663,  534167018, 1572398092, 3661915737,  504212902, 2582720499, 2597396263,  489528690, 3647231629, 1587074264,  485920062, 2601127787, 1598276756, 3636414145
     .long 1493410929, 3741263396,  448196059, 2638901134, 3743692392, 1490596925, 2626781122,  460193175,  407752003, 2679197462, 1543013609, 3691251388, 2657771354,  429317391, 3722385136, 1512281253
     .long 1771664375, 3999658402,  707541597, 2916136968, 4022264302, 1749181371, 2886445124,  737618449,  685185733, 2938869904, 1801605999, 3969831226, 2934999260,  688654985, 3980771702, 1790526243
     .long 3943014803, 1828266950, 2830166073,  793537132, 1830957962, 3940463071,  781679136, 2842425461, 2857093281,  766986996, 3925770507, 1845625694,  745298616, 2878396653, 1876497170, 3894776135
     .long  552376895, 2802849898, 1666831253, 3836039616, 2798323750,  557288051, 3850256780, 1652736985, 1638069005, 3864949080,  571980455, 2783656178, 3884278036, 1618600769, 2754619582,  600615659
     .long 2725267547,  629983758, 3787784689, 1715045284,  609737282, 2745915415, 1742902248, 3760067005, 3812499817, 1690477372, 2693490883,  662170262, 1696183152, 3806671141,  648870618, 2706405519
     .long 4218678314, 2089774719, 3100026240, 1060775893, 2102689331, 4205378662, 1054947225, 3105732044, 3124593944, 1036060493, 4186492082, 2121551591, 1008342785, 3152450900, 2142199467, 4166245630
     .long 2045722190, 4262706203,  979007460, 3181835697, 4291341399, 2016685570, 3162367485,  998336424,  950097788, 3210597673, 2064916182, 4243102851, 3196503397,  964314928, 4248014031, 2060390042
     .long 2986739170,  905611191, 4055059528, 1984941597,  874616827, 3017610670, 2006244945, 4033371140, 4081609936, 1958014597, 2969380218,  922855215, 1970273993, 4069751964,  920303459, 2972071222
     .long  815454086, 3076937171, 1932500524, 4107476089, 3065857439,  826394570, 4110945333, 1928629856, 1909767860, 4129832161,  845281054, 3046995275, 4159909037, 1880076024, 3024512263,  867886930
     .long          0, 1522660231, 3033508675, 3993917636,  634592134, 2131945473, 2434576581, 3420275522, 1256928833,  271238598, 4263812354, 2766499461, 1865952711,  905567808, 3690432132, 2167829763
     .long 2493213826, 3462045445,  542427073, 2056598598, 2974316292, 3951658115,   92789831, 1598435264, 3731905219, 2226235716, 1790964096,  813564423, 4221780293, 2707600066, 1332537862,  363665793
     .long 1702615113, 1069165518, 3518264074, 2339733645, 1084801999,  443101256, 4100417676, 2930154251,  798027272, 1968250255, 2606712139, 3248404172,  172225934, 1350698505, 3196870349, 3830295882
     .long 4058035403, 2871084876, 1160716168,  535751695, 3560157005, 2398248138, 1627128846,  977139593, 3138093706, 3788140813,  264513993, 1426446926, 2664995084, 3290000011,  706163279, 1893122504
     .long 3405184402, 2419527189, 2117686993,  620275030, 4012238356, 3051623827, 1542081879,   19644112, 2149436371, 3671865428,  886202512, 1846776599, 2781794389, 4279182290,  285309718, 1270909073
     .long 1584238864,   78406295, 3936500307, 2959329748, 2076084886,  562002193, 3480297941, 2511393362,  344368977, 1313297622, 2689141778, 4203282325,  827702487, 1804881744, 2241468308, 3747341331
     .long 2945263067, 4115453532,  457346712, 1099136287, 2321432157, 3500133850, 1049728286, 1682990745, 3848672154, 3215450141, 1370077401,  191384414, 3233089564, 2591357851, 1954194271,  784027864
     .long  991316313, 1641528030, 2413421082, 3575124381,  516248287, 1141154136, 2852845980, 4039838235, 1912438552,  725388447, 3308442715, 2683512796, 1412326558,  250582809, 3772895197, 3122674778
     .long 3651254121, 2204124398, 1835932714,  934277037, 4235373807, 2796773224, 1220347820,  310178859, 2471133480, 3381359279,  663038571, 2101664236, 3063519918, 3965217065,   39203309, 1486340714
     .long 1295703019,  402335852, 4193611944, 2738127663, 1760149613,  841495530, 3693505326, 2263324841,  131198378, 1561337389, 3005105897, 3923752302,  570619436, 2026046891, 2530041199, 3423383272
     .long 3168431904, 3860569255,  135644259, 1389639652, 2567533734, 3284698913,  768008165, 1996958818, 4130429281, 2901453542, 1124004386,  406782373, 3554820839, 2300817760, 1731062180, 1038883363
     .long  675349410, 1921052709, 2626595041, 3327089510,  227678244, 1465117603, 3109925735, 3818668256, 1655322083,  946587236, 3596983968, 2359586087, 1199124069,  498654690, 4088825126, 2843178657
     .long  324487931, 1234614652, 2811814328, 4250473023,  914641277, 1816503034, 2186017342, 3632925113, 1505524922,   58560317, 3983792121, 3081905278, 2087675708,  648975547, 3365981311, 2455846904
     .long 2278303353, 3708671486,  855870778, 1774354109, 2719956479, 4175351416,  382768828, 1276208443, 3441889336, 2548491199, 2045295483,  589908220, 3908307902, 2989881401, 1547411709,  117068666
     .long 1982632626,  753754421, 3269671409, 2552416886, 1409255732,  155089587, 3878691447, 3186741744, 1019716851, 1711691636, 2282229680, 3536452663,  420790133, 1138052338, 2916815926, 4145735601
     .long 3803708976, 3094744503, 1450726771,  213493492, 3345278390, 2644842033, 1940606709,  694861170, 2824652913, 4070390774,  479421234, 1179816117, 2375013367, 3612221552,  960526516, 1669434163
     .long          0, 1481055834, 2962111668, 3905495790,  760313893, 1964402303, 2648654993, 3315096267, 1520627786,   48623120, 3928804606, 2993410724, 2012448879,  800364085, 3346904283, 2671422081
     .long 3020533140, 3964580814,   75993376, 1556123514, 2572735921, 3240086507,  701950213, 1905391455, 4004208094, 3068937092, 1579508074,  107118384, 3287950843, 2612870049, 1936988495,  724764437
     .long  621942629, 2102724927, 2510040017, 3453695371,  138637120, 1342468378, 3100464116, 3767160238, 2142299951,  670562677, 3477003163, 2541340097, 1390518026,  178684240, 3798967230, 3123232228
     .long 2434513649, 3378291883,  563447365, 2043844639, 3159016148, 3826113678,  214236768, 1417928762, 3417918139, 2482918625, 2067232271,  594569301, 3873976990, 3199151300, 1449528874,  237047920
     .long 1243885258,  308490384, 4205449854, 2733444132, 1735743215, 1060260021, 3623578203, 2411492353,  277274240, 1220657370, 2684936756, 4165991534, 1037543077, 1703983359, 2371459601, 3575546955
     .long 4264395614, 2792004868, 1319354346,  384082352, 3548183419, 2335958305, 1676855247, 1001773461, 2760864532, 4240993614,  335630240, 1279676922, 2313030449, 3516470635,  961558405, 1628907999
     .long 1865824687,  930162677, 3753379099, 2281642817, 1114063242,  438329296, 4075388222, 2863555428,  898943461, 1842599871, 2233136465, 3713919755,  415609280, 1082306458, 2823523700, 4027355950
     .long 3678377019, 2205715041, 1806805135,  871806677, 4134464542, 2921984580, 1189138602,  514313968, 2174575729, 3654973995,  823351493, 1767130783, 2899057748, 4102750734,  474095840, 1141194426
     .long 2487770329, 3423552131,  616980589, 2088861239, 3105432828, 3781048998,  160897096, 1372587538, 3471486099, 2527965897, 2120519719,  639864445, 3820737718, 3153906412, 1396041730,  192083544
     .long  541192525, 2013720343, 2429537785, 3364410275,  219187560, 1431803698, 3181295068, 3856247686, 2061697287,  581181277, 3396156851, 2452235241, 1471314210,  267741048, 3879486870, 3212532684
     .long 2975484860, 3911013862,   30701320, 1502832978, 2617979801, 3293326787,  746917677, 1958875511, 3958946806, 3015681452, 1534494530,   53582104, 3333014483, 2666454409, 1982332775,  778101053
     .long   89384488, 1561655410, 3051215516, 3986343110,  671260173, 1883603031, 2559353529, 3234577635, 1609635426,  129370168, 4018088662, 3073913996, 1923116615,  719810589, 3257815795, 2590592169
     .long 3731649043, 2250992713, 1860325031,  916803837, 4080863798, 2876904556, 1135818370,  468986072, 2228126297, 3700005891,  876658413, 1812439223, 2845833852, 4057523238,  420595400, 1096210578
     .long 1785061255,  841138653, 3672892211, 2192375145, 1194633122,  527677944, 4156201750, 2952627532,  818360269, 1753231767, 2152272761, 3624799523,  496392168, 1171343794, 2904058716, 4116673798
     .long 4219364726, 2738453292, 1274042818,  330778520, 3593411923, 2389181193, 1721836007, 1055276989, 2715587900, 4187720550,  290630024, 1226160082, 2358111513, 3570070339, 1006883245, 1682231287
     .long 1333250274,  389076664, 4294571094, 2814306828, 1646702791,  979480221, 3534261363, 2330956329,  366295208, 1301423858, 2774205468, 4246477382,  948191373, 1623416535, 2282388537, 3494732387
     .long          0, 3685664344, 4212244912,  549390312, 3139620653, 1619790197, 1077087901, 2610809029,  994366298, 3773437186, 3226800874,  469488818, 2154175607, 1539889711, 2071453127, 2698582943
     .long 1988684724, 2904960492, 2375625220, 1446505564, 3450479769,  369418945,  918283561, 3977585521, 1305229550, 2523070134, 3068000606, 1836269318, 4142856131,  759181723,  234829427, 3595694123
     .long 3965557541,  938696061,  390879893, 3437403341, 1467962376, 2362544720, 2892928440, 2009093088, 3608758399,  213356071,  738757071, 4154871703, 1815840594, 3080012042, 2536130274, 1283752122
     .long 2597679249, 1098626761, 1640280353, 3127539577,  569884604, 4200167908, 3672538636,   21542996, 2710676427, 2050975123, 1518363259, 2167317539,  447966438, 3239946942, 3785534806,  973892366
     .long 2512026442, 1309981970, 1856748282, 3037035682,  781759591, 4113986111, 3582555607,  237482895, 2935924752, 1968205384, 1441753504, 2386669560,  366765885, 3463618917, 4006454925,  895705301
     .long 3811741950,  949769894,  404967758, 3280836374, 1477468115, 2210306443, 2734792291, 2024757307, 3631629220,   64521724,  593986068, 4173939788, 1666485385, 3103410897, 2554678585, 1139510113
     .long 2045239407, 2722702903, 2197168607, 1498998663, 3267702594,  426502426,  970256114, 3799656618, 1117991733, 2567828845, 3115512453, 1646015709, 4186045464,  573520448,   43007400, 3644783600
     .long  258935771, 3569470851, 4101950059,  802163763, 3024995574, 1877148334, 1331430726, 2498937630,  875288705, 4018478809, 3476691249,  345300841, 2399737772, 1420284404, 1947784732, 2947944516
     .long 1731851924, 3164025036, 2619881252, 1200025980, 3692771769,  129368033,  655030281, 4238622289, 1551705550, 2278810518, 2808931454, 2093097510, 3881822947, 1022438587,  474884947, 3353406731
     .long  296820000, 3391085432, 3936410768,  823007944, 2861814285, 1899828309, 1367479229, 2318194149,  720752250, 4049274914, 3521384394,  172673426, 2446786903, 1249494799, 1791410407, 2976384703
     .long 2338614705, 1355459561, 1886759937, 2883283545,  809935516, 3957875908, 3411501868,  284796276, 2954936043, 1804499123, 1261535067, 2426386691,  184709574, 3500980126, 4027822198,  733836846
     .long 4260136453,  641876061,  117262261, 3713237485, 1187924264, 2640351088, 3185543320, 1718701760, 3332920671,  486970119, 1035572463, 3860288183, 2106235506, 2787400746, 2258328514, 1563794842
     .long 4068707806,  690834310,  160582766, 3527182902, 1235305203, 2450490539, 2997912387, 1763591451, 3385286276,  308910300,  852926260, 3916978540, 1927647657, 2840287217, 2314489881, 1381668417
     .long 2215339626, 1604689970, 2132453338, 2763284866, 1059694919, 3834081055, 3292031223,  529968815, 3209671984, 1692496744, 1147040896, 2683351768,   74283549, 3754146885, 4286364589,  617774581
     .long  517871355, 3312504995, 3855603531, 1046548755, 2784811478, 2119311246, 1592596582, 2235817534,  630900129, 4264821753, 3733652497,   86360649, 2662861452, 1159122132, 1705626428, 3188133220
     .long 1750531407, 3019389719, 2470919423, 1223293607, 3547607650,  148567098,  677770194, 4090181002, 1393700373, 2294081613, 2818830245, 1940728317, 3895517496,  866002784,  320938120, 3364873936
     .long          0, 2654824667, 1903874299, 4014454816, 3807702459, 2093581664, 2475572544,  229856667, 2309330747,  395902944, 4175382464, 1726099227, 1800501888, 4117500507,  439069307, 2216084128
     .long 1594319734, 3241806765,  779989901, 2957040470, 3186855629,  600761878, 3431554614, 1387542253, 3601003597, 1218419862, 2815960246,  971328621,  878057974, 2859168045, 1160562957, 3675365846
     .long 3188639468,  540257847, 3480491543, 1363771084, 1559898967, 3267838860,  763427756, 3015545719,  933974487, 2845194508, 1188135212, 3639405047, 3579821164, 1264768183, 2753916055,  974652492
     .long 3775505818, 2134166849, 2423485793,  240000442,   66930721, 2646614266, 1921489114, 3971674113, 1756115617, 4136721018,  433513050, 2280360577, 2321080090,  342210497, 4213313505, 1696556858
     .long  823968149, 2938218830, 1080430958, 3730536885, 3555208238, 1305822453, 2727541973, 1018139662, 3099154094,  646200949, 3385034325, 1476325006, 1515043605, 3295728590,  725052398, 3037332277
     .long 1847304931, 4029073976,  526479896, 2170297027, 2364493656,  315762563, 4254441379, 1672017784, 3888002520, 2038652163, 2529486115,  150572536,   88791139, 2608312504, 1949304984, 3926745155
     .long 2400323449,  288321442, 4268283778, 1616232281, 1843849922, 4091249177,  480000569, 2191610594,  112693314, 2559244441, 2009940153, 3924830306, 3829628409, 2055083298, 2503585026,  184862169
     .long 3491062799, 1311247572, 2708452596, 1062394927,  853641652, 2900156783, 1134254415, 3718656404, 1504768820, 3347946479,  684336079, 3069659924, 3141803663,  628717140, 3393113716, 1409525423
     .long 1647890279, 4228229052,  323100572, 2373941063, 2160861916,  519129607, 4055298599, 1871420156, 3952957532, 1973432455, 2598865063,   81453180,  157922791, 2538921276, 2014536988, 3861777863
     .long 1027582993, 2734867658, 1279622378, 3531084849, 3754639786, 1106651505, 2930872657,  814545290, 3030006570,  715609073, 3319851985, 1541243658, 1450104465, 3360931402,  655623786, 3106500273
     .long 3694528907, 1108042064, 2907494768,  863089067, 1052959792, 2701102315, 1337472203, 3515178000, 1435737776, 3417241195,  619269707, 3134465680, 3077010187,  693771216, 3323831280, 1478544171
     .long 2201053949,  487326246, 4065049094, 1819726557, 1640335174, 4294504349,  280975293, 2390900582,  177536454, 2494141725, 2079206717, 3855828454, 3898609789, 1985837222, 2568667270,  120039517
     .long 1394872050, 3440993833,  576642569, 3160651474, 2983256905,  804096914, 3232379826, 1586977641, 3665926601, 1153233170, 2885372210,  902177257,  947221618, 2789743785, 1225761929, 3610430546
     .long  203648388, 2451440991, 2103033215, 3815036324, 4007100479, 1894443236, 2678935748,   26228767, 2240215743,  465277540, 4110166596, 1791050399, 1735530244, 4182736863,  369674239, 2285219620
     .long 3979003934, 1930928325, 2622494949,   40726590,  266216869, 2447592830, 2124739934, 3768163717, 1687117605, 4205983742,  368414686, 2345199365, 2256253598,  407296581, 4144063077, 1765542590
     .long 2989337448,  739296179, 3277290387, 1567232840, 1356416723, 3471060488,  564368936, 3214868211,  998784083, 2780124296, 1257434280, 3570369651, 3648836072, 1195489587, 2818965779,  909863368
     .long          0,   52028830,  103974769,   86729455,  207897570,  259892860,  173458579,  156180749,  415794825,  466707223,  519700984,  501474406,  346867051,  397746421,  312361498,  294102916
     .long  819806559,  868525249,  921683502,  905323440, 1018757821, 1067509539,  982222284,  965894226,  672516054,  722215496,  774324391,  759080249,  611419188,  661152170,  574817093,  559605467
     .long 1626833598, 1676568352, 1724188111, 1708974161, 1821622620, 1871324354, 1788954157, 1773708211, 2017395767, 2066145705, 2114814790, 2098489048, 1952139221, 2000855627, 1919533220, 1903174970
     .long 1344979937, 1395861119, 1444430992, 1426170126, 1548648451, 1599563165, 1518077810, 1499849452, 1222788456, 1274781942, 1322304025, 1305028487, 1149634186, 1201660692, 1119126011, 1101882469
     .long 3231926577, 3283791023, 3331444288, 3314035678, 3435596499, 3487493965, 3405090210, 3387713596, 3630944184, 3681692198, 3730393289, 3712003415, 3557788762, 3608570308, 3527215915, 3508858549
     .long 4034791534, 4083674608, 4132212511, 4116015745, 4229581708, 4278431250, 4196977917, 4180748643, 3904278247, 3954142073, 4001630614, 3986549768, 3839020293, 3888851099, 3806349940, 3791237098
     .long 2689911695, 2739744273, 2791722238, 2776607072, 2888861805, 2938727923, 2852261660, 2837179010, 3097251078, 3146098840, 3199126135, 3182899177, 3036155620, 3085036410, 2999617941, 2983422987
     .long 2424933072, 2475716430, 2528841121, 2510481471, 2632829234, 2683579564, 2598325827, 2579934173, 2285964377, 2337860039, 2389936936, 2372562614, 2217037755, 2268899877, 2182596810, 2165189972
     .long 3440087650, 3457316860, 3409515795, 3357601933, 3245330816, 3262526494, 3344783089, 3292836719, 3586331883, 3604672885, 3555824538, 3504895492, 3651622665, 3669930647, 3751137400, 3700176358
     .long 4258714429, 4274992803, 4226045004, 4177375698, 4055011551, 4071322945, 4152367022, 4103729712, 3843970484, 3859263530, 3811365573, 3761583963, 3917092438, 3932419016, 4014510375, 3964761273
     .long 2918977756, 2934306114, 2882443181, 2832691763, 2711114558, 2726409888, 2812990543, 2763207121, 3040122453, 3056432075, 3003519268, 2954884282, 3109082551, 3125358633, 3210891974, 3162224472
     .long 2636206467, 2654516253, 2601768690, 2550805356, 2437223009, 2455566335, 2541196560, 2490265742, 2246694666, 2263888532, 2212188283, 2160244197, 2307757288, 2324984182, 2411664281, 2359752199
     .long  229170003,  246496973,  194665506,  142850492,   30185649,   47545647,  134094784,   82311774,  358637018,  377075780,  324197035,  273366837,  419700280,  438172582,  523671881,  472874199
     .long 1031117324, 1047297938,  994516349,  945748195,  823253486,  839400560,  925064863,  876264193,  633150597,  648345883,  596614132,  546733674,  702111591,  717273849,  803985430,  754072968
     .long 1834965485, 1850129523, 1802362524, 1752447746, 1631263247, 1646460817, 1728683390, 1678801120, 1972887396, 1989032698, 1940215829, 1891417483, 2046008454, 2062186776, 2143362039, 2094595689
     .long 1568807090, 1587281196, 1538301891, 1487501917, 1374051152, 1392492238, 1473567777, 1422735807, 1162518075, 1179876261, 1131944266, 1080163540, 1227808217, 1245132871, 1327258280, 1275445046
mds: .long          0, 4025441025, 3082270210, 1482222851,  117900548, 3907542533, 2964370182, 1600120839,  235801096, 3789639945, 3115957258, 1448535819,  151588620, 3873854477, 3200170254, 1364320783
     .long  471602192, 4092808977, 2880152082, 1145370899,  454758676, 4109650453, 2896996118, 1128528919,  303177240, 4261233945, 2779097114, 1246425883,  353704732, 4210704413, 2728570142, 1296954911
     .long  943204384, 3621221153, 2408554018, 1616954659, 1061104932, 3503322661, 2290653990, 1734852647,  909517352, 3654908201, 2172752938, 1852755755,  825304876, 3739122733, 2256965934, 1768540719
     .long  606354480, 3419105073, 2475919922, 2088554803,  589510964, 3435946549, 2492763958, 2071712823,  707409464, 3318050105, 2644344890, 1920129851,  757936956, 3267520573, 2593817918, 1970658879
     .long 1886408768, 2678000449, 3351766594,  673758531, 2004309316, 2560101957, 3233866566,  791656519, 2122209864, 2442199369, 3385453642,  640071499, 2037997388, 2526413901, 3469666638,  555856463
     .long 1819034704, 2206408529, 3688624722,  875866451, 1802191188, 2223250005, 3705468758,  859024471, 1650609752, 2374833497, 3587569754,  976921435, 1701137244, 2324303965, 3537042782, 1027450463
     .long 1212708960, 2812748641, 4294954594,  269522275, 1330609508, 2694850149, 4177054566,  387420263, 1179021928, 2846435689, 4059153514,  505323371, 1094809452, 2930650221, 4143366510,  421108335
     .long 1414818928, 3149608817, 3823360626,  202146163, 1397975412, 3166450293, 3840204662,  185304183, 1515873912, 3048553849, 3991785594,   33721211, 1566401404, 2998024317, 3941258622,   84250239
     .long 3772817536,  252705665, 1465325186, 3099086211, 3890718084,  134807173, 1347425158, 3216984199, 4008618632,   16904585, 1499012234, 3065399179, 3924406156,  101119117, 1583225230, 2981184143
     .long 4244419728,  320073617, 1263207058, 2762234259, 4227576212,  336915093, 1280051094, 2745392279, 4075994776,  488498585, 1162152090, 2863289243, 4126522268,  437969053, 1111625118, 2913818271
     .long 3638069408,  926405537, 1869561506, 2155898275, 3755969956,  808507045, 1751661478, 2273796263, 3604382376,  960092585, 1633760426, 2391699371, 3520169900, 1044307117, 1717973422, 2307484335
     .long 3301219504,  724289457, 1936927410, 2627498419, 3284375988,  741130933, 1953771446, 2610656439, 3402274488,  623234489, 2105352378, 2459073467, 3452801980,  572704957, 2054825406, 2509602495
     .long 2425417920, 2139073473,  656885442, 3368558019, 2543318468, 2021174981,  538985414, 3486456007, 2661219016, 1903272393,  690572490, 3334870987, 2577006540, 1987486925,  774785486, 3250655951
     .long 2358043856, 1667481553,  993743570, 3570665939, 2341200340, 1684323029, 1010587606, 3553823959, 2189618904, 1835906521,  892688602, 3671720923, 2240146396, 1785376989,  842161630, 3722249951
     .long 2829637856, 1195869153,  522153698, 4042274275, 2947538404, 1077970661,  404253670, 4160172263, 2795950824, 1229556201,  286352618, 4278075371, 2711738348, 1313770733,  370565614, 4193860335
     .long 3031747824, 1532729329,   50559730, 3974898163, 3014904308, 1549570805,   67403766, 3958056183, 3132802808, 1431674361,  218984698, 3806473211, 3183330300, 1381144829,  168457726, 3857002239
     .long          0,   22802415,   45529015,   65886296,   67438343,   90106088,  112439472,  132669279,  134876686,  156361185,  180140473,  199710294,  202311945,  223667942,  247054014,  266490193
     .long  269753372,  290452467,  312650667,  335103044,  336665371,  357233908,  380087468,  402408259,  404623890,  424017405,  447260069,  468929098,  471536917,  490797818,  514695842,  536235341
     .long  539506744,  561240023,  580816783,  600137824,  606945087,  628543696,  647727240,  666920807,  673330742,  695851481,  714375553,  735014510,  740766001,  763158238,  781289094,  801794409
     .long  809247780,  828885963,  847942547,  869366908,  876159779,  895667404,  915379348,  936672123,  943073834,  963495365,  981507485, 1004237426, 1009986861, 1030275778, 1048943258, 1071543669
     .long 1079013488, 1091280799, 1122420679, 1136470056, 1146451831, 1158584472, 1189331136, 1203253039, 1213890174, 1224839569, 1257032137, 1270294054, 1281325433, 1292146326, 1323945678, 1337073953
     .long 1346661484, 1361019779, 1391647707, 1403597876, 1413573483, 1427801220, 1459084508, 1470903091, 1481532002, 1494584717, 1526257109, 1537423930, 1548445029, 1561365130, 1593692882, 1604730173
     .long 1618495560, 1629726631, 1657733119, 1670713360, 1685933903, 1697030304, 1724643576, 1737496343, 1752319558, 1764338089, 1791291889, 1805590046, 1819754817, 1831644846, 1858205430, 1872369945
     .long 1886147668, 1899477947, 1926947811, 1937837068, 1953059667, 1966259388, 1994384612, 2005142283, 2019973722, 2034087349, 2060512749, 2072707586, 2086886749, 2100867762, 2127948522, 2140013829
     .long 2158026976, 2180714255, 2182502231, 2202908856, 2225465319, 2248017928, 2249412688, 2269691839, 2292903662, 2314273025, 2317113689, 2336732854, 2360338921, 2381579782, 2384027230, 2403512753
     .long 2427780348, 2448364307, 2449623883, 2472125604, 2494692347, 2515145748, 2517060684, 2539430819, 2562650866, 2581929245, 2584233285, 2605951658, 2629563893, 2648709658, 2651669058, 2673257901
     .long 2693322968, 2714974007, 2722000751, 2741338240, 2760761311, 2782277680, 2788911208, 2808121223, 2827146966, 2849585465, 2855559521, 2876214926, 2894582225, 2916892222, 2922473062, 2942994825
     .long 2963064004, 2982619947, 2989126515, 3010567324, 3029976003, 3049401388, 3056563316, 3077872539, 3096890058, 3117229349, 3122691453, 3145437842, 3163803085, 3184009762, 3190127226, 3212744085
     .long 3236991120, 3249241983, 3259377447, 3273509064, 3304429463, 3316545656, 3326287904, 3340292047, 3371867806, 3382800753, 3393988905, 3407333062, 3439303065, 3450107510, 3460902446, 3474112961
     .long 3504639116, 3518980963, 3528604475, 3540636884, 3571551115, 3585762404, 3596041276, 3607942099, 3639509634, 3652545901, 3663213877, 3674462938, 3706422661, 3719326314, 3730649650, 3741769181
     .long 3772295336, 3783477063, 3798867743, 3811963120, 3839733679, 3850780736, 3865778200, 3878746103, 3906119334, 3918088521, 3932426513, 3946839806, 3973554593, 3985395278, 3999340054, 4013619705
     .long 4039947444, 4053228379, 4068082435, 4079086828, 4106859443, 4120009820, 4135519236, 4146392043, 4173773498, 4187837781, 4201647373, 4213957346, 4240686525, 4254618194, 4269083146, 4281263589
     .long          0, 4009881435, 3070408630, 1476614381,  117704453, 3892701278, 2953228467, 1594318824,  235408906, 3775521105, 3104487868, 1443583719,  151783695, 3859670612, 3188637369, 1359958498
     .long  470817812, 4078039887, 2870127522, 1142113529,  454302481, 4095079498, 2887167143, 1125598204,  303567390, 4246338885, 2769986984, 1243302643,  354161947, 4196268608, 2719916717, 1293897206
     .long  941635624, 3609319283, 2401406878, 1612931269, 1059340077, 3492139126, 2284226715, 1730635712,  908604962, 3643398521, 2167046548, 1848340175,  824979751, 3727548028, 2251196049, 1764714954
     .long  607134780, 3409038183, 2469565322, 2083749073,  590619449, 3426077794, 2486604943, 2067233748,  708323894, 3308897645, 2637864320, 1916498651,  758918451, 3258827368, 2587794053, 1967093214
     .long 1883271248, 2671877899, 3343042534,  675489981, 2000975701, 2554697742, 3225862371,  793194424, 2118680154, 2437517569, 3377121772,  642459319, 2035054943, 2521667076, 3461271273,  558834098
     .long 1817209924, 2203157279, 3679640562,  877868201, 1800694593, 2220196890, 3696680183,  861352876, 1649959502, 2371456277, 3579500024,  979057315, 1700554059, 2321386000, 3529429757, 1029651878
     .long 1214269560, 2808194851, 4284678094,  274927765, 1331974013, 2691014694, 4167497931,  392632208, 1181238898, 2842274089, 4050317764,  510336671, 1097613687, 2926423596, 4134467265,  426711450
     .long 1416647788, 3144792887, 3815957466,  208866433, 1400132457, 3161832498, 3832997087,  192351108, 1517836902, 3044652349, 3984256464,   41616011, 1568431459, 2994582072, 3934186197,   92210574
     .long 3766542496,  260116475, 1468159766, 3095640141, 3884246949,  142936318, 1350979603, 3213344584, 4001951402,   25756145, 1502239004, 3062609479, 3918326191,  109905652, 1586388505, 2978984258
     .long 4237360308,  328274927, 1267878658, 2761139289, 4220844977,  345314538, 1284918279, 2744623964, 4070109886,  496573925, 1167738120, 2862328403, 4120704443,  446503648, 1117667853, 2912922966
     .long 3634419848,  933312467, 1872916286, 2158198885, 3752124301,  816132310, 1755736123, 2275903328, 3601389186,  967391705, 1638555956, 2393607791, 3517763975, 1051541212, 1722705457, 2309982570
     .long 3299919004,  733031367, 1941074730, 2629016689, 3283403673,  750070978, 1958114351, 2612501364, 3401108118,  632890829, 2109373728, 2461766267, 3451702675,  582820552, 2059303461, 2512360830
     .long 2428539120, 2143387563,  667035462, 3368273949, 2546243573, 2026207406,  549855299, 3485978392, 2663948026, 1909027233,  701114700, 3335243287, 2580322815, 1993176740,  785264201, 3251618066
     .long 2362477796, 1674666943, 1003633490, 3570652169, 2345962465, 1691706554, 1020673111, 3554136844, 2195227374, 1842965941,  903492952, 3671841283, 2245821931, 1792895664,  853422685, 3722435846
     .long 2833295576, 1205946243,  534912878, 4041470005, 2951000029, 1088766086,  417732715, 4159174448, 2800264914, 1240025481,  300552548, 4276878911, 2716639703, 1324174988,  384702049, 4193253690
     .long 3035673804, 1542544279,   66192250, 3975408673, 3019158473, 1559583890,   83231871, 3958893348, 3136862918, 1442403741,  234491248, 3808158251, 3187457475, 1392333464,  184420981, 3858752814
     .long          0, 1542390107, 3065447094, 3981968365,   84345861, 1592264030, 3014657715, 3898542056,  168691722, 1373702481, 3166243516, 3881176039,  252251151, 1424362836, 3116240569, 3796963298
     .long  337383444, 1341329743, 2729120418, 4181988345,  286987281, 1257510218, 2813073063, 4232255484,  504502302, 1174214981, 2829392552, 4081720307,  454368283, 1090133312, 2913083053, 4132249590
     .long  674766888, 1943478643, 2660180638, 3311412165,  759112749, 1993352566, 2609391259, 3227985856,  573974562, 2044275065, 2491493012, 3480103887,  657533991, 2094935420, 2441490065, 3395891146
     .long 1009004604, 1741369703, 2324902538, 3514577873,  958608441, 1657550178, 2408855183, 3564845012,  908736566, 1841641837, 2157787776, 3681696731,  858602547, 1757560168, 2241478277, 3732226014
     .long 1349533776,  194986251, 3871818470, 3173532605, 1433879637,  244860174, 3821029091, 3090106296, 1518225498,   26298625, 3972614892, 3072740279, 1601784927,   76958980, 3922611945, 2988527538
     .long 1147949124,  528699679, 4074459890, 2838778793, 1097552961,  444880154, 4158412535, 2889045932, 1315067982,  361584917, 4174732024, 2738510755, 1264933963,  277503248, 4258422525, 2789040038
     .long 2018009208,  598171939, 3472843470, 2500879253, 2102355069,  648045862, 3422054091, 2417452944, 1917216882,  698968361, 3304155844, 2669570975, 2000776311,  749628716, 3254152897, 2585358234
     .long 1817473132,  935031095, 3672339162, 2165076865, 1767076969,  851211570, 3756291807, 2215344004, 1717205094, 1035303229, 3505224400, 2332195723, 1667071075,  951221560, 3588914901, 2382725006
     .long 2699067552, 4212097531,  374833686, 1303937869, 2783413413, 4261971454,  324044307, 1220511560, 2867759274, 4043409905,  475630108, 1203145543, 2951318703, 4094070260,  425627161, 1118932802
     .long 3036450996, 4011037167,   38507010, 1503957849, 2986054833, 3927217642,  122459655, 1554224988, 3203569854, 3843922405,  138779144, 1403689811, 3153435835, 3759840736,  222469645, 1454219094
     .long 2295898248, 3543638483, 1047503422, 1702929253, 2380244109, 3593512406,  996714043, 1619502944, 2195105922, 3644434905,  878815796, 1871620975, 2278665351, 3695095260,  828812849, 1787408234
     .long 2630135964, 3341529543,  712225322, 1906094961, 2579739801, 3257710018,  796177967, 1956362100, 2529867926, 3441801677,  545110560, 2073213819, 2479733907, 3357720008,  628801061, 2123743102
     .long 4036018416, 2877276587, 1177010758,  499696413, 4120364277, 2927150510, 1126221379,  416270104, 4204710138, 2708588961, 1277807180,  398904087, 4288269567, 2759249316, 1227804233,  314691346
     .long 3834433764, 3210990015, 1379652178,  164942601, 3784037601, 3127170490, 1463604823,  215209740, 4001552622, 3043875253, 1479924312,   64674563, 3951418603, 2959793584, 1563614813,  115203846
     .long 3634946264, 2202526083, 1847583342,  904979253, 3719292125, 2252400006, 1796793963,  821552944, 3534153938, 2303322505, 1678895716, 1073670975, 3617713367, 2353982860, 1628892769,  989458234
     .long 3434410188, 2539385239, 2047079034,  569176865, 3384014025, 2455565714, 2131031679,  619444004, 3334142150, 2639657373, 1879964272,  736295723, 3284008131, 2555575704, 1963654773,  786825006
q0:  .byte 169, 103, 179, 232,   4, 253, 163, 118, 154, 146, 128, 120, 228, 221, 209,  56
     .byte  13, 198,  53, 152,  24, 247, 236, 108,  67, 117,  55,  38, 250,  19, 148,  72
     .byte 242, 208, 139,  48, 132,  84, 223,  35,  25,  91,  61,  89, 243, 174, 162, 130
     .byte  99,   1, 131,  46, 217,  81, 155, 124, 166, 235, 165, 190,  22,  12, 227,  97
     .byte 192, 140,  58, 245, 115,  44,  37,  11, 187,  78, 137, 107,  83, 106, 180, 241
     .byte 225, 230, 189,  69, 226, 244, 182, 102, 204, 149,   3,  86, 212,  28,  30, 215
     .byte 251, 195, 142, 181, 233, 207, 191, 186, 234, 119,  57, 175,  51, 201,  98, 113
     .byte 129, 121,   9, 173,  36, 205, 249, 216, 229, 197, 185,  77,  68,   8, 134, 231
     .byte 161,  29, 170, 237,   6, 112, 178, 210,  65, 123, 160,  17,  49, 194,  39, 144
     .byte  32, 246,  96, 255, 150,  92, 177, 171, 158, 156,  82,  27,  95, 147,  10, 239
     .byte 145, 133,  73, 238,  45,  79, 143,  59,  71, 135, 109,  70, 214,  62, 105, 100
     .byte  42, 206, 203,  47, 252, 151,   5, 122, 172, 127, 213,  26,  75,  14, 167,  90
     .byte  40,  20,  63,  41, 136,  60,  76,   2, 184, 218, 176,  23,  85,  31, 138, 125
     .byte  87, 199, 141, 116, 183, 196, 159, 114, 126,  21,  34,  18,  88,   7, 153,  52
     .byte 110,  80, 222, 104, 101, 188, 219, 248, 200, 168,  43,  64, 220, 254,  50, 164
     .byte 202,  16,  33, 240, 211,  93,  15,   0, 111, 157,  54,  66,  74,  94, 193, 224
q1:  .byte 117, 243, 198, 244, 219, 123, 251, 200,  74, 211, 230, 107,  69, 125, 232,  75
     .byte 214,  50, 216, 253,  55, 113, 241, 225,  48,  15, 248,  27, 135, 250,   6,  63
     .byte  94, 186, 174,  91, 138,   0, 188, 157, 109, 193, 177,  14, 128,  93, 210, 213
     .byte 160, 132,   7,  20, 181, 144,  44, 163, 178, 115,  76,  84, 146, 116,  54,  81
     .byte  56, 176, 189,  90, 252,  96,  98, 150, 108,  66, 247,  16, 124,  40,  39, 140
     .byte  19, 149, 156, 199,  36,  70,  59, 112, 202, 227, 133, 203,  17, 208, 147, 184
     .byte 166, 131,  32, 255, 159, 119, 195, 204,   3, 111,   8, 191,  64, 231,  43, 226
     .byte 121,  12, 170, 130,  65,  58, 234, 185, 228, 154, 164, 151, 126, 218, 122,  23
     .byte 102, 148, 161,  29,  61, 240, 222, 179,  11, 114, 167,  28, 239, 209,  83,  62
     .byte 143,  51,  38,  95, 236, 118,  42,  73, 129, 136, 238,  33, 196,  26, 235, 217
     .byte 197,  57, 153, 205, 173,  49, 139,   1,  24,  35, 221,  31,  78,  45, 249,  72
     .byte  79, 242, 101, 142, 120,  92,  88,  25, 141, 229, 152,  87, 103, 127,   5, 100
     .byte 175,  99, 182, 254, 245, 183,  60, 165, 206, 233, 104,  68, 224,  77,  67, 105
     .byte  41,  46, 172,  21,  89, 168,  10, 158, 110,  71, 223,  52,  53, 106, 207, 220
     .byte  34, 201, 192, 155, 137, 212, 237, 171,  18, 162,  13,  82, 187,   2,  47, 169
     .byte 215,  97,  30, 180,  80,   4, 246, 194,  22,  37, 134,  86,  85,   9, 190, 145

twofish_128_key_schedule:
    stmdb   sp!, {r4-r11, lr}
    mov     r12, #2                     @ k
    ldmia   r0, {r2-r5}
    stmdb   sp!, {r3, r5}               @ Mo
    stmdb   sp!, {r2, r4}               @ Me
    b       .Ltwofish_key_schedule
twofish_192_key_schedule:
    stmdb   sp!, {r4-r11, lr}
    mov     r12, #3                     @ k
    ldmia   r0, {r2-r7}
    stmdb   sp!, {r3, r5, r7}           @ Mo
    stmdb   sp!, {r2, r4, r6}           @ Me
    b       .Ltwofish_key_schedule
twofish_256_key_schedule:
    stmdb   sp!, {r4-r11, lr}
    mov     r12, #4                     @ k
    ldmia   r0, {r2-r9}
    stmdb   sp!, {r3, r5, r7, r9}       @ Mo
    stmdb   sp!, {r2, r4, r6, r8}       @ Me
    b       .Ltwofish_key_schedule
.Ltwofish_key_schedule:
    sub     r3, pc, #80                 @ &twofish_128_key_schedule
    mov     r6, r12                     @ k
    sub     r3, #12800                  @ RS
.Ltwofish_key_schedule_sbox:
    mov     r4, #0
    mov     r5, #8
.Ltwofish_key_schedule_sbox_inernal:
    ldrb    r2, [r0], #1                @ m
    ldr     r2, [r3, r2, LSL #2]
    add     r3, #1024
    eor     r4, r2
    subs    r5, #1
    bne     .Ltwofish_key_schedule_sbox_inernal
    str     r4, [sp, #-4]!              @ S[i]
    sub     r3, #8192                   @ RS
    subs    r6, #1
    bne     .Ltwofish_key_schedule_sbox
    mov     r4, #1
    add     r9, r3, #8192               @ MDS
    mov     r2, #0                      @ i
    orr     r4, r4, LSL #8
    add     r10, r9, #4096              @ q0
    mov     r3, sp
    orr     r4, r4, LSL #16             @ rho = 16843009
    add     r11, r10, #256              @ q1
.Ltwofish_key_schedule_sbox_expand:
    bl      h
    and     r5, r7, #255
    ldr     r6, [r9, r5, ROR #30]
    str     r6, [r1, #0]
    add     r9, #1024
    and     r5, r7, #65280
    ldr     r6, [r9, r5, ROR #6]
    str     r6, [r1, #1024]
    add     r9, #1024
    and     r5, r7, #16711680
    ldr     r6, [r9, r5, ROR #14]
    str     r6, [r1, #2048]
    add     r9, #1024
    and     r5, r7, #4278190080
    ldr     r6, [r9, r5, ROR #22]
    str     r6, [r1, #3072]
    add     r9, #1024
    add     r2, r4
    add     r1, #4
    sub     r9, #4096
    tst     r2, #255
    bne     .Ltwofish_key_schedule_sbox_expand
    add     sp, r12, LSL #2
    mov     r2, #0
    sub     r0, r12, LSL #3
    mov     r1, #20
.Ltwofish_key_schedule_loop:
    add     r3, sp, r12, LSR #3         @ Me
    bl      h
    bl      .Lapply_mds                 @ h(2 * i * p, Me)
    add     r2, r4
    mov     r5, r6                      @ Ai = h(2 * i * p, Me)
    add     r3, sp, r12, LSL #2         @ Mo
    bl      h
    bl      .Lapply_mds                 @ h((2 * i + 1) * p, Mo)
    add     r2, r4
    mov     r6, r6, ROR #24             @ Bi = h((2 * i + 1) * p, Mo) <<< 8
    add     r5, r6                      @ K[2 * i] = Ai + Bi
    add     r6, r5                      @ Ai + 2 * Bi
    mov     r6, r6, ROR #23             @ K[2 * i + 1] = (Ai + 2 * Bi) <<<9
    stmia   r0!, {r5-r6}
    subs    r1, #1
    bne     .Ltwofish_key_schedule_loop
    add     sp, r12, LSL #3
    ldmia   sp!, {r4-r11, pc}

h:
    add     r3, r12, LSL #2
    mov     r7, r2
    tst     r12, #1
    bne     .Lh_192
    tst     r12, #2
    bne     .Lh_128
.Lh_256:
    ldrb    r6, [r11, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r10, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r10, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r11, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldr     r6, [r3, #-4]!
    eor     r7, r6
.Lh_192:
    ldrb    r6, [r10, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r10, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r11, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r11, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldr     r6, [r3, #-4]!
    eor     r7, r6
.Lh_128:
    ldrb    r6, [r11, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r10, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r11, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r10, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldr     r6, [r3, #-4]!
    eor     r7, r6
    ldrb    r6, [r11, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r11, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r10, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r10, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldr     r6, [r3, #-4]!
    eor     r7, r6
    ldrb    r6, [r10, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r11, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r10, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    ldrb    r6, [r11, r7, LSR #24]
    orr     r7, r6, r7, LSL #8
    mov     pc, lr

.Lapply_mds:
    mov     r6, #0
    and     r8, r7, #255
    ldr     r3, [r9, r8, ROR #30]
    eor     r6, r3
    add     r9, #1024
    and     r8, r7, #65280
    ldr     r3, [r9, r8, ROR #6]
    eor     r6, r3
    add     r9, #1024
    and     r8, r7, #16711680
    ldr     r3, [r9, r8, ROR #14]
    eor     r6, r3
    add     r9, #1024
    and     r8, r7, #4278190080
    ldr     r3, [r9, r8, ROR #22]
    eor     r6, r3
    add     r9, #1024
    sub     r9, #4096
    mov     pc, lr

twofish_encrypt:
    stmdb   sp!, {r4-r11}
    ldmia   r0, {r4-r7}
    ldmia   r1!, {r8-r11}               @ K0, K1, K2, K3
    mov     r12, #16                    @ number of rounds
    eor     r4, r8                      @ input whitening
    eor     r5, r9                      @ input whitening
    eor     r6, r10                     @ input whitening
    eor     r7, r11                     @ input whitening
    add     r1, #16
.Ltwofish_encrypt_round:
    mov     r7, r7, ROR #31
    mov     r8, #0                      @ f start
    mov     r9, #0
    and     r3, r4, #255                @ g start
    ldr     r3, [r2, r3, ROR #30]
    eor     r8, r3
    add     r2, #1024
    and     r3, r4, #65280
    ldr     r3, [r2, r3, ROR #6]
    eor     r8, r3
    add     r2, #1024
    and     r3, r4, #16711680
    ldr     r3, [r2, r3, ROR #14]
    eor     r8, r3
    add     r2, #1024
    and     r3, r4, #4278190080
    ldr     r3, [r2, r3, ROR #22]
    eor     r8, r3
    add     r2, #1024
    sub     r2, #4096                   @ g end
    and     r3, r5, #4278190080         @ g start
    ldr     r3, [r2, r3, ROR #22]
    eor     r9, r3
    add     r2, #1024
    and     r3, r5, #255
    ldr     r3, [r2, r3, ROR #30]
    eor     r9, r3
    add     r2, #1024
    and     r3, r5, #65280
    ldr     r3, [r2, r3, ROR #6]
    eor     r9, r3
    add     r2, #1024
    and     r3, r5, #16711680
    ldr     r3, [r2, r3, ROR #14]
    eor     r9, r3
    add     r2, #1024
    sub     r2, #4096                   @ g end
    ldmia   r1!, {r10-r11}              @ K
    add     r8, r9                      @ PHT
    add     r9, r8                      @ PHT
    add     r8, r10
    add     r9, r11                     @ f end
    eor     r8, r6
    eor     r9, r7
    mov     r8, r8, ROR #1
    mov     r6, r4
    mov     r7, r5
    mov     r4, r8
    mov     r5, r9
    subs    r12, #1
    bne     .Ltwofish_encrypt_round
    sub     r1, #144
    ldmia   r1!, {r4-r5}
    eor     r6, r4                      @ output whitening
    eor     r7, r5                      @ output whitening
    ldmia   r1!, {r4-r5}
    eor     r8, r4                      @ output whitening
    eor     r9, r5                      @ output whitening
    stmia   r0, {r6-r9}
    ldmia   sp!, {r4-r11}
    mov     pc, lr

twofish_decrypt:
    add     r1, #32
    stmdb   sp!, {r4-r11}
    ldmia   r0, {r4-r7}
    ldmdb   r1!, {r8-r11}               @ K0, K1, K2, K3
    mov     r12, #16                    @ number of rounds
    eor     r4, r8                      @ input whitening
    eor     r5, r9                      @ input whitening
    eor     r6, r10                     @ input whitening
    eor     r7, r11                     @ input whitening
    add     r1, #144
.Ltwofish_decrypt_round:
    mov     r6, r6, ROR #31
    mov     r8, #0                      @ f start
    mov     r9, #0
    and     r3, r4, #255                @ g start
    ldr     r3, [r2, r3, ROR #30]
    eor     r8, r3
    add     r2, #1024
    and     r3, r4, #65280
    ldr     r3, [r2, r3, ROR #6]
    eor     r8, r3
    add     r2, #1024
    and     r3, r4, #16711680
    ldr     r3, [r2, r3, ROR #14]
    eor     r8, r3
    add     r2, #1024
    and     r3, r4, #4278190080
    ldr     r3, [r2, r3, ROR #22]
    eor     r8, r3
    add     r2, #1024
    sub     r2, #4096                   @ g end
    and     r3, r5, #4278190080         @ g start
    ldr     r3, [r2, r3, ROR #22]
    eor     r9, r3
    add     r2, #1024
    and     r3, r5, #255
    ldr     r3, [r2, r3, ROR #30]
    eor     r9, r3
    add     r2, #1024
    and     r3, r5, #65280
    ldr     r3, [r2, r3, ROR #6]
    eor     r9, r3
    add     r2, #1024
    and     r3, r5, #16711680
    ldr     r3, [r2, r3, ROR #14]
    eor     r9, r3
    add     r2, #1024
    sub     r2, #4096                   @ g end
    ldmdb   r1!, {r10-r11}              @ K
    add     r8, r9                      @ PHT
    add     r9, r8                      @ PHT
    add     r8, r10
    add     r9, r11                     @ f end
    eor     r8, r6
    eor     r9, r7
    mov     r9, r9, ROR #1
    mov     r6, r4
    mov     r7, r5
    mov     r4, r8
    mov     r5, r9
    subs    r12, #1
    bne     .Ltwofish_decrypt_round
    sub     r1, #16
    ldmdb   r1!, {r4-r5}
    eor     r8, r4                      @ output whitening
    eor     r9, r5                      @ output whitening
    ldmdb   r1!, {r4-r5}
    eor     r6, r4                      @ output whitening
    eor     r7, r5                      @ output whitening
    stmia   r0, {r6-r9}
    ldmia   sp!, {r4-r11}
    mov     pc, lr
