1 /**
2 	Niels Provos' and David Mazières' bcrypt, a crypt(3) algorithm based on Bruce Schneier's Blowfish cipher
3 
4 	The main export is the `Bcrypt` struct.  The `genSalt()` method takes an optional cost parameter.
5 
6 	The high-level algorithm is described at https://en.wikipedia.org/w/index.php?title=Bcrypt&oldid=962257995
7 	The underlying Blowfish algorithm is specified at https://www.schneier.com/academic/blowfish/
8 */
9 module passwd.bcrypt;
10 
11 @safe:
12 
13 import std.algorithm;
14 import std.array : appender;
15 import std.range;
16 import std..string : representation;
17 public import std.typecons : Flag, No, Yes;
18 
19 import passwd.exception;
20 import passwd.util;
21 
22 /// Routines for bcrypt
23 struct Bcrypt
24 {
25 	// E.g.: $2b$31$pgoPUesaEcDx.as8gzqkj.ye6n10drk6PY6tP633rSsyao5HUggLa
26 	/// Maximum length needed for output of genSalt()
27 	enum kMaxSaltStrLength = "$2b$31$".length + 16 * 8 / 6;
28 	/// Maximum length needed for output of crypt()
29 	enum kMaxCryptStrLength = kMaxSaltStrLength + 1 + kDigestLength * 8 / 6;
30 
31 	/**
32 		Generate a good salt for this algorithm
33 
34 		Params:
35 			log_rounds = log base 2 of number of rounds (i.e., number of rounds is 2 ^^ log_rounds)
36 			             Minimum 4 and maximum 31.
37 	*/
38 	static string genSalt(size_t log_rounds=10)
39 	{
40 		auto ret_app = appender!string;
41 		Bcrypt.genSalt(ret_app, log_rounds);
42 		return ret_app[];
43 	}
44 
45 	/**
46 		Generate a good salt for this algorithm and write to an output range
47 
48 		Params:
49 			output     = output range taking `char`s
50 			log_rounds = log base 2 of number of rounds (i.e., number of rounds is 2 ^^ log_rounds)
51 			             Minimum 4 and maximum 31.
52 	*/
53 	static void genSalt(Out)(ref Out output, size_t log_rounds=10) if (isOutputRange!(Out, char))
54 	{
55 		output.writeSaltPrefix("2b", log_rounds);
56 		ubyte[kSaltBytesLength] random_buf;
57 		fillSecureRandom(random_buf[]);
58 		random_buf.bcryptB64Encode(output);
59 	}
60 
61 	/// Hash password and write full crypt(3) string or just encoded digest to an output range
62 	static void crypt(Out)(const(char)[] password, ref Out output, ref const(CryptPieces) salt_data, Flag!"writeSalt" write_salt = Yes.writeSalt) if (isOutputRange!(Out, char))
63 	{
64 		if (write_salt)
65 		{
66 			auto log_rounds = getLogRounds(salt_data.params);
67 			output.writeSaltPrefix(salt_data.algo_id, log_rounds);
68 			foreach (char c; salt_data.salt_txt) output.put(c);
69 		}
70 		auto digest = digestOf(password, salt_data);
71 		digest.bcryptB64Encode(output);
72 	}
73 
74 private:
75 	enum kSaltBytesLength = 16;
76 	enum kDigestLength = 23;
77 	alias Digest = ubyte[kDigestLength];
78 
79 	/// The heavy lifting of hashing the password to a binary digest
80 	static Digest digestOf(const(char)[] password, ref const(CryptPieces) salt_data)
81 	{
82 		BcryptCtx ctx;
83 		scope (exit) secureWipe(ctx);
84 
85 		ubyte[kSaltBytesLength] salt;
86 		salt_data.salt_txt.bcryptB64Decode(salt[]);
87 
88 		size_t log_rounds = getLogRounds(salt_data.params);
89 
90 		// The Blowfish key schedule is the only part that uses the password string, but the password string can't be used as-is.
91 		// * Need to include a C null byte string terminator
92 		// * Need to truncate long passwords (possibly losing the null byte)
93 		// Truncation needs to match OpenBSD for compatibility.
94 		{
95 			// The password affects the hash by getting mixed with the P box (subkeys) during the key schedule.
96 			// The initial value of the P box gets XORed with corresponding bytes from the password.
97 			// Only one pass of the P box is done, which limits the number of password bytes that can have any effect.
98 			char[ctx.p.sizeof] password_buf;
99 			scope (exit) secureWipe(password_buf);
100 			size_t length_used;
101 
102 			enforce!NotImplementedException(salt_data.algo_id.length == 2 && salt_data.algo_id[0] == '2', "Requested crypt(3) algorithm not supported by bcrypt implementation");
103 			switch (salt_data.algo_id[1])
104 			{
105 				case 'a':
106 					// OpenBSD used an unsigned char to store the password length in version 2a, causing an unintended wraparound at 256
107 					length_used = min((password.length+1) & 0xff, password_buf.length);
108 					// The wraparound can cause the length to be zero despite the null byte, but OpenBSD 2a always uses at least one byte
109 					if (length_used == 0) length_used = 1;
110 					break;
111 				case 'b':
112 					// This is the current version used by OpenBSD as of 2020
113 					// It justs caps the length
114 					length_used = min(password.length+1, password_buf.length);
115 					break;
116 				default:
117 					throw new NotImplementedException("Unsupported bcrypt version");
118 			}
119 
120 			auto copy_len = min(length_used, password.length, password_buf.length);
121 			copy(password[0..copy_len], password_buf[]);
122 			if (password.length < password_buf.length) password_buf[password.length] = '\0';
123 
124 			ctx.eksBlowfishSetup(password_buf[0..length_used].representation, salt, log_rounds);
125 		}
126 
127 		// This is based on the magic string "OrpheanBeholderScryDoubt"
128 		uint[bcrypt_plaintext_32b.length] data = bcrypt_plaintext_32b;
129 		scope (exit) secureWipe(data);
130 		foreach (_; 0..64)
131 		{
132 			// ECB encryption of the plaintext
133 			for (size_t j = 0; j < data.length; j += 2)
134 			{
135 				auto e = ctx.encrypt(BcryptCtx.Block(data[j], data[j+1]));
136 				data[j] = e.l;
137 				data[j+1] = e.r;
138 			}
139 		}
140 
141 		version (LittleEndian)
142 		{
143 			import core.bitop : bswap;
144 			foreach (ref d; data) d = bswap(d);
145 		}
146 
147 		// For some reason, the bcrypt digest ignores the last byte of the encrypted plaintext
148 		Digest ret = (cast(ubyte[])data[])[0..kDigestLength];
149 		return ret;
150 	}
151 }
152 
153 private:
154 
155 struct BcryptCtx
156 {
157 	uint[256][4] s = blowfish_init_s;
158 	uint[18] p = blowfish_init_p;
159 
160 	/// The time-wasting Blowfish "expensive key setup"
161 	void eksBlowfishSetup(const(ubyte)[] password, const(ubyte)[] salt, size_t log_rounds)
162 	{
163 		expandKey(salt, password);
164 		foreach (j; 0..1<<log_rounds)
165 		{
166 			// Inside this loop, only the second parameter is mixed into the state
167 			expandKey!true([], password);
168 			expandKey!true([], salt);
169 		}
170 	}
171 
172 	/**
173 		Blowfish key schedule.  Updates the S and P box state using the given salt and password
174 
175 		`ignore_salt` is for optimising the case where `salt` is all zero bytes and XORing has no effect.
176 		This case happens inside the tight inner loop of `eksBlowfishSetup()`.
177 	*/
178 	void expandKey(bool ignore_salt = false)(const(ubyte)[] salt, const(ubyte)[] password)
179 	{
180 		/// Reads the first 4 bytes as an MSB uint
181 		/// As used below, `input` is a cyclic range
182 		static uint getUint(R)(ref R input)
183 		{
184 			uint v = 0;
185 			foreach (_; 0..uint.sizeof)
186 			{
187 				v <<= 8;
188 				v += input.front;
189 				input.popFront();
190 			}
191 			return v;
192 		}
193 
194 		auto password_looped = cycle(password);
195 		foreach (j; 0..p.length)
196 		{
197 			p[j] ^= getUint(password_looped);
198 		}
199 
200 		static if (!ignore_salt) auto salt_looped = cycle(salt);
201 		Block b;
202 		for (size_t j = 0; j < p.length; j += 2)
203 		{
204 			static if (!ignore_salt)
205 			{
206 				b.l ^= getUint(salt_looped);
207 				b.r ^= getUint(salt_looped);
208 			}
209 			b = encrypt(b);
210 
211 			p[j] = b.l;
212 			p[j+1] = b.r;
213 		}
214 
215 		foreach (j; 0..s.length)
216 		{
217 			for (size_t k = 0; k < s[0].length; k += 2)
218 			{
219 				static if (!ignore_salt)
220 				{
221 					b.l ^= getUint(salt_looped);
222 					b.r ^= getUint(salt_looped);
223 				}
224 				b = encrypt(b);
225 
226 				s[j][k] = b.l;
227 				s[j][k+1] = b.r;
228 			}
229 		}
230 	}
231 
232 	Block encrypt(Block d)
233 	{
234 		// This loop is unrolled a step to avoid the explicit swapping in the original Blowfish spec for the Feistel network
235 		for (size_t j = 0; j < 16; j += 2)
236 		{
237 			d.l ^= p[j];
238 			d.r ^= f(d.l);
239 			d.r ^= p[j+1];
240 			d.l ^= f(d.r);
241 		}
242 		d.l ^= p[16];
243 		d.r ^= p[17];
244 		return Block(d.r, d.l);  // NB: values get swapped
245 	}
246 
247 	/// The "non-reversible function F" in the Blowfish spec
248 	uint f(uint x) const pure
249 	{
250 		ubyte a = x >> 24, b = (x >> 16) & 0xff, c = (x >> 8) & 0xff, d = x & 0xff; // Split x into four bytes
251 		return ((s[0][a] + s[1][b]) ^ s[2][c]) + s[3][d];
252 	}
253 
254 	struct Block
255 	{
256 		uint l, r;
257 	}
258 }
259 
260 /*
261 	bcrypt uses its own custom base 64 scheme, different from the one in other crypt(3) algorithms
262 
263 	The character set is the same, but with different value assignments.  Also, the values are encoded/decoded as MSB.
264 
265 	E.g., "Zz9/" is four b64 digits with values (27, 53, 63, 1)
266 	It has total value 27*64^^3 + 53*64^^2 + 63*64 + 1 == 7299009
267 	Which equals 111*256^^2 + 95*256 + 193
268 	So "Zz9/" decodes to [111, 95, 193]
269 */
270 
271 /// Fill `output` with decoded bcrypt base 64 `data` (extra data ignored)
272 void bcryptB64Decode(const(char)[] data, ubyte[] output)
273 {
274 	import std.range : chunks;
275 	import std.utf : byCodeUnit;
276 	foreach (chunk; data.byCodeUnit.chunks(4))
277 	{
278 		uint v = 0;
279 		foreach (c; chunk)
280 		{
281 			v <<= 6;
282 			v += bcryptB64DecodeChar(c);
283 		}
284 		foreach (_; chunk.length..4) v <<= 6;
285 
286 		int shift = 16;
287 		foreach (_; 0..3)
288 		{
289 			if (output.empty) return;
290 			output.put(cast(ubyte)((v >> shift) & 0xff));
291 			shift -= 8;
292 		}
293 	}
294 }
295 
296 unittest
297 {
298 	bool test(string encoded, size_t length, const(ubyte)[] ex_decoded)
299 	{
300 		auto decoded = new ubyte[](length);
301 		encoded.bcryptB64Decode(decoded);
302 		return ex_decoded == decoded;
303 	}
304 
305 	assert (test("/...", 3, [4, 0, 0]));
306 	assert (test("./..", 3, [0, 16, 0]));
307 	assert (test("../.", 3, [0, 0, 64]));
308 	assert (test(".../", 3, [0, 0, 1]));
309 	assert (test("..C.", 3, [0, 1, 0]));
310 	assert (test(".O..", 3, [1, 0, 0]));
311 	assert (test("Zz9/mM4.", 6, [111, 95, 193, 160, 238, 128]));
312 	assert (test("Zz9/mM4.", 5, [111, 95, 193, 160, 238]));
313 }
314 
315 /// Encode `data` to `output` as bcrypt base 64
316 void bcryptB64Encode(Out)(const(ubyte)[] data, ref Out output) if (isOutputRange!(Out, char))
317 {
318 	import std.range : chunks;
319 	foreach (chunk; data.chunks(3))
320 	{
321 		uint v = 0;
322 		foreach (b; chunk)
323 		{
324 			v <<= 8;
325 			v += b;
326 		}
327 		foreach (_; chunk.length..3) v <<= 8;
328 
329 		int shift = 18;
330 		foreach (_; 0..chunk.length+1)
331 		{
332 			output.put(bcrypt_b64_tab[(v >> shift) & 0x3f]);
333 			shift -= 6;
334 		}
335 	}
336 }
337 
338 unittest
339 {
340 	bool test(const(ubyte)[] decoded, string ex_encoded)
341 	{
342 		auto encoded_app = appender!(ubyte[]);
343 		decoded.bcryptB64Encode(encoded_app);
344 		return ex_encoded == encoded_app[];
345 	}
346 
347 	assert (test([4, 0, 0], "/..."));
348 	assert (test([0, 16, 0], "./.."));
349 	assert (test([0, 0, 64], "../."));
350 	assert (test([0, 0, 1], ".../"));
351 	assert (test([0, 1, 0], "..C."));
352 	assert (test([1, 0, 0], ".O.."));
353 	assert (test([111, 95, 193, 160, 238, 128], "Zz9/mM4."));
354 }
355 
356 immutable bcrypt_b64_tab = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
357 
358 /// Decode a single bcrypt base 64 digit to its numerical value
359 ubyte bcryptB64DecodeChar(char c) pure
360 {
361 	switch (c)
362 	{
363 		case 'a': .. case 'z':
364 			return cast(ubyte)(c - 'a' + 28);
365 		case 'A': .. case 'Z':
366 			return cast(ubyte)(c - 'A' + 2);
367 		case '0': .. case '9':
368 			return cast(ubyte)(c - '0' + 54);
369 		case '.': .. case '/':
370 			return cast(ubyte)(c - '.');
371 		default:
372 			throw new ValueException("Invalid bcrypt base 64 value");
373 	}
374 }
375 
376 unittest
377 {
378 	foreach (j; 0..64)
379 	{
380 		assert (j == bcryptB64DecodeChar(bcrypt_b64_tab[j]));
381 	}
382 }
383 
384 private:
385 
386 enum kMinLogRounds = 4;
387 enum kMaxLogRounds = 31;
388 
389 // Write formatted salt `algo_id` and `log_rounds` to `output`
390 void writeSaltPrefix(Out)(ref Out output, const(char)[] algo_id, size_t log_rounds) if (isOutputRange!(Out, char))
391 {
392 	import std.format : format;
393 	enforce!ValueException(log_rounds >= kMinLogRounds && log_rounds <= kMaxLogRounds, format("Bcrypt log rounds must be between %d and %d", kMinLogRounds, kMaxLogRounds));
394 	output.put('$');
395 	foreach (char c; algo_id) output.put(c);
396 	output.put('$');
397 	output.put(cast(char)('0' + log_rounds / 10));
398 	output.put(cast(char)('0' + log_rounds % 10));
399 	output.put('$');
400 }
401 
402 /// Interpret `params` as log rounds integer
403 size_t getLogRounds(const(char)[] params)
404 {
405 	import std.ascii : isDigit;
406 	import std.format : format;
407 	enforce!ValueException(params.length == 2 && isDigit(params[0]) && isDigit(params[1]), "Invalid format for bcrypt log rounds parameter");
408 	size_t ret = (params[0] - '0') * 10 + (params[1] - '0');
409 	enforce!ValueException(ret >= kMinLogRounds && ret <= kMaxLogRounds, format("Bcrypt log rounds must be between %d and %d", kMinLogRounds, kMaxLogRounds));
410 	return ret;
411 }
412 
413 // Bcrypt works by encrypting this magic string several times
414 // It needs to be converted to 32b blocks
415 enum bcrypt_plaintext = "OrpheanBeholderScryDoubt";
416 immutable(uint[bcrypt_plaintext.length / uint.sizeof]) bcrypt_plaintext_32b;
417 shared static this()
418 {
419 	bcrypt_plaintext_32b[] = cast(const(uint)[])(bcrypt_plaintext)[];
420 	version (LittleEndian)
421 	{
422 		import core.bitop : bswap;
423 		foreach (ref d; bcrypt_plaintext_32b) d = bswap(d);
424 	}
425 }
426 
427 // Magic Blowfish initial state constants
428 // They're "nothing up my sleeve" numbers based on the digits of pi
429 
430 immutable(uint[18]) blowfish_init_p = [
431 	0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L, 0xa4093822L, 0x299f31d0L,
432 	0x082efa98L, 0xec4e6c89L, 0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL,
433 	0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L, 0x9216d5d9L, 0x8979fb1bL
434 ];
435 
436 immutable(uint[256][4]) blowfish_init_s = [
437 	[
438 		0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, 0xd01adfb7L, 0xb8e1afedL, 0x6a267e96L,
439 		0xba7c9045L, 0xf12c7f99L, 0x24a19947L, 0xb3916cf7L, 0x0801f2e2L, 0x858efc16L,
440 		0x636920d8L, 0x71574e69L, 0xa458fea3L, 0xf4933d7eL, 0x0d95748fL, 0x728eb658L,
441 		0x718bcd58L, 0x82154aeeL, 0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L, 0x2af26013L,
442 		0xc5d1b023L, 0x286085f0L, 0xca417918L, 0xb8db38efL, 0x8e79dcb0L, 0x603a180eL,
443 		0x6c9e0e8bL, 0xb01e8a3eL, 0xd71577c1L, 0xbd314b27L, 0x78af2fdaL, 0x55605c60L,
444 		0xe65525f3L, 0xaa55ab94L, 0x57489862L, 0x63e81440L, 0x55ca396aL, 0x2aab10b6L,
445 		0xb4cc5c34L, 0x1141e8ceL, 0xa15486afL, 0x7c72e993L, 0xb3ee1411L, 0x636fbc2aL,
446 		0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, 0x9b87931eL, 0xafd6ba33L, 0x6c24cf5cL,
447 		0x7a325381L, 0x28958677L, 0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL, 0x66282193L,
448 		0x61d809ccL, 0xfb21a991L, 0x487cac60L, 0x5dec8032L, 0xef845d5dL, 0xe98575b1L,
449 		0xdc262302L, 0xeb651b88L, 0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L, 0x83f44239L,
450 		0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, 0x9e1f9b5eL, 0x21c66842L, 0xf6e96c9aL,
451 		0x670c9c61L, 0xabd388f0L, 0x6a51a0d2L, 0xd8542f68L, 0x960fa728L, 0xab5133a3L,
452 		0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, 0x7efb2a98L, 0xa1f1651dL, 0x39af0176L,
453 		0x66ca593eL, 0x82430e88L, 0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L, 0x3b8b5ebeL,
454 		0xe06f75d8L, 0x85c12073L, 0x401a449fL, 0x56c16aa6L, 0x4ed3aa62L, 0x363f7706L,
455 		0x1bfedf72L, 0x429b023dL, 0x37d0d724L, 0xd00a1248L, 0xdb0fead3L, 0x49f1c09bL,
456 		0x075372c9L, 0x80991b7bL, 0x25d479d8L, 0xf6e8def7L, 0xe3fe501aL, 0xb6794c3bL,
457 		0x976ce0bdL, 0x04c006baL, 0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L, 0x196a2463L,
458 		0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, 0x3b52ec6fL, 0x6dfc511fL, 0x9b30952cL,
459 		0xcc814544L, 0xaf5ebd09L, 0xbee3d004L, 0xde334afdL, 0x660f2807L, 0x192e4bb3L,
460 		0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, 0xb9d3fbdbL, 0x5579c0bdL, 0x1a60320aL,
461 		0xd6a100c6L, 0x402c7279L, 0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L, 0xdb3222f8L,
462 		0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, 0xad0552abL, 0x323db5faL, 0xfd238760L,
463 		0x53317b48L, 0x3e00df82L, 0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL, 0xdf1769dbL,
464 		0xd542a8f6L, 0x287effc3L, 0xac6732c6L, 0x8c4f5573L, 0x695b27b0L, 0xbbca58c8L,
465 		0xe1ffa35dL, 0xb8f011a0L, 0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL, 0x2dd1d35bL,
466 		0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, 0x4bfb9790L, 0xe1ddf2daL, 0xa4cb7e33L,
467 		0x62fb1341L, 0xcee4c6e8L, 0xef20cadaL, 0x36774c01L, 0xd07e9efeL, 0x2bf11fb4L,
468 		0x95dbda4dL, 0xae909198L, 0xeaad8e71L, 0x6b93d5a0L, 0xd08ed1d0L, 0xafc725e0L,
469 		0x8e3c5b2fL, 0x8e7594b7L, 0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L, 0x900df01cL,
470 		0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, 0xb3a8c1adL, 0x2f2f2218L, 0xbe0e1777L,
471 		0xea752dfeL, 0x8b021fa1L, 0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L, 0xce89e299L,
472 		0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, 0xd2ada8d9L, 0x165fa266L, 0x80957705L,
473 		0x93cc7314L, 0x211a1477L, 0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L, 0xfb9d35cfL,
474 		0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, 0xae1e7e49L, 0x00250e2dL, 0x2071b35eL,
475 		0x226800bbL, 0x57b8e0afL, 0x2464369bL, 0xf009b91eL, 0x5563911dL, 0x59dfa6aaL,
476 		0x78c14389L, 0xd95a537fL, 0x207d5ba2L, 0x02e5b9c5L, 0x83260376L, 0x6295cfa9L,
477 		0x11c81968L, 0x4e734a41L, 0xb3472dcaL, 0x7b14a94aL, 0x1b510052L, 0x9a532915L,
478 		0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, 0x81e67400L, 0x08ba6fb5L, 0x571be91fL,
479 		0xf296ec6bL, 0x2a0dd915L, 0xb6636521L, 0xe7b9f9b6L, 0xff34052eL, 0xc5855664L,
480 		0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, 0x6e85076aL,
481 	],
482 	[
483 		0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, 0xc4192623L, 0xad6ea6b0L, 0x49a7df7dL,
484 		0x9cee60b8L, 0x8fedb266L, 0xecaa8c71L, 0x699a17ffL, 0x5664526cL, 0xc2b19ee1L,
485 		0x193602a5L, 0x75094c29L, 0xa0591340L, 0xe4183a3eL, 0x3f54989aL, 0x5b429d65L,
486 		0x6b8fe4d6L, 0x99f73fd6L, 0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L, 0xf0255dc1L,
487 		0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, 0x021ecc5eL, 0x09686b3fL, 0x3ebaefc9L,
488 		0x3c971814L, 0x6b6a70a1L, 0x687f3584L, 0x52a0e286L, 0xb79c5305L, 0xaa500737L,
489 		0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, 0x5716f2b8L, 0xb03ada37L, 0xf0500c0dL,
490 		0xf01c1f04L, 0x0200b3ffL, 0xae0cf51aL, 0x3cb574b2L, 0x25837a58L, 0xdc0921bdL,
491 		0xd19113f9L, 0x7ca92ff6L, 0x94324773L, 0x22f54701L, 0x3ae5e581L, 0x37c2dadcL,
492 		0xc8b57634L, 0x9af3dda7L, 0xa9446146L, 0x0fd0030eL, 0xecc8c73eL, 0xa4751e41L,
493 		0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, 0x183eb331L, 0x4e548b38L, 0x4f6db908L,
494 		0x6f420d03L, 0xf60a04bfL, 0x2cb81290L, 0x24977c79L, 0x5679b072L, 0xbcaf89afL,
495 		0xde9a771fL, 0xd9930810L, 0xb38bae12L, 0xdccf3f2eL, 0x5512721fL, 0x2e6b7124L,
496 		0x501adde6L, 0x9f84cd87L, 0x7a584718L, 0x7408da17L, 0xbc9f9abcL, 0xe94b7d8cL,
497 		0xec7aec3aL, 0xdb851dfaL, 0x63094366L, 0xc464c3d2L, 0xef1c1847L, 0x3215d908L,
498 		0xdd433b37L, 0x24c2ba16L, 0x12a14d43L, 0x2a65c451L, 0x50940002L, 0x133ae4ddL,
499 		0x71dff89eL, 0x10314e55L, 0x81ac77d6L, 0x5f11199bL, 0x043556f1L, 0xd7a3c76bL,
500 		0x3c11183bL, 0x5924a509L, 0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL, 0x1e153c6eL,
501 		0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, 0x5a3e2ab3L, 0x771fe71cL, 0x4e3d06faL,
502 		0x2965dcb9L, 0x99e71d0fL, 0x803e89d6L, 0x5266c825L, 0x2e4cc978L, 0x9c10b36aL,
503 		0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, 0x1e0a2df4L, 0xf2f74ea7L, 0x361d2b3dL,
504 		0x1939260fL, 0x19c27960L, 0x5223a708L, 0xf71312b6L, 0xebadfe6eL, 0xeac31f66L,
505 		0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, 0x018cff28L, 0xc332ddefL, 0xbe6c5aa5L,
506 		0x65582185L, 0x68ab9802L, 0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL, 0x5b6e2f84L,
507 		0x1521b628L, 0x29076170L, 0xecdd4775L, 0x619f1510L, 0x13cca830L, 0xeb61bd96L,
508 		0x0334fe1eL, 0xaa0363cfL, 0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL, 0xcbaade14L,
509 		0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, 0xb2f3846eL, 0x648b1eafL, 0x19bdf0caL,
510 		0xa02369b9L, 0x655abb50L, 0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L, 0xc021b8f7L,
511 		0x9b540b19L, 0x875fa099L, 0x95f7997eL, 0x623d7da8L, 0xf837889aL, 0x97e32d77L,
512 		0x11ed935fL, 0x16681281L, 0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L, 0x7858ba99L,
513 		0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, 0x1ac24696L, 0xcdb30aebL, 0x532e3054L,
514 		0x8fd948e4L, 0x6dbc3128L, 0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L, 0xee7c3c73L,
515 		0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, 0x203e13e0L, 0x45eee2b6L, 0xa3aaabeaL,
516 		0xdb6c4f15L, 0xfacb4fd0L, 0xc742f442L, 0xef6abbb5L, 0x654f3b1dL, 0x41cd2105L,
517 		0xd81e799eL, 0x86854dc7L, 0xe44b476aL, 0x3d816250L, 0xcf62a1f2L, 0x5b8d2646L,
518 		0xfc8883a0L, 0xc1c7b6a3L, 0x7f1524c3L, 0x69cb7492L, 0x47848a0bL, 0x5692b285L,
519 		0x095bbf00L, 0xad19489dL, 0x1462b174L, 0x23820e00L, 0x58428d2aL, 0x0c55f5eaL,
520 		0x1dadf43eL, 0x233f7061L, 0x3372f092L, 0x8d937e41L, 0xd65fecf1L, 0x6c223bdbL,
521 		0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, 0xce77326eL, 0xa6078084L, 0x19f8509eL,
522 		0xe8efd855L, 0x61d99735L, 0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL, 0x800bcadcL,
523 		0x9e447a2eL, 0xc3453484L, 0xfdd56705L, 0x0e1e9ec9L, 0xdb73dbd3L, 0x105588cdL,
524 		0x675fda79L, 0xe3674340L, 0xc5c43465L, 0x713e38d8L, 0x3d28f89eL, 0xf16dff20L,
525 		0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, 0xdb83adf7L
526 	],
527 	[
528 		0xe93d5a68L, 0x948140f7L, 0xf64c261cL, 0x94692934L, 0x411520f7L, 0x7602d4f7L,
529 		0xbcf46b2eL, 0xd4a20068L, 0xd4082471L, 0x3320f46aL, 0x43b7d4b7L, 0x500061afL,
530 		0x1e39f62eL, 0x97244546L, 0x14214f74L, 0xbf8b8840L, 0x4d95fc1dL, 0x96b591afL,
531 		0x70f4ddd3L, 0x66a02f45L, 0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L, 0x31cb8504L,
532 		0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, 0xabca0a9aL, 0x28507825L, 0x530429f4L,
533 		0x0a2c86daL, 0xe9b66dfbL, 0x68dc1462L, 0xd7486900L, 0x680ec0a4L, 0x27a18deeL,
534 		0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, 0x7af4d6b6L, 0xaace1e7cL, 0xd3375fecL,
535 		0xce78a399L, 0x406b2a42L, 0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL, 0x3b124e8bL,
536 		0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, 0xeae397b2L, 0x3a6efa74L, 0xdd5b4332L,
537 		0x6841e7f7L, 0xca7820fbL, 0xfb0af54eL, 0xd8feb397L, 0x454056acL, 0xba489527L,
538 		0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, 0xd096954bL, 0x55a867bcL, 0xa1159a58L,
539 		0xcca92963L, 0x99e1db33L, 0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL, 0x9029317cL,
540 		0xfdf8e802L, 0x04272f70L, 0x80bb155cL, 0x05282ce3L, 0x95c11548L, 0xe4c66d22L,
541 		0x48c1133fL, 0xc70f86dcL, 0x07f9c9eeL, 0x41041f0fL, 0x404779a4L, 0x5d886e17L,
542 		0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, 0x41113564L, 0x257b7834L, 0x602a9c60L,
543 		0xdff8e8a3L, 0x1f636c1bL, 0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L, 0xcad18115L,
544 		0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, 0xeebeb922L, 0x85b2a20eL, 0xe6ba0d99L,
545 		0xde720c8cL, 0x2da2f728L, 0xd0127845L, 0x95b794fdL, 0x647d0862L, 0xe7ccf5f0L,
546 		0x5449a36fL, 0x877d48faL, 0xc39dfd27L, 0xf33e8d1eL, 0x0a476341L, 0x992eff74L,
547 		0x3a6f6eabL, 0xf4f8fd37L, 0xa812dc60L, 0xa1ebddf8L, 0x991be14cL, 0xdb6e6b0dL,
548 		0xc67b5510L, 0x6d672c37L, 0x2765d43bL, 0xdcd0e804L, 0xf1290dc7L, 0xcc00ffa3L,
549 		0xb5390f92L, 0x690fed0bL, 0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL, 0xd9155ea3L,
550 		0xbb132f88L, 0x515bad24L, 0x7b9479bfL, 0x763bd6ebL, 0x37392eb3L, 0xcc115979L,
551 		0x8026e297L, 0xf42e312dL, 0x6842ada7L, 0xc66a2b3bL, 0x12754cccL, 0x782ef11cL,
552 		0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, 0x4bfb6350L, 0x1a6b1018L, 0x11caedfaL,
553 		0x3d25bdd8L, 0xe2e1c3c9L, 0x44421659L, 0x0a121386L, 0xd90cec6eL, 0xd5abea2aL,
554 		0x64af674eL, 0xda86a85fL, 0xbebfe988L, 0x64e4c3feL, 0x9dbc8057L, 0xf0f7c086L,
555 		0x60787bf8L, 0x6003604dL, 0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L, 0xd736fcccL,
556 		0x83426b33L, 0xf01eab71L, 0xb0804187L, 0x3c005e5fL, 0x77a057beL, 0xbde8ae24L,
557 		0x55464299L, 0xbf582e61L, 0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L, 0x8789bdc2L,
558 		0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, 0x46fcd9b9L, 0x7aeb2661L, 0x8b1ddf84L,
559 		0x846a0e79L, 0x915f95e2L, 0x466e598eL, 0x20b45770L, 0x8cd55591L, 0xc902de4cL,
560 		0xb90bace1L, 0xbb8205d0L, 0x11a86248L, 0x7574a99eL, 0xb77f19b6L, 0xe0a9dc09L,
561 		0x662d09a1L, 0xc4324633L, 0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L, 0x1d6efe10L,
562 		0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, 0x2868f169L, 0xdcb7da83L, 0x573906feL,
563 		0xa1e2ce9bL, 0x4fcd7f52L, 0x50115e01L, 0xa70683faL, 0xa002b5c4L, 0x0de6d027L,
564 		0x9af88c27L, 0x773f8641L, 0xc3604c06L, 0x61a806b5L, 0xf0177a28L, 0xc0f586e0L,
565 		0x006058aaL, 0x30dc7d62L, 0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L, 0xc2c21634L,
566 		0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, 0xce591d76L, 0x6f05e409L, 0x4b7c0188L,
567 		0x39720a3dL, 0x7c927c24L, 0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L, 0xd39eb8fcL,
568 		0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, 0x4dad0fc4L, 0x1e50ef5eL, 0xb161e6f8L,
569 		0xa28514d9L, 0x6c51133cL, 0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL, 0xddc6c837L,
570 		0xd79a3234L, 0x92638212L, 0x670efa8eL, 0x406000e0L
571 	],
572 	[
573 		0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, 0x5ac52d1bL, 0x5cb0679eL, 0x4fa33742L,
574 		0xd3822740L, 0x99bc9bbeL, 0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL, 0xc700c47bL,
575 		0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, 0x6a366eb4L, 0x5748ab2fL, 0xbc946e79L,
576 		0xc6a376d2L, 0x6549c2c8L, 0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL, 0x4cd04dc6L,
577 		0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, 0xbe5ee304L, 0xa1fad5f0L, 0x6a2d519aL,
578 		0x63ef8ce2L, 0x9a86ee22L, 0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL, 0x9cf2d0a4L,
579 		0x83c061baL, 0x9be96a4dL, 0x8fe51550L, 0xba645bd6L, 0x2826a2f9L, 0xa73a3ae1L,
580 		0x4ba99586L, 0xef5562e9L, 0xc72fefd3L, 0xf752f7daL, 0x3f046f69L, 0x77fa0a59L,
581 		0x80e4a915L, 0x87b08601L, 0x9b09e6adL, 0x3b3ee593L, 0xe990fd5aL, 0x9e34d797L,
582 		0x2cf0b7d9L, 0x022b8b51L, 0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L, 0x7c7d2d28L,
583 		0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, 0x5a88f54cL, 0xe029ac71L, 0xe019a5e6L,
584 		0x47b0acfdL, 0xed93fa9bL, 0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L, 0x79132e28L,
585 		0x785f0191L, 0xed756055L, 0xf7960e44L, 0xe3d35e8cL, 0x15056dd4L, 0x88f46dbaL,
586 		0x03a16125L, 0x0564f0bdL, 0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL, 0xa93a072aL,
587 		0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, 0x26dcf319L, 0x7533d928L, 0xb155fdf5L,
588 		0x03563482L, 0x8aba3cbbL, 0x28517711L, 0xc20ad9f8L, 0xabcc5167L, 0xccad925fL,
589 		0x4de81751L, 0x3830dc8eL, 0x379d5862L, 0x9320f991L, 0xea7a90c2L, 0xfb3e7bceL,
590 		0x5121ce64L, 0x774fbe32L, 0xa8b6e37eL, 0xc3293d46L, 0x48de5369L, 0x6413e680L,
591 		0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, 0x09072166L, 0xb39a460aL, 0x6445c0ddL,
592 		0x586cdecfL, 0x1c20c8aeL, 0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL, 0x6bb4e3bbL,
593 		0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, 0xbcb4cdd5L, 0x72eacea8L, 0xfa6484bbL,
594 		0x8d6612aeL, 0xbf3c6f47L, 0xd29be463L, 0x542f5d9eL, 0xaec2771bL, 0xf64e6370L,
595 		0x740e0d8dL, 0xe75b1357L, 0xf8721671L, 0xaf537d5dL, 0x4040cb08L, 0x4eb4e2ccL,
596 		0x34d2466aL, 0x0115af84L, 0xe1b00428L, 0x95983a1dL, 0x06b89fb4L, 0xce6ea048L,
597 		0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, 0x277227f8L, 0x611560b1L, 0xe7933fdcL,
598 		0xbb3a792bL, 0x344525bdL, 0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L, 0xa01fbac9L,
599 		0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, 0xa1e8aac7L, 0x1a908749L, 0xd44fbd9aL,
600 		0xd0dadecbL, 0xd50ada38L, 0x0339c32aL, 0xc6913667L, 0x8df9317cL, 0xe0b12b4fL,
601 		0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, 0x27d9459cL, 0xbf97222cL, 0x15e6fc2aL,
602 		0x0f91fc71L, 0x9b941525L, 0xfae59361L, 0xceb69cebL, 0xc2a86459L, 0x12baa8d1L,
603 		0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, 0xcb03a442L, 0xe0ec6e0eL, 0x1698db3bL,
604 		0x4c98a0beL, 0x3278e964L, 0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL, 0x8971f21eL,
605 		0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, 0xc37632d8L, 0xdf359f8dL, 0x9b992f2eL,
606 		0xe60b6f47L, 0x0fe3f11dL, 0xe54cda54L, 0x1edad891L, 0xce6279cfL, 0xcd3e7e6fL,
607 		0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, 0xf6fb2299L, 0xf523f357L, 0xa6327623L,
608 		0x93a83531L, 0x56cccd02L, 0xacf08162L, 0x5a75ebb5L, 0x6e163697L, 0x88d273ccL,
609 		0xde966292L, 0x81b949d0L, 0x4c50901bL, 0x71c65614L, 0xe6c6c7bdL, 0x327a140aL,
610 		0x45e1d006L, 0xc3f27b9aL, 0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L, 0x35bdd2f6L,
611 		0x71126905L, 0xb2040222L, 0xb6cbcf7cL, 0xcd769c2bL, 0x53113ec0L, 0x1640e3d3L,
612 		0x38abbd60L, 0x2547adf0L, 0xba38209cL, 0xf746ce76L, 0x77afa1c5L, 0x20756060L,
613 		0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, 0x4cf9aa7eL, 0x1948c25cL, 0x02fb8a8cL,
614 		0x01c36ae4L, 0xd6ebe1f9L, 0x90d4f869L, 0xa65cdea0L, 0x3f09252dL, 0xc208e69fL,
615 		0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, 0x3ac372e6L
616 	],
617 ];