Skip to content

Instantly share code, notes, and snippets.

@Andoryuuta
Created June 8, 2025 10:41
Show Gist options
  • Select an option

  • Save Andoryuuta/dbf4e02d66e00a29ff3f62f4e5594c5c to your computer and use it in GitHub Desktop.

Select an option

Save Andoryuuta/dbf4e02d66e00a29ff3f62f4e5594c5c to your computer and use it in GitHub Desktop.
keen::ContentHash calculation for Enshrouded / KFC2 archive files.
#include <iostream>
#include <cstdint>
uint32_t AES_TABLE_1[256] = {
0x50A7F451, 0x5365417E, 0xC3A4171A, 0x965E273A, 0xCB6BAB3B, 0xF1459D1F, 0xAB58FAAC, 0x9303E34B,
0x55FA3020, 0xF66D76AD, 0x9176CC88, 0x254C02F5, 0xFCD7E54F, 0xD7CB2AC5, 0x80443526, 0x8FA362B5,
0x495AB1DE, 0x671BBA25, 0x980EEA45, 0xE1C0FE5D, 0x02752FC3, 0x12F04C81, 0xA397468D, 0xC6F9D36B,
0xE75F8F03, 0x959C9215, 0xEB7A6DBF, 0xDA595295, 0x2D83BED4, 0xD3217458, 0x2969E049, 0x44C8C98E,
0x6A89C275, 0x78798EF4, 0x6B3E5899, 0xDD71B927, 0xB64FE1BE, 0x17AD88F0, 0x66AC20C9, 0xB43ACE7D,
0x184ADF63, 0x82311AE5, 0x60335197, 0x457F5362, 0xE07764B1, 0x84AE6BBB, 0x1CA081FE, 0x942B08F9,
0x58684870, 0x19FD458F, 0x876CDE94, 0xB7F87B52, 0x23D373AB, 0xE2024B72, 0x578F1FE3, 0x2AAB5566,
0x0728EBB2, 0x03C2B52F, 0x9A7BC586, 0xA50837D3, 0xF2872830, 0xB2A5BF23, 0xBA6A0302, 0x5C8216ED,
0x2B1CCF8A, 0x92B479A7, 0xF0F207F3, 0xA1E2694E, 0xCDF4DA65, 0xD5BE0506, 0x1F6234D1, 0x8AFEA6C4,
0x9D532E34, 0xA055F3A2, 0x32E18A05, 0x75EBF6A4, 0x39EC830B, 0xAAEF6040, 0x069F715E, 0x51106EBD,
0xF98A213E, 0x3D06DD96, 0xAE053EDD, 0x46BDE64D, 0xB58D5491, 0x055DC471, 0x6FD40604, 0xFF155060,
0x24FB9819, 0x97E9BDD6, 0xCC434089, 0x779ED967, 0xBD42E8B0, 0x888B8907, 0x385B19E7, 0xDBEEC879,
0x470A7CA1, 0xE90F427C, 0xC91E84F8, 0x00000000, 0x83868009, 0x48ED2B32, 0xAC70111E, 0x4E725A6C,
0xFBFF0EFD, 0x5638850F, 0x1ED5AE3D, 0x27392D36, 0x64D90F0A, 0x21A65C68, 0xD1545B9B, 0x3A2E3624,
0xB1670A0C, 0x0FE75793, 0xD296EEB4, 0x9E919B1B, 0x4FC5C080, 0xA220DC61, 0x694B775A, 0x161A121C,
0x0ABA93E2, 0xE52AA0C0, 0x43E0223C, 0x1D171B12, 0x0B0D090E, 0xADC78BF2, 0xB9A8B62D, 0xC8A91E14,
0x8519F157, 0x4C0775AF, 0xBBDD99EE, 0xFD607FA3, 0x9F2601F7, 0xBCF5725C, 0xC53B6644, 0x347EFB5B,
0x7629438B, 0xDCC623CB, 0x68FCEDB6, 0x63F1E4B8, 0xCADC31D7, 0x10856342, 0x40229713, 0x2011C684,
0x7D244A85, 0xF83DBBD2, 0x1132F9AE, 0x6DA129C7, 0x4B2F9E1D, 0xF330B2DC, 0xEC52860D, 0xD0E3C177,
0x6C16B32B, 0x99B970A9, 0xFA489411, 0x2264E947, 0xC48CFCA8, 0x1A3FF0A0, 0xD82C7D56, 0xEF903322,
0xC74E4987, 0xC1D138D9, 0xFEA2CA8C, 0x360BD498, 0xCF81F5A6, 0x28DE7AA5, 0x268EB7DA, 0xA4BFAD3F,
0xE49D3A2C, 0x0D927850, 0x9BCC5F6A, 0x62467E54, 0xC2138DF6, 0xE8B8D890, 0x5EF7392E, 0xF5AFC382,
0xBE805D9F, 0x7C93D069, 0xA92DD56F, 0xB31225CF, 0x3B99ACC8, 0xA77D1810, 0x6E639CE8, 0x7BBB3BDB,
0x097826CD, 0xF418596E, 0x01B79AEC, 0xA89A4F83, 0x656E95E6, 0x7EE6FFAA, 0x08CFBC21, 0xE6E815EF,
0xD99BE7BA, 0xCE366F4A, 0xD4099FEA, 0xD67CB029, 0xAFB2A431, 0x31233F2A, 0x3094A5C6, 0xC066A235,
0x37BC4E74, 0xA6CA82FC, 0xB0D090E0, 0x15D8A733, 0x4A9804F1, 0xF7DAEC41, 0x0E50CD7F, 0x2FF69117,
0x8DD64D76, 0x4DB0EF43, 0x544DAACC, 0xDF0496E4, 0xE3B5D19E, 0x1B886A4C, 0xB81F2CC1, 0x7F516546,
0x04EA5E9D, 0x5D358C01, 0x737487FA, 0x2E410BFB, 0x5A1D67B3, 0x52D2DB92, 0x335610E9, 0x1347D66D,
0x8C61D79A, 0x7A0CA137, 0x8E14F859, 0x893C13EB, 0xEE27A9CE, 0x35C961B7, 0xEDE51CE1, 0x3CB1477A,
0x59DFD29C, 0x3F73F255, 0x79CE1418, 0xBF37C773, 0xEACDF753, 0x5BAAFD5F, 0x146F3DDF, 0x86DB4478,
0x81F3AFCA, 0x3EC468B9, 0x2C342438, 0x5F40A3C2, 0x72C31D16, 0x0C25E2BC, 0x8B493C28, 0x41950DFF,
0x7101A839, 0xDEB30C08, 0x9CE4B4D8, 0x90C15664, 0x6184CB7B, 0x70B632D5, 0x745C6C48, 0x4257B8D0 };
uint32_t AES_TABLE_2[256] = {
0x5150A7F4, 0x7E536541, 0x1AC3A417, 0x3A965E27, 0x3BCB6BAB, 0x1FF1459D, 0xACAB58FA, 0x4B9303E3,
0x2055FA30, 0xADF66D76, 0x889176CC, 0xF5254C02, 0x4FFCD7E5, 0xC5D7CB2A, 0x26804435, 0xB58FA362,
0xDE495AB1, 0x25671BBA, 0x45980EEA, 0x5DE1C0FE, 0xC302752F, 0x8112F04C, 0x8DA39746, 0x6BC6F9D3,
0x03E75F8F, 0x15959C92, 0xBFEB7A6D, 0x95DA5952, 0xD42D83BE, 0x58D32174, 0x492969E0, 0x8E44C8C9,
0x756A89C2, 0xF478798E, 0x996B3E58, 0x27DD71B9, 0xBEB64FE1, 0xF017AD88, 0xC966AC20, 0x7DB43ACE,
0x63184ADF, 0xE582311A, 0x97603351, 0x62457F53, 0xB1E07764, 0xBB84AE6B, 0xFE1CA081, 0xF9942B08,
0x70586848, 0x8F19FD45, 0x94876CDE, 0x52B7F87B, 0xAB23D373, 0x72E2024B, 0xE3578F1F, 0x662AAB55,
0xB20728EB, 0x2F03C2B5, 0x869A7BC5, 0xD3A50837, 0x30F28728, 0x23B2A5BF, 0x02BA6A03, 0xED5C8216,
0x8A2B1CCF, 0xA792B479, 0xF3F0F207, 0x4EA1E269, 0x65CDF4DA, 0x06D5BE05, 0xD11F6234, 0xC48AFEA6,
0x349D532E, 0xA2A055F3, 0x0532E18A, 0xA475EBF6, 0x0B39EC83, 0x40AAEF60, 0x5E069F71, 0xBD51106E,
0x3EF98A21, 0x963D06DD, 0xDDAE053E, 0x4D46BDE6, 0x91B58D54, 0x71055DC4, 0x046FD406, 0x60FF1550,
0x1924FB98, 0xD697E9BD, 0x89CC4340, 0x67779ED9, 0xB0BD42E8, 0x07888B89, 0xE7385B19, 0x79DBEEC8,
0xA1470A7C, 0x7CE90F42, 0xF8C91E84, 0x00000000, 0x09838680, 0x3248ED2B, 0x1EAC7011, 0x6C4E725A,
0xFDFBFF0E, 0x0F563885, 0x3D1ED5AE, 0x3627392D, 0x0A64D90F, 0x6821A65C, 0x9BD1545B, 0x243A2E36,
0x0CB1670A, 0x930FE757, 0xB4D296EE, 0x1B9E919B, 0x804FC5C0, 0x61A220DC, 0x5A694B77, 0x1C161A12,
0xE20ABA93, 0xC0E52AA0, 0x3C43E022, 0x121D171B, 0x0E0B0D09, 0xF2ADC78B, 0x2DB9A8B6, 0x14C8A91E,
0x578519F1, 0xAF4C0775, 0xEEBBDD99, 0xA3FD607F, 0xF79F2601, 0x5CBCF572, 0x44C53B66, 0x5B347EFB,
0x8B762943, 0xCBDCC623, 0xB668FCED, 0xB863F1E4, 0xD7CADC31, 0x42108563, 0x13402297, 0x842011C6,
0x857D244A, 0xD2F83DBB, 0xAE1132F9, 0xC76DA129, 0x1D4B2F9E, 0xDCF330B2, 0x0DEC5286, 0x77D0E3C1,
0x2B6C16B3, 0xA999B970, 0x11FA4894, 0x472264E9, 0xA8C48CFC, 0xA01A3FF0, 0x56D82C7D, 0x22EF9033,
0x87C74E49, 0xD9C1D138, 0x8CFEA2CA, 0x98360BD4, 0xA6CF81F5, 0xA528DE7A, 0xDA268EB7, 0x3FA4BFAD,
0x2CE49D3A, 0x500D9278, 0x6A9BCC5F, 0x5462467E, 0xF6C2138D, 0x90E8B8D8, 0x2E5EF739, 0x82F5AFC3,
0x9FBE805D, 0x697C93D0, 0x6FA92DD5, 0xCFB31225, 0xC83B99AC, 0x10A77D18, 0xE86E639C, 0xDB7BBB3B,
0xCD097826, 0x6EF41859, 0xEC01B79A, 0x83A89A4F, 0xE6656E95, 0xAA7EE6FF, 0x2108CFBC, 0xEFE6E815,
0xBAD99BE7, 0x4ACE366F, 0xEAD4099F, 0x29D67CB0, 0x31AFB2A4, 0x2A31233F, 0xC63094A5, 0x35C066A2,
0x7437BC4E, 0xFCA6CA82, 0xE0B0D090, 0x3315D8A7, 0xF14A9804, 0x41F7DAEC, 0x7F0E50CD, 0x172FF691,
0x768DD64D, 0x434DB0EF, 0xCC544DAA, 0xE4DF0496, 0x9EE3B5D1, 0x4C1B886A, 0xC1B81F2C, 0x467F5165,
0x9D04EA5E, 0x015D358C, 0xFA737487, 0xFB2E410B, 0xB35A1D67, 0x9252D2DB, 0xE9335610, 0x6D1347D6,
0x9A8C61D7, 0x377A0CA1, 0x598E14F8, 0xEB893C13, 0xCEEE27A9, 0xB735C961, 0xE1EDE51C, 0x7A3CB147,
0x9C59DFD2, 0x553F73F2, 0x1879CE14, 0x73BF37C7, 0x53EACDF7, 0x5F5BAAFD, 0xDF146F3D, 0x7886DB44,
0xCA81F3AF, 0xB93EC468, 0x382C3424, 0xC25F40A3, 0x1672C31D, 0xBC0C25E2, 0x288B493C, 0xFF41950D,
0x397101A8, 0x08DEB30C, 0xD89CE4B4, 0x6490C156, 0x7B6184CB, 0xD570B632, 0x48745C6C, 0xD04257B8 };
uint32_t AES_TABLE_3[256] = {
0xF45150A7, 0x417E5365, 0x171AC3A4, 0x273A965E, 0xAB3BCB6B, 0x9D1FF145, 0xFAACAB58, 0xE34B9303,
0x302055FA, 0x76ADF66D, 0xCC889176, 0x02F5254C, 0xE54FFCD7, 0x2AC5D7CB, 0x35268044, 0x62B58FA3,
0xB1DE495A, 0xBA25671B, 0xEA45980E, 0xFE5DE1C0, 0x2FC30275, 0x4C8112F0, 0x468DA397, 0xD36BC6F9,
0x8F03E75F, 0x9215959C, 0x6DBFEB7A, 0x5295DA59, 0xBED42D83, 0x7458D321, 0xE0492969, 0xC98E44C8,
0xC2756A89, 0x8EF47879, 0x58996B3E, 0xB927DD71, 0xE1BEB64F, 0x88F017AD, 0x20C966AC, 0xCE7DB43A,
0xDF63184A, 0x1AE58231, 0x51976033, 0x5362457F, 0x64B1E077, 0x6BBB84AE, 0x81FE1CA0, 0x08F9942B,
0x48705868, 0x458F19FD, 0xDE94876C, 0x7B52B7F8, 0x73AB23D3, 0x4B72E202, 0x1FE3578F, 0x55662AAB,
0xEBB20728, 0xB52F03C2, 0xC5869A7B, 0x37D3A508, 0x2830F287, 0xBF23B2A5, 0x0302BA6A, 0x16ED5C82,
0xCF8A2B1C, 0x79A792B4, 0x07F3F0F2, 0x694EA1E2, 0xDA65CDF4, 0x0506D5BE, 0x34D11F62, 0xA6C48AFE,
0x2E349D53, 0xF3A2A055, 0x8A0532E1, 0xF6A475EB, 0x830B39EC, 0x6040AAEF, 0x715E069F, 0x6EBD5110,
0x213EF98A, 0xDD963D06, 0x3EDDAE05, 0xE64D46BD, 0x5491B58D, 0xC471055D, 0x06046FD4, 0x5060FF15,
0x981924FB, 0xBDD697E9, 0x4089CC43, 0xD967779E, 0xE8B0BD42, 0x8907888B, 0x19E7385B, 0xC879DBEE,
0x7CA1470A, 0x427CE90F, 0x84F8C91E, 0x00000000, 0x80098386, 0x2B3248ED, 0x111EAC70, 0x5A6C4E72,
0x0EFDFBFF, 0x850F5638, 0xAE3D1ED5, 0x2D362739, 0x0F0A64D9, 0x5C6821A6, 0x5B9BD154, 0x36243A2E,
0x0A0CB167, 0x57930FE7, 0xEEB4D296, 0x9B1B9E91, 0xC0804FC5, 0xDC61A220, 0x775A694B, 0x121C161A,
0x93E20ABA, 0xA0C0E52A, 0x223C43E0, 0x1B121D17, 0x090E0B0D, 0x8BF2ADC7, 0xB62DB9A8, 0x1E14C8A9,
0xF1578519, 0x75AF4C07, 0x99EEBBDD, 0x7FA3FD60, 0x01F79F26, 0x725CBCF5, 0x6644C53B, 0xFB5B347E,
0x438B7629, 0x23CBDCC6, 0xEDB668FC, 0xE4B863F1, 0x31D7CADC, 0x63421085, 0x97134022, 0xC6842011,
0x4A857D24, 0xBBD2F83D, 0xF9AE1132, 0x29C76DA1, 0x9E1D4B2F, 0xB2DCF330, 0x860DEC52, 0xC177D0E3,
0xB32B6C16, 0x70A999B9, 0x9411FA48, 0xE9472264, 0xFCA8C48C, 0xF0A01A3F, 0x7D56D82C, 0x3322EF90,
0x4987C74E, 0x38D9C1D1, 0xCA8CFEA2, 0xD498360B, 0xF5A6CF81, 0x7AA528DE, 0xB7DA268E, 0xAD3FA4BF,
0x3A2CE49D, 0x78500D92, 0x5F6A9BCC, 0x7E546246, 0x8DF6C213, 0xD890E8B8, 0x392E5EF7, 0xC382F5AF,
0x5D9FBE80, 0xD0697C93, 0xD56FA92D, 0x25CFB312, 0xACC83B99, 0x1810A77D, 0x9CE86E63, 0x3BDB7BBB,
0x26CD0978, 0x596EF418, 0x9AEC01B7, 0x4F83A89A, 0x95E6656E, 0xFFAA7EE6, 0xBC2108CF, 0x15EFE6E8,
0xE7BAD99B, 0x6F4ACE36, 0x9FEAD409, 0xB029D67C, 0xA431AFB2, 0x3F2A3123, 0xA5C63094, 0xA235C066,
0x4E7437BC, 0x82FCA6CA, 0x90E0B0D0, 0xA73315D8, 0x04F14A98, 0xEC41F7DA, 0xCD7F0E50, 0x91172FF6,
0x4D768DD6, 0xEF434DB0, 0xAACC544D, 0x96E4DF04, 0xD19EE3B5, 0x6A4C1B88, 0x2CC1B81F, 0x65467F51,
0x5E9D04EA, 0x8C015D35, 0x87FA7374, 0x0BFB2E41, 0x67B35A1D, 0xDB9252D2, 0x10E93356, 0xD66D1347,
0xD79A8C61, 0xA1377A0C, 0xF8598E14, 0x13EB893C, 0xA9CEEE27, 0x61B735C9, 0x1CE1EDE5, 0x477A3CB1,
0xD29C59DF, 0xF2553F73, 0x141879CE, 0xC773BF37, 0xF753EACD, 0xFD5F5BAA, 0x3DDF146F, 0x447886DB,
0xAFCA81F3, 0x68B93EC4, 0x24382C34, 0xA3C25F40, 0x1D1672C3, 0xE2BC0C25, 0x3C288B49, 0x0DFF4195,
0xA8397101, 0x0C08DEB3, 0xB4D89CE4, 0x566490C1, 0xCB7B6184, 0x32D570B6, 0x6C48745C, 0xB8D04257 };
uint32_t AES_TABLE_4[256] = {
0xA7F45150, 0x65417E53, 0xA4171AC3, 0x5E273A96, 0x6BAB3BCB, 0x459D1FF1, 0x58FAACAB, 0x03E34B93,
0xFA302055, 0x6D76ADF6, 0x76CC8891, 0x4C02F525, 0xD7E54FFC, 0xCB2AC5D7, 0x44352680, 0xA362B58F,
0x5AB1DE49, 0x1BBA2567, 0x0EEA4598, 0xC0FE5DE1, 0x752FC302, 0xF04C8112, 0x97468DA3, 0xF9D36BC6,
0x5F8F03E7, 0x9C921595, 0x7A6DBFEB, 0x595295DA, 0x83BED42D, 0x217458D3, 0x69E04929, 0xC8C98E44,
0x89C2756A, 0x798EF478, 0x3E58996B, 0x71B927DD, 0x4FE1BEB6, 0xAD88F017, 0xAC20C966, 0x3ACE7DB4,
0x4ADF6318, 0x311AE582, 0x33519760, 0x7F536245, 0x7764B1E0, 0xAE6BBB84, 0xA081FE1C, 0x2B08F994,
0x68487058, 0xFD458F19, 0x6CDE9487, 0xF87B52B7, 0xD373AB23, 0x024B72E2, 0x8F1FE357, 0xAB55662A,
0x28EBB207, 0xC2B52F03, 0x7BC5869A, 0x0837D3A5, 0x872830F2, 0xA5BF23B2, 0x6A0302BA, 0x8216ED5C,
0x1CCF8A2B, 0xB479A792, 0xF207F3F0, 0xE2694EA1, 0xF4DA65CD, 0xBE0506D5, 0x6234D11F, 0xFEA6C48A,
0x532E349D, 0x55F3A2A0, 0xE18A0532, 0xEBF6A475, 0xEC830B39, 0xEF6040AA, 0x9F715E06, 0x106EBD51,
0x8A213EF9, 0x06DD963D, 0x053EDDAE, 0xBDE64D46, 0x8D5491B5, 0x5DC47105, 0xD406046F, 0x155060FF,
0xFB981924, 0xE9BDD697, 0x434089CC, 0x9ED96777, 0x42E8B0BD, 0x8B890788, 0x5B19E738, 0xEEC879DB,
0x0A7CA147, 0x0F427CE9, 0x1E84F8C9, 0x00000000, 0x86800983, 0xED2B3248, 0x70111EAC, 0x725A6C4E,
0xFF0EFDFB, 0x38850F56, 0xD5AE3D1E, 0x392D3627, 0xD90F0A64, 0xA65C6821, 0x545B9BD1, 0x2E36243A,
0x670A0CB1, 0xE757930F, 0x96EEB4D2, 0x919B1B9E, 0xC5C0804F, 0x20DC61A2, 0x4B775A69, 0x1A121C16,
0xBA93E20A, 0x2AA0C0E5, 0xE0223C43, 0x171B121D, 0x0D090E0B, 0xC78BF2AD, 0xA8B62DB9, 0xA91E14C8,
0x19F15785, 0x0775AF4C, 0xDD99EEBB, 0x607FA3FD, 0x2601F79F, 0xF5725CBC, 0x3B6644C5, 0x7EFB5B34,
0x29438B76, 0xC623CBDC, 0xFCEDB668, 0xF1E4B863, 0xDC31D7CA, 0x85634210, 0x22971340, 0x11C68420,
0x244A857D, 0x3DBBD2F8, 0x32F9AE11, 0xA129C76D, 0x2F9E1D4B, 0x30B2DCF3, 0x52860DEC, 0xE3C177D0,
0x16B32B6C, 0xB970A999, 0x489411FA, 0x64E94722, 0x8CFCA8C4, 0x3FF0A01A, 0x2C7D56D8, 0x903322EF,
0x4E4987C7, 0xD138D9C1, 0xA2CA8CFE, 0x0BD49836, 0x81F5A6CF, 0xDE7AA528, 0x8EB7DA26, 0xBFAD3FA4,
0x9D3A2CE4, 0x9278500D, 0xCC5F6A9B, 0x467E5462, 0x138DF6C2, 0xB8D890E8, 0xF7392E5E, 0xAFC382F5,
0x805D9FBE, 0x93D0697C, 0x2DD56FA9, 0x1225CFB3, 0x99ACC83B, 0x7D1810A7, 0x639CE86E, 0xBB3BDB7B,
0x7826CD09, 0x18596EF4, 0xB79AEC01, 0x9A4F83A8, 0x6E95E665, 0xE6FFAA7E, 0xCFBC2108, 0xE815EFE6,
0x9BE7BAD9, 0x366F4ACE, 0x099FEAD4, 0x7CB029D6, 0xB2A431AF, 0x233F2A31, 0x94A5C630, 0x66A235C0,
0xBC4E7437, 0xCA82FCA6, 0xD090E0B0, 0xD8A73315, 0x9804F14A, 0xDAEC41F7, 0x50CD7F0E, 0xF691172F,
0xD64D768D, 0xB0EF434D, 0x4DAACC54, 0x0496E4DF, 0xB5D19EE3, 0x886A4C1B, 0x1F2CC1B8, 0x5165467F,
0xEA5E9D04, 0x358C015D, 0x7487FA73, 0x410BFB2E, 0x1D67B35A, 0xD2DB9252, 0x5610E933, 0x47D66D13,
0x61D79A8C, 0x0CA1377A, 0x14F8598E, 0x3C13EB89, 0x27A9CEEE, 0xC961B735, 0xE51CE1ED, 0xB1477A3C,
0xDFD29C59, 0x73F2553F, 0xCE141879, 0x37C773BF, 0xCDF753EA, 0xAAFD5F5B, 0x6F3DDF14, 0xDB447886,
0xF3AFCA81, 0xC468B93E, 0x3424382C, 0x40A3C25F, 0xC31D1672, 0x25E2BC0C, 0x493C288B, 0x950DFF41,
0x01A83971, 0xB30C08DE, 0xE4B4D89C, 0xC1566490, 0x84CB7B61, 0xB632D570, 0x5C6C4874, 0x57B8D042 };
struct content_hash_part_128
{
uint32_t x;
uint32_t y;
uint32_t z;
uint32_t w;
};
static uint8_t BYTE0(uint32_t x)
{
return (x>>0) & 0xFF;
}
static uint8_t BYTE1(uint32_t x)
{
return (x>>8) & 0xFF;
}
static uint8_t BYTE2(uint32_t x)
{
return (x>>16) & 0xFF;
}
static uint8_t BYTE3(uint32_t x)
{
return (x>>24) & 0xFF;
}
void perform_aes_round_block_16(content_hash_part_128* cur_state, content_hash_part_128* input)
{
uint32_t x = cur_state->x;
uint32_t y = cur_state->y;
uint32_t z = cur_state->z;
uint32_t w = cur_state->w;
cur_state->x = input->x ^ AES_TABLE_1[BYTE0(x)] ^ AES_TABLE_2[BYTE3(y)] ^ AES_TABLE_4[BYTE1(w)] ^ AES_TABLE_3[BYTE2(z)];
cur_state->y = input->y ^ AES_TABLE_1[BYTE0(y)] ^ AES_TABLE_2[BYTE3(z)] ^ AES_TABLE_3[BYTE2(w)] ^ AES_TABLE_4[BYTE1(x)];
cur_state->z = input->z ^ AES_TABLE_1[BYTE0(z)] ^ AES_TABLE_2[BYTE3(w)] ^ AES_TABLE_3[BYTE2(x)] ^ AES_TABLE_4[BYTE1(y)];
cur_state->w = input->w ^ AES_TABLE_1[BYTE0(w)] ^ AES_TABLE_2[BYTE3(x)] ^ AES_TABLE_4[BYTE1(z)] ^ AES_TABLE_3[BYTE2(y)];
}
content_hash_part_128* calcuate_content_hash(
content_hash_part_128* output,
uint64_t unknown_arg,
size_t data_size,
uint8_t* data_ptr)
{
// Initial state
content_hash_part_128 state1 = { 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C };
content_hash_part_128 state2 = { 0x13121110, 0x17161514, 0x1B1A1918, 0x1F1E1D1C };
content_hash_part_128 state3 = { 0x23222120, 0x27262524, 0x2B2A2928, 0x2F2E2D2C };
content_hash_part_128 state4 = { 0x33323130, 0x37363534, 0x3B3A3938, 0x3F3E3D3C };
size_t b64_blocks_remaining = data_size >> 6;
size_t non_b64_bytes_remaining = data_size - (data_size >> 6 << 6);
// Process in blocks of 64 bytes
if (b64_blocks_remaining)
{
do
{
perform_aes_round_block_16(&state1, (content_hash_part_128*)data_ptr);
perform_aes_round_block_16(&state2, (content_hash_part_128*)data_ptr + 1);
perform_aes_round_block_16(&state3, (content_hash_part_128*)data_ptr + 2);
perform_aes_round_block_16(&state4, (content_hash_part_128*)data_ptr + 3);
data_ptr += 64;
--b64_blocks_remaining;
} while (b64_blocks_remaining);
}
// Process remaining in blocks of 16 bytes
size_t b16_blocks_remaining = non_b64_bytes_remaining >> 4;
if (b16_blocks_remaining == 1)
{
perform_aes_round_block_16(&state1, (content_hash_part_128*)data_ptr);
}
if (b16_blocks_remaining == 2)
{
perform_aes_round_block_16(&state2, (content_hash_part_128*)data_ptr + 1);
}
if (b16_blocks_remaining == 2)
{
perform_aes_round_block_16(&state3, (content_hash_part_128*)data_ptr + 2);
}
// Process all the other bytes that are <16 in a block.
uint8_t* unaligned_byte_data_ptr = &data_ptr[non_b64_bytes_remaining & 0xF0];
uint32_t unaligned_byte_remaining_count = non_b64_bytes_remaining & 0xF;
content_hash_part_128 final_unaligned_byte_data = {};
if (unaligned_byte_remaining_count)
{
do
{
uint8_t tmp = unaligned_byte_data_ptr[--unaligned_byte_remaining_count];
*((uint8_t*)&final_unaligned_byte_data.x + unaligned_byte_remaining_count) = tmp;
} while (unaligned_byte_remaining_count);
perform_aes_round_block_16(&state4, &final_unaligned_byte_data);
}
// Finalize
*(uint64_t*)&final_unaligned_byte_data.x = unknown_arg - data_size;
*(uint64_t*)&final_unaligned_byte_data.z = unknown_arg + data_size + 1;
perform_aes_round_block_16(&state4, &final_unaligned_byte_data);
perform_aes_round_block_16(&state3, &final_unaligned_byte_data);
perform_aes_round_block_16(&state2, &final_unaligned_byte_data);
perform_aes_round_block_16(&state1, &final_unaligned_byte_data);
perform_aes_round_block_16(&state3, &state4);
perform_aes_round_block_16(&state1, &state2);
perform_aes_round_block_16(&state3, &final_unaligned_byte_data);
perform_aes_round_block_16(&state1, &state3);
perform_aes_round_block_16(&state1, &final_unaligned_byte_data);
*output = state1;
return output;
}
int main()
{
uint8_t data[] = { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x40 };
uint32_t data_size = sizeof(data);
// The second argument `0` is hardcoded in the game binary when calculating content hashes.
content_hash_part_128 out;
calcuate_content_hash(&out, 0, data_size, data);
std::cout << "Original hash: " << std::hex <<
"out.x: 0x" << out.x << ", " <<
"out.y: 0x" << out.y << ", " <<
"out.z: 0x" << out.z << ", " <<
"out.w: 0x" << out.w << "\n";
// The keen::ContentHash essentially just replaces the first 4 bytes with the data size.
std::cout << "keen::ContentHash: " << std::hex <<
"size: 0x" << data_size << ", " <<
"hash0: 0x" << out.y << ", " <<
"hash1: 0x" << out.z << ", " <<
"hash2: 0x" << out.w << "\n";
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment