1/**
2 * Author......: See docs/credits.txt
3 * License.....: MIT
4 */
5
6#include "inc_vendor.h"
7#include "inc_types.h"
8#include "inc_platform.h"
9#include "inc_common.h"
10#include "inc_hash_streebog512.h"
11
12CONSTANT_VK u64a sbob512_sl64[8][256] =
13{
14  {
15    0xd031c397ce553fe6UL, 0x16ba5b01b006b525UL, 0xa89bade6296e70c8UL, 0x6a1f525d77d3435bUL,
16    0x6e103570573dfa0bUL, 0x660efb2a17fc95abUL, 0x76327a9e97634bf6UL, 0x4bad9d6462458bf5UL,
17    0xf1830caedbc3f748UL, 0xc5c8f542669131ffUL, 0x95044a1cdc48b0cbUL, 0x892962df3cf8b866UL,
18    0xb0b9e208e930c135UL, 0xa14fb3f0611a767cUL, 0x8d2605f21c160136UL, 0xd6b71922fecc549eUL,
19    0x37089438a5907d8bUL, 0x0b5da38e5803d49cUL, 0x5a5bcc9cea6f3cbcUL, 0xedae246d3b73ffe5UL,
20    0xd2b87e0fde22edceUL, 0x5e54abb1ca8185ecUL, 0x1de7f88fe80561b9UL, 0xad5e1a870135a08cUL,
21    0x2f2adbd665cecc76UL, 0x5780b5a782f58358UL, 0x3edc8a2eede47b3fUL, 0xc9d95c3506bee70fUL,
22    0x83be111d6c4e05eeUL, 0xa603b90959367410UL, 0x103c81b4809fde5dUL, 0x2c69b6027d0c774aUL,
23    0x399080d7d5c87953UL, 0x09d41e16487406b4UL, 0xcdd63b1826505e5fUL, 0xf99dc2f49b0298e8UL,
24    0x9cd0540a943cb67fUL, 0xbca84b7f891f17c5UL, 0x723d1db3b78df2a6UL, 0x78aa6e71e73b4f2eUL,
25    0x1433e699a071670dUL, 0x84f21be454620782UL, 0x98df3327b4d20f2fUL, 0xf049dce2d3769e5cUL,
26    0xdb6c60199656eb7aUL, 0x648746b2078b4783UL, 0x32cd23598dcbadcfUL, 0x1ea4955bf0c7da85UL,
27    0xe9a143401b9d46b5UL, 0xfd92a5d9bbec21b8UL, 0xc8138c790e0b8e1bUL, 0x2ee00b9a6d7ba562UL,
28    0xf85712b893b7f1fcUL, 0xeb28fed80bea949dUL, 0x564a65eb8a40ea4cUL, 0x6c9988e8474a2823UL,
29    0x4535898b121d8f2dUL, 0xabd8c03231accbf4UL, 0xba2e91cab9867cbdUL, 0x7960be3def8e263aUL,
30    0x0c11a977602fd6f0UL, 0xcb50e1ad16c93527UL, 0xeae22e94035ffd89UL, 0x2866d12f5de2ce1aUL,
31    0xff1b1841ab9bf390UL, 0x9f9339de8cfe0d43UL, 0x964727c8c48a0bf7UL, 0x524502c6aaae531cUL,
32    0x9b9c5ef3ac10b413UL, 0x4fa2fa4942ab32a5UL, 0x3f165a62e551122bUL, 0xc74148da76e6e3d7UL,
33    0x924840e5e464b2a7UL, 0xd372ae43d69784daUL, 0x233b72a105e11a86UL, 0xa48a04914941a638UL,
34    0xb4b68525c9de7865UL, 0xddeabaaca6cf8002UL, 0x0a9773c250b6bd88UL, 0xc284ffbb5ebd3393UL,
35    0x8ba0df472c8f6a4eUL, 0x2aef6cb74d951c32UL, 0x427983722a318d41UL, 0x73f7cdffbf389bb2UL,
36    0x074c0af9382c026cUL, 0x8a6a0f0b243a035aUL, 0x6fdae53c5f88931fUL, 0xc68b98967e538ac3UL,
37    0x44ff59c71aa8e639UL, 0xe2fce0ce439e9229UL, 0xa20cde2479d8cd40UL, 0x19e89fa2c8ebd8e9UL,
38    0xf446bbcff398270cUL, 0x43b3533e2284e455UL, 0xd82f0dcd8e945046UL, 0x51066f12b26ce820UL,
39    0xe73957af6bc5426dUL, 0x081ece5a40c16fa0UL, 0x3b193d4fc5bfab7bUL, 0x7fe66488df174d42UL,
40    0x0e9814ef705804d8UL, 0x8137ac857c39d7c6UL, 0xb1733244e185a821UL, 0x695c3f896f11f867UL,
41    0xf6cf0657e3eff524UL, 0x1aabf276d02963d5UL, 0x2da3664e75b91e5eUL, 0x0289bd981077d228UL,
42    0x90c1fd7df413608fUL, 0x3c5537b6fd93a917UL, 0xaa12107e3919a2e0UL, 0x0686dab530996b78UL,
43    0xdaa6b0559ee3826eUL, 0xc34e2ff756085a87UL, 0x6d5358a44fff4137UL, 0xfc587595b35948acUL,
44    0x7ca5095cc7d5f67eUL, 0xfb147f6c8b754ac0UL, 0xbfeb26ab91ddacf9UL, 0x6896efc567a49173UL,
45    0xca9a31e11e7c5c33UL, 0xbbe44186b13315a9UL, 0x0ddb793b689abfe4UL, 0x70b4a02ba7fa208eUL,
46    0xe47a3a7b7307f951UL, 0x8cecd5be14a36822UL, 0xeeed49b923b144d9UL, 0x17708b4db8b3dc31UL,
47    0x6088219f2765fed3UL, 0xb3fa8fdcf1f27a09UL, 0x910b2d31fca6099bUL, 0x0f52c4a378ed6dccUL,
48    0x50ccbf5ebad98134UL, 0x6bd582117f662a4fUL, 0x94ce9a50d4fdd9dfUL, 0x2b25bcfb45207526UL,
49    0x67c42b661f49fcbfUL, 0x492420fc723259ddUL, 0x03436dd418c2bb3cUL, 0x1f6e4517f872b391UL,
50    0xa08563bc69af1f68UL, 0xd43ea4baeebb86b6UL, 0x01cad04c08b56914UL, 0xac94cacb0980c998UL,
51    0x54c3d8739a373864UL, 0x26fec5c02dbacac2UL, 0xdea9d778be0d3b3eUL, 0x040f672d20eeb950UL,
52    0xe5b0ea377bb29045UL, 0xf30ab136cbb42560UL, 0x62019c0737122cfbUL, 0xe86b930c13282fa1UL,
53    0xcc1ceb542ee5374bUL, 0x538fd28aa21b3a08UL, 0x1b61223ad89c0ac1UL, 0x36c24474ad25149fUL,
54    0x7a23d3e9f74c9d06UL, 0xbe21f6e79968c5edUL, 0xcf5f868036278c77UL, 0xf705d61beb5a9c30UL,
55    0x4d2b47d152dce08dUL, 0x5f9e7bfdc234ecf8UL, 0x247778583dcd18eaUL, 0x867ba67c4415d5aaUL,
56    0x4ce1979d5a698999UL, 0x0000000000000000UL, 0xec64f42133c696f1UL, 0xb57c5569c16b1171UL,
57    0xc1c7926f467f88afUL, 0x654d96fe0f3e2e97UL, 0x15f936d5a8c40e19UL, 0xb8a72c52a9f1ae95UL,
58    0xa9517daa21db19dcUL, 0x58d27104fa18ee94UL, 0x5918a148f2ad8780UL, 0x5cdd1629daf657c4UL,
59    0x8274c15164fb6cfaUL, 0xd1fb13dbc6e056f2UL, 0x7d6fd910cf609f6aUL, 0xb63f38bdd9a9aa4dUL,
60    0x3d9fe7faf526c003UL, 0x74bbc706871499deUL, 0xdf630734b6b8522aUL, 0x3ad3ed03cd0ac26fUL,
61    0xfadeaf2083c023d4UL, 0xc00d42234ecae1bbUL, 0x8538cba85cd76e96UL, 0xc402250e6e2458ebUL,
62    0x47bc3413026a5d05UL, 0xafd7a71f114272a4UL, 0x978df784cc3f62e3UL, 0xb96dfc1ea144c781UL,
63    0x21b2cf391596c8aeUL, 0x318e4e8d950916f3UL, 0xce9556cc3e92e563UL, 0x385a509bdd7d1047UL,
64    0x358129a0b5e7afa3UL, 0xe6f387e363702b79UL, 0xe0755d5653e94001UL, 0x7be903a5fff9f412UL,
65    0x12b53c2c90e80c75UL, 0x3307f315857ec4dbUL, 0x8fafb86a0c61d31eUL, 0xd9e5dd8186213952UL,
66    0x77f8aad29fd622e2UL, 0x25bda814357871feUL, 0x7571174a8fa1f0caUL, 0x137fec60985d6561UL,
67    0x30449ec19dbc7fe7UL, 0xa540d4dd41f4cf2cUL, 0xdc206ae0ae7ae916UL, 0x5b911cd0e2da55a8UL,
68    0xb2305f90f947131dUL, 0x344bf9ecbd52c6b7UL, 0x5d17c665d2433ed0UL, 0x18224feec05eb1fdUL,
69    0x9e59e992844b6457UL, 0x9a568ebfa4a5dd07UL, 0xa3c60e68716da454UL, 0x7e2cb4c4d7a22456UL,
70    0x87b176304ca0bcbeUL, 0x413aeea632f3367dUL, 0x9915e36bbc67663bUL, 0x40f03eea3a465f69UL,
71    0x1c2d28c3e0b008adUL, 0x4e682a054a1e5bb1UL, 0x05c5b761285bd044UL, 0xe1bf8d1a5b5c2915UL,
72    0xf2c0617ac3014c74UL, 0xb7f5e8f1d11cc359UL, 0x63cb4c4b3fa745efUL, 0x9d1a84469c89df6bUL,
73    0xe33630824b2bfb3dUL, 0xd5f474f6e60eefa2UL, 0xf58c6b83fb2d4e18UL, 0x4676e45f0adf3411UL,
74    0x20781f751d23a1baUL, 0xbd629b3381aa7ed1UL, 0xae1d775319f71bb0UL, 0xfed1c80da32e9a84UL,
75    0x5509083f92825170UL, 0x29ac01635557a70eUL, 0xa7c9694551831d04UL, 0x8e65682604d4ba0aUL,
76    0x11f651f8882ab749UL, 0xd77dc96ef6793d8aUL, 0xef2799f52b042dcdUL, 0x48eef0b07a8730c9UL,
77    0x22f1a2ed0d547392UL, 0x6142f1d32fd097c7UL, 0x4a674d286af0e2e1UL, 0x80fd7cc9748cbed2UL,
78    0x717e7067af4f499aUL, 0x938290a9ecd1dbb3UL, 0x88e3b293344dd172UL, 0x2734158c250fa3d6UL,
79  },
80  {
81    0x7e37e62dfc7d40c3UL, 0x776f25a4ee939e5bUL, 0xe045c850dd8fb5adUL, 0x86ed5ba711ff1952UL,
82    0xe91d0bd9cf616b35UL, 0x37e0ab256e408ffbUL, 0x9607f6c031025a7aUL, 0x0b02f5e116d23c9dUL,
83    0xf3d8486bfb50650cUL, 0x621cff27c40875f5UL, 0x7d40cb71fa5fd34aUL, 0x6daa6616daa29062UL,
84    0x9f5f354923ec84e2UL, 0xec847c3dc507c3b3UL, 0x025a3668043ce205UL, 0xa8bf9e6c4dac0b19UL,
85    0xfa808be2e9bebb94UL, 0xb5b99c5277c74fa3UL, 0x78d9bc95f0397bccUL, 0xe332e50cdbad2624UL,
86    0xc74fce129332797eUL, 0x1729eceb2ea709abUL, 0xc2d6b9f69954d1f8UL, 0x5d898cbfbab8551aUL,
87    0x859a76fb17dd8adbUL, 0x1be85886362f7fb5UL, 0xf6413f8ff136cd8aUL, 0xd3110fa5bbb7e35cUL,
88    0x0a2feed514cc4d11UL, 0xe83010edcd7f1ab9UL, 0xa1e75de55f42d581UL, 0xeede4a55c13b21b6UL,
89    0xf2f5535ff94e1480UL, 0x0cc1b46d1888761eUL, 0xbce15fdb6529913bUL, 0x2d25e8975a7181c2UL,
90    0x71817f1ce2d7a554UL, 0x2e52c5cb5c53124bUL, 0xf9f7a6beef9c281dUL, 0x9e722e7d21f2f56eUL,
91    0xce170d9b81dca7e6UL, 0x0e9b82051cb4941bUL, 0x1e712f623c49d733UL, 0x21e45cfa42f9f7dcUL,
92    0xcb8e7a7f8bba0f60UL, 0x8e98831a010fb646UL, 0x474ccf0d8e895b23UL, 0xa99285584fb27a95UL,
93    0x8cc2b57205335443UL, 0x42d5b8e984eff3a5UL, 0x012d1b34021e718cUL, 0x57a6626aae74180bUL,
94    0xff19fc06e3d81312UL, 0x35ba9d4d6a7c6dfeUL, 0xc9d44c178f86ed65UL, 0x506523e6a02e5288UL,
95    0x03772d5c06229389UL, 0x8b01f4fe0b691ec0UL, 0xf8dabd8aed825991UL, 0x4c4e3aec985b67beUL,
96    0xb10df0827fbf96a9UL, 0x6a69279ad4f8dae1UL, 0xe78689dcd3d5ff2eUL, 0x812e1a2b1fa553d1UL,
97    0xfbad90d6eba0ca18UL, 0x1ac543b234310e39UL, 0x1604f7df2cb97827UL, 0xa6241c6951189f02UL,
98    0x753513cceaaf7c5eUL, 0x64f2a59fc84c4efaUL, 0x247d2b1e489f5f5aUL, 0xdb64d718ab474c48UL,
99    0x79f4a7a1f2270a40UL, 0x1573da832a9bebaeUL, 0x3497867968621c72UL, 0x514838d2a2302304UL,
100    0xf0af6537fd72f685UL, 0x1d06023e3a6b44baUL, 0x678588c3ce6edd73UL, 0x66a893f7cc70acffUL,
101    0xd4d24e29b5eda9dfUL, 0x3856321470ea6a6cUL, 0x07c3418c0e5a4a83UL, 0x2bcbb22f5635bacdUL,
102    0x04b46cd00878d90aUL, 0x06ee5ab80c443b0fUL, 0x3b211f4876c8f9e5UL, 0x0958c38912eede98UL,
103    0xd14b39cdbf8b0159UL, 0x397b292072f41be0UL, 0x87c0409313e168deUL, 0xad26e98847caa39fUL,
104    0x4e140c849c6785bbUL, 0xd5ff551db7f3d853UL, 0xa0ca46d15d5ca40dUL, 0xcd6020c787fe346fUL,
105    0x84b76dcf15c3fb57UL, 0xdefda0fca121e4ceUL, 0x4b8d7b6096012d3dUL, 0x9ac642ad298a2c64UL,
106    0x0875d8bd10f0af14UL, 0xb357c6ea7b8374acUL, 0x4d6321d89a451632UL, 0xeda96709c719b23fUL,
107    0xf76c24bbf328bc06UL, 0xc662d526912c08f2UL, 0x3ce25ec47892b366UL, 0xb978283f6f4f39bdUL,
108    0xc08c8f9e9d6833fdUL, 0x4f3917b09e79f437UL, 0x593de06fb2c08c10UL, 0xd6887841b1d14bdaUL,
109    0x19b26eee32139db0UL, 0xb494876675d93e2fUL, 0x825937771987c058UL, 0x90e9ac783d466175UL,
110    0xf1827e03ff6c8709UL, 0x945dc0a8353eb87fUL, 0x4516f9658ab5b926UL, 0x3f9573987eb020efUL,
111    0xb855330b6d514831UL, 0x2ae6a91b542bcb41UL, 0x6331e413c6160479UL, 0x408f8e8180d311a0UL,
112    0xeff35161c325503aUL, 0xd06622f9bd9570d5UL, 0x8876d9a20d4b8d49UL, 0xa5533135573a0c8bUL,
113    0xe168d364df91c421UL, 0xf41b09e7f50a2f8fUL, 0x12b09b0f24c1a12dUL, 0xda49cc2ca9593dc4UL,
114    0x1f5c34563e57a6bfUL, 0x54d14f36a8568b82UL, 0xaf7cdfe043f6419aUL, 0xea6a2685c943f8bcUL,
115    0xe5dcbfb4d7e91d2bUL, 0xb27addde799d0520UL, 0x6b443caed6e6ab6dUL, 0x7bae91c9f61be845UL,
116    0x3eb868ac7cae5163UL, 0x11c7b65322e332a4UL, 0xd23c1491b9a992d0UL, 0x8fb5982e0311c7caUL,
117    0x70ac6428e0c9d4d8UL, 0x895bc2960f55fcc5UL, 0x76423e90ec8defd7UL, 0x6ff0507ede9e7267UL,
118    0x3dcf45f07a8cc2eaUL, 0x4aa06054941f5cb1UL, 0x5810fb5bb0defd9cUL, 0x5efea1e3bc9ac693UL,
119    0x6edd4b4adc8003ebUL, 0x741808f8e8b10dd2UL, 0x145ec1b728859a22UL, 0x28bc9f7350172944UL,
120    0x270a06424ebdccd3UL, 0x972aedf4331c2bf6UL, 0x059977e40a66a886UL, 0x2550302a4a812ed6UL,
121    0xdd8a8da0a7037747UL, 0xc515f87a970e9b7bUL, 0x3023eaa9601ac578UL, 0xb7e3aa3a73fbada6UL,
122    0x0fb699311eaae597UL, 0x0000000000000000UL, 0x310ef19d6204b4f4UL, 0x229371a644db6455UL,
123    0x0decaf591a960792UL, 0x5ca4978bb8a62496UL, 0x1c2b190a38753536UL, 0x41a295b582cd602cUL,
124    0x3279dcc16426277dUL, 0xc1a194aa9f764271UL, 0x139d803b26dfd0a1UL, 0xae51c4d441e83016UL,
125    0xd813fa44ad65dfc1UL, 0xac0bf2bc45d4d213UL, 0x23be6a9246c515d9UL, 0x49d74d08923dcf38UL,
126    0x9d05032127d066e7UL, 0x2f7fdeff5e4d63c7UL, 0xa47e2a0155247d07UL, 0x99b16ff12fa8bfedUL,
127    0x4661d4398c972aafUL, 0xdfd0bbc8a33f9542UL, 0xdca79694a51d06cbUL, 0xb020ebb67da1e725UL,
128    0xba0f0563696daa34UL, 0xe4f1a480d5f76ca7UL, 0xc438e34e9510eaf7UL, 0x939e81243b64f2fcUL,
129    0x8defae46072d25cfUL, 0x2c08f3a3586ff04eUL, 0xd7a56375b3cf3a56UL, 0x20c947ce40e78650UL,
130    0x43f8a3dd86f18229UL, 0x568b795eac6a6987UL, 0x8003011f1dbb225dUL, 0xf53612d3f7145e03UL,
131    0x189f75da300dec3cUL, 0x9570db9c3720c9f3UL, 0xbb221e576b73dbb8UL, 0x72f65240e4f536ddUL,
132    0x443be25188abc8aaUL, 0xe21ffe38d9b357a8UL, 0xfd43ca6ee7e4f117UL, 0xcaa3614b89a47eecUL,
133    0xfe34e732e1c6629eUL, 0x83742c431b99b1d4UL, 0xcf3a16af83c2d66aUL, 0xaae5a8044990e91cUL,
134    0x26271d764ca3bd5fUL, 0x91c4b74c3f5810f9UL, 0x7c6dd045f841a2c6UL, 0x7f1afd19fe63314fUL,
135    0xc8f957238d989ce9UL, 0xa709075d5306ee8eUL, 0x55fc5402aa48fa0eUL, 0x48fa563c9023beb4UL,
136    0x65dfbeabca523f76UL, 0x6c877d22d8bce1eeUL, 0xcc4d3bf385e045e3UL, 0xbebb69b36115733eUL,
137    0x10eaad6720fd4328UL, 0xb6ceb10e71e5dc2aUL, 0xbdcc44ef6737e0b7UL, 0x523f158ea412b08dUL,
138    0x989c74c52db6ce61UL, 0x9beb59992b945de8UL, 0x8a2cefca09776f4cUL, 0xa3bd6b8d5b7e3784UL,
139    0xeb473db1cb5d8930UL, 0xc3fba2c29b4aa074UL, 0x9c28181525ce176bUL, 0x683311f2d0c438e4UL,
140    0x5fd3bad7be84b71fUL, 0xfc6ed15ae5fa809bUL, 0x36cdb0116c5efe77UL, 0x29918447520958c8UL,
141    0xa29070b959604608UL, 0x53120ebaa60cc101UL, 0x3a0c047c74d68869UL, 0x691e0ac6d2da4968UL,
142    0x73db4974e6eb4751UL, 0x7a838afdf40599c9UL, 0x5a4acd33b4e21f99UL, 0x6046c94fc03497f0UL,
143    0xe6ab92e8d1cb8ea2UL, 0x3354c7f5663856f1UL, 0xd93ee170af7bae4dUL, 0x616bd27bc22ae67cUL,
144    0x92b39a10397a8370UL, 0xabc8b3304b8e9890UL, 0xbf967287630b02b2UL, 0x5b67d607b6fc6e15UL,
145  },
146  {
147    0x8ab0a96846e06a6dUL, 0x43c7e80b4bf0b33aUL, 0x08c9b3546b161ee5UL, 0x39f1c235eba990beUL,
148    0xc1bef2376606c7b2UL, 0x2c209233614569aaUL, 0xeb01523b6fc3289aUL, 0x946953ab935aceddUL,
149    0x272838f63e13340eUL, 0x8b0455eca12ba052UL, 0x77a1b2c4978ff8a2UL, 0xa55122ca13e54086UL,
150    0x2276135862d3f1cdUL, 0xdb8ddfde08b76cfeUL, 0x5d1e12c89e4a178aUL, 0x0e56816b03969867UL,
151    0xee5f79953303ed59UL, 0xafed748bab78d71dUL, 0x6d929f2df93e53eeUL, 0xf5d8a8f8ba798c2aUL,
152    0xf619b1698e39cf6bUL, 0x95ddaf2f749104e2UL, 0xec2a9c80e0886427UL, 0xce5c8fd8825b95eaUL,
153    0xc4e0d9993ac60271UL, 0x4699c3a5173076f9UL, 0x3d1b151f50a29f42UL, 0x9ed505ea2bc75946UL,
154    0x34665acfdc7f4b98UL, 0x61b1fb53292342f7UL, 0xc721c0080e864130UL, 0x8693cd1696fd7b74UL,
155    0x872731927136b14bUL, 0xd3446c8a63a1721bUL, 0x669a35e8a6680e4aUL, 0xcab658f239509a16UL,
156    0xa4e5de4ef42e8ab9UL, 0x37a7435ee83f08d9UL, 0x134e6239e26c7f96UL, 0x82791a3c2df67488UL,
157    0x3f6ef00a8329163cUL, 0x8e5a7e42fdeb6591UL, 0x5caaee4c7981ddb5UL, 0x19f234785af1e80dUL,
158    0x255ddde3ed98bd70UL, 0x50898a32a99cccacUL, 0x28ca4519da4e6656UL, 0xae59880f4cb31d22UL,
159    0x0d9798fa37d6db26UL, 0x32f968f0b4ffcd1aUL, 0xa00f09644f258545UL, 0xfa3ad5175e24de72UL,
160    0xf46c547c5db24615UL, 0x713e80fbff0f7e20UL, 0x7843cf2b73d2aafaUL, 0xbd17ea36aedf62b4UL,
161    0xfd111bacd16f92cfUL, 0x4abaa7dbc72d67e0UL, 0xb3416b5dad49fad3UL, 0xbca316b24914a88bUL,
162    0x15d150068aecf914UL, 0xe27c1debe31efc40UL, 0x4fe48c759beda223UL, 0x7edcfd141b522c78UL,
163    0x4e5070f17c26681cUL, 0xe696cac15815f3bcUL, 0x35d2a64b3bb481a7UL, 0x800cff29fe7dfdf6UL,
164    0x1ed9fac3d5baa4b0UL, 0x6c2663a91ef599d1UL, 0x03c1199134404341UL, 0xf7ad4ded69f20554UL,
165    0xcd9d9649b61bd6abUL, 0xc8c3bde7eadb1368UL, 0xd131899fb02afb65UL, 0x1d18e352e1fae7f1UL,
166    0xda39235aef7ca6c1UL, 0xa1bbf5e0a8ee4f7aUL, 0x91377805cf9a0b1eUL, 0x3138716180bf8e5bUL,
167    0xd9f83acbdb3ce580UL, 0x0275e515d38b897eUL, 0x472d3f21f0fbbcc6UL, 0x2d946eb7868ea395UL,
168    0xba3c248d21942e09UL, 0xe7223645bfde3983UL, 0xff64feb902e41bb1UL, 0xc97741630d10d957UL,
169    0xc3cb1722b58d4eccUL, 0xa27aec719cae0c3bUL, 0x99fecb51a48c15fbUL, 0x1465ac826d27332bUL,
170    0xe1bd047ad75ebf01UL, 0x79f733af941960c5UL, 0x672ec96c41a3c475UL, 0xc27feba6524684f3UL,
171    0x64efd0fd75e38734UL, 0xed9e60040743ae18UL, 0xfb8e2993b9ef144dUL, 0x38453eb10c625a81UL,
172    0x6978480742355c12UL, 0x48cf42ce14a6ee9eUL, 0x1cac1fd606312dceUL, 0x7b82d6ba4792e9bbUL,
173    0x9d141c7b1f871a07UL, 0x5616b80dc11c4a2eUL, 0xb849c198f21fa777UL, 0x7ca91801c8d9a506UL,
174    0xb1348e487ec273adUL, 0x41b20d1e987b3a44UL, 0x7460ab55a3cfbbe3UL, 0x84e628034576f20aUL,
175    0x1b87d16d897a6173UL, 0x0fe27defe45d5258UL, 0x83cde6b8ca3dbeb7UL, 0x0c23647ed01d1119UL,
176    0x7a362a3ea0592384UL, 0xb61f40f3f1893f10UL, 0x75d457d1440471dcUL, 0x4558da34237035b8UL,
177    0xdca6116587fc2043UL, 0x8d9b67d3c9ab26d0UL, 0x2b0b5c88ee0e2517UL, 0x6fe77a382ab5da90UL,
178    0x269cc472d9d8fe31UL, 0x63c41e46faa8cb89UL, 0xb7abbc771642f52fUL, 0x7d1de4852f126f39UL,
179    0xa8c6ba3024339ba0UL, 0x600507d7cee888c8UL, 0x8fee82c61a20afaeUL, 0x57a2448926d78011UL,
180    0xfca5e72836a458f0UL, 0x072bcebb8f4b4cbdUL, 0x497bbe4af36d24a1UL, 0x3cafe99bb769557dUL,
181    0x12fa9ebd05a7b5a9UL, 0xe8c04baa5b836bdbUL, 0x4273148fac3b7905UL, 0x908384812851c121UL,
182    0xe557d3506c55b0fdUL, 0x72ff996acb4f3d61UL, 0x3eda0c8e64e2dc03UL, 0xf0868356e6b949e9UL,
183    0x04ead72abb0b0ffcUL, 0x17a4b5135967706aUL, 0xe3c8e16f04d5367fUL, 0xf84f30028daf570cUL,
184    0x1846c8fcbd3a2232UL, 0x5b8120f7f6ca9108UL, 0xd46fa231ecea3ea6UL, 0x334d947453340725UL,
185    0x58403966c28ad249UL, 0xbed6f3a79a9f21f5UL, 0x68ccb483a5fe962dUL, 0xd085751b57e1315aUL,
186    0xfed0023de52fd18eUL, 0x4b0e5b5f20e6addfUL, 0x1a332de96eb1ab4cUL, 0xa3ce10f57b65c604UL,
187    0x108f7ba8d62c3cd7UL, 0xab07a3a11073d8e1UL, 0x6b0dad1291bed56cUL, 0xf2f366433532c097UL,
188    0x2e557726b2cee0d4UL, 0x0000000000000000UL, 0xcb02a476de9b5029UL, 0xe4e32fd48b9e7ac2UL,
189    0x734b65ee2c84f75eUL, 0x6e5386bccd7e10afUL, 0x01b4fc84e7cbca3fUL, 0xcfe8735c65905fd5UL,
190    0x3613bfda0ff4c2e6UL, 0x113b872c31e7f6e8UL, 0x2fe18ba255052aebUL, 0xe974b72ebc48a1e4UL,
191    0x0abc5641b89d979bUL, 0xb46aa5e62202b66eUL, 0x44ec26b0c4bbff87UL, 0xa6903b5b27a503c7UL,
192    0x7f680190fc99e647UL, 0x97a84a3aa71a8d9cUL, 0xdd12ede16037ea7cUL, 0xc554251ddd0dc84eUL,
193    0x88c54c7d956be313UL, 0x4d91696048662b5dUL, 0xb08072cc9909b992UL, 0xb5de5962c5c97c51UL,
194    0x81b803ad19b637c9UL, 0xb2f597d94a8230ecUL, 0x0b08aac55f565da4UL, 0xf1327fd2017283d6UL,
195    0xad98919e78f35e63UL, 0x6ab9519676751f53UL, 0x24e921670a53774fUL, 0xb9fd3d1c15d46d48UL,
196    0x92f66194fbda485fUL, 0x5a35dc7311015b37UL, 0xded3f4705477a93dUL, 0xc00a0eb381cd0d8dUL,
197    0xbb88d809c65fe436UL, 0x16104997beacba55UL, 0x21b70ac95693b28cUL, 0x59f4c5e225411876UL,
198    0xd5db5eb50b21f499UL, 0x55d7a19cf55c096fUL, 0xa97246b4c3f8519fUL, 0x8552d487a2bd3835UL,
199    0x54635d181297c350UL, 0x23c2efdc85183bf2UL, 0x9f61f96ecc0c9379UL, 0x534893a39ddc8fedUL,
200    0x5edf0b59aa0a54cbUL, 0xac2c6d1a9f38945cUL, 0xd7aebba0d8aa7de7UL, 0x2abfa00c09c5ef28UL,
201    0xd84cc64f3cf72fbfUL, 0x2003f64db15878b3UL, 0xa724c7dfc06ec9f8UL, 0x069f323f68808682UL,
202    0xcc296acd51d01c94UL, 0x055e2bae5cc0c5c3UL, 0x6270e2c21d6301b6UL, 0x3b842720382219c0UL,
203    0xd2f0900e846ab824UL, 0x52fc6f277a1745d2UL, 0xc6953c8ce94d8b0fUL, 0xe009f8fe3095753eUL,
204    0x655b2c7992284d0bUL, 0x984a37d54347dfc4UL, 0xeab5aebf8808e2a5UL, 0x9a3fd2c090cc56baUL,
205    0x9ca0e0fff84cd038UL, 0x4c2595e4afade162UL, 0xdf6708f4b3bc6302UL, 0xbf620f237d54ebcaUL,
206    0x93429d101c118260UL, 0x097d4fd08cddd4daUL, 0x8c2f9b572e60ecefUL, 0x708a7c7f18c4b41fUL,
207    0x3a30dba4dfe9d3ffUL, 0x4006f19a7fb0f07bUL, 0x5f6bf7dd4dc19ef4UL, 0x1f6d064732716e8fUL,
208    0xf9fbcc866a649d33UL, 0x308c8de567744464UL, 0x8971b0f972a0292cUL, 0xd61a47243f61b7d8UL,
209    0xefeb8511d4c82766UL, 0x961cb6be40d147a3UL, 0xaab35f25f7b812deUL, 0x76154e407044329dUL,
210    0x513d76b64e570693UL, 0xf3479ac7d2f90aa8UL, 0x9b8b2e4477079c85UL, 0x297eb99d3d85ac69UL,
211  },
212  {
213    0x3ef29d249b2c0a19UL, 0xe9e16322b6f8622fUL, 0x5536994047757f7aUL, 0x9f4d56d5a47b0b33UL,
214    0x822567466aa1174cUL, 0xb8f5057deb082fb2UL, 0xcc48c10bf4475f53UL, 0x373088d4275dec3aUL,
215    0x968f4325180aed10UL, 0x173d232cf7016151UL, 0xae4ed09f946fcc13UL, 0xfd4b4741c4539873UL,
216    0x1b5b3f0dd9933765UL, 0x2ffcb0967b644052UL, 0xe02376d20a89840cUL, 0xa3ae3a70329b18d7UL,
217    0x419cbd2335de8526UL, 0xfafebf115b7c3199UL, 0x0397074f85aa9b0dUL, 0xc58ad4fb4836b970UL,
218    0xbec60be3fc4104a8UL, 0x1eff36dc4b708772UL, 0x131fdc33ed8453b6UL, 0x0844e33e341764d3UL,
219    0x0ff11b6eab38cd39UL, 0x64351f0a7761b85aUL, 0x3b5694f509cfba0eUL, 0x30857084b87245d0UL,
220    0x47afb3bd2297ae3cUL, 0xf2ba5c2f6f6b554aUL, 0x74bdc4761f4f70e1UL, 0xcfdfc64471edc45eUL,
221    0xe610784c1dc0af16UL, 0x7aca29d63c113f28UL, 0x2ded411776a859afUL, 0xac5f211e99a3d5eeUL,
222    0xd484f949a87ef33bUL, 0x3ce36ca596e013e4UL, 0xd120f0983a9d432cUL, 0x6bc40464dc597563UL,
223    0x69d5f5e5d1956c9eUL, 0x9ae95f043698bb24UL, 0xc9ecc8da66a4ef44UL, 0xd69508c8a5b2eac6UL,
224    0xc40c2235c0503b80UL, 0x38c193ba8c652103UL, 0x1ceec75d46bc9e8fUL, 0xd331011937515ad1UL,
225    0xd8e2e56886eca50fUL, 0xb137108d5779c991UL, 0x709f3b6905ca4206UL, 0x4feb50831680caefUL,
226    0xec456af3241bd238UL, 0x58d673afe181abbeUL, 0x242f54e7cad9bf8cUL, 0x0211f1810dcc19fdUL,
227    0x90bc4dbb0f43c60aUL, 0x9518446a9da0761dUL, 0xa1bfcbf13f57012aUL, 0x2bde4f8961e172b5UL,
228    0x27b853a84f732481UL, 0xb0b1e643df1f4b61UL, 0x18cc38425c39ac68UL, 0xd2b7f7d7bf37d821UL,
229    0x3103864a3014c720UL, 0x14aa246372abfa5cUL, 0x6e600db54ebac574UL, 0x394765740403a3f3UL,
230    0x09c215f0bc71e623UL, 0x2a58b947e987f045UL, 0x7b4cdf18b477bdd8UL, 0x9709b5eb906c6fe0UL,
231    0x73083c268060d90bUL, 0xfedc400e41f9037eUL, 0x284948c6e44be9b8UL, 0x728ecae808065bfbUL,
232    0x06330e9e17492b1aUL, 0x5950856169e7294eUL, 0xbae4f4fce6c4364fUL, 0xca7bcf95e30e7449UL,
233    0x7d7fd186a33e96c2UL, 0x52836110d85ad690UL, 0x4dfaa1021b4cd312UL, 0x913abb75872544faUL,
234    0xdd46ecb9140f1518UL, 0x3d659a6b1e869114UL, 0xc23f2cabd719109aUL, 0xd713fe062dd46836UL,
235    0xd0a60656b2fbc1dcUL, 0x221c5a79dd909496UL, 0xefd26dbca1b14935UL, 0x0e77eda0235e4fc9UL,
236    0xcbfd395b6b68f6b9UL, 0x0de0eaefa6f4d4c4UL, 0x0422ff1f1a8532e7UL, 0xf969b85eded6aa94UL,
237    0x7f6e2007aef28f3fUL, 0x3ad0623b81a938feUL, 0x6624ee8b7aada1a7UL, 0xb682e8ddc856607bUL,
238    0xa78cc56f281e2a30UL, 0xc79b257a45faa08dUL, 0x5b4174e0642b30b3UL, 0x5f638bff7eae0254UL,
239    0x4bc9af9c0c05f808UL, 0xce59308af98b46aeUL, 0x8fc58da9cc55c388UL, 0x803496c7676d0eb1UL,
240    0xf33caae1e70dd7baUL, 0xbb6202326ea2b4bfUL, 0xd5020f87201871cbUL, 0x9d5ca754a9b712ceUL,
241    0x841669d87de83c56UL, 0x8a6184785eb6739fUL, 0x420bba6cb0741e2bUL, 0xf12d5b60eac1ce47UL,
242    0x76ac35f71283691cUL, 0x2c6bb7d9fecedb5fUL, 0xfccdb18f4c351a83UL, 0x1f79c012c3160582UL,
243    0xf0abadae62a74cb7UL, 0xe1a5801c82ef06fcUL, 0x67a21845f2cb2357UL, 0x5114665f5df04d9dUL,
244    0xbf40fd2d74278658UL, 0xa0393d3fb73183daUL, 0x05a409d192e3b017UL, 0xa9fb28cf0b4065f9UL,
245    0x25a9a22942bf3d7cUL, 0xdb75e22703463e02UL, 0xb326e10c5ab5d06cUL, 0xe7968e8295a62de6UL,
246    0xb973f3b3636ead42UL, 0xdf571d3819c30ce5UL, 0xee549b7229d7cbc5UL, 0x12992afd65e2d146UL,
247    0xf8ef4e9056b02864UL, 0xb7041e134030e28bUL, 0xc02edd2adad50967UL, 0x932b4af48ae95d07UL,
248    0x6fe6fb7bc6dc4784UL, 0x239aacb755f61666UL, 0x401a4bedbdb807d6UL, 0x485ea8d389af6305UL,
249    0xa41bc220adb4b13dUL, 0x753b32b89729f211UL, 0x997e584bb3322029UL, 0x1d683193ceda1c7fUL,
250    0xff5ab6c0c99f818eUL, 0x16bbd5e27f67e3a1UL, 0xa59d34ee25d233cdUL, 0x98f8ae853b54a2d9UL,
251    0x6df70afacb105e79UL, 0x795d2e99b9bba425UL, 0x8e437b6744334178UL, 0x0186f6ce886682f0UL,
252    0xebf092a3bb347bd2UL, 0xbcd7fa62f18d1d55UL, 0xadd9d7d011c5571eUL, 0x0bd3e471b1bdffdeUL,
253    0xaa6c2f808eeafef4UL, 0x5ee57d31f6c880a4UL, 0xf50fa47ff044fca0UL, 0x1addc9c351f5b595UL,
254    0xea76646d3352f922UL, 0x0000000000000000UL, 0x85909f16f58ebea6UL, 0x46294573aaf12cccUL,
255    0x0a5512bf39db7d2eUL, 0x78dbd85731dd26d5UL, 0x29cfbe086c2d6b48UL, 0x218b5d36583a0f9bUL,
256    0x152cd2adfacd78acUL, 0x83a39188e2c795bcUL, 0xc3b9da655f7f926aUL, 0x9ecba01b2c1d89c3UL,
257    0x07b5f8509f2fa9eaUL, 0x7ee8d6c926940dcfUL, 0x36b67e1aaf3b6ecaUL, 0x86079859702425abUL,
258    0xfb7849dfd31ab369UL, 0x4c7c57cc932a51e2UL, 0xd96413a60e8a27ffUL, 0x263ea566c715a671UL,
259    0x6c71fc344376dc89UL, 0x4a4f595284637af8UL, 0xdaf314e98b20bcf2UL, 0x572768c14ab96687UL,
260    0x1088db7c682ec8bbUL, 0x887075f9537a6a62UL, 0x2e7a4658f302c2a2UL, 0x619116dbe582084dUL,
261    0xa87dde018326e709UL, 0xdcc01a779c6997e8UL, 0xedc39c3dac7d50c8UL, 0xa60a33a1a078a8c0UL,
262    0xc1a82be452b38b97UL, 0x3f746bea134a88e9UL, 0xa228ccbebafd9a27UL, 0xabead94e068c7c04UL,
263    0xf48952b178227e50UL, 0x5cf48cb0fb049959UL, 0x6017e0156de48abdUL, 0x4438b4f2a73d3531UL,
264    0x8c528ae649ff5885UL, 0xb515ef924dfcfb76UL, 0x0c661c212e925634UL, 0xb493195cc59a7986UL,
265    0x9cda519a21d1903eUL, 0x32948105b5be5c2dUL, 0x194ace8cd45f2e98UL, 0x438d4ca238129cdbUL,
266    0x9b6fa9cabefe39d4UL, 0x81b26009ef0b8c41UL, 0xded1ebf691a58e15UL, 0x4e6da64d9ee6481fUL,
267    0x54b06f8ecf13fd8aUL, 0x49d85e1d01c9e1f5UL, 0xafc826511c094ee3UL, 0xf698a33075ee67adUL,
268    0x5ac7822eec4db243UL, 0x8dd47c28c199da75UL, 0x89f68337db1ce892UL, 0xcdce37c57c21dda3UL,
269    0x530597de503c5460UL, 0x6a42f2aa543ff793UL, 0x5d727a7e73621ba9UL, 0xe232875307459df1UL,
270    0x56a19e0fc2dfe477UL, 0xc61dd3b4cd9c227dUL, 0xe5877f03986a341bUL, 0x949eb2a415c6f4edUL,
271    0x6206119460289340UL, 0x6380e75ae84e11b0UL, 0x8be772b6d6d0f16fUL, 0x50929091d596cf6dUL,
272    0xe86795ec3e9ee0dfUL, 0x7cf927482b581432UL, 0xc86a3e14eec26db4UL, 0x7119cda78dacc0f6UL,
273    0xe40189cd100cb6ebUL, 0x92adbc3a028fdff7UL, 0xb2a017c2d2d3529cUL, 0x200dabf8d05c8d6bUL,
274    0x34a78f9ba2f77737UL, 0xe3b4719d8f231f01UL, 0x45be423c2f5bb7c1UL, 0xf71e55fefd88e55dUL,
275    0x6853032b59f3ee6eUL, 0x65b3e9c4ff073aaaUL, 0x772ac3399ae5ebecUL, 0x87816e97f842a75bUL,
276    0x110e2db2e0484a4bUL, 0x331277cb3dd8deddUL, 0xbd510cac79eb9fa5UL, 0x352179552a91f5c7UL,
277  },
278  {
279    0x05ba7bc82c9b3220UL, 0x31a54665f8b65e4fUL, 0xb1b651f77547f4d4UL, 0x8bfa0d857ba46682UL,
280    0x85a96c5aa16a98bbUL, 0x990faef908eb79c9UL, 0xa15e37a247f4a62dUL, 0x76857dcd5d27741eUL,
281    0xf8c50b800a1820bcUL, 0xbe65dcb201f7a2b4UL, 0x666d1b986f9426e7UL, 0x4cc921bf53c4e648UL,
282    0x95410a0f93d9ca42UL, 0x20cdccaa647ba4efUL, 0x429a4060890a1871UL, 0x0c4ea4f69b32b38bUL,
283    0xccda362dde354cd3UL, 0x96dc23bc7c5b2fa9UL, 0xc309bb68aa851ab3UL, 0xd26131a73648e013UL,
284    0x021dc52941fc4db2UL, 0xcd5adab7704be48aUL, 0xa77965d984ed71e6UL, 0x32386fd61734bba4UL,
285    0xe82d6dd538ab7245UL, 0x5c2147ea6177b4b1UL, 0x5da1ab70cf091ce8UL, 0xac907fce72b8bdffUL,
286    0x57c85dfd972278a8UL, 0xa4e44c6a6b6f940dUL, 0x3851995b4f1fdfe4UL, 0x62578ccaed71bc9eUL,
287    0xd9882bb0c01d2c0aUL, 0x917b9d5d113c503bUL, 0xa2c31e11a87643c6UL, 0xe463c923a399c1ceUL,
288    0xf71686c57ea876dcUL, 0x87b4a973e096d509UL, 0xaf0d567d9d3a5814UL, 0xb40c2a3f59dcc6f4UL,
289    0x3602f88495d121ddUL, 0xd3e1dd3d9836484aUL, 0xf945e71aa46688e5UL, 0x7518547eb2a591f5UL,
290    0x9366587450c01d89UL, 0x9ea81018658c065bUL, 0x4f54080cbc4603a3UL, 0x2d0384c65137bf3dUL,
291    0xdc325078ec861e2aUL, 0xea30a8fc79573ff7UL, 0x214d2030ca050cb6UL, 0x65f0322b8016c30cUL,
292    0x69be96dd1b247087UL, 0xdb95ee9981e161b8UL, 0xd1fc1814d9ca05f8UL, 0x820ed2bbcc0de729UL,
293    0x63d76050430f14c7UL, 0x3bccb0e8a09d3a0fUL, 0x8e40764d573f54a2UL, 0x39d175c1e16177bdUL,
294    0x12f5a37c734f1f4bUL, 0xab37c12f1fdfc26dUL, 0x5648b167395cd0f1UL, 0x6c04ed1537bf42a7UL,
295    0xed97161d14304065UL, 0x7d6c67daab72b807UL, 0xec17fa87ba4ee83cUL, 0xdfaf79cb0304fbc1UL,
296    0x733f060571bc463eUL, 0x78d61c1287e98a27UL, 0xd07cf48e77b4ada1UL, 0xb9c262536c90dd26UL,
297    0xe2449b5860801605UL, 0x8fc09ad7f941fcfbUL, 0xfad8cea94be46d0eUL, 0xa343f28b0608eb9fUL,
298    0x9b126bd04917347bUL, 0x9a92874ae7699c22UL, 0x1b017c42c4e69ee0UL, 0x3a4c5c720ee39256UL,
299    0x4b6e9f5e3ea399daUL, 0x6ba353f45ad83d35UL, 0xe7fee0904c1b2425UL, 0x22d009832587e95dUL,
300    0x842980c00f1430e2UL, 0xc6b3c0a0861e2893UL, 0x087433a419d729f2UL, 0x341f3dadd42d6c6fUL,
301    0xee0a3faefbb2a58eUL, 0x4aee73c490dd3183UL, 0xaab72db5b1a16a34UL, 0xa92a04065e238fdfUL,
302    0x7b4b35a1686b6fccUL, 0x6a23bf6ef4a6956cUL, 0x191cb96b851ad352UL, 0x55d598d4d6de351aUL,
303    0xc9604de5f2ae7ef3UL, 0x1ca6c2a3a981e172UL, 0xde2f9551ad7a5398UL, 0x3025aaff56c8f616UL,
304    0x15521d9d1e2860d9UL, 0x506fe31cfa45073aUL, 0x189c55f12b647b0bUL, 0x0180ec9aae7ea859UL,
305    0x7cec8b40050c105eUL, 0x2350e5198bf94104UL, 0xef8ad33455cc0dd7UL, 0x07a7bee16d677f92UL,
306    0xe5e325b90de76997UL, 0x5a061591a26e637aUL, 0xb611ef1618208b46UL, 0x09f4df3eb7a981abUL,
307    0x1ebb078ae87dacc0UL, 0xb791038cb65e231fUL, 0x0fd38d4574b05660UL, 0x67edf702c1ea8ebeUL,
308    0xba5f4be0831238cdUL, 0xe3c477c2cefebe5cUL, 0x0dce486c354c1bd2UL, 0x8c5db36416c31910UL,
309    0x26ea9ed1a7627324UL, 0x039d29b3ef82e5ebUL, 0x9f28fc82cbf2ae02UL, 0xa8aae89cf05d2786UL,
310    0x431aacfa2774b028UL, 0xcf471f9e31b7a938UL, 0x581bd0b8e3922ec8UL, 0xbc78199b400bef06UL,
311    0x90fb71c7bf42f862UL, 0x1f3beb1046030499UL, 0x683e7a47b55ad8deUL, 0x988f4263a695d190UL,
312    0xd808c72a6e638453UL, 0x0627527bc319d7cbUL, 0xebb04466d72997aeUL, 0xe67e0c0ae2658c7cUL,
313    0x14d2f107b056c880UL, 0x7122c32c30400b8cUL, 0x8a7ae11fd5dacedbUL, 0xa0dedb38e98a0e74UL,
314    0xad109354dcc615a6UL, 0x0be91a17f655cc19UL, 0x8ddd5ffeb8bdb149UL, 0xbfe53028af890aedUL,
315    0xd65ba6f5b4ad7a6aUL, 0x7956f0882997227eUL, 0x10e8665532b352f9UL, 0x0e5361dfdacefe39UL,
316    0xcec7f3049fc90161UL, 0xff62b561677f5f2eUL, 0x975ccf26d22587f0UL, 0x51ef0f86543baf63UL,
317    0x2f1e41ef10cbf28fUL, 0x52722635bbb94a88UL, 0xae8dbae73344f04dUL, 0x410769d36688fd9aUL,
318    0xb3ab94de34bbb966UL, 0x801317928df1aa9bUL, 0xa564a0f0c5113c54UL, 0xf131d4bebdb1a117UL,
319    0x7f71a2f3ea8ef5b5UL, 0x40878549c8f655c3UL, 0x7ef14e6944f05decUL, 0xd44663dcf55137d8UL,
320    0xf2acfd0d523344fcUL, 0x0000000000000000UL, 0x5fbc6e598ef5515aUL, 0x16cf342ef1aa8532UL,
321    0xb036bd6ddb395c8dUL, 0x13754fe6dd31b712UL, 0xbbdfa77a2d6c9094UL, 0x89e7c8ac3a582b30UL,
322    0x3c6b0e09cdfa459dUL, 0xc4ae0589c7e26521UL, 0x49735a777f5fd468UL, 0xcafd64561d2c9b18UL,
323    0xda1502032f9fc9e1UL, 0x8867243694268369UL, 0x3782141e3baf8984UL, 0x9cb5d53124704be9UL,
324    0xd7db4a6f1ad3d233UL, 0xa6f989432a93d9bfUL, 0x9d3539ab8a0ee3b0UL, 0x53f2caaf15c7e2d1UL,
325    0x6e19283c76430f15UL, 0x3debe2936384edc4UL, 0x5e3c82c3208bf903UL, 0x33b8834cb94a13fdUL,
326    0x6470deb12e686b55UL, 0x359fd1377a53c436UL, 0x61caa57902f35975UL, 0x043a975282e59a79UL,
327    0xfd7f70482683129cUL, 0xc52ee913699ccd78UL, 0x28b9ff0e7dac8d1dUL, 0x5455744e78a09d43UL,
328    0xcb7d88ccb3523341UL, 0x44bd121b4a13cfbaUL, 0x4d49cd25fdba4e11UL, 0x3e76cb208c06082fUL,
329    0x3ff627ba2278a076UL, 0xc28957f204fbb2eaUL, 0x453dfe81e46d67e3UL, 0x94c1e6953da7621bUL,
330    0x2c83685cff491764UL, 0xf32c1197fc4deca5UL, 0x2b24d6bd922e68f6UL, 0xb22b78449ac5113fUL,
331    0x48f3b6edd1217c31UL, 0x2e9ead75beb55ad6UL, 0x174fd8b45fd42d6bUL, 0x4ed4e4961238abfaUL,
332    0x92e6b4eefebeb5d0UL, 0x46a0d7320bef8208UL, 0x47203ba8a5912a51UL, 0x24f75bf8e69e3e96UL,
333    0xf0b1382413cf094eUL, 0xfee259fbc901f777UL, 0x276a724b091cdb7dUL, 0xbdf8f501ee75475fUL,
334    0x599b3c224dec8691UL, 0x6d84018f99c1eafeUL, 0x7498b8e41cdb39acUL, 0xe0595e71217c5bb7UL,
335    0x2aa43a273c50c0afUL, 0xf50b43ec3f543b6eUL, 0x838e3e2162734f70UL, 0xc09492db4507ff58UL,
336    0x72bfea9fdfc2ee67UL, 0x11688acf9ccdfaa0UL, 0x1a8190d86a9836b9UL, 0x7acbd93bc615c795UL,
337    0xc7332c3a286080caUL, 0x863445e94ee87d50UL, 0xf6966a5fd0d6de85UL, 0xe9ad814f96d5da1cUL,
338    0x70a22fb69e3ea3d5UL, 0x0a69f68d582b6440UL, 0xb8428ec9c2ee757fUL, 0x604a49e3ac8df12cUL,
339    0x5b86f90b0c10cb23UL, 0xe1d9b2eb8f02f3eeUL, 0x29391394d3d22544UL, 0xc8e0a17f5cd0d6aaUL,
340    0xb58cc6a5f7a26eadUL, 0x8193fb08238f02c2UL, 0xd5c68f465b2f9f81UL, 0xfcff9cd288fdbac5UL,
341    0x77059157f359dc47UL, 0x1d262e3907ff492bUL, 0xfb582233e59ac557UL, 0xddb2bce242f8b673UL,
342    0x2577b76248e096cfUL, 0x6f99c4a6d83da74cUL, 0xc1147e41eb795701UL, 0xf48baf76912a9337UL,
343  },
344  {
345    0x45b268a93acde4ccUL, 0xaf7f0be884549d08UL, 0x048354b3c1468263UL, 0x925435c2c80efed2UL,
346    0xee4e37f27fdffba7UL, 0x167a33920c60f14dUL, 0xfb123b52ea03e584UL, 0x4a0cab53fdbb9007UL,
347    0x9deaf6380f788a19UL, 0xcb48ec558f0cb32aUL, 0xb59dc4b2d6fef7e0UL, 0xdcdbca22f4f3ecb6UL,
348    0x11df5813549a9c40UL, 0xe33fdedf568aced3UL, 0xa0c1c8124322e9c3UL, 0x07a56b8158fa6d0dUL,
349    0x77279579b1e1f3ddUL, 0xd9b18b74422ac004UL, 0xb8ec2d9fffabc294UL, 0xf4acf8a82d75914fUL,
350    0x7bbf69b1ef2b6878UL, 0xc4f62faf487ac7e1UL, 0x76ce809cc67e5d0cUL, 0x6711d88f92e4c14cUL,
351    0x627b99d9243dedfeUL, 0x234aa5c3dfb68b51UL, 0x909b1f15262dbf6dUL, 0x4f66ea054b62bcb5UL,
352    0x1ae2cf5a52aa6ae8UL, 0xbea053fbd0ce0148UL, 0xed6808c0e66314c9UL, 0x43fe16cd15a82710UL,
353    0xcd049231a06970f6UL, 0xe7bc8a6c97cc4cb0UL, 0x337ce835fcb3b9c0UL, 0x65def2587cc780f3UL,
354    0x52214ede4132bb50UL, 0x95f15e4390f493dfUL, 0x870839625dd2e0f1UL, 0x41313c1afb8b66afUL,
355    0x91720af051b211bcUL, 0x477d427ed4eea573UL, 0x2e3b4ceef6e3be25UL, 0x82627834eb0bcc43UL,
356    0x9c03e3dd78e724c8UL, 0x2877328ad9867df9UL, 0x14b51945e243b0f2UL, 0x574b0f88f7eb97e2UL,
357    0x88b6fa989aa4943aUL, 0x19c4f068cb168586UL, 0x50ee6409af11faefUL, 0x7df317d5c04eaba4UL,
358    0x7a567c5498b4c6a9UL, 0xb6bbfb804f42188eUL, 0x3cc22bcf3bc5cd0bUL, 0xd04336eaaa397713UL,
359    0xf02fac1bec33132cUL, 0x2506dba7f0d3488dUL, 0xd7e65d6bf2c31a1eUL, 0x5eb9b2161ff820f5UL,
360    0x842e0650c46e0f9fUL, 0x716beb1d9e843001UL, 0xa933758cab315ed4UL, 0x3fe414fda2792265UL,
361    0x27c9f1701ef00932UL, 0x73a4c1ca70a771beUL, 0x94184ba6e76b3d0eUL, 0x40d829ff8c14c87eUL,
362    0x0fbec3fac77674cbUL, 0x3616a9634a6a9572UL, 0x8f139119c25ef937UL, 0xf545ed4d5aea3f9eUL,
363    0xe802499650ba387bUL, 0x6437e7bd0b582e22UL, 0xe6559f89e053e261UL, 0x80ad52e305288dfcUL,
364    0x6dc55a23e34b9935UL, 0xde14e0f51ad0ad09UL, 0xc6390578a659865eUL, 0x96d7617109487cb1UL,
365    0xe2d6cb3a21156002UL, 0x01e915e5779faed1UL, 0xadb0213f6a77dcb7UL, 0x9880b76eb9a1a6abUL,
366    0x5d9f8d248644cf9bUL, 0xfd5e4536c5662658UL, 0xf1c6b9fe9bacbdfdUL, 0xeacd6341be9979c4UL,
367    0xefa7221708405576UL, 0x510771ecd88e543eUL, 0xc2ba51cb671f043dUL, 0x0ad482ac71af5879UL,
368    0xfe787a045cdac936UL, 0xb238af338e049aedUL, 0xbd866cc94972ee26UL, 0x615da6ebbd810290UL,
369    0x3295fdd08b2c1711UL, 0xf834046073bf0aeaUL, 0xf3099329758ffc42UL, 0x1caeb13e7dcfa934UL,
370    0xba2307481188832bUL, 0x24efce42874ce65cUL, 0x0e57d61fb0e9da1aUL, 0xb3d1bad6f99b343cUL,
371    0xc0757b1c893c4582UL, 0x2b510db8403a9297UL, 0x5c7698c1f1db614aUL, 0x3e0d0118d5e68cb4UL,
372    0xd60f488e855cb4cfUL, 0xae961e0df3cb33d9UL, 0x3a8e55ab14a00ed7UL, 0x42170328623789c1UL,
373    0x838b6dd19c946292UL, 0x895fef7ded3b3aebUL, 0xcfcbb8e64e4a3149UL, 0x064c7e642f65c3dcUL,
374    0x3d2b3e2a4c5a63daUL, 0x5bd3f340a9210c47UL, 0xb474d157a1615931UL, 0xac5934da1de87266UL,
375    0x6ee365117af7765bUL, 0xc86ed36716b05c44UL, 0x9ba6885c201d49c5UL, 0xb905387a88346c45UL,
376    0x131072c4bab9ddffUL, 0xbf49461ea751af99UL, 0xd52977bc1ce05ba1UL, 0xb0f785e46027db52UL,
377    0x546d30ba6e57788cUL, 0x305ad707650f56aeUL, 0xc987c682612ff295UL, 0xa5ab8944f5fbc571UL,
378    0x7ed528e759f244caUL, 0x8ddcbbce2c7db888UL, 0xaa154abe328db1baUL, 0x1e619be993ece88bUL,
379    0x09f2bd9ee813b717UL, 0x7401aa4b285d1cb3UL, 0x21858f143195caeeUL, 0x48c381841398d1b8UL,
380    0xfcb750d3b2f98889UL, 0x39a86a998d1ce1b9UL, 0x1f888e0ce473465aUL, 0x7899568376978716UL,
381    0x02cf2ad7ee2341bfUL, 0x85c713b5b3f1a14eUL, 0xff916fe12b4567e7UL, 0x7c1a0230b7d10575UL,
382    0x0c98fcc85eca9ba5UL, 0xa3e7f720da9e06adUL, 0x6a6031a2bbb1f438UL, 0x973e74947ed7d260UL,
383    0x2cf4663918c0ff9aUL, 0x5f50a7f368678e24UL, 0x34d983b4a449d4cdUL, 0x68af1b755592b587UL,
384    0x7f3c3d022e6dea1bUL, 0xabfc5f5b45121f6bUL, 0x0d71e92d29553574UL, 0xdffdf5106d4f03d8UL,
385    0x081ba87b9f8c19c6UL, 0xdb7ea1a3ac0981bbUL, 0xbbca12ad66172dfaUL, 0x79704366010829c7UL,
386    0x179326777bff5f9cUL, 0x0000000000000000UL, 0xeb2476a4c906d715UL, 0x724dd42f0738df6fUL,
387    0xb752ee6538ddb65fUL, 0x37ffbc863df53ba3UL, 0x8efa84fcb5c157e6UL, 0xe9eb5c73272596aaUL,
388    0x1b0bdabf2535c439UL, 0x86e12c872a4d4e20UL, 0x9969a28bce3e087aUL, 0xfafb2eb79d9c4b55UL,
389    0x056a4156b6d92cb2UL, 0x5a3ae6a5debea296UL, 0x22a3b026a8292580UL, 0x53c85b3b36ad1581UL,
390    0xb11e900117b87583UL, 0xc51f3a4a3fe56930UL, 0xe019e1edcf3621bdUL, 0xec811d2591fcba18UL,
391    0x445b7d4c4d524a1dUL, 0xa8da6069dcaef005UL, 0x58f5cc72309de329UL, 0xd4c062596b7ff570UL,
392    0xce22ad0339d59f98UL, 0x591cd99747024df8UL, 0x8b90c5aa03187b54UL, 0xf663d27fc356d0f0UL,
393    0xd8589e9135b56ed5UL, 0x35309651d3d67a1cUL, 0x12f96721cd26732eUL, 0xd28c1c3d441a36acUL,
394    0x492a946164077f69UL, 0x2d1d73dc6f5f514bUL, 0x6f0a70f40d68d88aUL, 0x60b4b30eca1eac41UL,
395    0xd36509d83385987dUL, 0x0b3d97490630f6a8UL, 0x9eccc90a96c46577UL, 0xa20ee2c5ad01a87cUL,
396    0xe49ab55e0e70a3deUL, 0xa4429ca182646ba0UL, 0xda97b446db962f6aUL, 0xcced87d4d7f6de27UL,
397    0x2ab8185d37a53c46UL, 0x9f25dcefe15bcba6UL, 0xc19c6ef9fea3eb53UL, 0xa764a3931bd884ceUL,
398    0x2fd2590b817c10f4UL, 0x56a21a6d80743933UL, 0xe573a0bb79ef0d0fUL, 0x155c0ca095dc1e23UL,
399    0x6c2c4fc694d437e4UL, 0x10364df623053291UL, 0xdd32dfc7836c4267UL, 0x03263f3299bcef6eUL,
400    0x66f8cd6ae57b6f9dUL, 0x8c35ae2b5be21659UL, 0x31b3c2e21290f87fUL, 0x93bd2027bf915003UL,
401    0x69460e90220d1b56UL, 0x299e276fae19d328UL, 0x63928c3c53a2432fUL, 0x7082fef8e91b9ed0UL,
402    0xbc6f792c3eed40f7UL, 0x4c40d537d2de53dbUL, 0x75e8bfae5fc2b262UL, 0x4da9c0d2a541fd0aUL,
403    0x4e8fffe03cfd1264UL, 0x2620e495696fa7e3UL, 0xe1f0f408b8a98f6cUL, 0xd1aa230fdda6d9c2UL,
404    0xc7d0109dd1c6288fUL, 0x8a79d04f7487d585UL, 0x4694579ba3710ba2UL, 0x38417f7cfa834f68UL,
405    0x1d47a4db0a5007e5UL, 0x206c9af1460a643fUL, 0xa128ddf734bd4712UL, 0x8144470672b7232dUL,
406    0xf2e086cc02105293UL, 0x182de58dbc892b57UL, 0xcaa1f9b0f8931dfbUL, 0x6b892447cc2e5ae9UL,
407    0xf9dd11850420a43bUL, 0x4be5beb68a243ed6UL, 0x5584255f19c8d65dUL, 0x3b67404e633fa006UL,
408    0xa68db6766c472a1fUL, 0xf78ac79ab4c97e21UL, 0xc353442e1080aaecUL, 0x9a4f9db95782e714UL,
409  },
410  {
411    0xc811a8058c3f55deUL, 0x65f5b43196b50619UL, 0xf74f96b1d6706e43UL, 0x859d1e8bcb43d336UL,
412    0x5aab8a85ccfa3d84UL, 0xf9c7bf99c295fcfdUL, 0xa21fd5a1de4b630fUL, 0xcdb3ef763b8b456dUL,
413    0x803f59f87cf7c385UL, 0xb27c73be5f31913cUL, 0x98e3ac6633b04821UL, 0xbf61674c26b8f818UL,
414    0x0ffbc995c4c130c8UL, 0xaaa0862010761a98UL, 0x6057f342210116aaUL, 0xf63c760c0654cc35UL,
415    0x2ddb45cc667d9042UL, 0xbcf45a964bd40382UL, 0x68e8a0c3ef3c6f3dUL, 0xa7bd92d269ff73bcUL,
416    0x290ae20201ed2287UL, 0xb7de34cde885818fUL, 0xd901eea7dd61059bUL, 0xd6fa273219a03553UL,
417    0xd56f1ae874cccec9UL, 0xea31245c2e83f554UL, 0x7034555da07be499UL, 0xce26d2ac56e7bef7UL,
418    0xfd161857a5054e38UL, 0x6a0e7da4527436d1UL, 0x5bd86a381cde9ff2UL, 0xcaf7756231770c32UL,
419    0xb09aaed9e279c8d0UL, 0x5def1091c60674dbUL, 0x111046a2515e5045UL, 0x23536ce4729802fcUL,
420    0xc50cbcf7f5b63cfaUL, 0x73a16887cd171f03UL, 0x7d2941afd9f28dbdUL, 0x3f5e3eb45a4f3b9dUL,
421    0x84eefe361b677140UL, 0x3db8e3d3e7076271UL, 0x1a3a28f9f20fd248UL, 0x7ebc7c75b49e7627UL,
422    0x74e5f293c7eb565cUL, 0x18dcf59e4f478ba4UL, 0x0c6ef44fa9adcb52UL, 0xc699812d98dac760UL,
423    0x788b06dc6e469d0eUL, 0xfc65f8ea7521ec4eUL, 0x30a5f7219e8e0b55UL, 0x2bec3f65bca57b6bUL,
424    0xddd04969baf1b75eUL, 0x99904cdbe394ea57UL, 0x14b201d1e6ea40f6UL, 0xbbb0c08241284addUL,
425    0x50f20463bf8f1dffUL, 0xe8d7f93b93cbacb8UL, 0x4d8cb68e477c86e8UL, 0xc1dd1b3992268e3fUL,
426    0x7c5aa11209d62fcbUL, 0x2f3d98abdb35c9aeUL, 0x671369562bfd5ff5UL, 0x15c1e16c36cee280UL,
427    0x1d7eb2edf8f39b17UL, 0xda94d37db00dfe01UL, 0x877bc3ec760b8adaUL, 0xcb8495dfe153ae44UL,
428    0x05a24773b7b410b3UL, 0x12857b783c32abdfUL, 0x8eb770d06812513bUL, 0x536739b9d2e3e665UL,
429    0x584d57e271b26468UL, 0xd789c78fc9849725UL, 0xa935bbfa7d1ae102UL, 0x8b1537a3dfa64188UL,
430    0xd0cd5d9bc378de7aUL, 0x4ac82c9a4d80cfb7UL, 0x42777f1b83bdb620UL, 0x72d2883a1d33bd75UL,
431    0x5e7a2d4bab6a8f41UL, 0xf4daab6bbb1c95d9UL, 0x905cffe7fd8d31b6UL, 0x83aa6422119b381fUL,
432    0xc0aefb8442022c49UL, 0xa0f908c663033ae3UL, 0xa428af0804938826UL, 0xade41c341a8a53c7UL,
433    0xae7121ee77e6a85dUL, 0xc47f5c4a25929e8cUL, 0xb538e9aa55cdd863UL, 0x06377aa9dad8eb29UL,
434    0xa18ae87bb3279895UL, 0x6edfda6a35e48414UL, 0x6b7d9d19825094a7UL, 0xd41cfa55a4e86cbfUL,
435    0xe5caedc9ea42c59cUL, 0xa36c351c0e6fc179UL, 0x5181e4de6fabbf89UL, 0xfff0c530184d17d4UL,
436    0x9d41eb1584045892UL, 0x1c0d525028d73961UL, 0xf178ec180ca8856aUL, 0x9a0571018ef811cdUL,
437    0x4091a27c3ef5efccUL, 0x19af15239f6329d2UL, 0x347450eff91eb990UL, 0xe11b4a078dd27759UL,
438    0xb9561de5fc601331UL, 0x912f1f5a2da993c0UL, 0x1654dcb65ba2191aUL, 0x3e2dde098a6b99ebUL,
439    0x8a66d71e0f82e3feUL, 0x8c51adb7d55a08d7UL, 0x4533e50f8941ff7fUL, 0x02e6dd67bd4859ecUL,
440    0xe068aaba5df6d52fUL, 0xc24826e3ff4a75a5UL, 0x6c39070d88acddf8UL, 0x6486548c4691a46fUL,
441    0xd1bebd26135c7c0cUL, 0xb30f93038f15334aUL, 0x82d9849fc1bf9a69UL, 0x9c320ba85420fae4UL,
442    0xfa528243aff90767UL, 0x9ed4d6cfe968a308UL, 0xb825fd582c44b147UL, 0x9b7691bc5edcb3bbUL,
443    0xc7ea619048fe6516UL, 0x1063a61f817af233UL, 0x47d538683409a693UL, 0x63c2ce984c6ded30UL,
444    0x2a9fdfd86c81d91dUL, 0x7b1e3b06032a6694UL, 0x666089ebfbd9fd83UL, 0x0a598ee67375207bUL,
445    0x07449a140afc495fUL, 0x2ca8a571b6593234UL, 0x1f986f8a45bbc2fbUL, 0x381aa4a050b372c2UL,
446    0x5423a3add81faf3aUL, 0x17273c0b8b86bb6cUL, 0xfe83258dc869b5a2UL, 0x287902bfd1c980f1UL,
447    0xf5a94bd66b3837afUL, 0x88800a79b2caba12UL, 0x55504310083b0d4cUL, 0xdf36940e07b9eeb2UL,
448    0x04d1a7ce6790b2c5UL, 0x612413fff125b4dcUL, 0x26f12b97c52c124fUL, 0x86082351a62f28acUL,
449    0xef93632f9937e5e7UL, 0x3507b052293a1be6UL, 0xe72c30ae570a9c70UL, 0xd3586041ae1425e0UL,
450    0xde4574b3d79d4cc4UL, 0x92ba228040c5685aUL, 0xf00b0ca5dc8c271cUL, 0xbe1287f1f69c5a6eUL,
451    0xf39e317fb1e0dc86UL, 0x495d114020ec342dUL, 0x699b407e3f18cd4bUL, 0xdca3a9d46ad51528UL,
452    0x0d1d14f279896924UL, 0x0000000000000000UL, 0x593eb75fa196c61eUL, 0x2e4e78160b116bd8UL,
453    0x6d4ae7b058887f8eUL, 0xe65fd013872e3e06UL, 0x7a6ddbbbd30ec4e2UL, 0xac97fc89caaef1b1UL,
454    0x09ccb33c1e19dbe1UL, 0x89f3eac462ee1864UL, 0x7770cf49aa87adc6UL, 0x56c57eca6557f6d6UL,
455    0x03953dda6d6cfb9aUL, 0x36928d884456e07cUL, 0x1eeb8f37959f608dUL, 0x31d6179c4eaaa923UL,
456    0x6fac3ad7e5c02662UL, 0x43049fa653991456UL, 0xabd3669dc052b8eeUL, 0xaf02c153a7c20a2bUL,
457    0x3ccb036e3723c007UL, 0x93c9c23d90e1ca2cUL, 0xc33bc65e2f6ed7d3UL, 0x4cff56339758249eUL,
458    0xb1e94e64325d6aa6UL, 0x37e16d359472420aUL, 0x79f8e661be623f78UL, 0x5214d90402c74413UL,
459    0x482ef1fdf0c8965bUL, 0x13f69bc5ec1609a9UL, 0x0e88292814e592beUL, 0x4e198b542a107d72UL,
460    0xccc00fcbebafe71bUL, 0x1b49c844222b703eUL, 0x2564164da840e9d5UL, 0x20c6513e1ff4f966UL,
461    0xbac3203f910ce8abUL, 0xf2edd1c261c47ef0UL, 0x814cb945acd361f3UL, 0x95feb8944a392105UL,
462    0x5c9cf02c1622d6adUL, 0x971865f3f77178e9UL, 0xbd87ba2b9bf0a1f4UL, 0x444005b259655d09UL,
463    0xed75be48247fbc0bUL, 0x7596122e17cff42aUL, 0xb44b091785e97a15UL, 0x966b854e2755da9fUL,
464    0xeee0839249134791UL, 0x32432a4623c652b9UL, 0xa8465b47ad3e4374UL, 0xf8b45f2412b15e8bUL,
465    0x2417f6f078644ba3UL, 0xfb2162fe7fdda511UL, 0x4bbbcc279da46dc1UL, 0x0173e0bdd024a276UL,
466    0x22208c59a2bca08aUL, 0x8fc4906db836f34dUL, 0xe4b90d743a6667eaUL, 0x7147b5e0705f46efUL,
467    0x2782cb2a1508b039UL, 0xec065ef5f45b1e7dUL, 0x21b5b183cfd05b10UL, 0xdbe733c060295c77UL,
468    0x9fa73672394c017eUL, 0xcf55321186c31c81UL, 0xd8720e1a0d45a7edUL, 0x3b8f997a3ddf8958UL,
469    0x3afc79c7edfb2b2eUL, 0xe9a4198643ef0eceUL, 0x5f09cdf67b4e2d37UL, 0x4f6a6be9fa34df04UL,
470    0xb6add47038a123f9UL, 0x8d224d0a057eaaa1UL, 0xc96248b85c1bf7a8UL, 0xe3fd9760309a2eb5UL,
471    0x0b2a6e5ba351820dUL, 0xeb42c4e1fea75722UL, 0x948d58299a1d8373UL, 0x7fcf9cc864bad451UL,
472    0xa55b4fb5d4b72a50UL, 0x08bf5381ce3d7997UL, 0x46a6d8d5e42d04e5UL, 0xd22b80fc7e308796UL,
473    0x57b69e77b57354a0UL, 0x3969441d8097d0b4UL, 0x3330cafbf3e2f0cfUL, 0xe28e77dde0be8cc3UL,
474    0x62b12e259c494f46UL, 0xa6ce726fb9dbd1caUL, 0x41e242c1eed14dbaUL, 0x76032ff47aa30fb0UL,
475  },
476  {
477    0xe6f87e5c5b711fd0UL, 0x258377800924fa16UL, 0xc849e07e852ea4a8UL, 0x5b4686a18f06c16aUL,
478    0x0b32e9a2d77b416eUL, 0xabda37a467815c66UL, 0xf61796a81a686676UL, 0xf5dc0b706391954bUL,
479    0x4862f38db7e64bf1UL, 0xff5c629a68bd85c5UL, 0xcb827da6fcd75795UL, 0x66d36daf69b9f089UL,
480    0x356c9f74483d83b0UL, 0x7cbcecb1238c99a1UL, 0x36a702ac31c4708dUL, 0x9eb6a8d02fbcdfd6UL,
481    0x8b19fa51e5b3ae37UL, 0x9ccfb5408a127d0bUL, 0xbc0c78b508208f5aUL, 0xe533e3842288ecedUL,
482    0xcec2c7d377c15fd2UL, 0xec7817b6505d0f5eUL, 0xb94cc2c08336871dUL, 0x8c205db4cb0b04adUL,
483    0x763c855b28a0892fUL, 0x588d1b79f6ff3257UL, 0x3fecf69e4311933eUL, 0x0fc0d39f803a18c9UL,
484    0xee010a26f5f3ad83UL, 0x10efe8f4411979a6UL, 0x5dcda10c7de93a10UL, 0x4a1bee1d1248e92cUL,
485    0x53bff2db21847339UL, 0xb4f50ccfa6a23d09UL, 0x5fb4bc9cd84798cdUL, 0xe88a2d8b071c56f9UL,
486    0x7f7771695a756a9cUL, 0xc5f02e71a0ba1ebcUL, 0xa663f9ab4215e672UL, 0x2eb19e22de5fbb78UL,
487    0x0db9ce0f2594ba14UL, 0x82520e6397664d84UL, 0x2f031e6a0208ea98UL, 0x5c7f2144a1be6bf0UL,
488    0x7a37cb1cd16362dbUL, 0x83e08e2b4b311c64UL, 0xcf70479bab960e32UL, 0x856ba986b9dee71eUL,
489    0xb5478c877af56ce9UL, 0xb8fe42885f61d6fdUL, 0x1bdd0156966238c8UL, 0x622157923ef8a92eUL,
490    0xfc97ff42114476f8UL, 0x9d7d350856452cebUL, 0x4c90c9b0e0a71256UL, 0x2308502dfbcb016cUL,
491    0x2d7a03faa7a64845UL, 0xf46e8b38bfc6c4abUL, 0xbdbef8fdd477debaUL, 0x3aac4cebc8079b79UL,
492    0xf09cb105e8879d0cUL, 0x27fa6a10ac8a58cbUL, 0x8960e7c1401d0ceaUL, 0x1a6f811e4a356928UL,
493    0x90c4fb0773d196ffUL, 0x43501a2f609d0a9fUL, 0xf7a516e0c63f3796UL, 0x1ce4a6b3b8da9252UL,
494    0x1324752c38e08a9bUL, 0xa5a864733bec154fUL, 0x2bf124575549b33fUL, 0xd766db15440dc5c7UL,
495    0xa7d179e39e42b792UL, 0xdadf151a61997fd3UL, 0x86a0345ec0271423UL, 0x38d5517b6da939a4UL,
496    0x6518f077104003b4UL, 0x02791d90a5aea2ddUL, 0x88d267899c4a5d0aUL, 0x930f66df0a2865c2UL,
497    0x4ee9d4204509b08bUL, 0x325538916685292aUL, 0x412907bfc533a842UL, 0xb27e2b62544dc673UL,
498    0x6c5304456295e007UL, 0x5af406e95351908aUL, 0x1f2f3b6bc123616fUL, 0xc37b09dc5255e5c6UL,
499    0x3967d133b1fe6844UL, 0x298839c7f0e711e2UL, 0x409b87f71964f9a2UL, 0xe938adc3db4b0719UL,
500    0x0c0b4e47f9c3ebf4UL, 0x5534d576d36b8843UL, 0x4610a05aeb8b02d8UL, 0x20c3cdf58232f251UL,
501    0x6de1840dbec2b1e7UL, 0xa0e8de06b0fa1d08UL, 0x7b854b540d34333bUL, 0x42e29a67bcca5b7fUL,
502    0xd8a6088ac437dd0eUL, 0xc63bb3a9d943ed81UL, 0x21714dbd5e65a3b1UL, 0x6761ede7b5eea169UL,
503    0x2431f7c8d573abf6UL, 0xd51fc685e1a3671aUL, 0x5e063cd40410c92dUL, 0x283ab98f2cb04002UL,
504    0x8febc06cb2f2f790UL, 0x17d64f116fa1d33cUL, 0xe07359f1a99ee4aaUL, 0x784ed68c74cdc006UL,
505    0x6e2a19d5c73b42daUL, 0x8712b4161c7045c3UL, 0x371582e4ed93216dUL, 0xace390414939f6fcUL,
506    0x7ec5f12186223b7cUL, 0xc0b094042bac16fbUL, 0xf9d745379a527ebfUL, 0x737c3f2ea3b68168UL,
507    0x33e7b8d9bad278caUL, 0xa9a32a34c22ffebbUL, 0xe48163ccfedfbd0dUL, 0x8e5940246ea5a670UL,
508    0x51c6ef4b842ad1e4UL, 0x22bad065279c508cUL, 0xd91488c218608ceeUL, 0x319ea5491f7cda17UL,
509    0xd394e128134c9c60UL, 0x094bf43272d5e3b3UL, 0x9bf612a5a4aad791UL, 0xccbbda43d26ffd0fUL,
510    0x34de1f3c946ad250UL, 0x4f5b5468995ee16bUL, 0xdf9faf6fea8f7794UL, 0x2648ea5870dd092bUL,
511    0xbfc7e56d71d97c67UL, 0xdde6b2ff4f21d549UL, 0x3c276b463ae86003UL, 0x91767b4faf86c71fUL,
512    0x68a13e7835d4b9a0UL, 0xb68c115f030c9fd4UL, 0x141dd2c916582001UL, 0x983d8f7ddd5324acUL,
513    0x64aa703fcc175254UL, 0xc2c989948e02b426UL, 0x3e5e76d69f46c2deUL, 0x50746f03587d8004UL,
514    0x45db3d829272f1e5UL, 0x60584a029b560bf3UL, 0xfbae58a73ffcdc62UL, 0xa15a5e4e6cad4ce8UL,
515    0x4ba96e55ce1fb8ccUL, 0x08f9747aae82b253UL, 0xc102144cf7fb471bUL, 0x9f042898f3eb8e36UL,
516    0x068b27adf2effb7aUL, 0xedca97fe8c0a5ebeUL, 0x778e0513f4f7d8cfUL, 0x302c2501c32b8bf7UL,
517    0x8d92ddfc175c554dUL, 0xf865c57f46052f5fUL, 0xeaf3301ba2b2f424UL, 0xaa68b7ecbbd60d86UL,
518    0x998f0f350104754cUL, 0x0000000000000000UL, 0xf12e314d34d0ccecUL, 0x710522be061823b5UL,
519    0xaf280d9930c005c1UL, 0x97fd5ce25d693c65UL, 0x19a41cc633cc9a15UL, 0x95844172f8c79eb8UL,
520    0xdc5432b7937684a9UL, 0x9436c13a2490cf58UL, 0x802b13f332c8ef59UL, 0xc442ae397ced4f5cUL,
521    0xfa1cd8efe3ab8d82UL, 0xf2e5ac954d293fd1UL, 0x6ad823e8907a1b7dUL, 0x4d2249f83cf043b6UL,
522    0x03cb9dd879f9f33dUL, 0xde2d2f2736d82674UL, 0x2a43a41f891ee2dfUL, 0x6f98999d1b6c133aUL,
523    0xd4ad46cd3df436faUL, 0xbb35df50269825c0UL, 0x964fdcaa813e6d85UL, 0xeb41b0537ee5a5c4UL,
524    0x0540ba758b160847UL, 0xa41ae43be7bb44afUL, 0xe3b8c429d0671797UL, 0x819993bbee9fbeb9UL,
525    0xae9a8dd1ec975421UL, 0xf3572cdd917e6e31UL, 0x6393d7dae2aff8ceUL, 0x47a2201237dc5338UL,
526    0xa32343dec903ee35UL, 0x79fc56c4a89a91e6UL, 0x01b28048dc5751e0UL, 0x1296f564e4b7db7bUL,
527    0x75f7188351597a12UL, 0xdb6d9552bdce2e33UL, 0x1e9dbb231d74308fUL, 0x520d7293fdd322d9UL,
528    0xe20a44610c304677UL, 0xfeeee2d2b4ead425UL, 0xca30fdee20800675UL, 0x61eaca4a47015a13UL,
529    0xe74afe1487264e30UL, 0x2cc883b27bf119a5UL, 0x1664cf59b3f682dcUL, 0xa811aa7c1e78af5bUL,
530    0x1d5626fb648dc3b2UL, 0xb73e9117df5bce34UL, 0xd05f7cf06ab56f5dUL, 0xfd257f0acd132718UL,
531    0x574dc8e676c52a9eUL, 0x0739a7e52eb8aa9aUL, 0x5486553e0f3cd9a3UL, 0x56ff48aeaa927b7eUL,
532    0xbe756525ad8e2d87UL, 0x7d0e6cf9ffdbc841UL, 0x3b1ecca31450ca99UL, 0x6913be30e983e840UL,
533    0xad511009956ea71cUL, 0xb1b5b6ba2db4354eUL, 0x4469bdca4e25a005UL, 0x15af5281ca0f71e1UL,
534    0x744598cb8d0e2bf2UL, 0x593f9b312aa863b7UL, 0xefb38a6e29a4fc63UL, 0x6b6aa3a04c2d4a9dUL,
535    0x3d95eb0ee6bf31e3UL, 0xa291c3961554bfd5UL, 0x18169c8eef9bcbf5UL, 0x115d68bc9d4e2846UL,
536    0xba875f18facf7420UL, 0xd1edfcb8b6e23ebdUL, 0xb00736f2f1e364aeUL, 0x84d929ce6589b6feUL,
537    0x70b7a2f6da4f7255UL, 0x0e7253d75c6d4929UL, 0x04f23a3d574159a7UL, 0x0a8069ea0b2c108eUL,
538    0x49d073c56bb11a11UL, 0x8aab7a1939e4ffd7UL, 0xcd095a0b0e38acefUL, 0xc9fb60365979f548UL,
539    0x92bde697d67f3422UL, 0xc78933e10514bc61UL, 0xe1c1d9b975c9b54aUL, 0xd2266160cf1bcd80UL,
540    0x9a4492ed78fd8671UL, 0xb3ccab2a881a9793UL, 0x72cebf667fe1d088UL, 0xd6d45b5d985a9427UL,
541  },
542};
543
544CONSTANT_VK u64a sbob512_rc64[12][8] =
545{
546  {
547    0xe9daca1eda5b08b1UL, 0x1f7c65c0812fcbebUL, 0x16d0452e43766a2fUL, 0xfcc485758db84e71UL,
548    0x0169679291e07c4bUL, 0x15d360a4082a42a2UL, 0x234d74cc36747605UL, 0x0745a6f2596580ddUL,
549  },
550  {
551    0x1a2f9da98ab5a36fUL, 0xd7b5700f469de34fUL, 0x982b230a72eafef3UL, 0x3101b5160f5ed561UL,
552    0x5899d6126b17b59aUL, 0xcaa70adbc261b55cUL, 0x56cdcbd71ba2dd55UL, 0xb79bb121700479e6UL,
553  },
554  {
555    0xc72fce2bacdc74f5UL, 0x35843d6a28fc390aUL, 0x8b1f9c525f5ef106UL, 0x7b7b29b11475eaf2UL,
556    0xb19e3590e40fe2d3UL, 0x09db6260373ac9c1UL, 0x31db7a8643f4b6c2UL, 0xb20aba0af5961e99UL,
557  },
558  {
559    0xd26615e8b3df1fefUL, 0xdde4715da0e148f9UL, 0x7d3c5c337e858e48UL, 0x3f355e68ad1c729dUL,
560    0x75d603ed822cd7a9UL, 0xbe0352933313b7d8UL, 0xf137e893a1ea5334UL, 0x2ed1e384bcbe0c22UL,
561  },
562  {
563    0x994747adac6bea4bUL, 0x6323a96c0c413f9aUL, 0x4a1086161f1c157fUL, 0xbdff0f80d7359e35UL,
564    0xa3f53a254717cdbfUL, 0x161a2723b700ffdfUL, 0xf563eaa97ea2567aUL, 0x57fe6c7cfd581760UL,
565  },
566  {
567    0xd9d33a1daeae4faeUL, 0xc039307a3bc3a46fUL, 0x6ca44251f9c4662dUL, 0xc68ef09ab49a7f18UL,
568    0xb4b79a1cb7a6facfUL, 0xb6c6bec2661ff20aUL, 0x354f903672c571bfUL, 0x6e7d64467a4068faUL,
569  },
570  {
571    0xecc5aaee160ec7f4UL, 0x540924bffe86ac51UL, 0xc987bfe6c7c69e39UL, 0xc9937a19333e47d3UL,
572    0x372c822dc5ab9209UL, 0x04054a2883694706UL, 0xf34a3ca24c451735UL, 0x93d4143a4d568688UL,
573  },
574  {
575    0xa7c9934d425b1f9bUL, 0x41416e0c02aae703UL, 0x1ede369c71f8b74eUL, 0x9ac4db4d3b44b489UL,
576    0x90069b92cb2b89f4UL, 0x2fc4a5d12b8dd169UL, 0xd9a8515935c2ac36UL, 0x1ee702bfd40d7fa4UL,
577  },
578  {
579    0x9b223116545a8f37UL, 0xde5f16ecd89a4c94UL, 0x244289251b3a7d3aUL, 0x84090de0b755d93cUL,
580    0xb1ceb2db0b440a80UL, 0x549c07a69a8a2b7bUL, 0x602a1fcb92dc380eUL, 0xdb5a238351446172UL,
581  },
582  {
583    0x526f0580a6debeabUL, 0xf3f3e4b248e52a38UL, 0xdb788aff1ce74189UL, 0x0361331b8ae1ff1fUL,
584    0x4b3369af0267e79fUL, 0xf452763b306c1e7aUL, 0xc3b63b15d1fa9836UL, 0xed9c4598fbc7b474UL,
585  },
586  {
587    0xfb89c8efd09ecd7bUL, 0x94fe5a63cdc60230UL, 0x6107abebbb6bfad8UL, 0x7966841421800120UL,
588    0xcab948eaef711d8aUL, 0x986e477d1dcdbaefUL, 0x5dd86fc04a59a2deUL, 0x1b2df381cda4ca6bUL,
589  },
590  {
591    0xba3116f167e78e37UL, 0x7ab14904b08013d2UL, 0x771ddfbc323ca4cdUL, 0x9b9f2130d41220f8UL,
592    0x86cc91189def805dUL, 0x5228e188aaa41de7UL, 0x991bb2d9d517f4faUL, 0x20d71bf14a92bc48UL,
593  },
594};
595
596DECLSPEC void streebog512_init (streebog512_ctx_t *ctx, SHM_TYPE u64a (*s_sbob_sl64)[256])
597{
598  ctx->h[0] = 0;
599  ctx->h[1] = 0;
600  ctx->h[2] = 0;
601  ctx->h[3] = 0;
602  ctx->h[4] = 0;
603  ctx->h[5] = 0;
604  ctx->h[6] = 0;
605  ctx->h[7] = 0;
606
607  ctx->s[0] = 0;
608  ctx->s[1] = 0;
609  ctx->s[2] = 0;
610  ctx->s[3] = 0;
611  ctx->s[4] = 0;
612  ctx->s[5] = 0;
613  ctx->s[6] = 0;
614  ctx->s[7] = 0;
615
616  ctx->n[0] = 0;
617  ctx->n[1] = 0;
618  ctx->n[2] = 0;
619  ctx->n[3] = 0;
620  ctx->n[4] = 0;
621  ctx->n[5] = 0;
622  ctx->n[6] = 0;
623  ctx->n[7] = 0;
624
625  ctx->w0[0] = 0;
626  ctx->w0[1] = 0;
627  ctx->w0[2] = 0;
628  ctx->w0[3] = 0;
629
630  ctx->w1[0] = 0;
631  ctx->w1[1] = 0;
632  ctx->w1[2] = 0;
633  ctx->w1[3] = 0;
634
635  ctx->w2[0] = 0;
636  ctx->w2[1] = 0;
637  ctx->w2[2] = 0;
638  ctx->w2[3] = 0;
639
640  ctx->w3[0] = 0;
641  ctx->w3[1] = 0;
642  ctx->w3[2] = 0;
643  ctx->w3[3] = 0;
644
645  ctx->len = 0;
646
647  ctx->s_sbob_sl64 = s_sbob_sl64;
648}
649
650DECLSPEC void streebog512_add (u64 *x, const u64 *y)
651{
652  u64 carry = 0;
653
654  #ifdef _unroll
655  #pragma unroll
656  #endif
657  for (int i = 7; i >=0; i--)
658  {
659    const u64 left  = hc_swap64_S (x[i]);
660    const u64 right = hc_swap64_S (y[i]);
661    const u64 sum   = left + right + carry;
662
663    carry = (sum < left) ? (u64) 1 : (u64) 0;
664
665    x[i] = hc_swap64_S (sum);
666  }
667}
668
669DECLSPEC void streebog512_g (u64 *h, const u64 *n, const u64 *m, SHM_TYPE u64a (*s_sbob_sl64)[256])
670{
671  u64 k[8];
672  u64 s[8];
673  u64 t[8];
674
675  #ifdef _unroll
676  #pragma unroll
677  #endif
678  for (int i = 0; i < 8; i++)
679  {
680    t[i] = h[i] ^ n[i];
681  }
682
683  for (int i = 0; i < 8; i++)
684  {
685    k[i] = SBOG_LPSti64_S;
686  }
687
688  #ifdef _unroll
689  #pragma unroll
690  #endif
691  for (int i = 0; i < 8; i++)
692  {
693    s[i] = m[i];
694  }
695
696  for (int r = 0; r < 12; r++)
697  {
698    #ifdef _unroll
699    #pragma unroll
700    #endif
701    for (int i = 0; i < 8; i++)
702    {
703      t[i] = s[i] ^ k[i];
704    }
705
706    #ifdef _unroll
707    #pragma unroll
708    #endif
709    for (int i = 0; i < 8; i++)
710    {
711      s[i] = SBOG_LPSti64_S;
712    }
713
714    for (int i = 0; i < 8; i++)
715    {
716      t[i] = k[i] ^ sbob512_rc64[r][i];
717    }
718
719    #ifdef _unroll
720    #pragma unroll
721    #endif
722    for (int i = 0; i < 8; i++)
723    {
724      k[i] = SBOG_LPSti64_S;
725    }
726  }
727
728  #ifdef _unroll
729  #pragma unroll
730  #endif
731  for (int i = 0; i < 8; i++)
732  {
733    h[i] ^= s[i] ^ k[i] ^ m[i];
734  }
735}
736
737DECLSPEC void streebog512_transform (streebog512_ctx_t *ctx, const u32 *w0, const u32 *w1, const u32 *w2, const u32 *w3)
738{
739  u64 m[8];
740
741  m[0] = hl32_to_64_S (w3[2], w3[3]);
742  m[1] = hl32_to_64_S (w3[0], w3[1]);
743  m[2] = hl32_to_64_S (w2[2], w2[3]);
744  m[3] = hl32_to_64_S (w2[0], w2[1]);
745  m[4] = hl32_to_64_S (w1[2], w1[3]);
746  m[5] = hl32_to_64_S (w1[0], w1[1]);
747  m[6] = hl32_to_64_S (w0[2], w0[3]);
748  m[7] = hl32_to_64_S (w0[0], w0[1]);
749
750  streebog512_g (ctx->h, ctx->n, m, ctx->s_sbob_sl64);
751
752  u64 counterbuf[8] = { 0 };
753  counterbuf[7] = 0x0002000000000000UL;
754  streebog512_add (ctx->n, counterbuf);
755
756  streebog512_add (ctx->s, m);
757}
758
759DECLSPEC void streebog512_update_64 (streebog512_ctx_t *ctx, u32 *w0, u32 *w1, u32 *w2, u32 *w3, const int len)
760{
761  if (len == 0) return;
762
763  const int pos = ctx->len & 63;
764
765  ctx->len += len;
766
767  if (pos == 0)
768  {
769    ctx->w0[0] = w0[0];
770    ctx->w0[1] = w0[1];
771    ctx->w0[2] = w0[2];
772    ctx->w0[3] = w0[3];
773    ctx->w1[0] = w1[0];
774    ctx->w1[1] = w1[1];
775    ctx->w1[2] = w1[2];
776    ctx->w1[3] = w1[3];
777    ctx->w2[0] = w2[0];
778    ctx->w2[1] = w2[1];
779    ctx->w2[2] = w2[2];
780    ctx->w2[3] = w2[3];
781    ctx->w3[0] = w3[0];
782    ctx->w3[1] = w3[1];
783    ctx->w3[2] = w3[2];
784    ctx->w3[3] = w3[3];
785
786    if (len == 64)
787    {
788      streebog512_transform (ctx, ctx->w0, ctx->w1, ctx->w2, ctx->w3);
789
790      ctx->w0[0] = 0;
791      ctx->w0[1] = 0;
792      ctx->w0[2] = 0;
793      ctx->w0[3] = 0;
794      ctx->w1[0] = 0;
795      ctx->w1[1] = 0;
796      ctx->w1[2] = 0;
797      ctx->w1[3] = 0;
798      ctx->w2[0] = 0;
799      ctx->w2[1] = 0;
800      ctx->w2[2] = 0;
801      ctx->w2[3] = 0;
802      ctx->w3[0] = 0;
803      ctx->w3[1] = 0;
804      ctx->w3[2] = 0;
805      ctx->w3[3] = 0;
806    }
807  }
808  else
809  {
810    if ((pos + len) < 64)
811    {
812      switch_buffer_by_offset_be_S (w0, w1, w2, w3, pos);
813
814      ctx->w0[0] |= w0[0];
815      ctx->w0[1] |= w0[1];
816      ctx->w0[2] |= w0[2];
817      ctx->w0[3] |= w0[3];
818      ctx->w1[0] |= w1[0];
819      ctx->w1[1] |= w1[1];
820      ctx->w1[2] |= w1[2];
821      ctx->w1[3] |= w1[3];
822      ctx->w2[0] |= w2[0];
823      ctx->w2[1] |= w2[1];
824      ctx->w2[2] |= w2[2];
825      ctx->w2[3] |= w2[3];
826      ctx->w3[0] |= w3[0];
827      ctx->w3[1] |= w3[1];
828      ctx->w3[2] |= w3[2];
829      ctx->w3[3] |= w3[3];
830    }
831    else
832    {
833      u32 c0[4] = { 0 };
834      u32 c1[4] = { 0 };
835      u32 c2[4] = { 0 };
836      u32 c3[4] = { 0 };
837
838      switch_buffer_by_offset_carry_be_S (w0, w1, w2, w3, c0, c1, c2, c3, pos);
839
840      ctx->w0[0] |= w0[0];
841      ctx->w0[1] |= w0[1];
842      ctx->w0[2] |= w0[2];
843      ctx->w0[3] |= w0[3];
844      ctx->w1[0] |= w1[0];
845      ctx->w1[1] |= w1[1];
846      ctx->w1[2] |= w1[2];
847      ctx->w1[3] |= w1[3];
848      ctx->w2[0] |= w2[0];
849      ctx->w2[1] |= w2[1];
850      ctx->w2[2] |= w2[2];
851      ctx->w2[3] |= w2[3];
852      ctx->w3[0] |= w3[0];
853      ctx->w3[1] |= w3[1];
854      ctx->w3[2] |= w3[2];
855      ctx->w3[3] |= w3[3];
856
857      streebog512_transform (ctx, ctx->w0, ctx->w1, ctx->w2, ctx->w3);
858
859      ctx->w0[0] = c0[0];
860      ctx->w0[1] = c0[1];
861      ctx->w0[2] = c0[2];
862      ctx->w0[3] = c0[3];
863      ctx->w1[0] = c1[0];
864      ctx->w1[1] = c1[1];
865      ctx->w1[2] = c1[2];
866      ctx->w1[3] = c1[3];
867      ctx->w2[0] = c2[0];
868      ctx->w2[1] = c2[1];
869      ctx->w2[2] = c2[2];
870      ctx->w2[3] = c2[3];
871      ctx->w3[0] = c3[0];
872      ctx->w3[1] = c3[1];
873      ctx->w3[2] = c3[2];
874      ctx->w3[3] = c3[3];
875    }
876  }
877}
878
879DECLSPEC void streebog512_update (streebog512_ctx_t *ctx, const u32 *w, int len)
880{
881  u32 w0[4];
882  u32 w1[4];
883  u32 w2[4];
884  u32 w3[4];
885
886  int off = 0;
887
888  while (len > 63)
889  {
890    w0[0] = w[off +  0];
891    w0[1] = w[off +  1];
892    w0[2] = w[off +  2];
893    w0[3] = w[off +  3];
894    w1[0] = w[off +  4];
895    w1[1] = w[off +  5];
896    w1[2] = w[off +  6];
897    w1[3] = w[off +  7];
898    w2[0] = w[off +  8];
899    w2[1] = w[off +  9];
900    w2[2] = w[off + 10];
901    w2[3] = w[off + 11];
902    w3[0] = w[off + 12];
903    w3[1] = w[off + 13];
904    w3[2] = w[off + 14];
905    w3[3] = w[off + 15];
906
907    off += 16;
908    len -= 64;
909
910    streebog512_update_64 (ctx, w0, w1, w2, w3, 64);
911  }
912
913  if (len > 0)
914  {
915    w0[0] = w[off +  0];
916    w0[1] = w[off +  1];
917    w0[2] = w[off +  2];
918    w0[3] = w[off +  3];
919    w1[0] = w[off +  4];
920    w1[1] = w[off +  5];
921    w1[2] = w[off +  6];
922    w1[3] = w[off +  7];
923    w2[0] = w[off +  8];
924    w2[1] = w[off +  9];
925    w2[2] = w[off + 10];
926    w2[3] = w[off + 11];
927    w3[0] = w[off + 12];
928    w3[1] = w[off + 13];
929    w3[2] = w[off + 14];
930    w3[3] = w[off + 15];
931
932    streebog512_update_64 (ctx, w0, w1, w2, w3, len);
933  }
934}
935
936DECLSPEC void streebog512_update_swap (streebog512_ctx_t *ctx, const u32 *w, int len)
937{
938  u32 w0[4];
939  u32 w1[4];
940  u32 w2[4];
941  u32 w3[4];
942
943  int off = 0;
944
945  while (len > 63)
946  {
947    w0[0] = hc_swap32_S (w[off +  0]);
948    w0[1] = hc_swap32_S (w[off +  1]);
949    w0[2] = hc_swap32_S (w[off +  2]);
950    w0[3] = hc_swap32_S (w[off +  3]);
951    w1[0] = hc_swap32_S (w[off +  4]);
952    w1[1] = hc_swap32_S (w[off +  5]);
953    w1[2] = hc_swap32_S (w[off +  6]);
954    w1[3] = hc_swap32_S (w[off +  7]);
955    w2[0] = hc_swap32_S (w[off +  8]);
956    w2[1] = hc_swap32_S (w[off +  9]);
957    w2[2] = hc_swap32_S (w[off + 10]);
958    w2[3] = hc_swap32_S (w[off + 11]);
959    w3[0] = hc_swap32_S (w[off + 12]);
960    w3[1] = hc_swap32_S (w[off + 13]);
961    w3[2] = hc_swap32_S (w[off + 14]);
962    w3[3] = hc_swap32_S (w[off + 15]);
963
964    off += 16;
965    len -= 64;
966
967    streebog512_update_64 (ctx, w0, w1, w2, w3, 64);
968  }
969
970  if (len > 0)
971  {
972    w0[0] = hc_swap32_S (w[off +  0]);
973    w0[1] = hc_swap32_S (w[off +  1]);
974    w0[2] = hc_swap32_S (w[off +  2]);
975    w0[3] = hc_swap32_S (w[off +  3]);
976    w1[0] = hc_swap32_S (w[off +  4]);
977    w1[1] = hc_swap32_S (w[off +  5]);
978    w1[2] = hc_swap32_S (w[off +  6]);
979    w1[3] = hc_swap32_S (w[off +  7]);
980    w2[0] = hc_swap32_S (w[off +  8]);
981    w2[1] = hc_swap32_S (w[off +  9]);
982    w2[2] = hc_swap32_S (w[off + 10]);
983    w2[3] = hc_swap32_S (w[off + 11]);
984    w3[0] = hc_swap32_S (w[off + 12]);
985    w3[1] = hc_swap32_S (w[off + 13]);
986    w3[2] = hc_swap32_S (w[off + 14]);
987    w3[3] = hc_swap32_S (w[off + 15]);
988
989    streebog512_update_64 (ctx, w0, w1, w2, w3, len);
990  }
991}
992
993DECLSPEC void streebog512_update_global_swap (streebog512_ctx_t *ctx, GLOBAL_AS const u32 *w, int len)
994{
995  u32 w0[4];
996  u32 w1[4];
997  u32 w2[4];
998  u32 w3[4];
999
1000  int off = 0;
1001
1002  while (len > 63)
1003  {
1004    w0[0] = hc_swap32_S (w[off +  0]);
1005    w0[1] = hc_swap32_S (w[off +  1]);
1006    w0[2] = hc_swap32_S (w[off +  2]);
1007    w0[3] = hc_swap32_S (w[off +  3]);
1008    w1[0] = hc_swap32_S (w[off +  4]);
1009    w1[1] = hc_swap32_S (w[off +  5]);
1010    w1[2] = hc_swap32_S (w[off +  6]);
1011    w1[3] = hc_swap32_S (w[off +  7]);
1012    w2[0] = hc_swap32_S (w[off +  8]);
1013    w2[1] = hc_swap32_S (w[off +  9]);
1014    w2[2] = hc_swap32_S (w[off + 10]);
1015    w2[3] = hc_swap32_S (w[off + 11]);
1016    w3[0] = hc_swap32_S (w[off + 12]);
1017    w3[1] = hc_swap32_S (w[off + 13]);
1018    w3[2] = hc_swap32_S (w[off + 14]);
1019    w3[3] = hc_swap32_S (w[off + 15]);
1020
1021    off += 16;
1022    len -= 64;
1023
1024    streebog512_update_64 (ctx, w0, w1, w2, w3, 64);
1025  }
1026
1027  if (len > 0)
1028  {
1029    w0[0] = hc_swap32_S (w[off +  0]);
1030    w0[1] = hc_swap32_S (w[off +  1]);
1031    w0[2] = hc_swap32_S (w[off +  2]);
1032    w0[3] = hc_swap32_S (w[off +  3]);
1033    w1[0] = hc_swap32_S (w[off +  4]);
1034    w1[1] = hc_swap32_S (w[off +  5]);
1035    w1[2] = hc_swap32_S (w[off +  6]);
1036    w1[3] = hc_swap32_S (w[off +  7]);
1037    w2[0] = hc_swap32_S (w[off +  8]);
1038    w2[1] = hc_swap32_S (w[off +  9]);
1039    w2[2] = hc_swap32_S (w[off + 10]);
1040    w2[3] = hc_swap32_S (w[off + 11]);
1041    w3[0] = hc_swap32_S (w[off + 12]);
1042    w3[1] = hc_swap32_S (w[off + 13]);
1043    w3[2] = hc_swap32_S (w[off + 14]);
1044    w3[3] = hc_swap32_S (w[off + 15]);
1045
1046    streebog512_update_64 (ctx, w0, w1, w2, w3, len);
1047  }
1048}
1049
1050DECLSPEC void streebog512_final (streebog512_ctx_t *ctx)
1051{
1052  const int pos = ctx->len & 63;
1053
1054  append_0x01_4x4_S (ctx->w0, ctx->w1, ctx->w2, ctx->w3, pos ^ 3);
1055
1056  u64 m[8];
1057
1058  m[0] = hl32_to_64_S (ctx->w3[2], ctx->w3[3]);
1059  m[1] = hl32_to_64_S (ctx->w3[0], ctx->w3[1]);
1060  m[2] = hl32_to_64_S (ctx->w2[2], ctx->w2[3]);
1061  m[3] = hl32_to_64_S (ctx->w2[0], ctx->w2[1]);
1062  m[4] = hl32_to_64_S (ctx->w1[2], ctx->w1[3]);
1063  m[5] = hl32_to_64_S (ctx->w1[0], ctx->w1[1]);
1064  m[6] = hl32_to_64_S (ctx->w0[2], ctx->w0[3]);
1065  m[7] = hl32_to_64_S (ctx->w0[0], ctx->w0[1]);
1066
1067  streebog512_g (ctx->h, ctx->n, m, ctx->s_sbob_sl64);
1068
1069  u64 sizebuf[8] = { 0 };
1070  sizebuf[7] = hc_swap64_S ((u64) (pos << 3));
1071
1072  streebog512_add (ctx->n, sizebuf);
1073
1074  streebog512_add (ctx->s, m);
1075
1076  const u64 nullbuf[8] = { 0 };
1077
1078  streebog512_g (ctx->h, nullbuf, ctx->n, ctx->s_sbob_sl64);
1079
1080  streebog512_g (ctx->h, nullbuf, ctx->s, ctx->s_sbob_sl64);
1081}
1082
1083DECLSPEC void streebog512_hmac_init_64 (streebog512_hmac_ctx_t *ctx, const u32 *w0, const u32 *w1, const u32 *w2, const u32 *w3, SHM_TYPE u64a (*s_sbob_sl64)[256])
1084{
1085  u32 a0[4];
1086  u32 a1[4];
1087  u32 a2[4];
1088  u32 a3[4];
1089
1090  // ipad
1091
1092  a0[0] = w0[0] ^ 0x36363636;
1093  a0[1] = w0[1] ^ 0x36363636;
1094  a0[2] = w0[2] ^ 0x36363636;
1095  a0[3] = w0[3] ^ 0x36363636;
1096  a1[0] = w1[0] ^ 0x36363636;
1097  a1[1] = w1[1] ^ 0x36363636;
1098  a1[2] = w1[2] ^ 0x36363636;
1099  a1[3] = w1[3] ^ 0x36363636;
1100  a2[0] = w2[0] ^ 0x36363636;
1101  a2[1] = w2[1] ^ 0x36363636;
1102  a2[2] = w2[2] ^ 0x36363636;
1103  a2[3] = w2[3] ^ 0x36363636;
1104  a3[0] = w3[0] ^ 0x36363636;
1105  a3[1] = w3[1] ^ 0x36363636;
1106  a3[2] = w3[2] ^ 0x36363636;
1107  a3[3] = w3[3] ^ 0x36363636;
1108
1109  streebog512_init (&ctx->ipad, s_sbob_sl64);
1110
1111  streebog512_update_64 (&ctx->ipad, a0, a1, a2, a3, 64);
1112
1113  // opad
1114
1115  u32 b0[4];
1116  u32 b1[4];
1117  u32 b2[4];
1118  u32 b3[4];
1119
1120  b0[0] = w0[0] ^ 0x5c5c5c5c;
1121  b0[1] = w0[1] ^ 0x5c5c5c5c;
1122  b0[2] = w0[2] ^ 0x5c5c5c5c;
1123  b0[3] = w0[3] ^ 0x5c5c5c5c;
1124  b1[0] = w1[0] ^ 0x5c5c5c5c;
1125  b1[1] = w1[1] ^ 0x5c5c5c5c;
1126  b1[2] = w1[2] ^ 0x5c5c5c5c;
1127  b1[3] = w1[3] ^ 0x5c5c5c5c;
1128  b2[0] = w2[0] ^ 0x5c5c5c5c;
1129  b2[1] = w2[1] ^ 0x5c5c5c5c;
1130  b2[2] = w2[2] ^ 0x5c5c5c5c;
1131  b2[3] = w2[3] ^ 0x5c5c5c5c;
1132  b3[0] = w3[0] ^ 0x5c5c5c5c;
1133  b3[1] = w3[1] ^ 0x5c5c5c5c;
1134  b3[2] = w3[2] ^ 0x5c5c5c5c;
1135  b3[3] = w3[3] ^ 0x5c5c5c5c;
1136
1137  streebog512_init (&ctx->opad, s_sbob_sl64);
1138
1139  streebog512_update_64 (&ctx->opad, b0, b1, b2, b3, 64);
1140}
1141
1142DECLSPEC void streebog512_hmac_init (streebog512_hmac_ctx_t *ctx, const u32 *w, const int len, SHM_TYPE u64a (*s_sbob_sl64)[256])
1143{
1144  u32 w0[4];
1145  u32 w1[4];
1146  u32 w2[4];
1147  u32 w3[4];
1148
1149  if (len > 64)
1150  {
1151    streebog512_ctx_t tmp;
1152
1153    streebog512_init (&tmp, s_sbob_sl64);
1154
1155    streebog512_update (&tmp, w, len);
1156
1157    streebog512_final (&tmp);
1158
1159    w0[0] = h32_from_64_S (tmp.h[7]);
1160    w0[1] = l32_from_64_S (tmp.h[7]);
1161    w0[2] = h32_from_64_S (tmp.h[6]);
1162    w0[3] = l32_from_64_S (tmp.h[6]);
1163    w1[0] = h32_from_64_S (tmp.h[5]);
1164    w1[1] = l32_from_64_S (tmp.h[5]);
1165    w1[2] = h32_from_64_S (tmp.h[4]);
1166    w1[3] = l32_from_64_S (tmp.h[4]);
1167    w2[0] = h32_from_64_S (tmp.h[3]);
1168    w2[1] = l32_from_64_S (tmp.h[3]);
1169    w2[2] = h32_from_64_S (tmp.h[2]);
1170    w2[3] = l32_from_64_S (tmp.h[2]);
1171    w3[0] = h32_from_64_S (tmp.h[1]);
1172    w3[1] = l32_from_64_S (tmp.h[1]);
1173    w3[2] = h32_from_64_S (tmp.h[0]);
1174    w3[3] = l32_from_64_S (tmp.h[0]);
1175  }
1176  else
1177  {
1178    w0[0] = w[ 0];
1179    w0[1] = w[ 1];
1180    w0[2] = w[ 2];
1181    w0[3] = w[ 3];
1182    w1[0] = w[ 4];
1183    w1[1] = w[ 5];
1184    w1[2] = w[ 6];
1185    w1[3] = w[ 7];
1186    w2[0] = w[ 8];
1187    w2[1] = w[ 9];
1188    w2[2] = w[10];
1189    w2[3] = w[11];
1190    w3[0] = w[12];
1191    w3[1] = w[13];
1192    w3[2] = w[14];
1193    w3[3] = w[15];
1194  }
1195
1196  streebog512_hmac_init_64 (ctx, w0, w1, w2, w3, s_sbob_sl64);
1197}
1198
1199DECLSPEC void streebog512_hmac_init_swap (streebog512_hmac_ctx_t *ctx, const u32 *w, const int len, SHM_TYPE u64a (*s_sbob_sl64)[256])
1200{
1201  u32 w0[4];
1202  u32 w1[4];
1203  u32 w2[4];
1204  u32 w3[4];
1205
1206  if (len > 64)
1207  {
1208    streebog512_ctx_t tmp;
1209
1210    streebog512_init (&tmp, s_sbob_sl64);
1211
1212    streebog512_update_swap (&tmp, w, len);
1213
1214    streebog512_final (&tmp);
1215
1216    w0[0] = h32_from_64_S (tmp.h[7]);
1217    w0[1] = l32_from_64_S (tmp.h[7]);
1218    w0[2] = h32_from_64_S (tmp.h[6]);
1219    w0[3] = l32_from_64_S (tmp.h[6]);
1220    w1[0] = h32_from_64_S (tmp.h[5]);
1221    w1[1] = l32_from_64_S (tmp.h[5]);
1222    w1[2] = h32_from_64_S (tmp.h[4]);
1223    w1[3] = l32_from_64_S (tmp.h[4]);
1224    w2[0] = h32_from_64_S (tmp.h[3]);
1225    w2[1] = l32_from_64_S (tmp.h[3]);
1226    w2[2] = h32_from_64_S (tmp.h[2]);
1227    w2[3] = l32_from_64_S (tmp.h[2]);
1228    w3[0] = h32_from_64_S (tmp.h[1]);
1229    w3[1] = l32_from_64_S (tmp.h[1]);
1230    w3[2] = h32_from_64_S (tmp.h[0]);
1231    w3[3] = l32_from_64_S (tmp.h[0]);
1232  }
1233  else
1234  {
1235    w0[0] = hc_swap32_S (w[ 0]);
1236    w0[1] = hc_swap32_S (w[ 1]);
1237    w0[2] = hc_swap32_S (w[ 2]);
1238    w0[3] = hc_swap32_S (w[ 3]);
1239    w1[0] = hc_swap32_S (w[ 4]);
1240    w1[1] = hc_swap32_S (w[ 5]);
1241    w1[2] = hc_swap32_S (w[ 6]);
1242    w1[3] = hc_swap32_S (w[ 7]);
1243    w2[0] = hc_swap32_S (w[ 8]);
1244    w2[1] = hc_swap32_S (w[ 9]);
1245    w2[2] = hc_swap32_S (w[10]);
1246    w2[3] = hc_swap32_S (w[11]);
1247    w3[0] = hc_swap32_S (w[12]);
1248    w3[1] = hc_swap32_S (w[13]);
1249    w3[2] = hc_swap32_S (w[14]);
1250    w3[3] = hc_swap32_S (w[15]);
1251  }
1252
1253  streebog512_hmac_init_64 (ctx, w0, w1, w2, w3, s_sbob_sl64);
1254}
1255
1256DECLSPEC void streebog512_hmac_update_64 (streebog512_hmac_ctx_t *ctx, u32 *w0, u32 *w1, u32 *w2, u32 *w3, const int len)
1257{
1258  streebog512_update_64 (&ctx->ipad, w0, w1, w2, w3, len);
1259}
1260
1261DECLSPEC void streebog512_hmac_update (streebog512_hmac_ctx_t *ctx, const u32 *w, const int len)
1262{
1263  streebog512_update (&ctx->ipad, w, len);
1264}
1265
1266DECLSPEC void streebog512_hmac_update_swap (streebog512_hmac_ctx_t *ctx, const u32 *w, const int len)
1267{
1268  streebog512_update_swap (&ctx->ipad, w, len);
1269}
1270
1271DECLSPEC void streebog512_hmac_update_global_swap (streebog512_hmac_ctx_t *ctx, GLOBAL_AS const u32 *w, const int len)
1272{
1273  streebog512_update_global_swap (&ctx->ipad, w, len);
1274}
1275
1276DECLSPEC void streebog512_hmac_final (streebog512_hmac_ctx_t *ctx)
1277{
1278  streebog512_final (&ctx->ipad);
1279
1280  ctx->opad.w0[0] = h32_from_64_S (ctx->ipad.h[7]);
1281  ctx->opad.w0[1] = l32_from_64_S (ctx->ipad.h[7]);
1282  ctx->opad.w0[2] = h32_from_64_S (ctx->ipad.h[6]);
1283  ctx->opad.w0[3] = l32_from_64_S (ctx->ipad.h[6]);
1284  ctx->opad.w1[0] = h32_from_64_S (ctx->ipad.h[5]);
1285  ctx->opad.w1[1] = l32_from_64_S (ctx->ipad.h[5]);
1286  ctx->opad.w1[2] = h32_from_64_S (ctx->ipad.h[4]);
1287  ctx->opad.w1[3] = l32_from_64_S (ctx->ipad.h[4]);
1288  ctx->opad.w2[0] = h32_from_64_S (ctx->ipad.h[3]);
1289  ctx->opad.w2[1] = l32_from_64_S (ctx->ipad.h[3]);
1290  ctx->opad.w2[2] = h32_from_64_S (ctx->ipad.h[2]);
1291  ctx->opad.w2[3] = l32_from_64_S (ctx->ipad.h[2]);
1292  ctx->opad.w3[0] = h32_from_64_S (ctx->ipad.h[1]);
1293  ctx->opad.w3[1] = l32_from_64_S (ctx->ipad.h[1]);
1294  ctx->opad.w3[2] = h32_from_64_S (ctx->ipad.h[0]);
1295  ctx->opad.w3[3] = l32_from_64_S (ctx->ipad.h[0]);
1296
1297  ctx->opad.len = 0;
1298
1299  streebog512_transform (&ctx->opad, ctx->opad.w0, ctx->opad.w1, ctx->opad.w2, ctx->opad.w3);
1300
1301  ctx->opad.w0[0] = 0;
1302  ctx->opad.w0[1] = 0;
1303  ctx->opad.w0[2] = 0;
1304  ctx->opad.w0[3] = 0;
1305  ctx->opad.w1[0] = 0;
1306  ctx->opad.w1[1] = 0;
1307  ctx->opad.w1[2] = 0;
1308  ctx->opad.w1[3] = 0;
1309  ctx->opad.w2[0] = 0;
1310  ctx->opad.w2[1] = 0;
1311  ctx->opad.w2[2] = 0;
1312  ctx->opad.w2[3] = 0;
1313  ctx->opad.w3[0] = 0;
1314  ctx->opad.w3[1] = 0;
1315  ctx->opad.w3[2] = 0;
1316  ctx->opad.w3[3] = 0;
1317
1318  streebog512_final (&ctx->opad);
1319}
1320
1321DECLSPEC void streebog512_init_vector (streebog512_ctx_vector_t *ctx, SHM_TYPE u64a (*s_sbob_sl64)[256])
1322{
1323  ctx->h[0] = 0;
1324  ctx->h[1] = 0;
1325  ctx->h[2] = 0;
1326  ctx->h[3] = 0;
1327  ctx->h[4] = 0;
1328  ctx->h[5] = 0;
1329  ctx->h[6] = 0;
1330  ctx->h[7] = 0;
1331
1332  ctx->s[0] = 0;
1333  ctx->s[1] = 0;
1334  ctx->s[2] = 0;
1335  ctx->s[3] = 0;
1336  ctx->s[4] = 0;
1337  ctx->s[5] = 0;
1338  ctx->s[6] = 0;
1339  ctx->s[7] = 0;
1340
1341  ctx->n[0] = 0;
1342  ctx->n[1] = 0;
1343  ctx->n[2] = 0;
1344  ctx->n[3] = 0;
1345  ctx->n[4] = 0;
1346  ctx->n[5] = 0;
1347  ctx->n[6] = 0;
1348  ctx->n[7] = 0;
1349
1350  ctx->w0[0] = 0;
1351  ctx->w0[1] = 0;
1352  ctx->w0[2] = 0;
1353  ctx->w0[3] = 0;
1354
1355  ctx->w1[0] = 0;
1356  ctx->w1[1] = 0;
1357  ctx->w1[2] = 0;
1358  ctx->w1[3] = 0;
1359
1360  ctx->w2[0] = 0;
1361  ctx->w2[1] = 0;
1362  ctx->w2[2] = 0;
1363  ctx->w2[3] = 0;
1364
1365  ctx->w3[0] = 0;
1366  ctx->w3[1] = 0;
1367  ctx->w3[2] = 0;
1368  ctx->w3[3] = 0;
1369
1370  ctx->len = 0;
1371
1372  ctx->s_sbob_sl64 = s_sbob_sl64;
1373}
1374
1375DECLSPEC void streebog512_add_vector (u64x *x, const u64x *y)
1376{
1377  u64x carry = 0;
1378
1379  #ifdef _unroll
1380  #pragma unroll
1381  #endif
1382  for (int i = 7; i >=0; i--)
1383  {
1384    const u64x left  = hc_swap64 (x[i]);
1385    const u64x right = hc_swap64 (y[i]);
1386    const u64x sum   = left + right + carry;
1387
1388    carry = (sum < left) ? make_u64x (1) : make_u64x (0);
1389
1390    x[i] = hc_swap64 (sum);
1391  }
1392}
1393
1394DECLSPEC void streebog512_g_vector (u64x *h, const u64x *n, const u64x *m, SHM_TYPE u64a (*s_sbob_sl64)[256])
1395{
1396  u64x k[8];
1397  u64x s[8];
1398  u64x t[8];
1399
1400  #ifdef _unroll
1401  #pragma unroll
1402  #endif
1403  for (int i = 0; i < 8; i++)
1404  {
1405    t[i] = h[i] ^ n[i];
1406  }
1407
1408  for (int i = 0; i < 8; i++)
1409  {
1410    k[i] = SBOG_LPSti64;
1411  }
1412
1413  #ifdef _unroll
1414  #pragma unroll
1415  #endif
1416  for (int i = 0; i < 8; i++)
1417  {
1418    s[i] = m[i];
1419  }
1420
1421  for (int r = 0; r < 12; r++)
1422  {
1423    #ifdef _unroll
1424    #pragma unroll
1425    #endif
1426    for (int i = 0; i < 8; i++)
1427    {
1428      t[i] = s[i] ^ k[i];
1429    }
1430
1431    #ifdef _unroll
1432    #pragma unroll
1433    #endif
1434    for (int i = 0; i < 8; i++)
1435    {
1436      s[i] = SBOG_LPSti64;
1437    }
1438
1439    for (int i = 0; i < 8; i++)
1440    {
1441      t[i] = k[i] ^ sbob512_rc64[r][i];
1442    }
1443
1444    #ifdef _unroll
1445    #pragma unroll
1446    #endif
1447    for (int i = 0; i < 8; i++)
1448    {
1449      k[i] = SBOG_LPSti64;
1450    }
1451  }
1452
1453  #ifdef _unroll
1454  #pragma unroll
1455  #endif
1456  for (int i = 0; i < 8; i++)
1457  {
1458    h[i] ^= s[i] ^ k[i] ^ m[i];
1459  }
1460}
1461
1462DECLSPEC void streebog512_transform_vector (streebog512_ctx_vector_t *ctx, const u32x *w0, const u32x *w1, const u32x *w2, const u32x *w3)
1463{
1464  u64x m[8];
1465
1466  m[0] = hl32_to_64 (w3[2], w3[3]);
1467  m[1] = hl32_to_64 (w3[0], w3[1]);
1468  m[2] = hl32_to_64 (w2[2], w2[3]);
1469  m[3] = hl32_to_64 (w2[0], w2[1]);
1470  m[4] = hl32_to_64 (w1[2], w1[3]);
1471  m[5] = hl32_to_64 (w1[0], w1[1]);
1472  m[6] = hl32_to_64 (w0[2], w0[3]);
1473  m[7] = hl32_to_64 (w0[0], w0[1]);
1474
1475  streebog512_g_vector (ctx->h, ctx->n, m, ctx->s_sbob_sl64);
1476
1477  u64x counterbuf[8] = { 0 };
1478  counterbuf[7] = 0x0002000000000000UL;
1479  streebog512_add_vector (ctx->n, counterbuf);
1480
1481  streebog512_add_vector (ctx->s, m);
1482}
1483
1484DECLSPEC void streebog512_update_vector_64 (streebog512_ctx_vector_t *ctx, u32x *w0, u32x *w1, u32x *w2, u32x *w3, const int len)
1485{
1486  if (len == 0) return;
1487
1488  const int pos = ctx->len & 63;
1489
1490  ctx->len += len;
1491
1492  if (pos == 0)
1493  {
1494    ctx->w0[0] = w0[0];
1495    ctx->w0[1] = w0[1];
1496    ctx->w0[2] = w0[2];
1497    ctx->w0[3] = w0[3];
1498    ctx->w1[0] = w1[0];
1499    ctx->w1[1] = w1[1];
1500    ctx->w1[2] = w1[2];
1501    ctx->w1[3] = w1[3];
1502    ctx->w2[0] = w2[0];
1503    ctx->w2[1] = w2[1];
1504    ctx->w2[2] = w2[2];
1505    ctx->w2[3] = w2[3];
1506    ctx->w3[0] = w3[0];
1507    ctx->w3[1] = w3[1];
1508    ctx->w3[2] = w3[2];
1509    ctx->w3[3] = w3[3];
1510
1511    if (len == 64)
1512    {
1513      streebog512_transform_vector (ctx, ctx->w0, ctx->w1, ctx->w2, ctx->w3);
1514
1515      ctx->w0[0] = 0;
1516      ctx->w0[1] = 0;
1517      ctx->w0[2] = 0;
1518      ctx->w0[3] = 0;
1519      ctx->w1[0] = 0;
1520      ctx->w1[1] = 0;
1521      ctx->w1[2] = 0;
1522      ctx->w1[3] = 0;
1523      ctx->w2[0] = 0;
1524      ctx->w2[1] = 0;
1525      ctx->w2[2] = 0;
1526      ctx->w2[3] = 0;
1527      ctx->w3[0] = 0;
1528      ctx->w3[1] = 0;
1529      ctx->w3[2] = 0;
1530      ctx->w3[3] = 0;
1531    }
1532  }
1533  else
1534  {
1535    if ((pos + len) < 64)
1536    {
1537      switch_buffer_by_offset_be (w0, w1, w2, w3, pos);
1538
1539      ctx->w0[0] |= w0[0];
1540      ctx->w0[1] |= w0[1];
1541      ctx->w0[2] |= w0[2];
1542      ctx->w0[3] |= w0[3];
1543      ctx->w1[0] |= w1[0];
1544      ctx->w1[1] |= w1[1];
1545      ctx->w1[2] |= w1[2];
1546      ctx->w1[3] |= w1[3];
1547      ctx->w2[0] |= w2[0];
1548      ctx->w2[1] |= w2[1];
1549      ctx->w2[2] |= w2[2];
1550      ctx->w2[3] |= w2[3];
1551      ctx->w3[0] |= w3[0];
1552      ctx->w3[1] |= w3[1];
1553      ctx->w3[2] |= w3[2];
1554      ctx->w3[3] |= w3[3];
1555    }
1556    else
1557    {
1558      u32x c0[4] = { 0 };
1559      u32x c1[4] = { 0 };
1560      u32x c2[4] = { 0 };
1561      u32x c3[4] = { 0 };
1562
1563      switch_buffer_by_offset_carry_be (w0, w1, w2, w3, c0, c1, c2, c3, pos);
1564
1565      ctx->w0[0] |= w0[0];
1566      ctx->w0[1] |= w0[1];
1567      ctx->w0[2] |= w0[2];
1568      ctx->w0[3] |= w0[3];
1569      ctx->w1[0] |= w1[0];
1570      ctx->w1[1] |= w1[1];
1571      ctx->w1[2] |= w1[2];
1572      ctx->w1[3] |= w1[3];
1573      ctx->w2[0] |= w2[0];
1574      ctx->w2[1] |= w2[1];
1575      ctx->w2[2] |= w2[2];
1576      ctx->w2[3] |= w2[3];
1577      ctx->w3[0] |= w3[0];
1578      ctx->w3[1] |= w3[1];
1579      ctx->w3[2] |= w3[2];
1580      ctx->w3[3] |= w3[3];
1581
1582      streebog512_transform_vector (ctx, ctx->w0, ctx->w1, ctx->w2, ctx->w3);
1583
1584      ctx->w0[0] = c0[0];
1585      ctx->w0[1] = c0[1];
1586      ctx->w0[2] = c0[2];
1587      ctx->w0[3] = c0[3];
1588      ctx->w1[0] = c1[0];
1589      ctx->w1[1] = c1[1];
1590      ctx->w1[2] = c1[2];
1591      ctx->w1[3] = c1[3];
1592      ctx->w2[0] = c2[0];
1593      ctx->w2[1] = c2[1];
1594      ctx->w2[2] = c2[2];
1595      ctx->w2[3] = c2[3];
1596      ctx->w3[0] = c3[0];
1597      ctx->w3[1] = c3[1];
1598      ctx->w3[2] = c3[2];
1599      ctx->w3[3] = c3[3];
1600    }
1601  }
1602}
1603
1604DECLSPEC void streebog512_update_vector (streebog512_ctx_vector_t *ctx, const u32x *w, int len)
1605{
1606  u32x w0[4];
1607  u32x w1[4];
1608  u32x w2[4];
1609  u32x w3[4];
1610
1611  int off = 0;
1612
1613  while (len > 63)
1614  {
1615    w0[0] = w[off +  0];
1616    w0[1] = w[off +  1];
1617    w0[2] = w[off +  2];
1618    w0[3] = w[off +  3];
1619    w1[0] = w[off +  4];
1620    w1[1] = w[off +  5];
1621    w1[2] = w[off +  6];
1622    w1[3] = w[off +  7];
1623    w2[0] = w[off +  8];
1624    w2[1] = w[off +  9];
1625    w2[2] = w[off + 10];
1626    w2[3] = w[off + 11];
1627    w3[0] = w[off + 12];
1628    w3[1] = w[off + 13];
1629    w3[2] = w[off + 14];
1630    w3[3] = w[off + 15];
1631
1632    off += 16;
1633    len -= 64;
1634
1635    streebog512_update_vector_64 (ctx, w0, w1, w2, w3, 64);
1636  }
1637
1638  if (len > 0)
1639  {
1640    w0[0] = w[off +  0];
1641    w0[1] = w[off +  1];
1642    w0[2] = w[off +  2];
1643    w0[3] = w[off +  3];
1644    w1[0] = w[off +  4];
1645    w1[1] = w[off +  5];
1646    w1[2] = w[off +  6];
1647    w1[3] = w[off +  7];
1648    w2[0] = w[off +  8];
1649    w2[1] = w[off +  9];
1650    w2[2] = w[off + 10];
1651    w2[3] = w[off + 11];
1652    w3[0] = w[off + 12];
1653    w3[1] = w[off + 13];
1654    w3[2] = w[off + 14];
1655    w3[3] = w[off + 15];
1656
1657    streebog512_update_vector_64 (ctx, w0, w1, w2, w3, len);
1658  }
1659}
1660
1661DECLSPEC void streebog512_update_vector_swap (streebog512_ctx_vector_t *ctx, const u32x *w, int len)
1662{
1663  u32x w0[4];
1664  u32x w1[4];
1665  u32x w2[4];
1666  u32x w3[4];
1667
1668  int off = 0;
1669
1670  while (len > 63)
1671  {
1672    w0[0] = hc_swap32 (w[off +  0]);
1673    w0[1] = hc_swap32 (w[off +  1]);
1674    w0[2] = hc_swap32 (w[off +  2]);
1675    w0[3] = hc_swap32 (w[off +  3]);
1676    w1[0] = hc_swap32 (w[off +  4]);
1677    w1[1] = hc_swap32 (w[off +  5]);
1678    w1[2] = hc_swap32 (w[off +  6]);
1679    w1[3] = hc_swap32 (w[off +  7]);
1680    w2[0] = hc_swap32 (w[off +  8]);
1681    w2[1] = hc_swap32 (w[off +  9]);
1682    w2[2] = hc_swap32 (w[off + 10]);
1683    w2[3] = hc_swap32 (w[off + 11]);
1684    w3[0] = hc_swap32 (w[off + 12]);
1685    w3[1] = hc_swap32 (w[off + 13]);
1686    w3[2] = hc_swap32 (w[off + 14]);
1687    w3[3] = hc_swap32 (w[off + 15]);
1688
1689    off += 16;
1690    len -= 64;
1691
1692    streebog512_update_vector_64 (ctx, w0, w1, w2, w3, 64);
1693  }
1694
1695  if (len > 0)
1696  {
1697    w0[0] = hc_swap32 (w[off +  0]);
1698    w0[1] = hc_swap32 (w[off +  1]);
1699    w0[2] = hc_swap32 (w[off +  2]);
1700    w0[3] = hc_swap32 (w[off +  3]);
1701    w1[0] = hc_swap32 (w[off +  4]);
1702    w1[1] = hc_swap32 (w[off +  5]);
1703    w1[2] = hc_swap32 (w[off +  6]);
1704    w1[3] = hc_swap32 (w[off +  7]);
1705    w2[0] = hc_swap32 (w[off +  8]);
1706    w2[1] = hc_swap32 (w[off +  9]);
1707    w2[2] = hc_swap32 (w[off + 10]);
1708    w2[3] = hc_swap32 (w[off + 11]);
1709    w3[0] = hc_swap32 (w[off + 12]);
1710    w3[1] = hc_swap32 (w[off + 13]);
1711    w3[2] = hc_swap32 (w[off + 14]);
1712    w3[3] = hc_swap32 (w[off + 15]);
1713
1714    streebog512_update_vector_64 (ctx, w0, w1, w2, w3, len);
1715  }
1716}
1717
1718DECLSPEC void streebog512_final_vector (streebog512_ctx_vector_t *ctx)
1719{
1720  const int pos = ctx->len & 63;
1721
1722  append_0x01_4x4_VV (ctx->w0, ctx->w1, ctx->w2, ctx->w3, pos ^ 3);
1723
1724  u64x m[8];
1725
1726  m[0] = hl32_to_64 (ctx->w3[2], ctx->w3[3]);
1727  m[1] = hl32_to_64 (ctx->w3[0], ctx->w3[1]);
1728  m[2] = hl32_to_64 (ctx->w2[2], ctx->w2[3]);
1729  m[3] = hl32_to_64 (ctx->w2[0], ctx->w2[1]);
1730  m[4] = hl32_to_64 (ctx->w1[2], ctx->w1[3]);
1731  m[5] = hl32_to_64 (ctx->w1[0], ctx->w1[1]);
1732  m[6] = hl32_to_64 (ctx->w0[2], ctx->w0[3]);
1733  m[7] = hl32_to_64 (ctx->w0[0], ctx->w0[1]);
1734
1735  streebog512_g_vector (ctx->h, ctx->n, m, ctx->s_sbob_sl64);
1736
1737  u64x sizebuf[8] = { 0 };
1738  sizebuf[7] = hc_swap64 (make_u64x (pos << 3));
1739
1740  streebog512_add_vector (ctx->n, sizebuf);
1741
1742  streebog512_add_vector (ctx->s, m);
1743
1744  const u64x nullbuf[8] = { 0 };
1745
1746  streebog512_g_vector (ctx->h, nullbuf, ctx->n, ctx->s_sbob_sl64);
1747
1748  streebog512_g_vector (ctx->h, nullbuf, ctx->s, ctx->s_sbob_sl64);
1749}
1750
1751DECLSPEC void streebog512_hmac_init_vector_64 (streebog512_hmac_ctx_vector_t *ctx, const u32x *w0, const u32x *w1, const u32x *w2, const u32x *w3, SHM_TYPE u64a (*s_sbob_sl64)[256])
1752{
1753  u32x a0[4];
1754  u32x a1[4];
1755  u32x a2[4];
1756  u32x a3[4];
1757
1758  // ipad
1759
1760  a0[0] = w0[0] ^ 0x36363636;
1761  a0[1] = w0[1] ^ 0x36363636;
1762  a0[2] = w0[2] ^ 0x36363636;
1763  a0[3] = w0[3] ^ 0x36363636;
1764  a1[0] = w1[0] ^ 0x36363636;
1765  a1[1] = w1[1] ^ 0x36363636;
1766  a1[2] = w1[2] ^ 0x36363636;
1767  a1[3] = w1[3] ^ 0x36363636;
1768  a2[0] = w2[0] ^ 0x36363636;
1769  a2[1] = w2[1] ^ 0x36363636;
1770  a2[2] = w2[2] ^ 0x36363636;
1771  a2[3] = w2[3] ^ 0x36363636;
1772  a3[0] = w3[0] ^ 0x36363636;
1773  a3[1] = w3[1] ^ 0x36363636;
1774  a3[2] = w3[2] ^ 0x36363636;
1775  a3[3] = w3[3] ^ 0x36363636;
1776
1777  streebog512_init_vector (&ctx->ipad, s_sbob_sl64);
1778
1779  streebog512_update_vector_64 (&ctx->ipad, a0, a1, a2, a3, 64);
1780
1781  // opad
1782
1783  u32x b0[4];
1784  u32x b1[4];
1785  u32x b2[4];
1786  u32x b3[4];
1787
1788  b0[0] = w0[0] ^ 0x5c5c5c5c;
1789  b0[1] = w0[1] ^ 0x5c5c5c5c;
1790  b0[2] = w0[2] ^ 0x5c5c5c5c;
1791  b0[3] = w0[3] ^ 0x5c5c5c5c;
1792  b1[0] = w1[0] ^ 0x5c5c5c5c;
1793  b1[1] = w1[1] ^ 0x5c5c5c5c;
1794  b1[2] = w1[2] ^ 0x5c5c5c5c;
1795  b1[3] = w1[3] ^ 0x5c5c5c5c;
1796  b2[0] = w2[0] ^ 0x5c5c5c5c;
1797  b2[1] = w2[1] ^ 0x5c5c5c5c;
1798  b2[2] = w2[2] ^ 0x5c5c5c5c;
1799  b2[3] = w2[3] ^ 0x5c5c5c5c;
1800  b3[0] = w3[0] ^ 0x5c5c5c5c;
1801  b3[1] = w3[1] ^ 0x5c5c5c5c;
1802  b3[2] = w3[2] ^ 0x5c5c5c5c;
1803  b3[3] = w3[3] ^ 0x5c5c5c5c;
1804
1805  streebog512_init_vector (&ctx->opad, s_sbob_sl64);
1806
1807  streebog512_update_vector_64 (&ctx->opad, b0, b1, b2, b3, 64);
1808}
1809
1810DECLSPEC void streebog512_hmac_init_vector (streebog512_hmac_ctx_vector_t *ctx, const u32x *w, const int len, SHM_TYPE u64a (*s_sbob_sl64)[256])
1811{
1812  u32x w0[4];
1813  u32x w1[4];
1814  u32x w2[4];
1815  u32x w3[4];
1816
1817  if (len > 64)
1818  {
1819    streebog512_ctx_vector_t tmp;
1820
1821    streebog512_init_vector (&tmp, s_sbob_sl64);
1822
1823    streebog512_update_vector (&tmp, w, len);
1824
1825    streebog512_final_vector (&tmp);
1826
1827    w0[0] = h32_from_64 (tmp.h[7]);
1828    w0[1] = l32_from_64 (tmp.h[7]);
1829    w0[2] = h32_from_64 (tmp.h[6]);
1830    w0[3] = l32_from_64 (tmp.h[6]);
1831    w1[0] = h32_from_64 (tmp.h[5]);
1832    w1[1] = l32_from_64 (tmp.h[5]);
1833    w1[2] = h32_from_64 (tmp.h[4]);
1834    w1[3] = l32_from_64 (tmp.h[4]);
1835    w2[0] = h32_from_64 (tmp.h[3]);
1836    w2[1] = l32_from_64 (tmp.h[3]);
1837    w2[2] = h32_from_64 (tmp.h[2]);
1838    w2[3] = l32_from_64 (tmp.h[2]);
1839    w3[0] = h32_from_64 (tmp.h[1]);
1840    w3[1] = l32_from_64 (tmp.h[1]);
1841    w3[2] = h32_from_64 (tmp.h[0]);
1842    w3[3] = l32_from_64 (tmp.h[0]);
1843  }
1844  else
1845  {
1846    w0[0] = w[ 0];
1847    w0[1] = w[ 1];
1848    w0[2] = w[ 2];
1849    w0[3] = w[ 3];
1850    w1[0] = w[ 4];
1851    w1[1] = w[ 5];
1852    w1[2] = w[ 6];
1853    w1[3] = w[ 7];
1854    w2[0] = w[ 8];
1855    w2[1] = w[ 9];
1856    w2[2] = w[10];
1857    w2[3] = w[11];
1858    w3[0] = w[12];
1859    w3[1] = w[13];
1860    w3[2] = w[14];
1861    w3[3] = w[15];
1862  }
1863
1864  streebog512_hmac_init_vector_64 (ctx, w0, w1, w2, w3, s_sbob_sl64);
1865}
1866
1867DECLSPEC void streebog512_hmac_init_vector_swap (streebog512_hmac_ctx_vector_t *ctx, const u32x *w, const int len, SHM_TYPE u64a (*s_sbob_sl64)[256])
1868{
1869  u32x w0[4];
1870  u32x w1[4];
1871  u32x w2[4];
1872  u32x w3[4];
1873
1874  if (len > 64)
1875  {
1876    streebog512_ctx_vector_t tmp;
1877
1878    streebog512_init_vector (&tmp, s_sbob_sl64);
1879
1880    streebog512_update_vector_swap (&tmp, w, len);
1881
1882    streebog512_final_vector (&tmp);
1883
1884    w0[0] = h32_from_64 (tmp.h[7]);
1885    w0[1] = l32_from_64 (tmp.h[7]);
1886    w0[2] = h32_from_64 (tmp.h[6]);
1887    w0[3] = l32_from_64 (tmp.h[6]);
1888    w1[0] = h32_from_64 (tmp.h[5]);
1889    w1[1] = l32_from_64 (tmp.h[5]);
1890    w1[2] = h32_from_64 (tmp.h[4]);
1891    w1[3] = l32_from_64 (tmp.h[4]);
1892    w2[0] = h32_from_64 (tmp.h[3]);
1893    w2[1] = l32_from_64 (tmp.h[3]);
1894    w2[2] = h32_from_64 (tmp.h[2]);
1895    w2[3] = l32_from_64 (tmp.h[2]);
1896    w3[0] = h32_from_64 (tmp.h[1]);
1897    w3[1] = l32_from_64 (tmp.h[1]);
1898    w3[2] = h32_from_64 (tmp.h[0]);
1899    w3[3] = l32_from_64 (tmp.h[0]);
1900  }
1901  else
1902  {
1903    w0[0] = hc_swap32 (w[ 0]);
1904    w0[1] = hc_swap32 (w[ 1]);
1905    w0[2] = hc_swap32 (w[ 2]);
1906    w0[3] = hc_swap32 (w[ 3]);
1907    w1[0] = hc_swap32 (w[ 4]);
1908    w1[1] = hc_swap32 (w[ 5]);
1909    w1[2] = hc_swap32 (w[ 6]);
1910    w1[3] = hc_swap32 (w[ 7]);
1911    w2[0] = hc_swap32 (w[ 8]);
1912    w2[1] = hc_swap32 (w[ 9]);
1913    w2[2] = hc_swap32 (w[10]);
1914    w2[3] = hc_swap32 (w[11]);
1915    w3[0] = hc_swap32 (w[12]);
1916    w3[1] = hc_swap32 (w[13]);
1917    w3[2] = hc_swap32 (w[14]);
1918    w3[3] = hc_swap32 (w[15]);
1919  }
1920
1921  streebog512_hmac_init_vector_64 (ctx, w0, w1, w2, w3, s_sbob_sl64);
1922}
1923
1924DECLSPEC void streebog512_hmac_update_vector (streebog512_hmac_ctx_vector_t *ctx, const u32x *w, const int len)
1925{
1926  streebog512_update_vector (&ctx->ipad, w, len);
1927}
1928
1929DECLSPEC void streebog512_hmac_update_vector_swap (streebog512_hmac_ctx_vector_t *ctx, const u32x *w, const int len)
1930{
1931  streebog512_update_vector_swap (&ctx->ipad, w, len);
1932}
1933
1934DECLSPEC void streebog512_hmac_final_vector (streebog512_hmac_ctx_vector_t *ctx)
1935{
1936  streebog512_final_vector (&ctx->ipad);
1937
1938  ctx->opad.w0[0] = h32_from_64 (ctx->ipad.h[7]);
1939  ctx->opad.w0[1] = l32_from_64 (ctx->ipad.h[7]);
1940  ctx->opad.w0[2] = h32_from_64 (ctx->ipad.h[6]);
1941  ctx->opad.w0[3] = l32_from_64 (ctx->ipad.h[6]);
1942  ctx->opad.w1[0] = h32_from_64 (ctx->ipad.h[5]);
1943  ctx->opad.w1[1] = l32_from_64 (ctx->ipad.h[5]);
1944  ctx->opad.w1[2] = h32_from_64 (ctx->ipad.h[4]);
1945  ctx->opad.w1[3] = l32_from_64 (ctx->ipad.h[4]);
1946  ctx->opad.w2[0] = h32_from_64 (ctx->ipad.h[3]);
1947  ctx->opad.w2[1] = l32_from_64 (ctx->ipad.h[3]);
1948  ctx->opad.w2[2] = h32_from_64 (ctx->ipad.h[2]);
1949  ctx->opad.w2[3] = l32_from_64 (ctx->ipad.h[2]);
1950  ctx->opad.w3[0] = h32_from_64 (ctx->ipad.h[1]);
1951  ctx->opad.w3[1] = l32_from_64 (ctx->ipad.h[1]);
1952  ctx->opad.w3[2] = h32_from_64 (ctx->ipad.h[0]);
1953  ctx->opad.w3[3] = l32_from_64 (ctx->ipad.h[0]);
1954
1955  ctx->opad.len = 0;
1956
1957  streebog512_transform_vector (&ctx->opad, ctx->opad.w0, ctx->opad.w1, ctx->opad.w2, ctx->opad.w3);
1958
1959  ctx->opad.w0[0] = 0;
1960  ctx->opad.w0[1] = 0;
1961  ctx->opad.w0[2] = 0;
1962  ctx->opad.w0[3] = 0;
1963  ctx->opad.w1[0] = 0;
1964  ctx->opad.w1[1] = 0;
1965  ctx->opad.w1[2] = 0;
1966  ctx->opad.w1[3] = 0;
1967  ctx->opad.w2[0] = 0;
1968  ctx->opad.w2[1] = 0;
1969  ctx->opad.w2[2] = 0;
1970  ctx->opad.w2[3] = 0;
1971  ctx->opad.w3[0] = 0;
1972  ctx->opad.w3[1] = 0;
1973  ctx->opad.w3[2] = 0;
1974  ctx->opad.w3[3] = 0;
1975
1976  streebog512_final_vector (&ctx->opad);
1977}
1978