github.com/scottcagno/storage@v1.8.0/pkg/hash/spooky/spooky.go (about) 1 /* 2 * // Copyright (c) 2021. Scott Cagno. All rights reserved. 3 * // The license can be found in the root of this project; see LICENSE. 4 */ 5 6 package spooky 7 8 import "fmt" 9 import "unsafe" 10 11 // sc_const: a constant which: 12 // * is not zero 13 // * is odd 14 // * is a not-very-regular mix of 1's and 0's 15 // * does not need any other special mathematical properties 16 var sc_const = uint64(0xdeadbeefdeadbeef) 17 18 // number of uint64's in internal state 19 const sc_numVars = 12 20 21 // size of the internal state 22 const sc_blockSize = sc_numVars * 8 23 24 // size of buffer of unhashed data, in bytes 25 const sc_bufSize = 2 * sc_blockSize 26 27 func Rot64(x, k uint64) uint64 { 28 return (x << k) | (x >> (64 - k)) 29 } 30 31 // this makes a new slice of uint64 that points to the same slice passed in as []byte 32 // we should check alignment for architectures that don't handle unaligned reads 33 // and fallback to a copy maybe using encoding/binary. 34 // One question is what are the right test vevtors for big-endian machines. 35 func sliceUI64(in []byte) []uint64 { 36 return (*(*[]uint64)(unsafe.Pointer(&in)))[:len(in)/8] 37 } 38 39 // 40 // This is used if the input is 96 bytes long or longer. 41 // 42 // The internal state is fully overwritten every 96 bytes. 43 // Every input bit appears to cause at least 128 bits of entropy 44 // before 96 other bytes are combined, when run forward or backward 45 // For every input bit, 46 // Two inputs differing in just that input bit 47 // Where "differ" means xor or subtraction 48 // And the base value is random 49 // When run forward or backwards one Mix 50 // I tried 3 pairs of each; they all differed by at least 212 bits. 51 // 52 func Mix(data []uint64, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11 uint64) (uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64) { 53 s0 += data[0] 54 s2 ^= s10 55 s11 ^= s0 56 s0 = Rot64(s0, 11) 57 s11 += s1 58 s1 += data[1] 59 s3 ^= s11 60 s0 ^= s1 61 s1 = Rot64(s1, 32) 62 s0 += s2 63 s2 += data[2] 64 s4 ^= s0 65 s1 ^= s2 66 s2 = Rot64(s2, 43) 67 s1 += s3 68 s3 += data[3] 69 s5 ^= s1 70 s2 ^= s3 71 s3 = Rot64(s3, 31) 72 s2 += s4 73 s4 += data[4] 74 s6 ^= s2 75 s3 ^= s4 76 s4 = Rot64(s4, 17) 77 s3 += s5 78 s5 += data[5] 79 s7 ^= s3 80 s4 ^= s5 81 s5 = Rot64(s5, 28) 82 s4 += s6 83 s6 += data[6] 84 s8 ^= s4 85 s5 ^= s6 86 s6 = Rot64(s6, 39) 87 s5 += s7 88 s7 += data[7] 89 s9 ^= s5 90 s6 ^= s7 91 s7 = Rot64(s7, 57) 92 s6 += s8 93 s8 += data[8] 94 s10 ^= s6 95 s7 ^= s8 96 s8 = Rot64(s8, 55) 97 s7 += s9 98 s9 += data[9] 99 s11 ^= s7 100 s8 ^= s9 101 s9 = Rot64(s9, 54) 102 s8 += s10 103 s10 += data[10] 104 s0 ^= s8 105 s9 ^= s10 106 s10 = Rot64(s10, 22) 107 s9 += s11 108 s11 += data[11] 109 s1 ^= s9 110 s10 ^= s11 111 s11 = Rot64(s11, 46) 112 s10 += s0 113 return s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11 114 } 115 116 // 117 // Mix all 12 inputs together so that h0, h1 are a hash of them all. 118 // 119 // For two inputs differing in just the input bits 120 // Where "differ" means xor or subtraction 121 // And the base value is random, or a counting value starting at that bit 122 // The final result will have each bit of h0, h1 flip 123 // For every input bit, 124 // with probability 50 +- .3% 125 // For every pair of input bits, 126 // with probability 50 +- 3% 127 // 128 // This does not rely on the last Mix() call having already mixed some. 129 // Two iterations was almost good enough for a 64-bit result, but a 130 // 128-bit result is reported, so End() does three iterations. 131 // 132 133 func EndPartial(h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11 uint64) (uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64) { 134 h11 += h1 135 h2 ^= h11 136 h1 = Rot64(h1, 44) 137 h0 += h2 138 h3 ^= h0 139 h2 = Rot64(h2, 15) 140 h1 += h3 141 h4 ^= h1 142 h3 = Rot64(h3, 34) 143 h2 += h4 144 h5 ^= h2 145 h4 = Rot64(h4, 21) 146 h3 += h5 147 h6 ^= h3 148 h5 = Rot64(h5, 38) 149 h4 += h6 150 h7 ^= h4 151 h6 = Rot64(h6, 33) 152 h5 += h7 153 h8 ^= h5 154 h7 = Rot64(h7, 10) 155 h6 += h8 156 h9 ^= h6 157 h8 = Rot64(h8, 13) 158 h7 += h9 159 h10 ^= h7 160 h9 = Rot64(h9, 38) 161 h8 += h10 162 h11 ^= h8 163 h10 = Rot64(h10, 53) 164 h9 += h11 165 h0 ^= h9 166 h11 = Rot64(h11, 42) 167 h10 += h0 168 h1 ^= h10 169 h0 = Rot64(h0, 54) 170 return h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11 171 } 172 173 func End(data []uint64, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11 uint64) (uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64, uint64) { 174 h0 += data[0] 175 h1 += data[1] 176 h2 += data[2] 177 h3 += data[3] 178 h4 += data[4] 179 h5 += data[5] 180 h6 += data[6] 181 h7 += data[7] 182 h8 += data[8] 183 h9 += data[9] 184 h10 += data[10] 185 h11 += data[11] 186 h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11 = EndPartial(h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11) 187 h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11 = EndPartial(h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11) 188 h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11 = EndPartial(h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11) 189 return h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11 190 } 191 192 // do the whole hash in one call 193 func SpookyHash128(in []byte, hash1, hash2 uint64) (uint64, uint64) { 194 b := make([]byte, 96, 96) 195 length := len(in) 196 if length < sc_bufSize { 197 h1, h2 := SpookyHashShort(in, hash1, hash2) 198 return h1, h2 199 } 200 //fmt.Printf("SpookyHash128: len(in)=%d, hash1=0x%08x, hash2=0x%08x, in=%x\n", len(in), hash1, hash2, in) 201 remainder := length % 96 202 203 h0, h3, h6, h9 := hash1, hash1, hash1, hash1 204 h1, h4, h7, h10 := hash2, hash2, hash2, hash2 205 h2, h5, h8, h11 := sc_const, sc_const, sc_const, sc_const 206 207 //end = u.p64 + (length/sc_blockSize)*sc_numVars; 208 //inl := a += *(*uint32)(unsafe.Pointer(&in[0])) 209 210 // handle all whole sc_blockSize blocks of bytes 211 for l := length; l >= 96; l -= 96 { 212 //fmt.Printf("SpookyHash128: do 128 l=%d, len(in)=%d\n", l, len(in)) 213 inul := sliceUI64(in) 214 //fmt.Printf("in[0]=%x, in[1]=%x, in[2]=%x, in[3]=%x, inul=%x\n", in[0], in[1], in[2], in[3], inul[0]) 215 h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11 = Mix(inul, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11) 216 //fmt.Printf("h0=0x%016x, h1=0x%016x, h2=0x%016x, h3=0x%016x, h4=0x%016x, h5=0x%016x\nh6=0x%016x, h7=0x%016x, h8=0x%016x, h9=0x%016x, h10=0x%016x, h11=0x%016x\n", 217 // h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11) 218 in = in[96:] 219 } 220 //fmt.Printf("SpookyHash128: len(in)=%d, remainder=%d\n", len(in), remainder) 221 if len(in) != remainder { 222 panic("SpookyHash128") 223 } 224 if remainder > 0 { 225 for k, v := range in { 226 b[k] = v 227 } 228 } 229 b[len(b)-1] = byte(remainder) 230 inul := sliceUI64(b) 231 232 // handle the last partial block of sc_blockSize bytes 233 // do some final mixing 234 //fmt.Printf("inul=%x\n", inul) 235 h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11 = End(inul, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11) 236 //fmt.Printf("h0=0x%016x, h1=0x%016x, h2=0x%016x, h3=0x%016x, h4=0x%016x, h5=0x%016x\nh6=0x%016x, h7=0x%016x, h8=0x%016x, h9=0x%016x, h10=0x%016x, h11=0x%016x\n", 237 // h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11) 238 return h0, h1 239 } 240 241 // 242 // The goal is for each bit of the input to expand into 128 bits of 243 // apparent entropy before it is fully overwritten. 244 // n trials both set and cleared at least m bits of h0 h1 h2 h3 245 // n: 2 m: 29 246 // n: 3 m: 46 247 // n: 4 m: 57 248 // n: 5 m: 107 249 // n: 6 m: 146 250 // n: 7 m: 152 251 // when run forwards or backwards 252 // for all 1-bit and 2-bit diffs 253 // with diffs defined by either xor or subtraction 254 // with a base of all zeros plus a counter, or plus another bit, or random 255 // 256 func ShortMix(h0, h1, h2, h3 uint64) (uint64, uint64, uint64, uint64) { 257 h2 = Rot64(h2, 50) 258 h2 += h3 259 h0 ^= h2 260 h3 = Rot64(h3, 52) 261 h3 += h0 262 h1 ^= h3 263 h0 = Rot64(h0, 30) 264 h0 += h1 265 h2 ^= h0 266 h1 = Rot64(h1, 41) 267 h1 += h2 268 h3 ^= h1 269 h2 = Rot64(h2, 54) 270 h2 += h3 271 h0 ^= h2 272 h3 = Rot64(h3, 48) 273 h3 += h0 274 h1 ^= h3 275 h0 = Rot64(h0, 38) 276 h0 += h1 277 h2 ^= h0 278 h1 = Rot64(h1, 37) 279 h1 += h2 280 h3 ^= h1 281 h2 = Rot64(h2, 62) 282 h2 += h3 283 h0 ^= h2 284 h3 = Rot64(h3, 34) 285 h3 += h0 286 h1 ^= h3 287 h0 = Rot64(h0, 5) 288 h0 += h1 289 h2 ^= h0 290 h1 = Rot64(h1, 36) 291 h1 += h2 292 h3 ^= h1 293 return h0, h1, h2, h3 294 } 295 296 // 297 // Mix all 4 inputs together so that h0, h1 are a hash of them all. 298 // 299 // For two inputs differing in just the input bits 300 // Where "differ" means xor or subtraction 301 // And the base value is random, or a counting value starting at that bit 302 // The final result will have each bit of h0, h1 flip 303 // For every input bit, 304 // with probability 50 +- .3% (it is probably better than that) 305 // For every pair of input bits, 306 // with probability 50 +- .75% (the worst case is approximately that) 307 // 308 func ShortEnd(h0, h1, h2, h3 uint64) (uint64, uint64, uint64, uint64) { 309 h3 ^= h2 310 h2 = Rot64(h2, 15) 311 h3 += h2 312 h0 ^= h3 313 h3 = Rot64(h3, 52) 314 h0 += h3 315 h1 ^= h0 316 h0 = Rot64(h0, 26) 317 h1 += h0 318 h2 ^= h1 319 h1 = Rot64(h1, 51) 320 h2 += h1 321 h3 ^= h2 322 h2 = Rot64(h2, 28) 323 h3 += h2 324 h0 ^= h3 325 h3 = Rot64(h3, 9) 326 h0 += h3 327 h1 ^= h0 328 h0 = Rot64(h0, 47) 329 h1 += h0 330 h2 ^= h1 331 h1 = Rot64(h1, 54) 332 h2 += h1 333 h3 ^= h2 334 h2 = Rot64(h2, 32) 335 h3 += h2 336 h0 ^= h3 337 h3 = Rot64(h3, 25) 338 h0 += h3 339 h1 ^= h0 340 h0 = Rot64(h0, 63) 341 h1 += h0 342 return h0, h1, h2, h3 343 } 344 345 func U8tou64le(p []byte) uint64 { 346 return uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56 347 } 348 349 func U8tou32le(p []byte) uint64 { 350 return uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 351 } 352 353 // 354 // short hash ... it could be used on any message, 355 // but it's used by Spooky just for short messages. 356 // 357 func SpookyHashShort(in []byte, hash1, hash2 uint64) (uint64, uint64) { 358 //fmt.Printf("SpookyHashShort: len(in)=%d, hash1=0x%08x, hash2=0x%08x, in=%x\n", len(in), hash1, hash2, in) 359 //fmt.Printf("sc_const=0x%16x == 0x%16x\n", sc_const, uint64(0xdeadbeefdeadbeef)) 360 a, b := hash1, hash2 361 c, d := uint64(sc_const), uint64(sc_const) 362 length := len(in) 363 364 remainder := length % 32 365 if length >= 16 { 366 // handle all complete sets of 32 bytes 367 for l := length; l >= 32; l -= 32 { 368 c += U8tou64le(in) 369 in = in[8:] 370 d += U8tou64le(in) 371 in = in[8:] 372 //fmt.Printf("c=0x%016x, d=0x%016x\n", c, d) 373 a, b, c, d = ShortMix(a, b, c, d) 374 //fmt.Printf("a=0x%016x, b=0x%016x, c=0x%016x, d=0x%016x\n", a, b, c, d) 375 a += U8tou64le(in) 376 in = in[8:] 377 b += U8tou64le(in) 378 in = in[8:] 379 //fmt.Printf("a=0x%016x, b=0x%016x\n", a, b) 380 } 381 382 //Handle the case of 16+ remaining bytes. 383 if remainder >= 16 { 384 c += U8tou64le(in) 385 in = in[8:] 386 d += U8tou64le(in) 387 in = in[8:] 388 a, b, c, d = ShortMix(a, b, c, d) 389 remainder -= 16 390 } 391 } 392 393 // Handle the last 0..15 bytes, and its length 394 //fmt.Printf("remainder=%d, len(in)=%d\n", remainder, len(in)) 395 //fmt.Printf("d=0x%016x, l=0x%016x\n", d, uint64(length) << 56) 396 d += uint64(length) << 56 397 //fmt.Printf("d=0x%016x, l=0x%016x\n", d, uint64(length) << 56) 398 switch remainder { 399 case 15: 400 d += uint64(in[14]) << 48 401 fallthrough 402 case 14: 403 d += uint64(in[13]) << 40 404 fallthrough 405 case 13: 406 d += uint64(in[12]) << 32 407 fallthrough 408 case 12: 409 d += U8tou32le(in[8:]) 410 c += U8tou64le(in) 411 break 412 case 11: 413 d += uint64(in[10]) << 16 414 fallthrough 415 case 10: 416 d += uint64(in[9]) << 8 417 fallthrough 418 case 9: 419 d += uint64(in[8]) 420 fallthrough 421 case 8: 422 c += U8tou64le(in) 423 break 424 case 7: 425 c += uint64(in[6]) << 48 426 fallthrough 427 case 6: 428 c += uint64(in[5]) << 40 429 fallthrough 430 case 5: 431 c += uint64(in[4]) << 32 432 fallthrough 433 case 4: 434 c += U8tou32le(in) 435 break 436 case 3: 437 c += uint64(in[2]) << 16 438 fallthrough 439 case 2: 440 c += uint64(in[1]) << 8 441 fallthrough 442 case 1: 443 c += uint64(in[0]) 444 break 445 case 0: 446 c += sc_const 447 d += sc_const 448 default: 449 fmt.Printf("remainder=%d\n", remainder) 450 panic("SpookyHash") 451 } 452 //fmt.Printf("a=0x%016x, b=0x%016x, c=0x%016x, d=0x%016x\n", a, b, c, d) 453 a, b, c, d = ShortEnd(a, b, c, d) 454 //fmt.Printf("a=0x%016x, b=0x%016x, c=0x%016x, d=0x%016x\n", a, b, c, d) 455 //fmt.Printf("SpookyHash: a=0x%016x, b=0x%016x\n", a, b) 456 return a, b 457 } 458 459 // 460 // Hash128: hash a single message in one call, return 64-bit output 461 // 462 func Hash128(in []byte, seed uint64) (uint64, uint64) { 463 hash1, hash2 := uint64(seed), uint64(seed) 464 hash3, hash4 := SpookyHash128(in, hash1, hash2) 465 return hash3, hash4 466 } 467 468 // 469 // Hash64: hash a single message in one call, return 64-bit output 470 // 471 func Hash64(in []byte, seed uint64) uint64 { 472 hash1, hash2 := uint64(seed), uint64(seed) 473 hash3, _ := SpookyHash128(in, hash1, hash2) 474 return hash3 475 } 476 477 // 478 // Hash32: hash a single message in one call, produce 32-bit output 479 // 480 func Hash32(in []byte, seed uint32) uint32 { 481 hash1, hash2 := uint64(seed), uint64(seed) 482 hash3, _ := SpookyHash128(in, hash1, hash2) 483 return uint32(hash3) 484 } 485 486 var expected = []uint64{ 487 0x6bf50919, 0x70de1d26, 0xa2b37298, 0x35bc5fbf, 0x8223b279, 0x5bcb315e, 0x53fe88a1, 0xf9f1a233, 488 0xee193982, 0x54f86f29, 0xc8772d36, 0x9ed60886, 0x5f23d1da, 0x1ed9f474, 0xf2ef0c89, 0x83ec01f9, 489 0xf274736c, 0x7e9ac0df, 0xc7aed250, 0xb1015811, 0xe23470f5, 0x48ac20c4, 0xe2ab3cd5, 0x608f8363, 490 0xd0639e68, 0xc4e8e7ab, 0x863c7c5b, 0x4ea63579, 0x99ae8622, 0x170c658b, 0x149ba493, 0x027bca7c, 491 0xe5cfc8b6, 0xce01d9d7, 0x11103330, 0x5d1f5ed4, 0xca720ecb, 0xef408aec, 0x733b90ec, 0x855737a6, 492 0x9856c65f, 0x647411f7, 0x50777c74, 0xf0f1a8b7, 0x9d7e55a5, 0xc68dd371, 0xfc1af2cc, 0x75728d0a, 493 0x390e5fdc, 0xf389b84c, 0xfb0ccf23, 0xc95bad0e, 0x5b1cb85a, 0x6bdae14f, 0x6deb4626, 0x93047034, 494 0x6f3266c6, 0xf529c3bd, 0x396322e7, 0x3777d042, 0x1cd6a5a2, 0x197b402e, 0xc28d0d2b, 0x09c1afb4, 495 496 0x069c8bb7, 0x6f9d4e1e, 0xd2621b5c, 0xea68108d, 0x8660cb8f, 0xd61e6de6, 0x7fba15c7, 0xaacfaa97, 497 0xdb381902, 0x4ea22649, 0x5d414a1e, 0xc3fc5984, 0xa0fc9e10, 0x347dc51c, 0x37545fb6, 0x8c84b26b, 498 0xf57efa5d, 0x56afaf16, 0xb6e1eb94, 0x9218536a, 0xe3cc4967, 0xd3275ef4, 0xea63536e, 0x6086e499, 499 0xaccadce7, 0xb0290d82, 0x4ebfd0d6, 0x46ccc185, 0x2eeb10d3, 0x474e3c8c, 0x23c84aee, 0x3abae1cb, 500 0x1499b81a, 0xa2993951, 0xeed176ad, 0xdfcfe84c, 0xde4a961f, 0x4af13fe6, 0xe0069c42, 0xc14de8f5, 501 0x6e02ce8f, 0x90d19f7f, 0xbca4a484, 0xd4efdd63, 0x780fd504, 0xe80310e3, 0x03abbc12, 0x90023849, 502 0xd6f6fb84, 0xd6b354c5, 0x5b8575f0, 0x758f14e4, 0x450de862, 0x90704afb, 0x47209a33, 0xf226b726, 503 0xf858dab8, 0x7c0d6de9, 0xb05ce777, 0xee5ff2d4, 0x7acb6d5c, 0x2d663f85, 0x41c72a91, 0x82356bf2, 504 505 0x94e948ec, 0xd358d448, 0xeca7814d, 0x78cd7950, 0xd6097277, 0x97782a5d, 0xf43fc6f4, 0x105f0a38, 506 0x9e170082, 0x4bfe566b, 0x4371d25f, 0xef25a364, 0x698eb672, 0x74f850e4, 0x4678ff99, 0x4a290dc6, 507 0x3918f07c, 0x32c7d9cd, 0x9f28e0af, 0x0d3c5a86, 0x7bfc8a45, 0xddf0c7e1, 0xdeacb86b, 0x970b3c5c, 508 0x5e29e199, 0xea28346d, 0x6b59e71b, 0xf8a8a46a, 0x862f6ce4, 0x3ccb740b, 0x08761e9e, 0xbfa01e5f, 509 0xf17cfa14, 0x2dbf99fb, 0x7a0be420, 0x06137517, 0xe020b266, 0xd25bfc61, 0xff10ed00, 0x42e6be8b, 510 0x029ef587, 0x683b26e0, 0xb08afc70, 0x7c1fd59e, 0xbaae9a70, 0x98c8c801, 0xb6e35a26, 0x57083971, 511 0x90a6a680, 0x1b44169e, 0x1dce237c, 0x518e0a59, 0xccb11358, 0x7b8175fb, 0xb8fe701a, 0x10d259bb, 512 0xe806ce10, 0x9212be79, 0x4604ae7b, 0x7fa22a84, 0xe715b13a, 0x0394c3b2, 0x11efbbae, 0xe13d9e19, 513 514 0x77e012bd, 0x2d05114c, 0xaecf2ddd, 0xb2a2b4aa, 0xb9429546, 0x55dce815, 0xc89138f8, 0x46dcae20, 515 0x1f6f7162, 0x0c557ebc, 0x5b996932, 0xafbbe7e2, 0xd2bd5f62, 0xff475b9f, 0x9cec7108, 0xeaddcffb, 516 0x5d751aef, 0xf68f7bdf, 0xf3f4e246, 0x00983fcd, 0x00bc82bb, 0xbf5fd3e7, 0xe80c7e2c, 0x187d8b1f, 517 0xefafb9a7, 0x8f27a148, 0x5c9606a9, 0xf2d2be3e, 0xe992d13a, 0xe4bcd152, 0xce40b436, 0x63d6a1fc, 518 0xdc1455c4, 0x64641e39, 0xd83010c9, 0x2d535ae0, 0x5b748f3e, 0xf9a9146b, 0x80f10294, 0x2859acd4, 519 0x5fc846da, 0x56d190e9, 0x82167225, 0x98e4daba, 0xbf7865f3, 0x00da7ae4, 0x9b7cd126, 0x644172f8, 520 0xde40c78f, 0xe8803efc, 0xdd331a2b, 0x48485c3c, 0x4ed01ddc, 0x9c0b2d9e, 0xb1c6e9d7, 0xd797d43c, 521 0x274101ff, 0x3bf7e127, 0x91ebbc56, 0x7ffeb321, 0x4d42096f, 0xd6e9456a, 0x0bade318, 0x2f40ee0b, 522 523 0x38cebf03, 0x0cbc2e72, 0xbf03e704, 0x7b3e7a9a, 0x8e985acd, 0x90917617, 0x413895f8, 0xf11dde04, 524 0xc66f8244, 0xe5648174, 0x6c420271, 0x2469d463, 0x2540b033, 0xdc788e7b, 0xe4140ded, 0x0990630a, 525 0xa54abed4, 0x6e124829, 0xd940155a, 0x1c8836f6, 0x38fda06c, 0x5207ab69, 0xf8be9342, 0x774882a8, 526 0x56fc0d7e, 0x53a99d6e, 0x8241f634, 0x9490954d, 0x447130aa, 0x8cc4a81f, 0x0868ec83, 0xc22c642d, 527 0x47880140, 0xfbff3bec, 0x0f531f41, 0xf845a667, 0x08c15fb7, 0x1996cd81, 0x86579103, 0xe21dd863, 528 0x513d7f97, 0x3984a1f1, 0xdfcdc5f4, 0x97766a5e, 0x37e2b1da, 0x41441f3f, 0xabd9ddba, 0x23b755a9, 529 0xda937945, 0x103e650e, 0x3eef7c8f, 0x2760ff8d, 0x2493a4cd, 0x1d671225, 0x3bf4bd4c, 0xed6e1728, 530 0xc70e9e30, 0x4e05e529, 0x928d5aa6, 0x164d0220, 0xb5184306, 0x4bd7efb3, 0x63830f11, 0xf3a1526c, 531 532 0xf1545450, 0xd41d5df5, 0x25a5060d, 0x77b368da, 0x4fe33c7e, 0xeae09021, 0xfdb053c4, 0x2930f18d, 533 0xd37109ff, 0x8511a781, 0xc7e7cdd7, 0x6aeabc45, 0xebbeaeaa, 0x9a0c4f11, 0xda252cbb, 0x5b248f41, 534 0x5223b5eb, 0xe32ab782, 0x8e6a1c97, 0x11d3f454, 0x3e05bd16, 0x0059001d, 0xce13ac97, 0xf83b2b4c, 535 0x71db5c9a, 0xdc8655a6, 0x9e98597b, 0x3fcae0a2, 0x75e63ccd, 0x076c72df, 0x4754c6ad, 0x26b5627b, 536 0xd818c697, 0x998d5f3d, 0xe94fc7b2, 0x1f49ad1a, 0xca7ff4ea, 0x9fe72c05, 0xfbd0cbbf, 0xb0388ceb, 537 0xb76031e3, 0xd0f53973, 0xfb17907c, 0xa4c4c10f, 0x9f2d8af9, 0xca0e56b0, 0xb0d9b689, 0xfcbf37a3, 538 0xfede8f7d, 0xf836511c, 0x744003fc, 0x89eba576, 0xcfdcf6a6, 0xc2007f52, 0xaaaf683f, 0x62d2f9ca, 539 0xc996f77f, 0x77a7b5b3, 0x8ba7d0a4, 0xef6a0819, 0xa0d903c0, 0x01b27431, 0x58fffd4c, 0x4827f45c, 540 541 0x44eb5634, 0xae70edfc, 0x591c740b, 0x478bf338, 0x2f3b513b, 0x67bf518e, 0x6fef4a0c, 0x1e0b6917, 542 0x5ac0edc5, 0x2e328498, 0x077de7d5, 0x5726020b, 0x2aeda888, 0x45b637ca, 0xcf60858d, 0x3dc91ae2, 543 0x3e6d5294, 0xe6900d39, 0x0f634c71, 0x827a5fa4, 0xc713994b, 0x1c363494, 0x3d43b615, 0xe5fe7d15, 544 0xf6ada4f2, 0x472099d5, 0x04360d39, 0x7f2a71d0, 0x88a4f5ff, 0x2c28fac5, 0x4cd64801, 0xfd78dd33, 545 0xc9bdd233, 0x21e266cc, 0x9bbf419d, 0xcbf7d81d, 0x80f15f96, 0x04242657, 0x53fb0f66, 0xded11e46, 546 0xf2fdba97, 0x8d45c9f1, 0x4eeae802, 0x17003659, 0xb9db81a7, 0xe734b1b2, 0x9503c54e, 0xb7c77c3e, 547 0x271dd0ab, 0xd8b906b5, 0x0d540ec6, 0xf03b86e0, 0x0fdb7d18, 0x95e261af, 0xad9ec04e, 0x381f4a64, 548 0xfec798d7, 0x09ea20be, 0x0ef4ca57, 0x1e6195bb, 0xfd0da78b, 0xcea1653b, 0x157d9777, 0xf04af50f, 549 550 0xad7baa23, 0xd181714a, 0x9bbdab78, 0x6c7d1577, 0x645eb1e7, 0xa0648264, 0x35839ca6, 0x2287ef45, 551 0x32a64ca3, 0x26111f6f, 0x64814946, 0xb0cddaf1, 0x4351c59e, 0x1b30471c, 0xb970788a, 0x30e9f597, 552 0xd7e58df1, 0xc6d2b953, 0xf5f37cf4, 0x3d7c419e, 0xf91ecb2d, 0x9c87fd5d, 0xb22384ce, 0x8c7ac51c, 553 0x62c96801, 0x57e54091, 0x964536fe, 0x13d3b189, 0x4afd1580, 0xeba62239, 0xb82ea667, 0xae18d43a, 554 0xbef04402, 0x1942534f, 0xc54bf260, 0x3c8267f5, 0xa1020ddd, 0x112fcc8a, 0xde596266, 0xe91d0856, 555 0xf300c914, 0xed84478e, 0x5b65009e, 0x4764da16, 0xaf8e07a2, 0x4088dc2c, 0x9a0cad41, 0x2c3f179b, 556 0xa67b83f7, 0xf27eab09, 0xdbe10e28, 0xf04c911f, 0xd1169f87, 0x8e1e4976, 0x17f57744, 0xe4f5a33f, 557 0x27c2e04b, 0x0b7523bd, 0x07305776, 0xc6be7503, 0x918fa7c9, 0xaf2e2cd9, 0x82046f8e, 0xcc1c8250, 558 }