diff --git a/.gitignore b/.gitignore index 7332d1e..ab0efd0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,10 @@ +*.lock *.o *.user -*.lock /_release /**/.settings /**/.vs +/**/TestResults /**/bin /**/obj /**/out diff --git a/libnuhash/csharp/NuHash.sln b/libnuhash/csharp/NuHash.sln new file mode 100644 index 0000000..0894a37 --- /dev/null +++ b/libnuhash/csharp/NuHash.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.33801.447 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuHash", "NuHash\NuHash.csproj", "{0C96887C-85B6-43F2-A6B5-02850D5C3609}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NuHashTest", "NuHashTest\NuHashTest.csproj", "{FC474407-57AA-43A5-8963-4DA4EDD8BED6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0C96887C-85B6-43F2-A6B5-02850D5C3609}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C96887C-85B6-43F2-A6B5-02850D5C3609}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C96887C-85B6-43F2-A6B5-02850D5C3609}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C96887C-85B6-43F2-A6B5-02850D5C3609}.Release|Any CPU.Build.0 = Release|Any CPU + {FC474407-57AA-43A5-8963-4DA4EDD8BED6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FC474407-57AA-43A5-8963-4DA4EDD8BED6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FC474407-57AA-43A5-8963-4DA4EDD8BED6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FC474407-57AA-43A5-8963-4DA4EDD8BED6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {31837A4E-8923-447E-B05C-C1F7C0420AAB} + EndGlobalSection +EndGlobal diff --git a/libnuhash/csharp/NuHash/NuHash.cs b/libnuhash/csharp/NuHash/NuHash.cs new file mode 100644 index 0000000..392ea47 --- /dev/null +++ b/libnuhash/csharp/NuHash/NuHash.cs @@ -0,0 +1,639 @@ +/******************************************************************************/ +/* NuHash, by LoRd_MuldeR */ +/* This work has been released under the CC0 1.0 Universal license! */ +/******************************************************************************/ + +using System; +using System.IO; +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace LibNuHash +{ + public class NuHash : IDisposable + { + public const int NUHASH_WORDS = 6; + public const int NUHASH_BYTES = NUHASH_WORDS * sizeof(ulong); + + private const int ROUNDS = 5; + + private readonly ulong[] m_hash = new ulong[NUHASH_WORDS]; + private bool m_finished = false; + + /* ------------------------------------------------------------------------ */ + /* Constructor */ + /* ------------------------------------------------------------------------ */ + + public NuHash() + { + Array.Copy(NUHASH_INI, m_hash, NUHASH_INI.Length); + } + + public void Dispose() + { + Array.Clear(m_hash, 0, m_hash.Length); + } + + /* ------------------------------------------------------------------------ */ + /* Const tables */ + /* ------------------------------------------------------------------------ */ + + private static readonly ulong[] NUHASH_INI = new ulong[] + { + 0x243F6A8885A308D3UL, 0x13198A2E03707344UL, 0xA4093822299F31D0UL, + 0x082EFA98EC4E6C89UL, 0x452821E638D01377UL, 0xBE5466CF34E90C6CUL + }; + + private static readonly ulong[][] NUHASH_XOR = new ulong[][] + { + new ulong[] { 0x01DCDF00414B3037UL, 0xB1B3AF661B8E96F8UL, 0x944D2873DB393121UL, 0x73DA9A36662AE755UL, 0x1F4F318C4ECB56B1UL, 0xF09743D99C2AA5BCUL }, /*00*/ + new ulong[] { 0xA81FBBC6CBBFC954UL, 0x39DE43648959EDDBUL, 0x1A641A0BDA01822FUL, 0xB52E607266932658UL, 0x2C5B1731AC802084UL, 0xC2EF10671FC79DD4UL }, /*01*/ + new ulong[] { 0xCF2A8D8E08810046UL, 0x8B7E9B2089E268F6UL, 0x930461652C5D2DECUL, 0xF096E42223BFC8B9UL, 0x8DD338964CFE0970UL, 0x269C342F7CEC60BDUL }, /*02*/ + new ulong[] { 0xB970A920D2ED0552UL, 0x010F894A254DA7E1UL, 0x8D5F205F9D1A40D8UL, 0x50C33DCCC3FD5F58UL, 0xB49F31BDE7D82C57UL, 0x7CDE04F62A959033UL }, /*03*/ + new ulong[] { 0x49FAB2822B9C84ACUL, 0x34B8648CD68CBEF1UL, 0xE5121147BB4126DEUL, 0xC0B31F54B2FFE00FUL, 0x2F193DA38E8CC632UL, 0x058C984B429B8AFCUL }, /*04*/ + new ulong[] { 0xE07F9DA44D8C9942UL, 0xBE2AF9B39ACA65F2UL, 0x5D3D8FB1466DC295UL, 0xC0051E3EC3F962C7UL, 0xF8FDC3CCD4CE2BB6UL, 0x9024C0EFC6199937UL }, /*05*/ + new ulong[] { 0xA3111377EF01F5EFUL, 0x31F59B366C02A3FFUL, 0x61B82949760D16DCUL, 0xF6B958AF92BD3BDFUL, 0x7297AAEFEC69C0B2UL, 0xFE8A50AD9E8684CDUL }, /*06*/ + new ulong[] { 0x3D3DD0C829EA9AA0UL, 0x3E77597EEC96C7A3UL, 0x8FD038231E7F1684UL, 0x64617B131FB7EDE0UL, 0x85C99CE4C5405874UL, 0xA58735D41F19C5E3UL }, /*07*/ + new ulong[] { 0x8028628ACAF91B9AUL, 0x194A640538C97064UL, 0x04A15E018A4F1680UL, 0xF4BE1B04C2360955UL, 0xDFB24D4CEF581A20UL, 0x3C59D0A0FD15879DUL }, /*08*/ + new ulong[] { 0x88F8E2ECE78AF1BCUL, 0xB46B6E22297364C2UL, 0x9339F17F926B99F3UL, 0x31293489B3B8F07CUL, 0x3909CE1649C9BCF1UL, 0x0C46103BFA31BCE9UL }, /*09*/ + new ulong[] { 0x4D1A0B8CC7EFE2A9UL, 0xAFD7878CAD55E871UL, 0xC89CFBC858CF4153UL, 0xC4739486C74F75D6UL, 0x0BF7192C130AC9F2UL, 0x0084F2BC5E81BD9AUL }, /*0A*/ + new ulong[] { 0x4AFBE975014FCACFUL, 0x41DEAF8CFACC41E4UL, 0x3C1EC23B53ED16E9UL, 0x78B06EB30F1C3248UL, 0xDD11165D04285C72UL, 0x6546D9B5609491E4UL }, /*0B*/ + new ulong[] { 0xFFD1E2E04DC8D260UL, 0x07B186948A74ECCEUL, 0xB5120E45121AC531UL, 0xBD0BC86330810C85UL, 0xDE93AFDDDB487730UL, 0x78DEB0DE6EB99196UL }, /*0C*/ + new ulong[] { 0x79BAA2AC3FDEBA55UL, 0xB1B7E3E1C92A567EUL, 0xA53F69AB4A5B0794UL, 0xF0DA7499954F6DDDUL, 0x58117C89E1132248UL, 0xD95DF5F794C51A6EUL }, /*0D*/ + new ulong[] { 0x89BC8A0C65091C33UL, 0xB04EEAEE063135C2UL, 0xF53267E04AB6E689UL, 0xB4C579B7207E8BF2UL, 0x3FD31E51343CD2DFUL, 0x119E523E2F8197FEUL }, /*0E*/ + new ulong[] { 0x2E10CB1C6060F32DUL, 0xBC92E732A94E6B63UL, 0xF3220D831FD04267UL, 0x502C5F7414BCE87FUL, 0x89E0651DE91D2457UL, 0x759E56B04482D915UL }, /*0F*/ + new ulong[] { 0x43AEE32C6A84E803UL, 0x0C5007202C0BD7E3UL, 0xB4F464474205D32AUL, 0x7D17FC95DE386C06UL, 0xE8DFBF64567AA545UL, 0x55BD889D5853046FUL }, /*10*/ + new ulong[] { 0x687ABE14EAB8DA27UL, 0x397B3AB50D72C344UL, 0x505EAA6D1FDE618DUL, 0x61BE79865DA13F69UL, 0x17BBAB29B5E90E2DUL, 0x010C921972FA8B2FUL }, /*11*/ + new ulong[] { 0x8B7223A4F56FF453UL, 0x291B7B5CB98B6FE1UL, 0xFD421625786FBF7DUL, 0xE33D1020D0E8CDC8UL, 0xCA530C708B739E87UL, 0x878AF1F304B8A12FUL }, /*12*/ + new ulong[] { 0x7ECE1F24E56DD711UL, 0x2E0869241B2FA6DFUL, 0x84B834DCC459B2FDUL, 0xE022EDA6319E7D3BUL, 0x59839D8CA03C9928UL, 0x644790F491BBC774UL }, /*13*/ + new ulong[] { 0xCBDC6F49E6B0DD0DUL, 0x44BA2F8D00346732UL, 0x86BCC821586AE61CUL, 0xC7B7491285CEE55BUL, 0xED3912FFD97F3851UL, 0xF4AF0186BEBEBCBFUL }, /*14*/ + new ulong[] { 0xCA8A48E54ECCE516UL, 0xBEDF1864B7F8F506UL, 0xD56A1F60A4B36AA4UL, 0x49B25AB5FE0DD9D9UL, 0x21377DBB5E49FCE1UL, 0x708F64F5D59D99E7UL }, /*15*/ + new ulong[] { 0xE9F873A569AFE02CUL, 0xDA66BC05CA997390UL, 0x8C88174756D35385UL, 0xEAAAF16CF4FDA730UL, 0xB39F7A55653A3512UL, 0xF10AB727BC23E852UL }, /*16*/ + new ulong[] { 0x93E96FF8C5BBE2AFUL, 0xA47785420253E97CUL, 0x704B25D1F77D074CUL, 0xC0B2093F1470559CUL, 0x8D5BFDD4E364AACFUL, 0x550518673F5B1BF7UL }, /*17*/ + new ulong[] { 0x8DAC832E5BE81ACBUL, 0x588BFB202B7583D8UL, 0xA34D8A70DFD1D7E4UL, 0xD03B0627B687033EUL, 0xE3D0BE7EDBDC75CFUL, 0x818EE8C5B09F8BEAUL }, /*18*/ + new ulong[] { 0x8E3B02E1489D7D31UL, 0x5336752B64E3B532UL, 0xE4D4CC795C580A65UL, 0x6DAB08F313ED767EUL, 0x8E567E88FDBA36BFUL, 0x259490F1D8E933D0UL }, /*19*/ + new ulong[] { 0xEAB437D0D62CAA62UL, 0xC090AD28B982B003UL, 0xE255D768D25704ECUL, 0xA048511AF6256A43UL, 0xE79F078F4D498B5FUL, 0xC41735FB75B357FEUL }, /*1A*/ + new ulong[] { 0x70DA9FC3504FF29DUL, 0xB9AB1F388673FF25UL, 0x36922F4CD17357BAUL, 0xF09C3AB292E7E04AUL, 0x90CE0BC3D9BA13ECUL, 0x647C4CA63C918DE3UL }, /*1B*/ + new ulong[] { 0xD834A38DD1ECD688UL, 0xA97A0020DE46AB6AUL, 0x9CDEC7F6E62EA71FUL, 0x288A5A6FD74DC47EUL, 0xD44A2E2765CE50F1UL, 0xBB9B50B5DB9E4F3CUL }, /*1C*/ + new ulong[] { 0xC66DA90E41DDF2E6UL, 0x5A3FE86F160C5C09UL, 0x6F6AF0405108CCBEUL, 0xF938382EB627FC7FUL, 0x163DD634617F006CUL, 0x5184B1FEDC908497UL }, /*1D*/ + new ulong[] { 0xC95719ED07FCB21CUL, 0x5112DF043F6EE7EBUL, 0x50F9FD60012334CEUL, 0x589FA85104D96579UL, 0xB7129E44D71905A7UL, 0x3314766E0733528DUL }, /*1E*/ + new ulong[] { 0xDC6C8014C5457CB8UL, 0xD635FDCD286A69B6UL, 0xD66F232CE27D01BFUL, 0x56AF4AC0F682EC0FUL, 0x57DF1D55B64328F5UL, 0x651ED4C52A87CACAUL }, /*1F*/ + new ulong[] { 0x26D9D1CC79EEC502UL, 0x69BF340A34B1EBFEUL, 0xFAA5AAAC8E397174UL, 0xD0A8F9BD426BCF6FUL, 0x5B131F464D6D2452UL, 0x122DD15660D0D6DAUL }, /*20*/ + new ulong[] { 0x6E389AEC5F51A22FUL, 0x7EF68F1C54C127FBUL, 0x986D4D46E0485C30UL, 0xF0A47B39E7CF8A31UL, 0x1D398DFDB7F2A78FUL, 0x2FC651D1FBB10D2EUL }, /*21*/ + new ulong[] { 0xA44E4E8D1B49DCB0UL, 0x07A4822049C2F343UL, 0xC40AC04A8D6505BAUL, 0xD9B91D3F0729B16CUL, 0xAAF39951B50F9015UL, 0x966EF5D3AD3F9076UL }, /*22*/ + new ulong[] { 0xEA78CBAC0EB6D009UL, 0xA0FEA6725A23DEABUL, 0xCE729C7444CB94D9UL, 0x40A994626627AA0DUL, 0x37F738CDE3D018D5UL, 0x4C29491C01CDB3C5UL }, /*23*/ + new ulong[] { 0x7C9792AEA745C87AUL, 0xD1FF5620C5BD8FD4UL, 0x9ECA84E3004B56B9UL, 0x5AFD3923C228B1D6UL, 0xE5DBF79EB3FD283BUL, 0x441712E354084B9FUL }, /*24*/ + new ulong[] { 0xE35D288BD8E249BCUL, 0x91776C1453A366E5UL, 0xF5D1E1684E95EFECUL, 0x9108E117D7DDF606UL, 0x81B30F9DA2CE7C8CUL, 0x6497DBD786818C0DUL }, /*25*/ + new ulong[] { 0xC2F891FF45044BE0UL, 0x75A1A76D2B87E2EBUL, 0x85CE65798AF3C2BFUL, 0x213F532B4EFD09DCUL, 0x0DAA1DF5A53A6C88UL, 0x3028606A50D826B2UL }, /*26*/ + new ulong[] { 0x609A62616379F33AUL, 0xA339A3BC53E4516DUL, 0xD7AD92616A5ADBECUL, 0xD043726D86E924AAUL, 0x8555B564F4C29865UL, 0x56AA12AB31C1D6B0UL }, /*27*/ + new ulong[] { 0xCED9ED85C1C17BFFUL, 0xEB522325ACBAFFC2UL, 0x04D3D8F4B2D15394UL, 0xD271504C04756EEAUL, 0x2DDBA4A91AF827F1UL, 0x1F67D5C28F8002E4UL }, /*28*/ + new ulong[] { 0x8B9C08AD432DC08FUL, 0x5A7543E29796BBC7UL, 0x34A6DB5B3C1967DEUL, 0x016E3BC2A2804EE4UL, 0x5B9BCACCE5172F75UL, 0x7549598B80ADBDBAUL }, /*29*/ + new ulong[] { 0x6F3FB117C5CDD155UL, 0x16C3B0A59CD6EEC5UL, 0xD9A1A411DE538769UL, 0x938C54979F4AC37CUL, 0x3737BCC1D55284DBUL, 0x6CAD9F8AF9156BB7UL }, /*2A*/ + new ulong[] { 0xEBBF284F9C75EBDFUL, 0xB383EBB406753DE8UL, 0xAA86127AEE7C403CUL, 0x10BFDD10523DE027UL, 0x138BF6C4EB4A8A13UL, 0xB1EFF67DDB78B067UL }, /*2B*/ + new ulong[] { 0xF6D1138D7AA3DA5EUL, 0xBAA8098D8FB66371UL, 0xDAE76D1B8B6CAAF2UL, 0x400F1034368D1EDCUL, 0x7C937F5172E8D277UL, 0x7D05BBF83CADE6EFUL }, /*2C*/ + new ulong[] { 0x0E9C2EA6CF34B081UL, 0x9036B30D58F60BA0UL, 0xDB3A2C5848F08BCAUL, 0xC87AD1B94250D564UL, 0x7C892E09EEF96166UL, 0x26DB85CF571085F3UL }, /*2D*/ + new ulong[] { 0x251EE3F58718C12AUL, 0xF9438D81178A2AE4UL, 0xF0929A889039A8A8UL, 0xF06B65225EBDCCFDUL, 0x2E4D14EDF7BF73C6UL, 0xA9369895BC1DFACFUL }, /*2E*/ + new ulong[] { 0xCAE302B41D6979CBUL, 0xBBFA5A58B51EE623UL, 0x5113B99DC81AB52FUL, 0x6093795BEC17A056UL, 0x8F71FB4D2E5E355EUL, 0x762F92EDBA34A2F2UL }, /*2F*/ + new ulong[] { 0xD130015265A4D9FFUL, 0x09BEA253D71F26C8UL, 0x81B6EAEDC46521E6UL, 0xFAE268165682B8A9UL, 0xA89C3EC4774AB623UL, 0x0D2E45E055219DB2UL }, /*30*/ + new ulong[] { 0x2B560284C3A692ABUL, 0x37008AD0B379A7B8UL, 0xAF11CD2C30F90BFCUL, 0x7FE87A250F2762EDUL, 0xC3FBD711647242C3UL, 0x74ED8264F6B322BDUL }, /*31*/ + new ulong[] { 0x28195CC8A7AD3943UL, 0x53CBE808464C4FC4UL, 0xD58E3D7A765F8726UL, 0xD83052F60185AA4FUL, 0xEFCB0D85223BB4E7UL, 0x5A31305E787FAC28UL }, /*32*/ + new ulong[] { 0x725D0EE230F19543UL, 0x9091D2C6BDDF34E0UL, 0xE3BE49C6C2754601UL, 0x61BE300BA4AD566BUL, 0x02D79D7551FA7CC1UL, 0x6543910F5F1CDA58UL }, /*33*/ + new ulong[] { 0x4099ADC44481B43FUL, 0xFE1361922FD9EB81UL, 0xA989C09E441FCEACUL, 0x449B3A13D3CB9019UL, 0x45A9BE396F201134UL, 0xDC1AD05A046633FEUL }, /*34*/ + new ulong[] { 0x1A563A6D522F3E69UL, 0xBE589E079F475A9EUL, 0x75A2A9638E4C0038UL, 0xDA3B6202577A0362UL, 0x211D3F1E0D727AF6UL, 0x5E1FFC529AD99233UL }, /*35*/ + new ulong[] { 0x47B61E86C6D6D01BUL, 0x437D6F83ADADC318UL, 0xD5A361028DED738CUL, 0xA00D4C630425164BUL, 0x1A69AFA5AF4C9DD2UL, 0xF99E1C67F951B582UL }, /*36*/ + new ulong[] { 0xA66A7740B6BDEA79UL, 0xFEF7FF1496AF80A3UL, 0x05AFD43EEACD898CUL, 0xB00C78ED31AD7134UL, 0x0ED31A1AD7846673UL, 0x74B96844161499BEUL }, /*37*/ + new ulong[] { 0x46FA8D6CCBF6D12EUL, 0x31C2FC147F303956UL, 0x707F4401DE5F067FUL, 0x3AE5FEC7E33594E9UL, 0x28E39F8A63531714UL, 0xB7B329EA1E9FCAB2UL }, /*38*/ + new ulong[] { 0xEFD8F755825C7804UL, 0x1F5A93870BD30CD1UL, 0xEFBF894671FF8716UL, 0x28ED617FF22BDA58UL, 0x411289CCAE5CB62EUL, 0x95DD42F41801F2F9UL }, /*39*/ + new ulong[] { 0xA8525B8645FC59E1UL, 0x75E62DC00A5F7F0CUL, 0x09C56785210416ACUL, 0x50EF76E9B30D7626UL, 0x2B3B2CDC19F5D665UL, 0xA41297CD11D8F4FFUL }, /*3A*/ + new ulong[] { 0xEAC99A649EEE5039UL, 0xA593C92F143C0065UL, 0xB314735203071206UL, 0xEA2761A0C764A4ECUL, 0x02AA7FD46CAC25B3UL, 0xC68CC182A96D03BFUL }, /*3B*/ + new ulong[] { 0xB2873F024EC83CA8UL, 0x97470AB8FD8853EBUL, 0x18FE15C159B305BDUL, 0xB0AB08F687EAEAFDUL, 0x510A3FDE73602E43UL, 0x03E1B84DCCF0FCF0UL }, /*3C*/ + new ulong[] { 0xD85BBBDC8033C0D8UL, 0x9223D9C39CA9F34FUL, 0x7D3BCB6D5B63C3FDUL, 0x1C30F974DA0C0FB5UL, 0x8B24BC9EBEFB5143UL, 0xC58954925B7B84FCUL }, /*3D*/ + new ulong[] { 0x6ABD7C2E0844D7A7UL, 0xCCF2EA456CDF530DUL, 0xE8938CF52B3921B8UL, 0xBA023CA2F281657CUL, 0xEC635DA675D1EDAEUL, 0xB4AA52F22EE1BE6CUL }, /*3E*/ + new ulong[] { 0x981C3AC677CB5904UL, 0x6A92B54C84877B49UL, 0x745BA6BB40C55815UL, 0xB7AF550D22A371EDUL, 0xD5E8BD87C65F5374UL, 0x67874A37F0F538F5UL }, /*3F*/ + new ulong[] { 0xC23BBA2A9DECC021UL, 0x4E610E930B0E3450UL, 0x1A681AA91477577EUL, 0x38A3209714EDC376UL, 0x0FD15563EEEB4AB6UL, 0x7D57668A01D42178UL }, /*40*/ + new ulong[] { 0x6AF88CE145A098B5UL, 0x1AEB858CD88B8B46UL, 0xE8B733AFB8E2D6E8UL, 0x313FAA8C10A7EBFAUL, 0x127D375E77557CEAUL, 0x96BDA2F70B2F2155UL }, /*41*/ + new ulong[] { 0xEC8903978FAFB636UL, 0xC7213C425C079763UL, 0x760384036AB6D17CUL, 0xE0C63A26385F1F49UL, 0x299877D6811A6DF5UL, 0x876F90FC5304B88DUL }, /*42*/ + new ulong[] { 0xA6FABBC2D6E0BA16UL, 0x9B70C9640080E6BCUL, 0x29B2D5265598B27BUL, 0x4A9657C726E4397EUL, 0xA801CCC6766678D5UL, 0x800EF7CC72619998UL }, /*43*/ + new ulong[] { 0x235931A8CF5490BFUL, 0xE798F98E0E8F879FUL, 0xC6EEE29C38F30CA7UL, 0x929A79F2D53E0024UL, 0x88F2E12749587A45UL, 0x0B85B28F38891965UL }, /*44*/ + new ulong[] { 0x165E0303E4A4D827UL, 0x67994F42D1E8436AUL, 0xE6CC8BCF6E130D1BUL, 0x50101711709DDEFCUL, 0x373BDEC40CD05328UL, 0x40B274A4AA5109F6UL }, /*45*/ + new ulong[] { 0xA9F88BA008FDF8C8UL, 0xECC897E3476EE05AUL, 0xBCE290AB69D57A74UL, 0xFA44DB1811E3115DUL, 0x6267AEFD64480C88UL, 0x2697D04A2D3AECEBUL }, /*46*/ + new ulong[] { 0xC0782AF2ABCD3313UL, 0x02BA1290F2F96273UL, 0x63C82F1A56ADC2B9UL, 0x10F8E8C03EFE51C4UL, 0xE3EB348625CCAFFDUL, 0x93D607969CB8E7AEUL }, /*47*/ + new ulong[] { 0xCC6E179443E58FBCUL, 0xD21C93C655A7B8EEUL, 0x2B9834A31F2B8BA4UL, 0xC83B69516025ECEEUL, 0x9176EB7B427AAE94UL, 0x8CB65B9E30B7A76EUL }, /*48*/ + new ulong[] { 0xC1A33A0AD6EDD989UL, 0x18B3C5D95813B5F7UL, 0xB024BD263B359A8BUL, 0xC8C17C2216A99B50UL, 0x71F9A11D58237729UL, 0x3AA67C7618284290UL }, /*49*/ + new ulong[] { 0x99B7465E09201C7BUL, 0x9AF89FA01CA4FA81UL, 0xFC2EC63E761AD123UL, 0xE2A9A39585B17D14UL, 0x08394DE529F94E81UL, 0x479448E69794FAA4UL }, /*4A*/ + new ulong[] { 0x23CA3D1C4CBDCABBUL, 0xE3265436CE1A37E4UL, 0x1BBF10F69E8A4CC9UL, 0x05A66708048F5C4DUL, 0xE259DCDD9C5BFEFEUL, 0x439E65FAFD936EFDUL }, /*4B*/ + new ulong[] { 0xA24D73B6978F719CUL, 0x3F53F343CCB0BB8EUL, 0xBE3C72769EE07C6AUL, 0xFACB9E539CF558DDUL, 0x67B91D4E30DE986AUL, 0x1DB913D11698913AUL }, /*4C*/ + new ulong[] { 0x98BD4E140DC3C3C6UL, 0x142B1592BF3263E8UL, 0xCDBEAC59ED095B0EUL, 0x900763F0F625896AUL, 0xE213550F30324E39UL, 0x8A13A4417A803195UL }, /*4D*/ + new ulong[] { 0x2ACD98ED8C626073UL, 0x1CAAA6B4C4CF3238UL, 0x04DCB41EB677EB5DUL, 0xF88B5844A8105B68UL, 0x981D9E951A061A4DUL, 0xBC9471894C878EDBUL }, /*4E*/ + new ulong[] { 0x4959FEAD5D6C2DBDUL, 0x6ABD59E28C503049UL, 0x06D2C5494CAF8B34UL, 0x70E4541304A4293CUL, 0x520F3416CAF2F503UL, 0xB23D09D92613DB85UL }, /*4F*/ + new ulong[] { 0x26B5A815C32D1791UL, 0x2C99E7555BB033C6UL, 0x09CE9D6A0002514FUL, 0xD485282B2B8D7997UL, 0x9C5B792F4A4A14C6UL, 0x851D9D02DC0BB4E7UL }, /*50*/ + new ulong[] { 0x62FEB6CACFB060ECUL, 0x9D977D69D5C661EAUL, 0xBF08EFD806D81556UL, 0x25F1EEA460EA5718UL, 0xA25346B51F5A9665UL, 0xD92F9ADC358CA274UL }, /*51*/ + new ulong[] { 0x27E63DFC63E8FFA6UL, 0xCDB9CCE2CE99FDA3UL, 0x979D5B754974830DUL, 0x3298C8407D6693BEUL, 0x629D5FADA39B42B7UL, 0x2654D31271CD84E1UL }, /*52*/ + new ulong[] { 0xAB1FA4DAF66E583CUL, 0xEEB6B7A236D24766UL, 0xA90738CDFDF5C6B3UL, 0x28CBA9E5648E2D4CUL, 0xFDE5BF6C0CFE0DA3UL, 0x9D00B863D7D78485UL }, /*53*/ + new ulong[] { 0x75FBBF094EEA16AAUL, 0x48931F027CD729F2UL, 0x5D360679009B2E7FUL, 0xDDFCD148BD3DE21AUL, 0x4DBFF544B094D0E1UL, 0x9C0E5C6294352C22UL }, /*54*/ + new ulong[] { 0x283A27FF968853D2UL, 0xB0960C6CEA0D03F2UL, 0x172BBA07A473DB38UL, 0x688C87D296E6F4BBUL, 0x5CB7E9BC5D68CF0FUL, 0x57A5D71B0E47BFB4UL }, /*55*/ + new ulong[] { 0xDE0108AAC1E4FF2FUL, 0xD346CFABEAC62B99UL, 0xB72E203F98B5F608UL, 0x81853D8CA54B29BEUL, 0xA6AED7C89FAA1680UL, 0xD2093B155C39D7EDUL }, /*56*/ + new ulong[] { 0x0BAEAC99D4974B84UL, 0xC7F258A699C9B4DAUL, 0x6F622C5E4ACCF5C1UL, 0x58AB397D9781BEAAUL, 0xBF811F67E101FFE3UL, 0xAFBCC2881C3C0EF3UL }, /*57*/ + new ulong[] { 0x26B211FB518D6C3EUL, 0x64BADAD51A10784AUL, 0xE6BE4E06A587186CUL, 0xD471F5C61343CD5CUL, 0x8389BB0DD6AAED5DUL, 0xC88112678914A17DUL }, /*58*/ + new ulong[] { 0x2B2D0BC3BB88D27DUL, 0xC5A7D1FAFF517AD2UL, 0x96F39056A09F82ADUL, 0xFB38A61A6CED4D4EUL, 0x9D308E4EA6F9B264UL, 0x9097CE294AECC6B3UL }, /*59*/ + new ulong[] { 0x8FCA2B950690B1A2UL, 0x293EFCBF03D422DFUL, 0x8C9125B3E76353ABUL, 0x3D402092A1A70173UL, 0x9BAB974CAB9BF676UL, 0x5EA8FCC55D8C586EUL }, /*5A*/ + new ulong[] { 0x408C92E8C2E1EC8CUL, 0x4AF4C914B71B4350UL, 0x5186AEE0CDFB1069UL, 0x2385EAFAB9657C67UL, 0xF708E4D3C898CA80UL, 0x1EC8B9F89884907EUL }, /*5B*/ + new ulong[] { 0x46E8958B6A2C1878UL, 0x2172FD410F78A647UL, 0x9D8E9DD83A299004UL, 0x390913C3265AD025UL, 0xD231F1E23077CBF1UL, 0xE7EE3E574E80D7F3UL }, /*5C*/ + new ulong[] { 0x5A8567A3D85E40B2UL, 0x16ECF161133FCF73UL, 0x52DA5C6FBA3C0DD7UL, 0x56E57983DEB34BFBUL, 0x83254FDCB768D153UL, 0x9A14F95F35C6B82DUL }, /*5D*/ + new ulong[] { 0x498A29C6E19D4AE6UL, 0x2EF4AAF46027BA11UL, 0xBDBA7DAA84F39505UL, 0x940B2A04F6DC944DUL, 0x4E7ED35610FC0D53UL, 0xBADD94C2907E59E1UL }, /*5E*/ + new ulong[] { 0x14DF0FC43F475F80UL, 0x17E2AA8D264BF82FUL, 0x92625BDFE58B934DUL, 0x8384F415A4ACEA81UL, 0x8E9C5EAEC5D8642BUL, 0x4D8EF55F1C826687UL }, /*5F*/ + new ulong[] { 0x4A2335C4F77128D9UL, 0x544E1476D29ABA94UL, 0x654EC86321785044UL, 0xB04AD9B02F80445AUL, 0xB0E01B6480C8D020UL, 0x596E325E88A3CBBFUL }, /*60*/ + new ulong[] { 0x896955157448D062UL, 0x0DB08C4C0F236D68UL, 0x3BA8FC5B3CD1C4A2UL, 0x04F57C53E144535BUL, 0xB7D04DCC7BE46840UL, 0x4BBE993192334646UL }, /*61*/ + new ulong[] { 0x1D7837E6AB02CE27UL, 0x3EA35BAED4493EA4UL, 0xD1CAFDB5DF94FABEUL, 0x98B580BB62170C4FUL, 0xC3C57A6CA9421C43UL, 0x68D65FC2C1201634UL }, /*62*/ + new ulong[] { 0xFAEABABC48717536UL, 0x454251E8F62F7315UL, 0xB318E8A7FDCDC523UL, 0x7C2E832013C91344UL, 0x4D9E5DAFD1699052UL, 0x12262E8C870537A7UL }, /*63*/ + new ulong[] { 0x8A3E5D0BEF8402A2UL, 0xA33BC5FAFA019909UL, 0x63CBE8ACD00762F5UL, 0xEA26A3F181984178UL, 0x6EEB78D1BB4AF6BBUL, 0x7ECF9671300E845FUL }, /*64*/ + new ulong[] { 0x0811B67CCCF5D0FCUL, 0x9F8CAB3F3496BD6BUL, 0x57CB7D24F1355C2DUL, 0x58218594165BDE80UL, 0xFAF3368A653A78F8UL, 0xC04CD80176267762UL }, /*65*/ + new ulong[] { 0xE6417CE75AAA23B0UL, 0x34A7BFE3CBA61761UL, 0x8C13E396F8C9B6EDUL, 0x5C9066464B09ED63UL, 0x76CB6A642C5CE283UL, 0x498E082A3EB449C6UL }, /*66*/ + new ulong[] { 0x6F2ADEA6357B5AA0UL, 0x54DA382B15557B69UL, 0x302BD81946237AAEUL, 0x8F0CBB82111EFEDCUL, 0x45DD2DADCE20F2D3UL, 0x8A77A5E9E8A2D1D8UL }, /*67*/ + new ulong[] { 0xE1EC332735862A28UL, 0x92B68B1A7E9C7C44UL, 0xF45618DC99E963E3UL, 0x7CAC984502DD1A73UL, 0xC8650598CD70840DUL, 0x9A5DA584A26D4EFDUL }, /*68*/ + new ulong[] { 0x16B19B010740C15CUL, 0xB4544AC01016439AUL, 0x221F749C9E2F99A5UL, 0xA63E8A279A65570FUL, 0xC7231669ADD072ADUL, 0xC5BC35BA740BC801UL }, /*69*/ + new ulong[] { 0x6C44E75A4F378694UL, 0xD27ACE108A577647UL, 0x17C487FAFA7E15D6UL, 0x6A3654D5C8E29EDFUL, 0x0CE35EEDCC611FFAUL, 0xD88A8C03C0095093UL }, /*6A*/ + new ulong[] { 0xCF106948BC4B1F2CUL, 0x91C0DC9990B99712UL, 0x193B21E3E109AB32UL, 0x3340DE0608DD1666UL, 0x8A5BB677BF602828UL, 0x402C410B1197B771UL }, /*6B*/ + new ulong[] { 0xEB080FF49CA5543EUL, 0xB4B9429542D6CA27UL, 0x5999D45DC1533205UL, 0xF7EA9E398A1BEF3EUL, 0xBE8817775476DEC6UL, 0x17064D7790C84100UL }, /*6C*/ + new ulong[] { 0xF3328E9150A7F8D6UL, 0x52E3E61B04ACFDF8UL, 0x51D82010F3CEB015UL, 0x59D673336676D5D8UL, 0x4CB3BCEF1D91C342UL, 0x0C589AB58033BE49UL }, /*6D*/ + new ulong[] { 0x54B8E70EDCE03855UL, 0x7BB590E99687FD57UL, 0x6CFF08688D2B1FDDUL, 0xFD0F6D068BFE994FUL, 0xEB9BCE302489AE44UL, 0x66B21F200661E3E4UL }, /*6E*/ + new ulong[] { 0x2F5E0060189669ADUL, 0x473AF1D03C00CAE4UL, 0x0278299268D1F3B4UL, 0x888714BC3A7EC9D2UL, 0x9FF9C7F071EBD2D9UL, 0x875A5DC25DFFDB10UL }, /*6F*/ + new ulong[] { 0xE2A97A3E468399D8UL, 0x3BF7EACA32C80DA1UL, 0x13DCAC8EB6C2231DUL, 0x227EC90E1102EE97UL, 0xB2344832F0381434UL, 0x8613888303B190EBUL }, /*70*/ + new ulong[] { 0x3A3D3B6CE026BFFEUL, 0x18D4953B9A68ED59UL, 0x24BB7B574AB777A0UL, 0xE0CB7DD64983DCB1UL, 0xCF768C439869AC97UL, 0x8062BC7A900E6033UL }, /*71*/ + new ulong[] { 0x39D4C3B78A7A33C7UL, 0x43D72EF22AB0B4EBUL, 0x54AE8184DDA50394UL, 0x0C2A7DA083C38536UL, 0x9DBC6F921D4AD822UL, 0x2CBB61FE182EAA42UL }, /*72*/ + new ulong[] { 0xD8CE9A806C0BD24DUL, 0xF69D65A65845727CUL, 0xC3FF81CC76F2B048UL, 0x76B1FDC3CA67CE58UL, 0xCED0970AFBCBE78AUL, 0x57502941B726F5F3UL }, /*73*/ + new ulong[] { 0xE006AEC17FCEFCF9UL, 0x05CAA1629E003591UL, 0xB7050CC99F585312UL, 0x669260401E159490UL, 0x8442D25AA757CC5AUL, 0x228655CD4038770CUL }, /*74*/ + new ulong[] { 0x93EE8D67D3F1F3A1UL, 0xBEA46D48DBF8D7F4UL, 0x3C91F02B8646453CUL, 0x6C3D7C1F04188A58UL, 0xEFA97287F89CEF84UL, 0xCB40364E108BFF4BUL }, /*75*/ + new ulong[] { 0xC6DCE3730D4FF825UL, 0x02AF54F87D972790UL, 0x7D69D20F6F4F788FUL, 0x90C255C64C166E8FUL, 0xA3529FBF4BF9C9A2UL, 0x3ECEC41136694F6BUL }, /*76*/ + new ulong[] { 0x3DE10A5EC6CA7B3FUL, 0x7E196081D085ACAAUL, 0xDF5F0DE3705D60F7UL, 0x393E7C83DCC57075UL, 0xA5F33BC2DCB98F97UL, 0x0AEB7F050D1204C0UL }, /*77*/ + new ulong[] { 0x6F3B3B3D11A8BC05UL, 0xB52269AB2B95B8DCUL, 0x12EDE24EB1385F13UL, 0x202BBA6B5836B5E1UL, 0xEE3636C5925ACC49UL, 0x42224CF6EEB509BFUL }, /*78*/ + new ulong[] { 0x5F0CC3BBC4BE9A92UL, 0x584313FCCC54DD2EUL, 0xC11FE90F00394036UL, 0x3371667C72FC9723UL, 0x9611990B62AC8D9FUL, 0x4CFCB9EB3C317FADUL }, /*79*/ + new ulong[] { 0xCA8E520A894A3FBAUL, 0xBD9ED1B80098CC40UL, 0xBDF24507DFF3757CUL, 0x47AEC572E68D35ECUL, 0xF3D4523D27B373E4UL, 0x1AB11E16973A05ABUL }, /*7A*/ + new ulong[] { 0xFFC293A6C26B817DUL, 0x2C9E9D134959D828UL, 0x7FA5216408199BBFUL, 0xA6F002DE0DCCD861UL, 0xBE8F9DC57F2CF35DUL, 0x1352E2DF86A47647UL }, /*7B*/ + new ulong[] { 0x84B55BE101708E74UL, 0x3ADEC53721209F3EUL, 0xB18F9A1E68DFADBDUL, 0x09A050819774CF2DUL, 0xE4AB295D380A8762UL, 0xA3605B0C689C239FUL }, /*7C*/ + new ulong[] { 0xDDC7031FBFDFFE8FUL, 0x0B175DE65B832F0AUL, 0x31162ABC65719685UL, 0x51215E534BBC36B1UL, 0x9F2F7D3B5D01AE44UL, 0xCF43A2426E83B61BUL }, /*7D*/ + new ulong[] { 0x7E32DB672B16F04AUL, 0xCE6F45DE0E6AB788UL, 0x25718548B8E70B41UL, 0xD7368BCF39A0FAC4UL, 0x956863EC49880C47UL, 0x720E335796341674UL }, /*7E*/ + new ulong[] { 0x06707A8E33D9D6C6UL, 0xB684BFE26CD576C6UL, 0x44F47E5ECD5FC46CUL, 0xAF1B23A856D844B7UL, 0x98A627916AC5657EUL, 0x040C3964A1127E19UL }, /*7F*/ + new ulong[] { 0xA5DAEC3134C0A39BUL, 0x0CA04160BD5ADB1FUL, 0xB50EC5A9F29E1ACBUL, 0xBE2FA1126AF7BFAFUL, 0xBEFC0AC4C9C5A4B3UL, 0x994739C71FB1EB29UL }, /*80*/ + new ulong[] { 0x6FEC2D343E83A763UL, 0x5BDBA5715757F50CUL, 0xD6F6282EE46A11B3UL, 0xA8B501F5922A5524UL, 0xA782A21006B605CAUL, 0xA10BD2E896975C81UL }, /*81*/ + new ulong[] { 0xB8AAE0532226D0EDUL, 0x891831C0470E84B7UL, 0x74C824D648E8FF28UL, 0xB5E4E02EAD3906EBUL, 0x5ABB086ADA60A713UL, 0xA80C57666A9E29F1UL }, /*82*/ + new ulong[] { 0x529E3E52B1E7230AUL, 0x0C148861C9F08E26UL, 0x0CFC8A131BAD803DUL, 0x8C09F324902FAA9FUL, 0x0231EE4987999848UL, 0x3B0688492E2B5457UL }, /*83*/ + new ulong[] { 0xEFA6EAC5036814CDUL, 0x02773C1F8DAA5DF5UL, 0x0E4EEDBD0702DE31UL, 0xBA7FD757D0D740EFUL, 0xA8805F0C74005F8BUL, 0x1448467BFF3E1EF8UL }, /*84*/ + new ulong[] { 0x2A07B766016AC70DUL, 0x64215C35364219E9UL, 0xCD6F7EFE35FCF6F1UL, 0xF05CC06084C29267UL, 0xAB3BF2F32579A444UL, 0xAC75F42D9A25B9C9UL }, /*85*/ + new ulong[] { 0xEF3A14B5EDDB8464UL, 0x2314E0802D2DD0E9UL, 0x14DEAEA9F928762AUL, 0x5763EBB480E15A02UL, 0x25F7CA14E8CDF5E6UL, 0x8E594510DC61E6BCUL }, /*86*/ + new ulong[] { 0xE62C38DCFD21000BUL, 0x7BB32AE917EE3DA7UL, 0xE49F15E24CC9B656UL, 0x56E28259DCA361D8UL, 0xB43B8008A9285F48UL, 0x0DC6B4AF7E4AE61BUL }, /*87*/ + new ulong[] { 0x703C64241142DCAEUL, 0x732D33342C45063AUL, 0x37877EA1624567CBUL, 0x2871D534614DD114UL, 0xE748092A1D94F5D1UL, 0x4524056F0C6D1CB7UL }, /*88*/ + new ulong[] { 0xE325B1823A595DF9UL, 0x742D0DD5C96F397CUL, 0x44361C9540A9F451UL, 0x02382F9BF6331FB9UL, 0x8ECBAFBBE91A0467UL, 0x528EBF3811F904A8UL }, /*89*/ + new ulong[] { 0xFD2BC6534631FB0DUL, 0x27A5F036FEEB9A6CUL, 0xD0F876D7911D0775UL, 0x12EFB3A29C6E0B72UL, 0xDC4BCA3D5E871DA1UL, 0x028FB6E6E608F46FUL }, /*8A*/ + new ulong[] { 0xEF17ECC8930A7B4AUL, 0x9D97B34672FB273DUL, 0xC6AE835F35A25D8FUL, 0x6C27469530C21F5BUL, 0x2FBC16A26150E795UL, 0x02AD93AAE0B5C71AUL }, /*8B*/ + new ulong[] { 0x6D24BE43CF07DD56UL, 0x63681D62A38D2A2FUL, 0x9872C9B411724AA0UL, 0xB882B4857C19690AUL, 0x87B1BA8D2804C6F4UL, 0xD7B199CC36F40B49UL }, /*8C*/ + new ulong[] { 0xEEFB8D8573FD9E0FUL, 0x933403199B91560AUL, 0xFF0DB41665D5248CUL, 0x322EE105EA984196UL, 0xDB8CE0F83890D89BUL, 0x3A32F8983C901F80UL }, /*8D*/ + new ulong[] { 0x082CDAF93F215BACUL, 0x67C118A1B9274FACUL, 0xAF74501CFB93198AUL, 0x53525CABA0E812D3UL, 0xC9AF3A005EFE8A6EUL, 0xF242DCB60DA7B2FEUL }, /*8E*/ + new ulong[] { 0xD3887FBFBB7314DFUL, 0xDDDCCCF0F720C342UL, 0xB2C4331C33C8C415UL, 0x1666010767F4785BUL, 0x8455B7C1FD5DE487UL, 0xA821C5EA181875F2UL }, /*8F*/ + new ulong[] { 0x7E289831418562F0UL, 0x2AD12E3042B185C3UL, 0x7C20D0D735A6AE96UL, 0xA68BEF98E22CBD41UL, 0xA1411D22F8D93243UL, 0xD813FB404F3D2F38UL }, /*90*/ + new ulong[] { 0xE13FC0A76F664294UL, 0x7E21C9D9F7FDDDCBUL, 0x161E68B366D6B1F8UL, 0x55BF957EB5743874UL, 0xB23213EF8364D766UL, 0x529BB98AF96643D4UL }, /*91*/ + new ulong[] { 0x036D7ADDAADB5C33UL, 0x0525835F802D032EUL, 0x7DF7D0D8D7A2BEF2UL, 0x84927644B27696B7UL, 0x215E21E4D1F9B5B9UL, 0x77743669C40EB7FDUL }, /*92*/ + new ulong[] { 0xA9B3534BE8897784UL, 0x5BFD4283541A5090UL, 0x97AFFCCD121C9778UL, 0xC146C4C9637989C7UL, 0x0820E72FCBDA59C7UL, 0x5526E2F4A0AE4F4FUL }, /*93*/ + new ulong[] { 0xA4739E20FD72BDC2UL, 0x6D6EE5A5C1A54CA6UL, 0x70A97A6FCB884E5CUL, 0x2B6108339E979C48UL, 0x93A63730D6BB23A7UL, 0x5B1DCEAB00045EE5UL }, /*94*/ + new ulong[] { 0x427C14E4F88C8BDBUL, 0x1D8630868E039BC2UL, 0x33DB40A251502D1BUL, 0xE043C9CCB45D2B3DUL, 0x292B67B6EE077B2DUL, 0x1C3A2FBDE24C742AUL }, /*95*/ + new ulong[] { 0x3DED69F37016D86AUL, 0x9A947B13AC66D7C3UL, 0x822D8645DF4CB39CUL, 0x2BA20F98F19E10DAUL, 0x6703138D422AC4C4UL, 0x8D34D6138FA04A1DUL }, /*96*/ + new ulong[] { 0x28E59C8B257D112CUL, 0x8747068CC5499FCFUL, 0xD6C16EB780F9191AUL, 0xB416151633F7AF08UL, 0xA230E00D6BA1A1C3UL, 0xFD066FB9965B83D2UL }, /*97*/ + new ulong[] { 0x70F4BC1B7F8FFC37UL, 0x38DC0331E56B0FDCUL, 0xA9AB7290AD2B0BBDUL, 0xB307973C3D0783C6UL, 0xBDC455F6CDCA111FUL, 0x23F0E08317B8F0DCUL }, /*98*/ + new ulong[] { 0x0AEEC24E9285C50FUL, 0x3BCDA47833B61ACEUL, 0x839986F959EE0723UL, 0xC959034A8D7F5EB9UL, 0xD4AD7E05B05C4FB5UL, 0x6C37A3D39F7A0EC4UL }, /*99*/ + new ulong[] { 0x0227B7230FBF2D07UL, 0x28D7D2AD632BED47UL, 0x07BD8F8B5012EFD0UL, 0x48A0D43AE0403442UL, 0x9B8939207F1449A1UL, 0x351EAD01B9FDF219UL }, /*9A*/ + new ulong[] { 0xA7119D2E311CEF25UL, 0x1E532CD0C4ED0479UL, 0x2272F878D8D30A0BUL, 0x769C412CED9C4C42UL, 0x262FFBFA65CBDDF5UL, 0xDB73D86721EA368EUL }, /*9B*/ + new ulong[] { 0x4BDBE90B3FBADCB2UL, 0x1324EC3A8D6FEA57UL, 0x6D9EFBE530850D00UL, 0x401A88AFF8A4C8F4UL, 0x655CB76B8A2E271CUL, 0x35505B6DBDE16F43UL }, /*9C*/ + new ulong[] { 0x6E15E57E23F57037UL, 0x4962737362C1FA26UL, 0xC962372D1829B80BUL, 0xA1FE6832EA4D6211UL, 0x6726E307F96E7763UL, 0x04C761081677505BUL }, /*9D*/ + new ulong[] { 0x42E2FF3A8A6FC164UL, 0xFB85B2BC9D28B268UL, 0xC559CFF024533A28UL, 0x2EC83F3911DAB3CEUL, 0xAE0FC74A9D736A27UL, 0xDB9CDD048BAB4CCFUL }, /*9E*/ + new ulong[] { 0xD79C52221D20E765UL, 0x499EDD73903CE704UL, 0x9B016D987DF48349UL, 0xFCFAB44AD12FC5C1UL, 0x811293F3B800FDF9UL, 0x511DC619CA53CEBEUL }, /*9F*/ + new ulong[] { 0xA059EE78B826EDDFUL, 0x4673AF294D17C85AUL, 0x5E527D4E4DF282B5UL, 0xDB5B9A2693F95CE3UL, 0x6551D304FB54F296UL, 0xAB3EB70D65912FCCUL }, /*A0*/ + new ulong[] { 0x7D0C4F67B6C78135UL, 0x390CAEA7DE304D37UL, 0x49E19FABC8D494FEUL, 0x1A9E1B6437A04516UL, 0x886CC4BDAB6AF35AUL, 0x0529217344F502FEUL }, /*A1*/ + new ulong[] { 0x3CEDF34141B52CEEUL, 0x8133BA924753573FUL, 0xCB32BE22BC66025AUL, 0x0C480183DE403CB3UL, 0xBF5B84B427DFCF31UL, 0x7251428DB0232156UL }, /*A2*/ + new ulong[] { 0x86FCE831C58E25CBUL, 0x5CC43FFE45CBFC75UL, 0x33877CC042F199BEUL, 0x1212FA7F0CC22E1CUL, 0x448EAB4B7D1F9823UL, 0xA7B1363A9FA7599EUL }, /*A3*/ + new ulong[] { 0x2D8C2FEDA0E5106DUL, 0x192E366838BBEB3FUL, 0x36226AA60ACEA0AFUL, 0xE7E1285DC1F3926AUL, 0x900371FA1883D9ECUL, 0xBAC33B1AF360EB66UL }, /*A4*/ + new ulong[] { 0xD4A2A11612BDE0E3UL, 0x82AB0DA614CB4CB8UL, 0x189A4D50AC01F4C6UL, 0xE36A5DA1D9F6A647UL, 0xE43120D6B16B11B6UL, 0x7D395F4236E75378UL }, /*A5*/ + new ulong[] { 0xC0C155CD47F3877FUL, 0x4B03BFE5C334CA71UL, 0x77710F1F4B844FF7UL, 0x3443BBAB720E8DC5UL, 0xF03F8868C5863406UL, 0x0FD60511C872EB50UL }, /*A6*/ + new ulong[] { 0x8C253DAAB5286306UL, 0x9AA438F54A6196ACUL, 0x181D08C723A22C5EUL, 0x633C49C88E3910A1UL, 0xC9F54A67992675B0UL, 0x1FDD98ACBD38D976UL }, /*A7*/ + new ulong[] { 0xA10893DA7575A9F7UL, 0x8F5F4A025AB2A018UL, 0xD80538F0336BFFC0UL, 0x0F9751D33889626FUL, 0x30383EB925BF911AUL, 0xE6149F68CE19CC60UL }, /*A8*/ + new ulong[] { 0xB9081DBAC6BE0598UL, 0x785DD9BC69C71492UL, 0x8B035A0CA56E172BUL, 0x8946783500724888UL, 0xAF1E57C958650569UL, 0xE1DE4E944FF22261UL }, /*A9*/ + new ulong[] { 0xEA5EDC4D2718C0D2UL, 0xCB1C5D4DA15A8AE4UL, 0xC6272382F8163015UL, 0x94A934E5057B54CEUL, 0x658E481A3D68D10DUL, 0xE8F24929E50A46A0UL }, /*AA*/ + new ulong[] { 0x7DF146281AF482CDUL, 0x014B68E726407B06UL, 0x6CE564938C70DDBCUL, 0x36DAD2DE72A5DAA2UL, 0x6D573BF69C0B2980UL, 0x684DAB14B4AA0329UL }, /*AB*/ + new ulong[] { 0x9C69DC064E738B5FUL, 0x83CC16BD5A1C36F5UL, 0xA99B365E6E141B12UL, 0x2748FA5AD0FACCE8UL, 0x26D073A047D99C49UL, 0xB005B182505B0C0CUL }, /*AC*/ + new ulong[] { 0x15B6A2A20ED0FD1CUL, 0x9333AF729BD65A25UL, 0x22CC333293BD2C1BUL, 0xD724D949B15E8BE1UL, 0x69D0DB0512B97117UL, 0x85ACA8980DD7653CUL }, /*AD*/ + new ulong[] { 0x230EC629D77BB3F2UL, 0x43115B991D297CB2UL, 0xA2F955792C53C76FUL, 0x48A76728EBE25BA7UL, 0x7CE662A405384400UL, 0xDDC06B7E6BF49D66UL }, /*AE*/ + new ulong[] { 0x20DDB9BD7644410BUL, 0x056391B1FA2E8C06UL, 0xCA4EDE51CF167C00UL, 0x46602B550536F870UL, 0x5040672597C21FF4UL, 0x0AF8EC6E8AFB844BUL }, /*AF*/ + new ulong[] { 0x0023C5749251B883UL, 0x335A4F86D66B7E00UL, 0xAE353DED3EFACE8FUL, 0x3FC80526D67B35DEUL, 0x0D9078FBDA80BC53UL, 0x467900DFF3FE4C14UL }, /*B0*/ + new ulong[] { 0x0F9CB2BE6A448113UL, 0xE38D541B6A9A5829UL, 0x673953DAF354FC0EUL, 0x3C818A277F8569E9UL, 0x8D16EA77DB122A3BUL, 0xE40A860318B6EA84UL }, /*B1*/ + new ulong[] { 0x78CE11F42D7D5E50UL, 0x84F76DFF199C998DUL, 0x999B578E3AE935CBUL, 0xD9FD092C1BE63212UL, 0x31F33C63ACD316D8UL, 0x5AA08030B8D65C0CUL }, /*B2*/ + new ulong[] { 0x0098DBE19CA84FE9UL, 0xE2426617D1142137UL, 0x63C3C4166A78E21BUL, 0x74B145353E03B0E4UL, 0xF43C0824EAE508C4UL, 0x58C1E6622528602AUL }, /*B3*/ + new ulong[] { 0x9E27EBE6D1426A6FUL, 0x2A6A600A6B5FA342UL, 0x8FF7E2306BA90370UL, 0xDF83D91A683EDDDDUL, 0x29572442F0225388UL, 0xE9CC0F1B6437320AUL }, /*B4*/ + new ulong[] { 0x054DF380E896064EUL, 0xFAB81A4AA3AD88A4UL, 0xF87426486CCA156FUL, 0xBB1B3C8237472960UL, 0x7EC0B87CF73F960AUL, 0x5C57D7E6470F7808UL }, /*B5*/ + new ulong[] { 0x5758E103AC614A1AUL, 0x766AEE86F81358DFUL, 0x203FBA51DC74396AUL, 0x78C93DF969C5721FUL, 0xE69E32E230196597UL, 0xE287C6CECD8AB95BUL }, /*B6*/ + new ulong[] { 0x2A06A7C10C0DCC97UL, 0x99D5298268A6745FUL, 0xF2D818BB774858B3UL, 0xD52A820D4F64D886UL, 0x2F808EF87A263981UL, 0xBB91206E6347C676UL }, /*B7*/ + new ulong[] { 0x0847C6D71CE0C746UL, 0x86FD451B447C1E11UL, 0xC20623B0E2856FCCUL, 0x3ADDFA2D0398181EUL, 0x6736A0A06B336B46UL, 0xD1C70AEEB2B1257DUL }, /*B8*/ + new ulong[] { 0x5633260D141A9776UL, 0xD530805F596CA3DBUL, 0x8CE33EF69437CE46UL, 0xF62D54E97E747088UL, 0xDF5C9318489B45EAUL, 0xA4AAD29F0BA850CAUL }, /*B9*/ + new ulong[] { 0xBDBD7B16767F6D9FUL, 0xF7968427F1B7B6DDUL, 0x58C76599B35276EEUL, 0x286F4C7F6CADD791UL, 0x8188C0401742117BUL, 0xCEC4F1964266D163UL }, /*BA*/ + new ulong[] { 0x97E4E8A6B5135B24UL, 0x8A8BD785E5297977UL, 0x4545C1A0975BC5BBUL, 0x13FAE3BD9F59E37DUL, 0xAFD5627C0E91DE2BUL, 0xA223AC778474E1A9UL }, /*BB*/ + new ulong[] { 0xDE1BF1EAF86C6B3BUL, 0xA246A3ACD50035FEUL, 0x6F80179DD96A21CDUL, 0x3F8DB7CB17300D03UL, 0x497A798B5D94506CUL, 0xAD52DCC6F61AE841UL }, /*BC*/ + new ulong[] { 0xF4A4E1D08E1F440BUL, 0x5E27633CD56422E0UL, 0x1465C14F1DB41420UL, 0x9A939043988D37C2UL, 0xCBE65CFA245DB368UL, 0x6340AEDE28DDA855UL }, /*BD*/ + new ulong[] { 0x1F7AB65A3F892454UL, 0xD70AB4167EBEB5A1UL, 0x9B2631E824C2028DUL, 0xD5D97BDEE31519BCUL, 0xEA2DC77449E4058CUL, 0xEB204F2D6D2FBAFFUL }, /*BE*/ + new ulong[] { 0x6537E69171A2665DUL, 0x3FD2F835435A3F23UL, 0xADD5DD3E622D6C8AUL, 0xC522CDD5E5E243F8UL, 0x5AEC27F3DBFDA8A2UL, 0x477A65ED570E1445UL }, /*BF*/ + new ulong[] { 0x3BA7CB01D32E9D63UL, 0x9E335734E7B5416BUL, 0x0ED96A84F94539F6UL, 0x45CEE2E46DF5A70DUL, 0xDE142EE1E9AFEC1CUL, 0x78D6121C4FDC72DDUL }, /*C0*/ + new ulong[] { 0x7BB30AF653390B77UL, 0x2D394F2B7F8F7BB6UL, 0x0277A3C213AF3489UL, 0x7DF6E674DD56D084UL, 0x5643CD3073C42451UL, 0xFAB15F8BD1A1DC18UL }, /*C1*/ + new ulong[] { 0x42B453ABF5150D8BUL, 0x913F109C1188E18CUL, 0xC27BB7631FB43BF9UL, 0xEBDDE685EF108419UL, 0x76D67C87C56D33EAUL, 0x95EC73C0AF40F084UL }, /*C2*/ + new ulong[] { 0xBCE43D59A1F50BFBUL, 0xBA7027CA04D84600UL, 0xFB6FDB98A2BE644BUL, 0xD5DE777E993DED4AUL, 0xFCA39F1EDF710F3AUL, 0xA5E5893C858D8841UL }, /*C3*/ + new ulong[] { 0xC68AC776E6AEACFCUL, 0x538067C7866106EBUL, 0xD27B4A352F4EFDE3UL, 0x847DA2B3BF01E378UL, 0x3C79E3C136926D58UL, 0xF957BC8726AA1610UL }, /*C4*/ + new ulong[] { 0x95492C4203C7C612UL, 0x0DD60DB1EE8321FCUL, 0xE1D9EBA902F62B42UL, 0xEA2DBF7D0E37A4F2UL, 0xE11FB9098BF5DA48UL, 0xDBFE213F818EA338UL }, /*C5*/ + new ulong[] { 0x17CB21316D4756DDUL, 0xB88952498140146AUL, 0x648112F580844288UL, 0x4947ADC3F7D58F35UL, 0x651CCE28E26A5377UL, 0x0B3803DAF337F89BUL }, /*C6*/ + new ulong[] { 0xBEAB16E2DCE6B6E3UL, 0x8F39ECC8E39172DFUL, 0x607CC9553FF29C0EUL, 0x4BFD15154F4F0BA7UL, 0xEE6230B6BD408CE4UL, 0x35B654110D164E99UL }, /*C7*/ + new ulong[] { 0xADDDFF1BD2C11CD4UL, 0x2A1A262CBA6E1AA0UL, 0x0BF2291D09475A46UL, 0x4C93A0ABADF4DE32UL, 0x73EE8E1327333E63UL, 0xF3AE2031F5D13B28UL }, /*C8*/ + new ulong[] { 0x246C7CABB2D9A55CUL, 0x50E9C7282C1EE0F6UL, 0x2FBDA09565A0D3D7UL, 0x196552679C04A4EBUL, 0x137C66DA29A6DD82UL, 0x08A76B6B4BDA56BFUL }, /*C9*/ + new ulong[] { 0x7CA3C59BE3E28610UL, 0x6ADD75CF1F7AE248UL, 0x01747450737A6435UL, 0xA1F2259CB2B4923BUL, 0xE0C8F55E8ECE7210UL, 0xD7964398F350B69BUL }, /*CA*/ + new ulong[] { 0xE045864ED1825101UL, 0xAC54969193E1A1C5UL, 0x23D85A934D0794C7UL, 0xB4FA88CB734A4213UL, 0x7C5CBFD6BDA3D5F9UL, 0x66607FE938748825UL }, /*CB*/ + new ulong[] { 0xBAF36FD2A180D481UL, 0xEAC440AC1B9598F7UL, 0x9AA24D80FFB7B06CUL, 0x79601F517358F163UL, 0xD1071831418BB63BUL, 0x819609A6AE7D3A03UL }, /*CC*/ + new ulong[] { 0x3E9152D8CDBAE551UL, 0x86AD793F203DD016UL, 0xBE3AEB778AD4A891UL, 0x2810254DD76B6618UL, 0x9B5DCDE36636C327UL, 0x0A8AAD65868BC58CUL }, /*CD*/ + new ulong[] { 0x6D0672780D93152AUL, 0xEEE705247B828091UL, 0x9EBDB976F137463FUL, 0xA7DE3E73A2D0C1BFUL, 0xF871A00BA0046AC7UL, 0x484C96A803F23486UL }, /*CE*/ + new ulong[] { 0x0FC7BCDABB06BFFBUL, 0xF75C3FFB3D6309B3UL, 0xECA305D103109162UL, 0x373F503B204FFF61UL, 0xCE332C9F54963FA2UL, 0x9A4420A52242CDB4UL }, /*CF*/ + new ulong[] { 0xC71D481179D198C1UL, 0x505A2845CEE92569UL, 0xF339BFF6DD6755B5UL, 0x8BEAD52B8DE89245UL, 0x4B686E65920DCA2BUL, 0x99593FA43EE68A37UL }, /*D0*/ + new ulong[] { 0xD90A68D717E61501UL, 0x9BB920AEA19161A6UL, 0x2F3D6F96D90EB1E4UL, 0xDF15ECBA10513D7DUL, 0xE6E5D539B4F01831UL, 0xC7D17A7528FECE36UL }, /*D1*/ + new ulong[] { 0xA04FF0BEB4EBFBAFUL, 0xE5E90A5B3DDAA3CAUL, 0x8453542209F4A145UL, 0x80A6FFD72BB5A707UL, 0x14E0C4705A1ABF6AUL, 0xD699EC1FC18A677DUL }, /*D2*/ + new ulong[] { 0x7021A124E3181575UL, 0xDC7AAE2817AD945FUL, 0x8BB5521E7F0D565AUL, 0x6671D3792F0805EEUL, 0xD3888EA394413A1AUL, 0xCE4D7E47B55BF9CCUL }, /*D3*/ + new ulong[] { 0x22F440263CAADE68UL, 0xE77BB287772EAC7BUL, 0x29493775962A40E9UL, 0x1E06A27FA68CB91BUL, 0xDDEF02932ABDB9C7UL, 0x79F03B88DC175233UL }, /*D4*/ + new ulong[] { 0x65F6D517B53E2391UL, 0x97DB65A2F00B1C39UL, 0x1D77AE9B85AA4855UL, 0x19133B9B3E9B0771UL, 0x6376D9F11A7DB3D4UL, 0x949AD02F5AE16184UL }, /*D5*/ + new ulong[] { 0xFE4434CDE09D923BUL, 0x03B0FCFD713B7052UL, 0x2D713290D4A67238UL, 0x2B56946FF629EE96UL, 0x60A15D01B2B3C428UL, 0x0B1D5EAF793933A0UL }, /*D6*/ + new ulong[] { 0xBC40FCFB0E0D494BUL, 0xA31C4648C7B3D1DEUL, 0xF1113C219A07EC8DUL, 0x2378BEB1A5C2BD1CUL, 0x190CC3478070A194UL, 0x63DAB6E1CCF56329UL }, /*D7*/ + new ulong[] { 0x901B6B9E82BABF91UL, 0x872A234C45D61001UL, 0x6CA46A95C1CC6D6CUL, 0x22779315E0F02295UL, 0x60A59396346BE6ACUL, 0xFB67A503CB488846UL }, /*D8*/ + new ulong[] { 0x50D440F74C97660BUL, 0xE71ECABF64EDFE0CUL, 0x80201B895718CE22UL, 0xA05D89804D35D306UL, 0x8F700402A2B0D086UL, 0x326FCB334CA4DFC0UL }, /*D9*/ + new ulong[] { 0xBCFBD02EA005CDD5UL, 0xF0225A4675553115UL, 0x08E18B3692A7AF62UL, 0x05D34A820C8CED0AUL, 0x51A8D7CEC33E80EAUL, 0x0AC007503FAE879CUL }, /*DA*/ + new ulong[] { 0xF43EEFB5C83C521AUL, 0xE5E9B05FC48841ACUL, 0x79C52C38BF85B5F9UL, 0x26CD0818AE3BF7A9UL, 0x4F385C32CA8F5F74UL, 0xF17B22107B954752UL }, /*DB*/ + new ulong[] { 0x1A48FC969198A4B0UL, 0xD9A78940BB0C4E1CUL, 0x42781D9BE60E7691UL, 0x87D1CAF3680F8A30UL, 0xD09FF193606AAF29UL, 0x4518DABC60048793UL }, /*DC*/ + new ulong[] { 0xF05D48134A56A034UL, 0x89A65EEB91DC69B9UL, 0x8FC7F43960E63C62UL, 0xFA1C6B9FF9415E92UL, 0x7E219D4E56347935UL, 0x2B6A48D6DE0AEF85UL }, /*DD*/ + new ulong[] { 0x1A7FF9C54B045FFDUL, 0x44A0A9562E9468B2UL, 0xF11425A22D1EBF92UL, 0x208D33120BD28E0EUL, 0xF2D74197AF80E162UL, 0xCEEDCA73DFE66C93UL }, /*DE*/ + new ulong[] { 0xD57190439D29C9A4UL, 0x44C007DC2B5EAF9DUL, 0xEF6DDF48A780CEDCUL, 0x61B205E4A96024B1UL, 0x1885B6CE84C3FE5DUL, 0xB8B56986B6E2CE21UL }, /*DF*/ + new ulong[] { 0xF36DACFA34237E99UL, 0xBE45EB5253BCFED0UL, 0x402C6946B8B21AC0UL, 0x2460A6FCE7E9CD67UL, 0xF89A6D5B162629FCUL, 0xF66CCEA374DB821EUL }, /*E0*/ + new ulong[] { 0x16E06074DCC31A1DUL, 0xF172017AC3FA38C3UL, 0xBBC1CE4BB784ED60UL, 0xDA89A8BCE82AE671UL, 0xA6DACFFB8D26C0BBUL, 0x185181AE9609F6D6UL }, /*E1*/ + new ulong[] { 0xF110DBDD94D17661UL, 0xF59FBB4CBA69F393UL, 0x463B60FB3F3C5E00UL, 0x1C60B896FE8E78ACUL, 0x5EB3E26795DE5AB6UL, 0x997328D4654D6219UL }, /*E2*/ + new ulong[] { 0x21069118ABE24B61UL, 0x811CB8C48FCEFC6AUL, 0x483B032CFB56F902UL, 0xFB32E848198CC057UL, 0xA620815462A04F70UL, 0x900038D1894959E2UL }, /*E3*/ + new ulong[] { 0x5AD509789BFFECD0UL, 0xDDCD5E8325F69CA0UL, 0x154D8F1ACD9B8C82UL, 0xAC7DF75E94CE3CAFUL, 0x6D6554D1B38754BEUL, 0xB5DB64AF738486E7UL }, /*E4*/ + new ulong[] { 0x35A308A1AC9A43BFUL, 0x2647805AB3E6E492UL, 0x4BB74A616F61588FUL, 0xFA4602EE5BDBF54EUL, 0x3FDD62470A7174DBUL, 0x5795433CA808FAACUL }, /*E5*/ + new ulong[] { 0x51A094B8774CA605UL, 0x5F07974C74EEF225UL, 0x022AFEF7AD81A953UL, 0x0967C44BBA336FD6UL, 0x8AA327918AECBA3DUL, 0xF70B8436573C3F0AUL }, /*E6*/ + new ulong[] { 0xCF374F83420766C3UL, 0x71F31901A13EF07CUL, 0x63AD56C7DEF9DC0FUL, 0x9E5BB5E859F5A231UL, 0xD0BF453BB9893E4CUL, 0xA1E14B66C2719760UL }, /*E7*/ + new ulong[] { 0xB41861CC73FD3E48UL, 0x461D79A138B04BE1UL, 0x4010D37D37FBA817UL, 0x7D9622AA693225A4UL, 0x2204454B8126799AUL, 0x33A5D487DCCD6EB6UL }, /*E8*/ + new ulong[] { 0xD291D0317A053320UL, 0xE27678F1E50D1F76UL, 0x9A3D663A63159FC7UL, 0xAD7B4D3F67BAB452UL, 0x269CC05E2B33CE1CUL, 0x0FB8261CD734BCC3UL }, /*E9*/ + new ulong[] { 0xF3D0546D3D4A25EEUL, 0xB42874AD28C9B7F2UL, 0x73EC788B29962D28UL, 0x4AE73A48132B8553UL, 0x756C99D7A0910B66UL, 0xECA7E2C2712D555CUL }, /*EA*/ + new ulong[] { 0x559FA5BF24911FDDUL, 0xA1DDF5DE3770554BUL, 0xC7C3FD139366B946UL, 0x6E7ECC0C881D2BA4UL, 0x14E76D6A27E54B87UL, 0x7352D5FBC4FAB878UL }, /*EB*/ + new ulong[] { 0xF19A622BED8DAC0AUL, 0x35548E5D7EFC5A2EUL, 0xCAC84974B4F057B2UL, 0xAB317ED03D0335AEUL, 0x710FC138F2C51738UL, 0x9C90CC495A403416UL }, /*EC*/ + new ulong[] { 0x9FA7DEB936F10461UL, 0xA1529B0B58462F9DUL, 0x9F109111C8B9EC65UL, 0x23A3EB28444E33EAUL, 0x554084CA75118937UL, 0x599D58A7C946EAC2UL }, /*ED*/ + new ulong[] { 0x6EC3AABB7856AC4EUL, 0x980E6907C1CBCCAFUL, 0x1F8557ADC700CBF5UL, 0x7DCB1CE0AF48D9F4UL, 0x7FB3DADF8199AB8AUL, 0xE6B36DB8FADBF312UL }, /*EE*/ + new ulong[] { 0xC00F0D3F7A101660UL, 0x605B94B12DB6C697UL, 0x79944F7BA2B65F38UL, 0x40858ADEDD47E2BCUL, 0x1E044BDB0E9FB02BUL, 0x86C79D01A3109539UL }, /*EF*/ + new ulong[] { 0x9731893D5B98482AUL, 0xFB8DE267F9790326UL, 0x8780F407143A505DUL, 0xA41CAEFCCCD3A8E3UL, 0xA042F0B3D7B7A7FEUL, 0x3E3151FEBB19A1ACUL }, /*F0*/ + new ulong[] { 0xE7EDF679003A6950UL, 0xBAFC97D4A8C6AB12UL, 0x13C096B49C79559AUL, 0xC3052501434B5019UL, 0x1280FB23E7ADFB09UL, 0x1959905D31BD2FC0UL }, /*F1*/ + new ulong[] { 0x575C0C46FCFCC65BUL, 0xFE625E873F34B419UL, 0x1696FDCC7F51B8A3UL, 0xC79C56F30E5AE7C0UL, 0x14E3461CD27FAD15UL, 0x1B7BCCB9CB472859UL }, /*F2*/ + new ulong[] { 0x3806FE58E5CC8F16UL, 0xF8244ED76734C1BFUL, 0x4E04940E0F5DDB56UL, 0x5BD0AFDDC4158B7BUL, 0xA4C6BA949911C5C9UL, 0xFF6E2AC155AE9726UL }, /*F3*/ + new ulong[] { 0x49C7C844B8114144UL, 0xB450E41BCA35CB00UL, 0x302450EC67BEF97CUL, 0xA8662049DB1E0D8BUL, 0xDA69C022528EB8FAUL, 0x6ABBF16585C1A2F7UL }, /*F4*/ + new ulong[] { 0x37BB420DF67F044EUL, 0xDCC0E9F3E2EF07B3UL, 0x4D10088618777841UL, 0x0492E5379305DAAEUL, 0x3DA4791C37E4128FUL, 0x80688445CBA4EA17UL }, /*F5*/ + new ulong[] { 0x51398A7CE4CF8D9DUL, 0x49A5FCD891A69CA5UL, 0x3D72A60EC2392DA5UL, 0x0E8296B879AB5539UL, 0x6BCB00AF2EDC0BDEUL, 0xBEB93848E54B3E90UL }, /*F6*/ + new ulong[] { 0x7AD7C52A18922E19UL, 0x29292C57C4F5B8F5UL, 0xF0CF1F98A577C10BUL, 0x072B9F293BB660CDUL, 0x09B8604F5575B6FBUL, 0xDECB396A81B9FCDBUL }, /*F7*/ + new ulong[] { 0x254AD7ADB4C220DEUL, 0x6C62E20F95A0070DUL, 0xADEB89F339309BD8UL, 0xA2F685CC178B289FUL, 0x9343905B5DEE95A5UL, 0xE0C30F34A2977C86UL }, /*F8*/ + new ulong[] { 0x669CD51AF7CFBFAAUL, 0xE3E0806F6880271DUL, 0x6934C259E098BF90UL, 0x5DFEEAF0FBCA7249UL, 0x89F74B948B4118B6UL, 0x53640AEAFB6807C3UL }, /*F9*/ + new ulong[] { 0xDD3BACDCC04BE120UL, 0x6D4949BD64198E51UL, 0x31FDB39666598A74UL, 0xBBBC6DE9C0C15A81UL, 0xF27F201C61C06279UL, 0x2738AFE3E84E5CDDUL }, /*FA*/ + new ulong[] { 0xCDD71FD35A6411DEUL, 0x3CC012793E87523FUL, 0xB0CFF8720FCA36F3UL, 0x93E85FE07300F012UL, 0xE894A085263F090BUL, 0x2DF60A01DAFA90ECUL }, /*FB*/ + new ulong[] { 0x9DA50DB1EEB4FADDUL, 0xE524E49C9974799AUL, 0xDE09FFF26A24CBB9UL, 0xAF9D71E9F3ACE7CDUL, 0xEB62B1A62566EC9DUL, 0x06D02AB1217D3553UL }, /*FC*/ + new ulong[] { 0xDD31E6391AE03522UL, 0x93ACD1065B35E915UL, 0xF4EB56CC03E79218UL, 0x0717815C850C97F1UL, 0xBF4F6A8AC0540A6FUL, 0xFCF8AE5DE9507FF0UL }, /*FD*/ + new ulong[] { 0xAB45B413DC50B207UL, 0x40B417369551D8D5UL, 0xCA32286A108E7210UL, 0x03225E54D8D093AFUL, 0x4B6CA5591EA576E9UL, 0x4E12AB774DC4E062UL }, /*FE*/ + new ulong[] { 0xD9F4F850DF6CB96CUL, 0x8ABAD81B1667335DUL, 0xCB4079CFE79C72E5UL, 0xE5542F763E316996UL, 0x303E4B79B9D397C4UL, 0xE46933038B945111UL }, /*FF*/ + new ulong[] { 0x75B15CC53B0D2502UL, 0xDA1BCA6BA0524358UL, 0x9EDA977556C06B7EUL, 0x6C57727ECF0A1325UL, 0xDC613D5A78E5C3F8UL, 0xCE062D94A3B4945AUL } /*ZZ*/ + }; + + private static readonly ulong[][] NUHASH_RND = new ulong[][] + { + new ulong[] { 0x6A09E667F3BCC908UL, 0xB2FB1366EA957D3EUL, 0x3ADEC17512775099UL, 0xDA2F590B0667322AUL, 0x95F9060875714587UL, 0x5163FCDFB907B672UL }, /*R1*/ + new ulong[] { 0x1EE950BC8738F694UL, 0xF0090E6C7BF44ED1UL, 0xA4405D0E855E3E9CUL, 0xA60B38C0237866F7UL, 0x956379222D108B14UL, 0x8C1578E45EF89C67UL }, /*R2*/ + new ulong[] { 0x8DAB5147176FD3B9UL, 0x9654C68663E7909BUL, 0xEA5E241F06DCB05DUL, 0xD549411320819495UL, 0x0272956DB1FA1DFBUL, 0xE9A74059D7927C18UL }, /*R3*/ + new ulong[] { 0x84C9B579AA516CA3UL, 0x719E6836DF046D8EUL, 0x0209B803FC646A5EUL, 0x6654BD3EF7B43D7FUL, 0xED437C7F9444260FUL, 0xBD40C483EF550385UL }, /*R4*/ + new ulong[] { 0x83F97BBD45EFB866UL, 0x3107145D5FEBE765UL, 0xA49E94EC7F597105UL, 0xFBFC2E1FA763EF01UL, 0xF3599C82F2FE500BUL, 0x848CF0BD252AE046UL } /*R5*/ + }; + + private static readonly byte[] NUHASH_SBX = + { + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 + }; + + private static readonly byte[] NUHASH_FIN = + { + 0xB4, 0x98, 0x0C, 0x84, 0x24, 0xF3, 0x27, 0x8F, 0xA6, 0x5E, 0xF0, 0x65, 0x86, 0xBC, 0x09, 0x92, + 0x75, 0x21, 0xB9, 0x95, 0x66, 0x8A, 0x2F, 0x13, 0xB5, 0xB7, 0x6B, 0x33, 0x2A, 0xBF, 0xF7, 0x0F, + 0x0A, 0xE7, 0x16, 0x30, 0x77, 0x61, 0x48, 0x90, 0xDF, 0xAF, 0x72, 0x79, 0xF6, 0xA5, 0x58, 0xD1, + 0xF2, 0x40, 0x9F, 0x41, 0xE8, 0x03, 0xA1, 0x05, 0xC5, 0x35, 0xC7, 0x97, 0x54, 0x7B, 0xB3, 0xF5, + 0xB8, 0xA8, 0xD8, 0x68, 0x51, 0xAD, 0xE3, 0xC2, 0x5D, 0xCF, 0xEA, 0x89, 0x37, 0xF1, 0x55, 0x60, + 0xA4, 0x26, 0xAC, 0x32, 0x0E, 0xD2, 0x85, 0x6F, 0xC8, 0xDC, 0x36, 0x6D, 0xA3, 0x22, 0x5A, 0xC9, + 0x5C, 0x91, 0x1B, 0x5B, 0xE9, 0x78, 0xD7, 0x44, 0xEB, 0x1A, 0xC0, 0xCA, 0x94, 0x53, 0xC4, 0x11, + 0x12, 0xCC, 0xFF, 0x88, 0x0D, 0x4E, 0xB2, 0xB1, 0x4A, 0x3A, 0xE1, 0x2E, 0x0B, 0x4C, 0x5F, 0x06, + 0x81, 0x31, 0xD9, 0x3D, 0xFD, 0x43, 0x67, 0x62, 0x00, 0x9C, 0x50, 0xCE, 0x6E, 0x15, 0x82, 0x29, + 0x96, 0xDA, 0x87, 0xEF, 0x6C, 0xC1, 0x8B, 0x07, 0x8E, 0x17, 0xEC, 0x9A, 0xBA, 0x46, 0x04, 0x73, + 0x39, 0xE4, 0x63, 0xBE, 0x64, 0x47, 0xE6, 0x3F, 0x25, 0x52, 0x59, 0xA7, 0x42, 0x38, 0x99, 0x01, + 0xE5, 0x1D, 0x28, 0x7A, 0xB0, 0x7C, 0x9D, 0x56, 0xE2, 0xD6, 0xA0, 0xF4, 0x1E, 0xE0, 0xD3, 0x83, + 0x6A, 0xBB, 0x18, 0x20, 0xAE, 0x57, 0xAA, 0x8D, 0x71, 0x1F, 0x34, 0x4D, 0x2D, 0x3C, 0x2B, 0xF8, + 0x10, 0x7E, 0xCB, 0xFB, 0x49, 0xA2, 0x45, 0x7F, 0x3E, 0xBD, 0xC3, 0xFC, 0x14, 0x74, 0x23, 0x4F, + 0x7D, 0x69, 0x93, 0x19, 0xD0, 0x1C, 0x08, 0xF9, 0xDD, 0xC6, 0x2C, 0x9E, 0xA9, 0x4B, 0xFE, 0xED, + 0x76, 0xDB, 0xAB, 0xD4, 0x80, 0xCD, 0xB6, 0x8C, 0xDE, 0x70, 0x9B, 0xD5, 0xFA, 0xEE, 0x02, 0x3B + }; + + /* ------------------------------------------------------------------------ */ + /* Mix functions */ + /* ------------------------------------------------------------------------ */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ulong MixFunction1(ulong key) + { + key = (key ^ (key >> 31)) * 0x7FB5D329728EA185UL; + key = (key ^ (key >> 27)) * 0x81DADEF4BC2DD44DUL; + return key ^ (key >> 33); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ulong MixFunction2(ulong key) + { + key = (key ^ (key >> 31)) * 0x99BCF6822B23CA35UL; + key = (key ^ (key >> 30)) * 0x14020A57ACCED8B7UL; + return key ^ (key >> 33); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ulong MixFunction3(ulong key) + { + key = (key ^ (key >> 31)) * 0x69B0BC90BD9A8C49UL; + key = (key ^ (key >> 27)) * 0x3D5E661A2A77868DUL; + return key ^ (key >> 30); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ulong MixFunction4(ulong key) + { + key = (key ^ (key >> 30)) * 0x16A6AC37883AF045UL; + key = (key ^ (key >> 26)) * 0xCC9C31A4274686A5UL; + return key ^ (key >> 32); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ulong MixFunction5(ulong key) + { + key = (key ^ (key >> 30)) * 0xBF58476D1CE4E5B9UL; + key = (key ^ (key >> 27)) * 0x94D049BB133111EBUL; + return key ^ (key >> 31); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ulong MixFunction6(ulong key) + { + key = (key ^ (key >> 30)) * 0x4BE98134A5976FD3UL; + key = (key ^ (key >> 29)) * 0x3BC0993A5AD19A13UL; + return key ^ (key >> 31); + } + + /* ------------------------------------------------------------------------ */ + /* Substitution function */ + /* ------------------------------------------------------------------------ */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe void SubstituteBytes(ulong* buffer) + { + fixed (byte* substPtr = NUHASH_SBX) + { + byte* bytes = (byte*)buffer; + for (int pos = 0; pos < NUHASH_BYTES; ++pos) + { + bytes[pos] = substPtr[bytes[pos]]; + } + } + } + + /* ------------------------------------------------------------------------ */ + /* Update function */ + /* ------------------------------------------------------------------------ */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private unsafe void Update(uint index) + { + fixed (ulong* buffer = m_hash) + { + fixed (ulong* rowAddr = NUHASH_XOR[index]) + { + for (int round = 0; round < ROUNDS; ++round) + { + fixed (ulong* key = NUHASH_RND[round]) + { + ulong initValue = buffer[0]; + buffer[0] = MixFunction1(((buffer[0] << 32) | (buffer[1] >> 32)) ^ rowAddr[0] ^ key[0]); + buffer[1] = MixFunction2(((buffer[1] << 32) | (buffer[2] >> 32)) ^ rowAddr[1] ^ key[1]); + buffer[2] = MixFunction3(((buffer[2] << 32) | (buffer[3] >> 32)) ^ rowAddr[2] ^ key[2]); + buffer[3] = MixFunction4(((buffer[3] << 32) | (buffer[4] >> 32)) ^ rowAddr[3] ^ key[3]); + buffer[4] = MixFunction5(((buffer[4] << 32) | (buffer[5] >> 32)) ^ rowAddr[4] ^ key[4]); + buffer[5] = MixFunction6(((buffer[5] << 32) | (initValue >> 32)) ^ rowAddr[5] ^ key[5]); + } + SubstituteBytes(buffer); + } + } + } + } + + /* ------------------------------------------------------------------------ */ + /* Stream API */ + /* ------------------------------------------------------------------------ */ + + public NuHash Reset() + { + Array.Copy(NUHASH_INI, m_hash, NUHASH_INI.Length); + m_finished = false; + return this; + } + + public unsafe NuHash Update(byte* input, int length) + { + if (length < 0) + { + throw new ArgumentOutOfRangeException("Length must not be negative!"); + } + CheckState(); + for (int i = 0; i < length; ++i) + { + Update(input[i]); + } + return this; + } + + public NuHash Update(ReadOnlySpan input) + { + if (input == null) + { + throw new ArgumentNullException("Input must not be null!"); + } + unsafe + { + fixed (byte* src = input) + { + return Update(src, input.Length); + } + } + } + + public NuHash Update(string input) + { + if (input == null) + { + throw new ArgumentNullException("Input must not be null!"); + } + unsafe + { + fixed (char* src = input) + { + return Update((byte*)src, input.Length * sizeof(char)); + } + } + } + + public NuHash DoFinal(Span digestOut) + { + if (digestOut == null) + { + throw new ArgumentNullException("Output must not be null!"); + } + if (digestOut.Length < NUHASH_BYTES) + { + throw new ArgumentOutOfRangeException("Output is too small to store the digest!"); + } + CheckState(true); + Update(256U); + foreach (byte val in NUHASH_FIN) + { + Update(val); + } + ToByteArray(m_hash, digestOut); + return this; + } + + public byte[] DoFinal() + { + byte[] result; + DoFinal(result = new byte[NUHASH_BYTES]); + return result; + } + + /* ------------------------------------------------------------------------ */ + /* Simple API */ + /* ------------------------------------------------------------------------ */ + + public static unsafe byte[] Compute(byte* input, int length) + { + using (NuHash nuhash = new NuHash()) + { + return nuhash.Update(input, length).DoFinal(); + } + } + + public static unsafe void Compute(byte* input, int length, Span digestOut) + { + using (NuHash nuhash = new NuHash()) + { + nuhash.Update(input, length).DoFinal(digestOut); + } + } + + public byte[] Compute(ReadOnlySpan input) + { + using (NuHash nuhash = new NuHash()) + { + return nuhash.Update(input).DoFinal(); + } + } + + public void Compute(ReadOnlySpan input, Span digestOut) + { + using (NuHash nuhash = new NuHash()) + { + nuhash.Update(input).DoFinal(digestOut); + } + } + + public static byte[] Compute(string input) + { + using (NuHash nuhash = new NuHash()) + { + return nuhash.Update(input).DoFinal(); + } + } + + public static void Compute(string input, Span digestOut) + { + using (NuHash nuhash = new NuHash()) + { + nuhash.Update(input).DoFinal(digestOut); + } + } + + /* ------------------------------------------------------------------------ */ + /* Utilities */ + /* ------------------------------------------------------------------------ */ + + private static readonly Lazy version = new Lazy(GetVersion); + + public static Version Version + { + get + { + return version.Value; + } + } + + private static Version GetVersion() + { + try + { + Version vers = Assembly.GetExecutingAssembly().GetName().Version; + if (!ReferenceEquals(vers, null)) + { + return new Version(vers.Major, vers.Minor, vers.Build); + } + } + catch { } + return new Version(0, 0, 0); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void CheckState(bool setFlag = false) + { + if (m_finished) + { + throw new InvalidOperationException("Computation is already finished!"); + } + if (setFlag) + { + m_finished = true; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void ToByteArray(ulong[] hash, Span output) + { + for (int i = 0; i < NUHASH_BYTES; ++i) + { + output[i] = (byte)(hash[i >> 3] >> (56 - ((i & 0x7) << 3))); + } + } + } +} diff --git a/libnuhash/csharp/NuHash/NuHash.csproj b/libnuhash/csharp/NuHash/NuHash.csproj new file mode 100644 index 0000000..81b9a41 --- /dev/null +++ b/libnuhash/csharp/NuHash/NuHash.csproj @@ -0,0 +1,21 @@ + + + + net6.0 + warnings + LibNuHash + NuHash Core Library + Copyright © LoRd_MuldeR <MuldeR2@GMX.de> 2023 + Muldersoft.com + LoRd_MuldeR + + + + true + + + + true + + + diff --git a/libnuhash/csharp/NuHashTest/NuHashTest.cs b/libnuhash/csharp/NuHashTest/NuHashTest.cs new file mode 100644 index 0000000..ca08534 --- /dev/null +++ b/libnuhash/csharp/NuHashTest/NuHashTest.cs @@ -0,0 +1,156 @@ +/******************************************************************************/ +/* NuHash, by LoRd_MuldeR */ +/* This work has been released under the CC0 1.0 Universal license! */ +/******************************************************************************/ + +using LibNuHash; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Numerics; +using System.Reflection; +using System.Text; + +namespace LibNuHashTest +{ + [TestClass] + public class NuHashTest + { + /* ------------------------------------------------------------------------ */ + /* Test functions */ + /* ------------------------------------------------------------------------ */ + + private static void RunTest(uint iterations, string expected, byte[] input) + { + using (NuHash nuhash = new NuHash()) + { + for (uint iter = 0; iter < iterations; ++iter) + { + nuhash.Update(input); + } + string digest = BitConverter.ToString(nuhash.DoFinal()); + Console.Out.WriteLine(string.Format("{0} - {1}", digest, expected.Equals(digest, StringComparison.OrdinalIgnoreCase) ? "OK" : "Failed!")); + Assert.AreEqual(expected, digest, true); + } + } + + private static void RunTest(uint iterations, string expected, string input) + { + RunTest(iterations, expected, Encoding.UTF8.GetBytes(input)); + } + + /* ------------------------------------------------------------------------ */ + /* Test cases */ + /* ------------------------------------------------------------------------ */ + + [TestMethod] + public void TestMethod0() + { + ulong[][] xorTable = (ulong[][]) typeof(NuHash).GetField("NUHASH_XOR", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null); + for (int i = 0; i < 257; ++i) + { + for (int j = 0; j < 257; ++j) + { + int distance = ComputeDistance(xorTable[i], xorTable[j]); + Assert.IsTrue((i == j) || (distance >= 182)); + } + } + } + + [TestMethod] + public void TestMethod1() + { + RunTest( + 0x0000001, + "D7-96-4F-E1-BE-C2-B5-EC-F2-1E-CC-88-C8-6C-E4-F1-E8-9F-B1-EF-36-69-D5-2E-34-EB-04-9D-7F-D6-C4-2D-4B-2B-BE-EE-B7-0D-12-C3-FC-AF-43-DD-22-29-AB-C9", + "" + ); + } + + [TestMethod] + public void TestMethod2() + { + RunTest( + 0x0000001, + "B3-F1-3F-53-40-34-AE-8D-64-5D-41-0E-88-28-67-37-61-FE-2D-69-72-18-87-9F-9E-A5-28-D9-76-BA-2E-15-A3-F7-48-51-05-E6-12-B9-A4-6C-B3-98-86-35-A7-0F", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + ); + } + + [TestMethod] + public void TestMethod3() + { + RunTest( + 0x0000001, + "63-70-34-76-F4-FF-CE-4A-8C-75-8D-0D-3B-91-A8-57-B9-A2-E3-43-3E-E8-64-F9-31-BA-32-8F-A7-24-7B-1B-0A-C9-C2-E0-27-92-43-B8-30-51-AA-FA-C6-A7-E7-10", + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" + ); + } + + [TestMethod] + public void TestMethod4() + { + RunTest( + 0x00F4240, + "C6-80-8A-EB-91-1C-88-37-CE-E2-E6-86-7E-58-9A-B2-85-26-A8-15-34-94-CF-35-A4-0C-4B-D6-E2-03-12-DA-33-CA-C4-A3-90-CD-3B-51-A2-EB-42-26-E6-0B-53-E1", + "a" + ); + } + + [TestMethod] + public void TestMethod5() + { + RunTest( + 0x1000000, + "BC-CA-6B-C8-D1-13-DD-3F-C1-71-D7-43-AC-7A-D2-D3-E6-31-63-EA-71-07-D3-C7-85-17-CF-5B-53-EE-0B-2F-4A-0F-E0-79-E6-A7-4D-F3-50-C6-67-B7-CF-E3-CF-09", + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno" + ); + } + + [TestMethod] + public void TestMethod6() + { + RunTest( + 0x1000000, + "56-77-0E-13-3B-9E-B4-20-5F-11-82-4A-D7-28-0F-5C-31-BC-04-DD-33-3D-18-44-B3-58-9A-B8-B9-4A-B9-5D-C0-9B-77-BE-9A-81-28-D7-F1-55-FA-73-DE-61-75-97", + "g4tB,=[TU%/|8lv_c5Y?F9Sqs1PnV#bNO6DW\\0em~p3E7" + ); + } + + [TestMethod] + public void TestMethod7() + { + RunTest( + 0x1000000, + "9A-85-79-BB-88-11-2B-2F-32-85-78-1A-61-34-8D-7B-04-A5-63-2F-EC-12-A7-3A-7E-0E-36-7A-55-67-94-A2-4A-32-CA-7B-B1-4D-A6-8E-AE-D8-3E-99-C2-F8-F4-C0", + Decode("pCxVpbBe2DPzGPunIMc01x0tRo3Kiuf8aFtU2vnDdmKpPTm/F7eyjBCiH+N0akpsepLRUuqIumvWZJae5kxHQsVR8lD0e0/ph22USyPwRRqa5JEPO7RxgpnJSeW+KJOYKtlzZVjAg0iPAxRAGyQepj/3Z6s3Bqz2ZrbdHAo1n1YV7PErfFddAu2oYxZ13JtcfQ1f/QWgbpCVhdITYQijAcjThKoJ9XBv3rkEtdswvAeO/olgJk5ZyzaGEXLixq86i3/6QTjf7i8yoSdpMSlDxJx3IUS4edCtl+DhDhkuIr2A6LH4TT7CfgyzgRLMwVPPeM481Vq7nevvzf8LJa7U") + ); + } + + [TestMethod] + public void TestMethod8() + { + RunTest( + 0x1000000, + "FB-F4-44-4B-03-29-F5-08-BF-C6-CF-44-92-0B-31-1A-71-8E-5F-4C-4C-1A-F9-78-E7-82-23-EC-35-79-36-5F-F5-D1-5C-16-BB-5A-33-D6-9C-B3-6F-3D-40-56-47-57", + Decode("tcib0bpmKRnSMO0mW8SRTRT3FjVaaf6ZpUnxlCu83EzdT8obiJyp9nMv/T9AORPas3H03n8CPWR4ehcKk9/rnwcEeYyYuCiArR/ylmu9Rdn6LFbO8IcjIurFJ9NjryTHtwbkdYN7vy6k7/USXWCVp1MRdLSgnuOuu1VyWaad1Yltj0oMHc0q++7Xw/MlYo6wssI4PGpvTjsI1IY2GFzgHoF3+GjbWFT/l35hwFHJbOWCvs8yQwE6XlBHoTTMDXCsxkSaPhAO7APibqr8fTcxS+a2wRWLBYWKZ/mrjeGiSBzLUmV2DxohqKNCQZCS0IQJLTNf2HyxuVfo1gsg50bp") + ); + } + + /* ------------------------------------------------------------------------ */ + /* Utilities */ + /* ------------------------------------------------------------------------ */ + + private static int ComputeDistance(ulong[] array1, ulong[] array2) + { + Assert.AreEqual(array1.Length, array2.Length); + int distance = 0; + for (int i = 0; i < array1.Length; ++i) + { + distance += BitOperations.PopCount(array1[i] ^ array2[i]); + } + return distance; + } + + private static byte[] Decode(string base64string) => Convert.FromBase64String(base64string); + } +} diff --git a/libnuhash/csharp/NuHashTest/NuHashTest.csproj b/libnuhash/csharp/NuHashTest/NuHashTest.csproj new file mode 100644 index 0000000..b93e8e8 --- /dev/null +++ b/libnuhash/csharp/NuHashTest/NuHashTest.csproj @@ -0,0 +1,24 @@ + + + + net6.0 + false + LibNuHashTest + NuHash Unit Tests + Copyright © LoRd_MuldeR <MuldeR2@GMX.de> 2023 + Muldersoft.com + LoRd_MuldeR + + + + + + + + + + + + + +