X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/63af6f3a15c5c4779761761bd4d6185e4679eafc..190404d75c168ce1e6dbf6ee08bdbbf62b365e4b:/src/src/hash.c diff --git a/src/src/hash.c b/src/src/hash.c index 628df5b4b..eea2cb8a3 100644 --- a/src/src/hash.c +++ b/src/src/hash.c @@ -1,58 +1,84 @@ /* * Exim - an Internet mail transport agent * - * Copyright (C) 2016 Exim maintainers + * Copyright (C) 2010 - 2018 Exim maintainers + * Copyright (c) University of Cambridge 1995 - 2009 * * Hash interface functions */ -#include "exim.h" +#ifndef STAND_ALONE +# include "exim.h" -#ifndef SUPPORT_TLS -# error Need SUPPORT_TLS for DKIM -#endif - -#include "sha_ver.h" -#include "hash.h" +#else +/* For stand-alone testing, we need to have the structure defined, and +to be able to do I/O */ -#ifdef notdef -#ifdef RSA_OPENSSL -# include -# include -# include -#elif defined(RSA_GNUTLS) -# include -# include -# ifdef RSA_VERIFY_GNUTLS -# include -# endif -#endif -#endif +# include +# include +typedef unsigned char uschar; +typedef struct sha1 { + unsigned int H[5]; + unsigned int length; + } +sha1; +#endif /*STAND_ALONE*/ +#include /******************************************************************************/ #ifdef SHA_OPENSSL -void -exim_sha_init(hctx * h, BOOL sha1) +BOOL +exim_sha_init(hctx * h, hashmethod m) { -h->sha1 = sha1; -h->hashlen = sha1 ? 20 : 32; -if (h->sha1) - SHA1_Init (&h->u.sha1); -else - SHA256_Init(&h->u.sha2); +/*XXX extend for sha512 */ +switch (h->method = m) + { + case HASH_SHA1: h->hashlen = 20; SHA1_Init (&h->u.sha1); break; + case HASH_SHA2_256: h->hashlen = 32; SHA256_Init(&h->u.sha2_256); break; + case HASH_SHA2_384: h->hashlen = 48; SHA384_Init(&h->u.sha2_512); break; + case HASH_SHA2_512: h->hashlen = 64; SHA512_Init(&h->u.sha2_512); break; +#ifdef EXIM_HAVE_SHA3 + case HASH_SHA3_224: h->hashlen = 28; + EVP_DigestInit(h->u.mctx = EVP_MD_CTX_new(), EVP_sha3_224()); + break; + case HASH_SHA3_256: h->hashlen = 32; + EVP_DigestInit(h->u.mctx = EVP_MD_CTX_new(), EVP_sha3_256()); + break; + case HASH_SHA3_384: h->hashlen = 48; + EVP_DigestInit(h->u.mctx = EVP_MD_CTX_new(), EVP_sha3_384()); + break; + case HASH_SHA3_512: h->hashlen = 64; + EVP_DigestInit(h->u.mctx = EVP_MD_CTX_new(), EVP_sha3_512()); + break; +#endif + default: h->hashlen = 0; return FALSE; + } +return TRUE; } void exim_sha_update(hctx * h, const uschar * data, int len) { -if (h->sha1) - SHA1_Update (&h->u.sha1, data, len); -else - SHA256_Update(&h->u.sha2, data, len); +switch (h->method) + { + case HASH_SHA1: SHA1_Update (&h->u.sha1, data, len); break; + case HASH_SHA2_256: SHA256_Update(&h->u.sha2_256, data, len); break; + case HASH_SHA2_384: SHA384_Update(&h->u.sha2_512, data, len); break; + case HASH_SHA2_512: SHA512_Update(&h->u.sha2_512, data, len); break; +#ifdef EXIM_HAVE_SHA3 + case HASH_SHA3_224: + case HASH_SHA3_256: + case HASH_SHA3_384: + case HASH_SHA3_512: EVP_DigestUpdate(h->u.mctx, data, len); break; +#endif + /* should be blocked by init not handling these, but be explicit to + guard against accidents later (and hush up clang -Wswitch) */ + default: assert(0); + } } @@ -60,11 +86,20 @@ void exim_sha_finish(hctx * h, blob * b) { b->data = store_get(b->len = h->hashlen); - -if (h->sha1) - SHA1_Final (b->data, &h->u.sha1); -else - SHA256_Final(b->data, &h->u.sha2); +switch (h->method) + { + case HASH_SHA1: SHA1_Final (b->data, &h->u.sha1); break; + case HASH_SHA2_256: SHA256_Final(b->data, &h->u.sha2_256); break; + case HASH_SHA2_384: SHA384_Final(b->data, &h->u.sha2_512); break; + case HASH_SHA2_512: SHA512_Final(b->data, &h->u.sha2_512); break; +#ifdef EXIM_HAVE_SHA3 + case HASH_SHA3_224: + case HASH_SHA3_256: + case HASH_SHA3_384: + case HASH_SHA3_512: EVP_DigestFinal(h->u.mctx, b->data, NULL); break; +#endif + default: assert(0); + } } @@ -72,12 +107,25 @@ else #elif defined(SHA_GNUTLS) /******************************************************************************/ -void -exim_sha_init(hctx * h, BOOL sha1) +BOOL +exim_sha_init(hctx * h, hashmethod m) { -h->sha1 = sha1; -h->hashlen = sha1 ? 20 : 32; -gnutls_hash_init(&h->sha, sha1 ? GNUTLS_DIG_SHA1 : GNUTLS_DIG_SHA256); +/*XXX extend for sha512 */ +switch (h->method = m) + { + case HASH_SHA1: h->hashlen = 20; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA1); break; + case HASH_SHA2_256: h->hashlen = 32; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA256); break; + case HASH_SHA2_384: h->hashlen = 48; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA384); break; + case HASH_SHA2_512: h->hashlen = 64; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA512); break; +#ifdef EXIM_HAVE_SHA3 + case HASH_SHA3_224: h->hashlen = 28; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA3_224); break; + case HASH_SHA3_256: h->hashlen = 32; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA3_256); break; + case HASH_SHA3_384: h->hashlen = 48; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA3_384); break; + case HASH_SHA3_512: h->hashlen = 64; gnutls_hash_init(&h->sha, GNUTLS_DIG_SHA3_512); break; +#endif + default: h->hashlen = 0; return FALSE; + } +return TRUE; } @@ -100,12 +148,22 @@ gnutls_hash_output(h->sha, b->data); #elif defined(SHA_GCRYPT) /******************************************************************************/ -void -exim_sha_init(hctx * h, BOOL sha1) +BOOL +exim_sha_init(hctx * h, hashmethod m) { -h->sha1 = sha1; -h->hashlen = sha1 ? 20 : 32; -gcry_md_open(&h->sha, sha1 ? GCRY_MD_SHA1 : GCRY_MD_SHA256, 0); +/*XXX extend for sha512 */ +switch (h->method = m) + { + case HASH_SHA1: h->hashlen = 20; gcry_md_open(&h->sha, GCRY_MD_SHA1, 0); break; + case HASH_SHA2_256: h->hashlen = 32; gcry_md_open(&h->sha, GCRY_MD_SHA256, 0); break; + case HASH_SHA2_384: h->hashlen = 48; gcry_md_open(&h->sha, GCRY_MD_SHA384, 0); break; + case HASH_SHA2_512: h->hashlen = 64; gcry_md_open(&h->sha, GCRY_MD_SHA512, 0); break; + case HASH_SHA3_256: h->hashlen = 32; gcry_md_open(&h->sha, GCRY_MD_SHA3_256, 0); break; + case HASH_SHA3_384: h->hashlen = 48; gcry_md_open(&h->sha, GCRY_MD_SHA3_384, 0); break; + case HASH_SHA3_512: h->hashlen = 64; gcry_md_open(&h->sha, GCRY_MD_SHA3_512, 0); break; + default: h->hashlen = 0; return FALSE; + } +return TRUE; } @@ -129,25 +187,266 @@ memcpy(b->data, gcry_md_read(h->sha, 0), h->hashlen); #elif defined(SHA_POLARSSL) /******************************************************************************/ +BOOL +exim_sha_init(hctx * h, hashmethod m) +{ +/*XXX extend for sha512 */ +switch (h->method = m) + { + case HASH_SHA1: h->hashlen = 20; sha1_starts(&h->u.sha1); break; + case HASH_SHA2_256: h->hashlen = 32; sha2_starts(&h->u.sha2, 0); break; + default: h->hashlen = 0; return FALSE; + } +return TRUE; +} + + +void +exim_sha_update(hctx * h, const uschar * data, int len) +{ +switch (h->method) + { + case HASH_SHA1: sha1_update(h->u.sha1, US data, len); break; + case HASH_SHA2_256: sha2_update(h->u.sha2, US data, len); break; + } +} + + void -exim_sha_init(hctx * h, BOOL sha1) +exim_sha_finish(hctx * h, blob * b) +{ +b->data = store_get(b->len = h->hashlen); +switch (h->method) + { + case HASH_SHA1: sha1_finish(h->u.sha1, b->data); break; + case HASH_SHA2_256: sha2_finish(h->u.sha2, b->data); break; + } +} + + + + +#elif defined(SHA_NATIVE) +/******************************************************************************/ +/* Only sha-1 supported */ + +/************************************************* +* Start off a new SHA-1 computation. * +*************************************************/ + +/* +Argument: pointer to sha1 storage structure +Returns: nothing +*/ + +static void +native_sha1_start(sha1 *base) +{ +base->H[0] = 0x67452301; +base->H[1] = 0xefcdab89; +base->H[2] = 0x98badcfe; +base->H[3] = 0x10325476; +base->H[4] = 0xc3d2e1f0; +base->length = 0; +} + + + +/************************************************* +* Process another 64-byte block * +*************************************************/ + +/* This function implements central part of the algorithm + +Arguments: + base pointer to sha1 storage structure + text pointer to next 64 bytes of subject text + +Returns: nothing +*/ + +static void +native_sha1_mid(sha1 *base, const uschar *text) +{ +uint A, B, C, D, E; +uint W[80]; + +base->length += 64; + +for (int i = 0; i < 16; i++) + { + W[i] = ((uint)text[0] << 24) | (text[1] << 16) | (text[2] << 8) | text[3]; + text += 4; + } + +for (int i = 16; i < 80; i++) + { + register unsigned int x = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]; + W[i] = (x << 1) | (x >> 31); + } + +A = base->H[0]; +B = base->H[1]; +C = base->H[2]; +D = base->H[3]; +E = base->H[4]; + +for (int i = 0; i < 20; i++) + { + unsigned int T; + T = ((A << 5) | (A >> 27)) + ((B & C) | ((~B) & D)) + E + W[i] + 0x5a827999; + E = D; + D = C; + C = (B << 30) | (B >> 2); + B = A; + A = T; + } + +for (int i = 20; i < 40; i++) + { + unsigned int T; + T = ((A << 5) | (A >> 27)) + (B ^ C ^ D) + E + W[i] + 0x6ed9eba1; + E = D; + D = C; + C = (B << 30) | (B >> 2); + B = A; + A = T; + } + +for (int i = 40; i < 60; i++) + { + unsigned int T; + T = ((A << 5) | (A >> 27)) + ((B & C) | (B & D) | (C & D)) + E + W[i] + + 0x8f1bbcdc; + E = D; + D = C; + C = (B << 30) | (B >> 2); + B = A; + A = T; + } + +for (int i = 60; i < 80; i++) + { + unsigned int T; + T = ((A << 5) | (A >> 27)) + (B ^ C ^ D) + E + W[i] + 0xca62c1d6; + E = D; + D = C; + C = (B << 30) | (B >> 2); + B = A; + A = T; + } + +base->H[0] += A; +base->H[1] += B; +base->H[2] += C; +base->H[3] += D; +base->H[4] += E; +} + + + + +/************************************************* +* Process the final text string * +*************************************************/ + +/* The string may be of any length. It is padded out according to the rules +for computing SHA-1 digests. The final result is then converted to text form +and returned. + +Arguments: + base pointer to the sha1 storage structure + text pointer to the final text vector + length length of the final text vector + digest points to 16 bytes in which to place the result + +Returns: nothing +*/ + +static void +native_sha1_end(sha1 *base, const uschar *text, int length, uschar *digest) { -h->sha1 = sha1; -h->hashlen = sha1 ? 20 : 32; -if (h->sha1) - sha1_starts(&h->u.sha1); +uschar work[64]; + +/* Process in chunks of 64 until we have less than 64 bytes left. */ + +while (length >= 64) + { + native_sha1_mid(base, text); + text += 64; + length -= 64; + } + +/* If the remaining string contains more than 55 bytes, we must pad it +out to 64, process it, and then set up the final chunk as 56 bytes of +padding. If it has less than 56 bytes, we pad it out to 56 bytes as the +final chunk. */ + +memcpy(work, text, length); +work[length] = 0x80; + +if (length > 55) + { + memset(work+length+1, 0, 63-length); + native_sha1_mid(base, work); + base->length -= 64; + memset(work, 0, 56); + } else - sha2_starts(&h->u.sha2, 0); + { + memset(work+length+1, 0, 55-length); + } + +/* The final 8 bytes of the final chunk are a 64-bit representation of the +length of the input string *bits*, before padding, high order word first, and +high order bytes first in each word. This implementation is designed for short +strings, and so operates with a single int counter only. */ + +length += base->length; /* Total length in bytes */ +length <<= 3; /* Total length in bits */ + +work[63] = length & 0xff; +work[62] = (length >> 8) & 0xff; +work[61] = (length >> 16) & 0xff; +work[60] = (length >> 24) & 0xff; + +memset(work+56, 0, 4); + +/* Process the final 64-byte chunk */ + +native_sha1_mid(base, work); + +/* Pass back the result, high-order byte first in each word. */ + +for (int i = 0; i < 5; i++) + { + register int x = base->H[i]; + *digest++ = (x >> 24) & 0xff; + *digest++ = (x >> 16) & 0xff; + *digest++ = (x >> 8) & 0xff; + *digest++ = x & 0xff; + } +} + + + + + + +# ifdef notdef +BOOL +exim_sha_init(hctx * h, hashmethod m) +{ +h->hashlen = 20; +native_sha1_start(&h->sha1); +return TRUE; } void exim_sha_update(hctx * h, const uschar * data, int len) { -if (h->sha1) - sha1_update(h->u.sha1, US data, len); -else - sha2_update(h->u.sha2, US data, len); +native_sha1_mid(&h->sha1, US data); /* implicit size always 64 */ } @@ -156,21 +455,392 @@ exim_sha_finish(hctx * h, blob * b) { b->data = store_get(b->len = h->hashlen); -if (h->sha1) - sha1_finish(h->u.sha1, b->data); -else - sha2_finish(h->u.sha2, b->data); +native_sha1_end(&h->sha1, NULL, 0, b->data); } +# endif + #endif + + /******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ +/* Original sha-1 interface used by crypteq{shal1}, +${sha1:} ${hmac:} and ${prvs:} */ + +#ifdef SHA_NATIVE + +void +sha1_start(hctx * h) +{ +native_sha1_start(&h->sha1); +} + +void +sha1_mid(hctx * h, const uschar * data) +{ +native_sha1_mid(&h->sha1, data); +} -/* Common to all library versions */ -int -exim_sha_hashlen(hctx * h) +void +sha1_end(hctx * h, const uschar * data, int len, uschar *digest) +{ +native_sha1_end(&h->sha1, data, len, digest); +} + +#else + +void +sha1_start(hctx * h) +{ +(void) exim_sha_init(h, HASH_SHA1); +} + +void +sha1_mid(hctx * h, const uschar * data) { -return h->sha1 ? 20 : 32; +exim_sha_update(h, data, 64); } +void +sha1_end(hctx * h, const uschar * data, int len, uschar *digest) +{ +blob b; +exim_sha_update(h, data, len); +exim_sha_finish(h, &b); +memcpy(digest, b.data, 20); +} + +#endif + + + + + + +/************************************************* +************************************************** +* Stand-alone test program * +************************************************** +*************************************************/ + +# ifdef STAND_ALONE + +/* Test values. The first 128 may contain binary zeros and have increasing +length. */ + +static uschar *tests[] = { + "", + "\x24", + "\x70\xf0", + "\x0e\x1e\xf0", + "\x08\x38\x78\x8f", + "\x10\x3e\x08\xfc\x0f", + "\xe7\xc7\x1e\x07\xef\x03", + "\xe0\xfb\x71\xf8\xf9\xc1\xfc", + "\xff\x7c\x60\x3c\x1f\x80\xe2\x07", + "\xf0\x3f\xc8\x60\x81\xfe\x01\xf8\x7f", + "\x9f\xc7\xf8\x1f\xc1\xe3\xc7\xc7\x3f\x00", + "\x00\x7f\xbf\xdf\xc0\xfe\x02\x7e\x00\xf8\x7f", + "\x01\x01\xc0\x1e\x03\xf8\x30\x08\x0f\xf3\xf9\xff", + "\xc4\x03\xfc\x0f\xf8\x01\xc0\x0f\xf0\x06\x10\x41\xff", + "\xff\x07\x80\x47\xfc\x1f\xc0\x60\x30\x1f\xe0\x3c\x03\xff", + "\x80\x3f\x84\x3e\xff\xc0\x3f\x0f\x00\x7f\xc0\x1f\xe7\xfc\x00", + "\xff\xe0\x7f\x01\x81\x81\xff\x81\xff\x00\x3e\x00\x20\x7f\x80\x0f", + "\x00\x3e\x00\x70\x1f\xe0\x0f\xfa\xff\xc8\x3f\xf3\xfe\x00\xff\x80\xff", + "\x7f\xef\xc0\x1e\x7c\xff\xe0\x1f\xfe\x00\x1f\xf0\x08\xff\xc0\x7f\xf0\x00", + "\xe0\x0f\x80\x07\x0c\x01\xff\xe0\x03\xf0\x2f\xf8\x3f\xef\x00\x78\x01\xfe\x00", + "\xe7\x00\x10\x00\xf8\x18\x0f\xf0\xff\x00\xff\x80\x3f\xc3\xfe\xf0\x0f\xfc\x01\xff", + "\x00\x1f\xf8\x0f\xfc\x00\xfc\x00\xff\x87\xc0\x0f\x80\x7b\xff\x00\x0f\x02\x01\xff\xc0", + "\x00\x0f\xf0\x03\xc7\xf8\x3e\x03\xff\x80\x03\xff\x80\x07\xff\x0f\xff\x1f\x83\xff\x80\x1f", + "\xff\xc0\x1f\x80\x3f\x9f\xf8\x78\x3e\x7f\xf8\x00\x3e\x20\x04\x3f\x80\x7f\xfc\x00\x1f\xfe\x00", + "\x3f\x07\x80\xe0\x07\xe0\x00\xfc\x7f\xc0\xc0\x0f\x8f\xf0\x80\x0e\x0e\x03\xff\xbf\xfc\x01\xff\xe0", + "\xff\xfc\x11\xfc\xe0\x0e\x1f\xff\x87\x80\x1f\xe0\xff\xfd\xff\xc0\x03\xff\xc0\x0f\x00\x07\xf0\x01\xff", + "\xf0\x07\xc1\xfe\x00\xf8\x01\xe7\x80\xff\x80\x3f\x1f\x7f\x8c\x00\x1c\x00\x0f\xf8\x07\xfc\x00\xff\xfc\x00", + "\x00\x0f\xf8\x3f\xc0\x60\x00\x7f\xf8\xff\x00\x03\xf0\x3c\x07\xc0\x7f\xe0\x3f\xf8\x01\x00\x7e\x03\xff\xc0\x00", + "\x00\x0f\xf8\x03\x00\x1f\xff\x00\x0f\xfe\x00\x3f\x00\x03\xff\xe0\x07\xc0\xff\x00\x3c\x7f\xf0\x01\xff\xf8\x3f\xff", + "\x00\x01\xe0\xe0\x1f\xfe\x00\x03\xfc\x00\x0f\xff\xe0\x0f\xff\x00\x0e\x00\x7f\xfc\x0f\xfe\x00\x78\x00\x3f\xff\x00\xff", + "\x80\x41\xff\xc3\xfe\x00\x1e\x00\x0f\xff\xe0\xff\x80\x0f\xe0\x00\x7f\xf7\xff\x01\xfe\x01\xff\xdf\xff\x00\x01\xff\xe0\x00", + "\xf8\x07\x00\xff\xc0\x7f\xbe\x00\x0f\xff\x00\x03\xe3\xf0\xff\xf0\x00\x1f\x81\xff\x80\x0f\xff\x80\x20\x03\xf0\x03\x80\xff\xfc", + "\x00\x38\x20\x00\x7f\xf0\x01\xff\xfe\xcf\xfe\x07\xff\xc0\x00\x7f\xf8\x1f\x00\x00\xc0\x00\xc0\x0f\xff\x3e\x0f\xc0\x0f\xff\x80\x00", + "\x1f\xf8\x07\xff\xf8\x03\xe0\x01\xff\xfc\x3f\xf8\x00\x38\x1f\x00\x3f\xdc\x01\xc0\x04\xff\xff\x00\x0f\xfc\x08\x02\x00\x01\xf0\x3f\xff", + "\x80\x07\x86\x00\x03\xff\xe0\x00\x3f\xf8\x00\x0f\x80\x0f\xf8\x0f\xff\xe0\x00\x1f\x80\x00\x7f\xf8\xc0\x0f\xff\xf0\x7c\x04\x07\xff\x00\x00", + "\x01\xff\x00\x18\x3e\x0f\x00\x07\xff\xc0\x00\xf0\x1f\xfe\x07\x80\x60\x0f\xf8\x00\x3f\xfe\x38\x1f\xc0\x00\x3f\x81\xff\xfc\x1f\xe0\x00\x3f\xff", + "\xf0\x3f\xff\xc0\x00\x7f\xf0\x00\x3f\xff\x0f\xe0\x07\x0f\xfc\x7e\x03\xff\xf0\xfc\x0f\x9f\xc0\x3f\xff\xcf\xff\x00\x00\xff\xc0\x00\xe7\x01\xff\xf8", + "\x00\x01\xff\x80\x20\x00\x7f\xe0\x00\x7e\x07\xff\xf8\xc7\xf8\xff\xf0\x0f\xfe\x00\x00\xe0\x0f\xe0\x00\x1f\xff\x87\xff\x00\x01\xf0\x00\x7f\xc1\xff\xff", + "\x00\x00\x7f\xff\xc0\x01\xfe\x7e\x01\xff\xfe\xff\xf0\x7f\xff\xcf\xf8\x07\xfe\x00\x0f\xff\xc0\x07\xff\xfc\x00\x3e\x00\x07\xfc\x00\x7f\xc0\x07\x80\x0f\xff", + "\xff\xff\x03\xff\x07\xf8\xff\xff\x80\x00\x7f\xfe\xff\xfe\x00\x03\xff\xf8\x1f\xff\x3f\xf8\x1f\xff\x00\x1f\xff\x0f\xc0\x7f\xf0\x01\xff\xe0\x00\x1f\xff\x00\x00", + "\xff\xff\x00\x00\xff\xfc\x00\x03\x0f\xff\xf0\x01\xf8\x00\x0f\xe1\xff\xff\x03\xe0\x3f\x1f\xff\x80\x00\x7c\x00\x01\xff\xc0\x01\x7f\xfe\x00\x0e\x07\xff\xe0\xff\xff", + "\xc0\x00\x3f\xfe\x03\xfc\x0c\x00\x04\x01\xff\xe1\xe0\x03\xff\xe0\x30\x01\xff\x00\x00\x3c\x1e\x01\x80\x01\xff\x00\x40\x3f\xfe\x00\x3f\xff\x80\x7c\x01\xff\x80\x00\x7f", + "\x3f\xa0\x00\x0f\xff\x81\xff\xc0\x0f\xf0\x7f\xf8\x00\x0f\xc0\x00\x7f\xe0\x01\xe0\x00\x04\xff\x00\x1f\xfe\x00\x01\xff\x80\x07\xff\xfe\x00\x3f\xff\xc0\x03\xff\x80\x00\x3f", + "\xf0\x1f\xff\x01\xff\x80\xff\xc0\x80\x07\xf0\x00\x03\xff\x80\x00\x18\x01\xff\xfc\x00\xff\xfc\x03\xff\xff\x00\x7f\xc0\x03\xff\xc7\xff\xc0\x03\xf0\xff\x80\x00\x3f\xfe\x00\x00", + "\x07\xf1\xbf\xff\xe0\x00\x78\x00\x07\xe0\x00\x80\x03\xf0\x3f\xf7\x00\x00\x38\x00\xfe\x00\xf8\x0f\xfe\x00\x00\x80\x3f\xff\xc1\xff\xfc\x00\xff\xff\x8f\xf0\x00\x1f\xff\xf0\x0f\xff", + "\x00\x1c\x00\x07\xff\xfc\x00\x5e\x3f\xff\x00\x00\x3c\xff\xff\xc0\x3f\xff\x81\xe0\x70\x00\x1f\xfc\x00\x03\xff\x00\x00\x7f\xff\xc0\x1f\x8c\x0f\xff\xf0\xff\x80\x07\xe0\x10\x01\xff\xff", + "\xc0\x00\x07\xff\x80\x7f\xff\x80\x01\x80\x3f\xff\xcf\xc0\xfe\x00\xff\xc0\x1f\xfc\x01\xff\xf8\x00\xff\xfe\x0f\xff\xf0\x06\x00\x00\xc0\x3f\xff\x80\x78\xff\xfc\x00\x0f\xff\xf0\x00\x0f\xff", + "\xff\xe0\x07\xff\xf8\x00\x7f\xf0\x1f\xff\x80\x01\xff\xf8\x1f\xf8\x01\x03\xff\xe0\x00\x03\xe0\x78\x0f\xff\x00\x0f\xfc\x1f\xf8\x00\x0f\xff\xe0\x1f\x00\x07\xff\xfc\x00\x1f\x03\xff\xf7\xff\xff", + "\xc0\xf8\x00\x03\xfe\x00\x3f\xff\xf0\x00\x03\xfc\x0f\xff\x80\x00\xe3\xff\xf8\x3f\xfe\x00\x00\x73\xe0\xff\xfc\x07\xff\xc3\xff\xfe\x03\x00\x00\x70\x00\x03\xff\xf8\x0f\xff\xe0\x00\x1f\xff\xf8\x00", + "\xff\xf0\x0f\xc7\xff\xfc\x00\x3f\xfe\x00\x00\x3f\xff\x80\x3f\x80\x00\x3f\xff\xc0\x00\x70\x01\xff\xc1\x80\x03\xff\xff\x80\x00\x61\xff\xfe\x03\xfd\x80\x3f\xff\xe0\x01\xc1\xff\xff\x80\x00\x0f\xfe\x00", + "\xff\xfc\x00\x03\xff\xf0\x0f\xf8\x00\x07\xdf\x8f\xff\xf8\x00\x01\xff\xfe\x00\x80\x00\xff\x80\x1f\xf0\x00\x01\x1c\x00\x00\x3f\xf8\x00\x3f\xff\xef\xff\xfe\x01\xc3\x80\x80\x01\xff\xff\xc0\x00\x07\xff\xff", + "\xff\xff\xc0\x01\xff\xc1\xff\xff\x87\xff\xff\x00\x3f\x00\x00\x1f\xfc\x00\x01\xff\x80\x1f\xc0\x1f\xff\x00\x00\xff\x80\x1f\xff\xf8\x7f\xf8\x3f\xff\xc1\xff\xff\xe0\x01\xc0\x3f\xf7\xff\xfe\xfc\x00\x00\x3f\xff", + "\x00\xff\x81\xff\xe0\x03\xf8\x0e\x00\x00\xff\xf8\x1f\xff\xfe\x00\x00\xff\x80\x00\x07\xff\xf8\x01\xff\xe0\x00\x0f\xf0\x01\xfe\x00\x3f\xf0\x7f\xe0\x00\x7f\xff\xe0\x1f\xff\xfc\x01\xff\xe0\x01\x80\x00\x07\xff\xff", + "\x00\x0f\xff\xf0\x00\x00\xe0\x0f\xf8\x00\x00\xff\xff\x80\x03\xff\xe1\xff\xff\x3f\xf8\x0f\xff\xc7\xe0\x00\x1f\xff\x00\x3f\xfe\x0f\xff\xf0\x03\x00\xc0\x00\x1f\xff\xfc\x3f\xff\xe0\x3f\xff\xf8\x1f\xf0\x00\x1f\xff\xc0", + "\x01\x80\x00\x1f\x01\xff\xff\x83\x00\x01\xfc\x00\x7f\xe0\x0e\x7f\xfe\x00\x00\x38\x00\xff\x00\x00\x3f\xff\x83\x83\xff\xc0\x00\x7f\xff\x80\x1f\xff\xf0\x1f\xff\xfc\x00\x03\x7f\xff\x81\xc0\x00\x07\xff\x83\xff\xff\x00\x00", + "\xff\x80\x0d\xff\xe0\x03\xff\xf0\x00\xff\xfc\x00\xf0\x01\xf8\x07\xff\xf8\x0f\x80\x0f\xff\xff\x00\xff\xff\x87\xff\xe1\xff\xfc\x67\x8c\x7f\xfe\x00\x03\xff\x3f\xfc\x07\x01\xff\xff\xe0\x00\x01\xff\xff\xc0\x0c\x40\x0f\xff\xff", + "\x00\x00\x1f\xff\xfe\x00\x1f\x00\x00\x1f\xff\xff\x07\xff\xff\xc0\x07\xff\xe0\x00\x02\x00\x00\xff\x00\x78\x00\x00\xe0\x00\x08\x00\x1f\xff\xff\x00\x03\xf8\x1f\x00\x00\x0f\xff\xc0\x00\x01\xff\xff\xe1\xf8\x00\x00\x3f\x80\x0f\xff", + "\x00\x0f\xf8\x00\xfc\x00\x03\xff\xff\x00\x00\x3f\xf0\x01\xff\xff\xe0\x7f\xf8\x00\xf8\x0f\xff\xff\x80\x00\x0f\xff\xfc\x0f\xff\xe0\x00\x00\xff\xc3\xff\xf0\x07\xff\xff\x00\x38\xf8\x00\x20\x1f\xfe\x3f\xfe\x00\xfe\x00\x7f\xff\xc0\x00", + "\x00\x3f\x00\xe0\x00\x0f\xff\xfc\x7f\xff\xfc\x00\x00\x7e\x00\x00\xff\xfe\x1f\xf0\x00\x1f\xf0\x00\x1f\xff\x87\xf0\x00\x3f\xc0\x0f\xff\x87\xff\x00\x3f\x81\xff\xff\xf7\xff\xe0\xff\xe0\x3f\x9f\xff\x00\x07\x00\x7f\xfc\x03\xff\xf0\x00\x00", + "\xe0\x3f\xff\xf0\xff\x80\x3e\x00\x03\xff\xe0\x00\x0f\xfc\x00\x07\xff\xf8\x00\x00\x7f\x80\x00\x0f\xf8\x01\xff\x7f\xff\xf0\x00\x3f\xff\xfe\x7f\xff\xe0\x00\xff\xc3\xff\xff\x00\x00\xf0\x00\x00\x7f\xff\x00\x3f\xff\xf0\x00\x01\xc0\x03\xff\xff", + "\x00\x03\xc0\x01\xff\xdf\xfd\xff\x9f\xfe\x1f\xff\xff\x00\x3f\xff\xfe\x00\x00\x7f\xcf\xff\xf0\x1f\xff\xfe\x07\xf0\x00\xff\xff\xe0\x00\x01\x00\x07\xff\x80\x1f\xe0\x00\x00\xff\xfe\x03\xff\xff\x80\x03\xf0\x0f\xff\xfe\x00\x00\x1f\xff\xf8\x00\x00", + "\x00\x1f\xff\xfb\xff\xfe\x00\x07\xff\xf0\x00\x00\xff\xff\x00\x00\x0f\xf3\xff\xfe\x00\x78\x00\x00\x3e\x00\x00\x3f\xff\xf8\x00\x1f\xff\xff\x80\x00\x03\xff\xff\x00\x07\xff\xee\x00\x1f\xfc\x00\x78\x00\x00\x1f\xff\x07\xff\xfe\x03\xff\xff\xe0\x00\x00", + "\x00\x7f\xff\xfe\x00\x00\x3f\xfc\x03\xff\xfc\x1f\xff\xf0\x7f\xd8\x03\xf0\x00\xfd\xfc\x38\x00\x08\x00\x10\x00\xe0\x06\x00\x7f\xfe\x00\x00\x0f\xff\x80\x00\x3f\x03\xff\xfe\xff\xff\xf9\xff\xf8\x00\x07\xff\xfc\x01\xff\xc0\x00\x03\xff\xff\xe0\x03\xff\xff", + "\xff\xf0\x0f\xff\xff\x00\x06\x00\xff\xff\xf0\x07\xff\xe0\x04\x00\x03\x00\x00\x03\xf0\xff\xff\x00\x03\xff\xfb\xff\xc3\xff\xf0\x07\xff\xff\xc7\x00\x7f\x80\x00\x03\xff\xf8\x00\x1f\xe1\xff\xf8\x63\xfc\x00\x3f\xc0\x9f\xff\xf8\x00\x00\x7f\xff\x1f\xff\xfc\x00", + "\x00\x3f\xff\xfc\x00\x0f\xc7\x80\x00\x02\x00\x1e\x00\x00\x60\x7f\x03\xfe\x00\x00\x1f\xff\x80\x1f\xf8\x00\x00\xff\xff\x80\x00\x03\xff\xc0\x00\x7f\xff\xc0\x7f\xe0\x03\xfc\x00\xff\xf7\xff\xff\x00\x00\x1f\xf0\x00\x03\xff\xff\xe1\xff\xff\x80\x0f\xf8\x00\x00\x1f", + "\x00\x01\xfe\x00\x03\x83\xf3\xff\xff\x80\x07\xff\xfc\x3f\xff\xfc\x03\xff\x80\x00\x06\x00\x00\x78\x00\x07\xff\xff\x80\x07\xfc\x01\xf8\x00\x07\xff\xff\xc0\x00\x38\x00\x07\xff\xfe\x3f\xff\xf8\x3f\xff\xcf\x3f\xfc\x00\x7f\xff\x00\x1f\xff\x80\x00\x30\x03\xff\xff\x00", + "\xf8\x00\x38\x00\x00\x3e\x3f\x00\x00\x3f\xff\xf0\x02\x00\x00\x0f\xff\xff\x80\x80\x03\xff\xc0\x00\x04\x00\x0f\xc0\x3f\xff\xfe\x00\x00\x3f\xff\xfe\x00\x3f\xff\xf8\x00\x30\x00\x7b\xff\x00\x00\x03\xff\xfc\x3f\xe1\xff\x80\x00\x70\x1f\xff\xc0\x07\xfc\x00\x1f\xff\xf0\x00", + "\x00\x03\xf8\x18\x00\x00\x70\x3f\xff\xf8\x00\x00\xff\xcf\xff\xff\xc0\x03\xff\xfe\x00\x10\x00\x00\xfe\x03\xff\xf8\x00\x00\x7e\x00\x00\x7f\x8f\xff\xc0\x00\x00\x7f\xff\xe0\x00\x3c\x07\xc0\x00\x00\x7f\xff\x01\xff\xf8\x01\xff\x80\x00\x0f\xff\xf9\xe0\x00\x3f\xff\xe0\x00\x00", + "\xff\xfe\x00\x3f\xc0\x1f\xff\xf0\x7f\xf8\x00\x01\xff\xf8\x1f\xff\xfe\x00\x00\xff\xff\xf8\x00\x7f\xff\x80\x3f\xff\xff\x00\x7f\xff\xf8\x00\x0c\x00\x00\x0f\xfe\x7e\x00\x3f\xe0\x18\x7f\xfe\x00\x00\x38\x00\x00\x3f\xff\xfe\x00\x00\x03\xfc\xff\xe1\xfe\x1f\xff\xfe\x00\x00\x07\xff", + "\x00\x00\x07\xff\xfe\x00\x00\x07\xfe\x00\x00\x3f\xe0\x00\x7f\xff\xc0\x00\x00\x7f\xff\xfc\x00\xfe\x00\x03\xff\xe0\x00\x1f\x0f\xfc\x00\x1f\xff\x80\x00\x07\xff\xff\xf0\x00\xff\xff\xf0\x00\x00\x1f\xff\xf8\x01\xff\xe0\x1f\xff\xff\x00\x1f\x80\x07\xf0\x00\x01\xff\xf8\x00\x01\xff\xff", + "\x00\x00\x3f\xff\xff\x03\xfe\x00\x00\x07\xc0\x00\x00\x7f\xfc\x0f\xf0\x00\x00\x1f\xff\xfe\x00\x00\x07\xc0\x00\x00\xff\xfe\x00\x00\x3f\xff\xfc\x01\xff\x7f\xfc\x00\x1f\xf8\x00\x1f\xff\x07\xff\xff\xe0\x00\x7f\xff\xfc\x01\xff\xff\xf0\x00\x01\xff\xf8\x00\x1e\x00\x00\x7f\xfc\x00\x3f\xff", + "\xfe\x3f\xff\x83\xff\xfe\x00\x07\xff\xff\xf0\x00\x3e\x00\x00\xff\xff\xfc\x00\x40\x3f\xfe\x00\x00\x03\xf0\x00\x00\x70\x3f\xf8\x0f\xff\xff\xe0\x1f\x80\x00\x03\xc3\xff\xff\xf0\x00\x01\xff\xf0\x0f\x80\x00\x0f\xe0\xff\xff\xfe\xf0\x00\x01\xff\xc0\x00\x00\x7f\xf0\x00\x00\x7f\xfe\xe0\x00\x00", + "\x00\x00\x03\xff\xf0\x01\xfc\x00\x00\xff\xff\x00\x00\x7f\xff\xff\x80\x07\xff\x8f\xff\x80\x00\x0f\xff\xf0\x00\x00\x3c\x00\x03\xc0\xff\xff\xfe\x01\xff\xff\x80\x0c\x7f\xff\xf8\x00\x00\x1f\xf0\x00\x00\x7f\x80\x00\x00\x80\x00\x00\xff\xff\xf0\x1f\xff\xe0\x00\xff\xff\xfe\x1f\xff\x1f\xc0\x00\x00", + "\xff\xff\xfe\x07\xff\xc0\x00\x06\x3f\x9f\xf0\x07\xff\xf0\x3f\xfe\x1f\xff\xff\x81\xff\xff\xc0\x00\x02\x00\xfe\x00\x04\x00\x07\x00\x00\x01\xff\xff\xfe\x00\x00\x07\xff\xfe\x00\x1f\xfe\x00\x00\xff\xff\xe0\x07\xf8\x00\xff\xff\xfc\x00\x3f\xf3\xff\xff\xc0\x00\x7f\xff\xe0\x00\x0f\xff\xfc\x07\xff\xff", + "\xff\xf0\x00\x00\x7e\x00\x1e\x03\xff\xff\x00\x00\x73\xff\xf0\x00\x00\x0f\xff\xdf\xff\xff\xdf\xfc\x00\x07\xfe\x07\xff\xfe\x00\x00\x1f\xdf\xef\xff\xf0\x3f\xff\xfc\x00\x00\x07\xff\xff\xf0\x00\x00\x7f\xe0\x07\xff\x80\x00\x00\x7f\xe0\x03\xff\xff\xf9\xff\xe0\x00\x00\x3f\xe3\xff\xff\xfc\x00\x00\x03\xff", + "\x00\x03\xff\x00\x00\x3f\xff\x80\x01\xf0\x00\x0f\xfe\x00\x00\x06\x00\x03\xff\xff\xfc\x03\xff\xff\xf7\x80\x00\x00\x7f\xc0\x0f\xff\xe3\xfe\x0f\x00\x00\x7f\xff\x00\x7f\xf8\x00\x00\xff\xff\xee\x00\x7e\x01\xc0\x00\x1f\xe0\x00\x07\xff\xff\xf8\x00\x00\xe1\xff\xfc\x3f\xe7\xff\xff\xf8\x3f\xff\xfc\x00\x1f\xff", + "\x00\x00\x0f\xff\xf8\x00\x00\xff\xff\xfc\x00\x1f\xe0\x07\xff\xff\x00\x01\xff\xdf\xff\x80\x00\x3f\xff\xfc\x00\x00\x0f\xfc\x07\xff\x00\x00\xff\x80\x00\x03\xff\xff\xf0\x00\x07\xff\xff\xf0\x00\xff\xfe\x1f\xff\xff\xe0\x3f\xff\xfe\x00\x00\x60\x00\x00\xff\xff\x7f\xff\xf0\x00\x03\xff\xff\xc0\x07\x00\x01\xff\xff", + "\x00\x00\x20\x7f\xfe\x0f\x83\xff\xff\x80\x03\xff\x00\x00\x00\xff\xff\xe0\x00\x1f\xff\xff\xe0\x00\x3f\xfe\x7f\xff\xf0\x00\x1f\xff\xff\xe0\x00\x00\xff\xff\x87\xff\xc0\x00\x17\xfd\xff\x9f\xff\xfb\xff\xff\xe0\x00\x03\xe0\x00\x07\xff\x9f\xff\xff\x80\x00\x7f\xff\xff\x00\x01\xff\xff\xc0\xff\xff\xc0\x10\x00\x00\x1f", + "\x00\x00\x07\xff\xc0\x00\xff\xe0\x00\x07\xff\x80\x03\x80\x00\x0f\xf8\x00\x00\x7f\xff\xfe\x00\x00\x18\x00\xff\xf0\x20\x01\xff\xfe\x00\x00\x60\x0f\xf0\xe0\x03\xff\xfe\x00\x3e\x1f\xff\xfc\x00\x03\xff\x80\x00\x00\xff\xf8\x00\x01\x00\x00\x0f\xf3\xff\xfc\x00\x03\xff\xff\xe1\xff\xff\xc1\xf0\x00\x00\xff\xff\xff\x00\x00", + "\xff\xff\xf0\x00\x00\x07\xff\xfc\x00\x7f\x87\xff\xff\x00\x00\x00\x7f\xff\xc0\x7f\xff\x80\x00\x03\xf0\xff\x3f\xff\x80\x30\x07\xff\xff\x1f\x8e\x00\x7f\xff\xff\xc0\x01\xff\xfc\x07\xf8\x00\x00\x7f\xff\xfc\x00\x3f\xf0\x00\xf8\x00\x00\x07\xff\x00\x00\x0e\x00\x0f\xff\x80\x00\x7f\xc0\x01\xff\x8f\xf8\x00\x07\x01\xff\xff\xff", + "\xff\x80\x3f\xff\x3f\xfe\x00\x00\xff\xff\xff\x9f\xff\xf8\x3f\xff\xf8\x00\x00\x0f\xf8\x00\x00\x03\xfe\x00\x7f\xff\xff\x00\x0f\xff\x01\xff\xf0\x0f\xff\xe0\x20\x7f\xff\xfc\xff\x01\xf8\x00\x07\xff\xe0\x00\x7f\xf8\x00\x0f\xff\x80\x00\x00\x7f\xe0\x00\x3f\xf8\x01\xfe\x00\x07\xff\xf0\x00\x00\x7f\xff\xff\xc0\x00\x01\xff\xff\xff", + "\x00\x7f\xff\xe0\x00\x01\xff\xff\xf8\x00\x00\x3f\xff\xfc\x00\x7f\xfe\x00\x00\x03\xff\xff\xf0\x03\xff\xe0\x00\x7f\x80\x00\x0f\xff\x3f\xf8\x00\x00\x7f\xff\xff\x00\x07\x80\x1f\x83\xf8\x00\x00\x0f\xfe\x3f\xff\xc0\x3f\xff\xfe\x1f\xe0\x00\x07\xc0\x03\xff\xf0\x0f\xc0\x00\x03\xff\xff\x80\x00\x00\x7f\x80\x00\x00\xff\xff\x80\x00\x00", + "\xfe\x00\x00\x20\x00\x04\x00\x0f\xff\xff\xc0\x01\xff\xf8\x3f\xc0\x00\x00\xff\xff\xc0\x00\xff\xff\xff\x80\x00\x3f\xf8\x00\x7f\xff\xfe\x7f\xf8\x00\x7f\xff\x80\x07\xff\xc0\x00\x0f\xff\xf8\x00\x7f\xff\xc0\x00\xff\xff\xc0\x3f\xff\xff\xe0\x0f\xff\xff\xe0\xe0\x1f\xff\x80\x00\x00\x7f\xff\xc0\x71\xff\xff\xfc\x00\x01\xff\xff\xf8\x00\x00", + "\xff\xff\xe0\x00\x0f\xff\xf0\x00\x00\x3f\xff\xff\xc0\x00\xff\xff\x00\x00\x0f\xff\xff\xe0\x00\x01\xff\x00\x00\x1f\xff\xe0\x3f\xfc\x00\x03\xe0\x1f\xf0\x1f\xf8\x00\x00\x3f\xff\xff\xc0\x0f\xfe\x00\x00\x20\x00\x00\xff\xfc\x00\x0f\xff\xfe\x3f\xff\xff\x00\xff\xf0\x00\x00\x80\x00\x1f\x03\xe0\x01\xff\xfa\x00\x3f\xe0\x00\x00\x70\x00\x00\x0f", + "\xfd\xff\xc0\x00\x20\x01\xfe\x00\x3f\xf8\x00\x03\xff\x00\x00\x03\xf8\xff\xcf\xc3\xff\xff\xfc\x00\x03\xff\xff\xfc\x00\x00\x78\x3f\xff\xf0\x01\xff\xe0\x0f\xff\xff\x00\x00\x07\xff\xff\xfc\xff\xff\xf8\x00\x01\xff\x80\x00\x07\xff\xff\xfc\x00\x00\x1c\x00\x01\xff\xff\x07\xf8\x00\x00\x1f\xff\xff\xf0\x00\x01\xfe\x00\x7f\xff\xf0\x1f\xfc\x00\x00", + "\x00\x00\x00\x3f\xff\x00\x00\x07\xff\xff\xfc\x00\x00\x01\xe0\x0f\xff\x83\xfc\x01\xff\xff\xf0\x0f\xff\x00\x00\x00\x3f\xff\xff\xc0\x1f\xff\xff\xe0\x00\x20\x00\x00\x3f\xff\xff\x00\x00\xff\xfc\x03\xff\xff\xf0\x00\x1f\xff\xfc\x00\x00\x03\xff\xff\xc0\x7f\x80\x00\xff\xff\xff\x00\x0f\x0f\xff\xff\xe0\x00\x00\xff\xf8\x00\x00\xff\xfe\x00\x00\x0f\xff", + "\xff\xfe\x03\x80\x00\x03\xff\xff\xc0\x3f\xff\xff\x00\x03\xff\xff\xf8\x00\x00\x01\xff\xff\xcf\xfc\x00\x00\xe0\xef\xf8\x00\x0f\xff\xe3\xf8\x00\x3f\xff\xff\x80\x3f\xbf\xfe\x00\x00\xff\xfc\x00\x00\x01\xff\x00\x00\xcf\xc0\x01\xfc\x00\x00\x7f\xff\xff\xc0\x00\x10\x7f\xff\xfc\xfe\x00\x00\x07\xc0\xff\xff\xff\x8f\xff\x00\x00\x1f\x9e\x00\x00\x01\xff\xff", + "\x00\x7f\xff\xe0\x00\x01\xff\xff\xc3\xff\x80\x01\x03\xfc\x00\x00\x00\xfc\x01\xff\xff\xf8\x7f\xe7\xf0\x00\x00\x7f\xc0\x3f\xff\xff\xc0\x00\x00\x1f\xff\x80\x00\x01\xff\xe0\x00\x00\x70\x00\x00\x1c\x7f\xff\xf8\x1f\xfc\x00\x00\x07\xef\xe0\xff\xff\xc1\xff\xfc\x00\x00\x01\xff\xff\xff\xa0\x07\xff\x00\x1e\x00\x1f\xfc\x00\x00\x38\x00\x18\xc0\x00\x00\x7f\xff", + "\x00\x0f\xff\xf8\x00\x00\x07\xff\x00\xfc\x00\x00\x03\xff\xfc\x00\x07\xff\xff\xe0\x00\x00\xff\xfc\x0f\xff\x00\x00\x0f\xff\xfe\x0f\x80\x07\xff\x03\xff\xff\xf9\xff\xfe\x00\x00\x03\xf8\x00\x00\x07\xe0\x00\x00\xc0\x00\x1f\xff\xf0\x7f\xff\xff\xc0\x07\xff\xff\xfc\x00\x00\x3f\xff\xff\xe0\x00\x00\x1f\xff\xf8\x1f\xfe\x00\x00\x3f\xff\xff\xe0\x3f\x06\x00\x00\x00", + "\xff\xf0\x00\x08\x00\x0f\xef\xff\xff\xfc\x00\x00\x7f\xff\xf0\x00\x7f\xff\xf8\x00\xff\xff\x81\xff\xff\xe0\xff\xff\xff\x00\x00\x00\x80\x00\x03\xff\x80\x3f\xff\xfc\x00\x00\x1f\xff\xc0\x0f\xff\xfe\x00\x00\x00\x73\xf0\x1f\xfe\x00\xff\xc0\x3f\xff\x00\x3f\xff\x83\xff\xfe\x01\xff\xff\xf7\xff\xff\x80\x00\x00\x3f\x00\x00\x1f\xe3\xff\xff\xf0\x00\x0f\xff\xf0\x00\x00", + "\x00\x00\x7f\xfc\x00\x7f\xe0\x00\x0f\xff\xe0\x01\xf8\x00\x3f\xff\x00\x00\x78\x00\x7f\xe0\x00\x00\x1f\x00\x07\xff\xff\xf8\xf9\xf0\x01\xff\xf8\x07\xc0\x0f\xff\xf8\x00\x07\xf8\x7f\xfe\x00\x00\x0f\xff\xe3\xf0\x00\x07\xff\xff\xfc\x03\x1c\x00\x00\x7f\xe0\x00\xff\xff\xfc\x00\x00\x0f\xf3\xff\xe0\x00\x00\x0f\xff\xf9\x00\x00\x10\x00\x3f\xff\xfc\xf8\x7f\xff\x00\x00\x00", + "\x00\x03\xff\xff\xc0\x7f\xff\xff\xc0\x00\x03\xff\xff\xff\x00\x00\x0f\xff\xf0\x1f\xff\xf0\x00\x07\xff\xff\xef\xff\x81\xf7\xff\xfe\x00\x07\xff\xf0\x00\x00\x1f\xff\xc0\x0f\x80\x00\x0f\xff\xfc\x00\x00\xff\xff\xff\xc0\x03\xff\xe3\xff\xff\xfe\x00\x1f\xff\xff\x00\x00\xff\xff\xff\x0f\xff\xf1\xf8\x00\x00\x01\xff\xff\xff\x80\x1f\xff\xfe\x00\x08\x00\x00\x7f\xff\xff\x80\x00", + "\x1f\xe0\x00\x7c\x1f\xc0\x07\xff\xc0\x07\xff\xff\xfe\x00\x3c\x00\x00\x00\xff\xff\x80\x00\x07\xff\xff\x00\x1f\xf8\xff\xc0\x00\xff\x81\xff\x01\xff\xfe\x00\x78\x7f\xff\xf0\x00\x01\x80\x00\x00\x1f\xff\x00\x00\x1f\xff\xf0\x00\x1f\xff\xff\xe0\x00\x3c\x00\x00\x1f\xff\xff\x80\x03\xff\xe0\x01\xff\xff\xf9\xff\xf8\x00\x00\x7c\x00\x00\xfe\x00\x00\xff\xff\xff\x00\x00\x0f\xff\xff", + "\xfc\x00\x01\xff\x00\x00\x0c\x00\xff\xff\xe3\xff\xff\xf0\x80\x0e\x0e\x00\x00\x0f\xfe\x00\x03\xff\xc0\x00\x00\x7f\xff\xff\xe0\xc0\x00\x00\x07\xe0\xff\xff\x03\x9f\xff\xff\xc1\xc0\x00\x03\xff\xff\xc3\xff\xff\xfc\xff\xff\xc0\x00\x01\xfc\x00\x0f\xfc\x00\x00\x00\x7f\xff\xff\x03\xff\xff\xfc\x0f\xff\xfe\x00\x00\x03\x80\x3f\xff\xff\x00\x00\xff\xff\xf8\x00\x03\xff\xff\x80\x00\x00", + "\xff\xff\x80\xff\xff\xf8\x00\x00\xfc\x00\x03\xff\xf8\x00\x0f\xff\xff\x00\x03\x00\x00\x00\x7f\xff\xf0\x00\x3f\xff\xf0\x00\x01\xfc\x01\x00\x03\xff\x80\x1f\xff\xe3\xff\xff\xf8\x00\x1f\xff\xff\xf8\x01\xff\xdf\xff\xfb\xff\xc0\x00\x00\x3f\xff\xf8\x00\x00\x80\xc7\xff\xff\xf8\x0f\xff\x00\x60\x1f\xff\xe0\x00\x01\xff\xff\xfe\x0f\xff\xff\xfc\x00\x00\x00\xf0\x06\x03\xff\xff\xfe\x00\x00", + "\xff\x00\x0f\xff\xfc\x00\x0f\xff\xff\xfc\x07\xff\xfc\x00\x00\xf0\x00\x00\x80\x00\x7f\xfe\x00\x00\x0f\xff\xff\xfc\x3f\x00\xff\xff\xff\x00\x1f\xff\xff\xf0\x00\x1f\xff\xff\xe0\x00\x1f\xff\xff\xc3\xff\x00\x00\x01\xff\xff\xf0\x00\x00\x0f\xff\xe0\x07\xfc\x00\x00\x00\xfe\x00\x07\xff\xff\xf8\x00\x00\x3f\x00\x00\x0f\x80\x00\x3f\xff\xc0\x00\x11\xff\xef\x00\x07\x00\x7f\xff\xfc\x00\x00\x00", + "\xfe\x00\x00\x7f\xf7\xff\xff\x00\x00\x0f\xff\xff\xe0\x01\xff\xe0\x00\x00\x03\xff\xe0\x00\xff\xfe\x00\x01\xff\xf7\xff\xf8\x00\x0f\xff\x00\x00\x00\x38\x00\x07\xff\xf8\x07\xff\xfc\x00\x1f\xff\xff\x0f\xc1\xff\xff\xc0\x00\xff\xff\x0f\xff\xf0\x01\xff\xf8\x00\x01\xff\xff\x80\x00\x00\x0f\xf8\x00\x3f\xff\xfe\x3f\xff\xff\xf0\x00\x00\x38\x0f\xc3\xff\xff\xff\x1f\xff\xc0\x3f\xff\xff\xe0\x00\x00", + "\xff\xff\xf0\x00\x7f\xc0\x07\xff\xff\x81\xff\xc0\x00\x01\xff\xff\xff\xc0\x00\x00\x1f\xff\xfe\x03\xc0\x00\x0f\xff\xff\xfc\x00\x03\xff\xff\xff\x83\xff\xc0\x00\x07\xf0\x00\x00\x1f\x80\x00\x00\x3f\xff\xff\xe7\xff\x00\x07\xff\xff\xfc\x00\x00\x1f\xff\xf8\x00\x03\xf0\x00\xff\xfc\x00\x1f\xff\xff\xe0\x03\xff\xf0\x00\x01\xff\xff\xff\x80\x00\x00\x0f\xff\xff\xf8\x10\x00\x1e\x03\xff\xff\xff\x80\x00", + "\x00\x01\xff\xfe\x00\x00\x00\x7f\xff\xff\xf0\x00\x00\x1f\xff\x80\x07\xff\xff\xff\x80\x00\x01\xff\xfc\x03\xff\xff\x9f\xff\xfe\x00\x08\x00\x00\x06\x00\x00\x00\x81\xff\xff\xc0\x00\x07\xf8\x00\xff\xff\xff\x00\x00\x00\xff\xff\xf8\x00\x3f\xff\xff\xf8\x3f\xf8\x00\x00\x00\x7f\xff\xc0\x7f\xff\xff\xc0\xff\xff\xfe\x00\x00\x01\xff\xf8\x00\x00\x03\xff\xc1\xff\xf0\x00\x00\x03\x07\xf8\x01\xff\xfe\x00\x00", + "\xf8\x00\x00\x01\xff\xff\x80\x00\x0f\xff\xff\x8f\xff\x00\x1f\xff\x0f\xff\xc0\x00\x00\xff\xff\xfc\x00\x0f\xff\xf0\x00\x70\x00\x00\x3f\xff\xc0\x00\x00\x7c\x00\x00\x7e\x00\x0f\xfc\x00\x00\x00\xff\xff\x80\x00\x00\x0f\xff\xff\xfc\x38\x00\x00\x03\xf0\x00\x31\xf0\x1f\xff\xff\xc0\x07\xff\xff\xe0\x1f\xff\xff\xf3\xfe\x00\x00\x00\xff\xff\xc0\x00\x1f\xe7\xff\xe1\xff\xff\xdf\x00\x00\x00\x1f\xff\x00\x00\x00", + "\x3f\xff\xff\xf8\x00\x00\x00\x60\x00\x0f\xff\xff\xe0\x07\xff\xff\xff\x00\x00\x3f\xff\xff\xf0\x1f\xff\xff\x80\x00\x70\x00\x00\x01\x00\x00\x00\x3f\xff\xfe\x00\x00\x00\x1f\xf8\xfc\xc0\x0f\xff\xf8\x00\x3f\xff\xc0\xff\xff\x80\x00\x03\xff\xff\xf8\x00\x3f\xff\xfc\x00\x00\x0f\x81\xff\xc0\x03\xff\xc0\x3f\xff\xff\x80\x03\xff\xfe\x00\xff\xff\xfe\x00\x00\x1c\x00\x00\x00\x3f\xff\xff\xf8\x00\x7f\xff\xc0\x00\x00", + "\x00\x00\x00\x0f\xff\xfe\x0f\xff\xff\x87\xff\xff\xff\x00\x80\x00\x0f\xff\xc0\x00\x03\xf0\x1f\xf7\xe0\x00\x00\x70\x00\x01\xff\xff\xff\x80\x01\xfe\x07\xf0\x00\x01\xff\xfc\x00\x00\x04\x00\x01\xff\xfe\x07\xff\xff\xfe\x00\x07\xc0\x00\x00\xff\xff\xff\x87\xf0\x03\xff\xfc\x00\x00\x1f\xf8\x00\x01\xff\xff\xc0\x00\x00\x3f\xff\xc0\x00\x00\x7f\x8f\xff\xf8\x00\x00\x00\x7f\xff\xe0\x06\x0e\x00\x00\x0f\xff\xff\x80\x00", + "\x03\xff\xff\xfd\xe0\x00\x00\x1f\xff\xf8\x01\xff\xff\xfb\xff\xff\xe0\x01\xf0\xf0\x00\x00\xff\xff\xff\x80\x00\x00\x7f\xff\xff\xe0\x1f\xff\xff\xf0\x01\x80\xff\xff\xff\xe0\x00\x00\x7f\xff\xf0\xff\xff\xc0\x00\x00\x07\xfe\x00\x00\x00\x1e\x00\x1f\xff\xff\xe0\x1f\xff\xe0\x01\xff\xc0\x00\x3f\xff\xe0\x00\x00\x0f\xf0\x00\xff\xff\x7f\xc0\x1f\xf8\x3f\xff\xff\xc0\x00\x00\x7f\xff\xe0\xff\xfc\x00\x00\xff\x0f\xff\xff\xff", + "\x07\xff\xfc\x03\xff\xff\xff\xdf\xff\xff\x87\xff\x18\x00\x03\x80\x01\xff\x00\x00\x00\x1f\xff\x00\x00\x3f\xff\xff\xc0\x1f\xe0\x3f\xff\xff\xfc\x00\x00\x01\xff\xf8\x00\x00\x3f\xff\xff\xf8\x00\x00\x07\xe0\x00\x07\xff\xf9\xff\xe0\x00\x3f\xe0\x00\x7f\xef\xf0\x00\x07\x81\xff\xfc\x00\x00\x00\xff\xe0\x00\x30\x00\x00\x00\xff\xff\xf0\x00\x00\x03\xff\xfc\x7f\x07\xf8\x03\xff\xff\xff\x00\x3f\xfc\x00\x00\x01\xff\xc0\x00\x00", + "\x00\x7f\xfc\x00\x00\x03\xff\xf8\x00\x00\x61\xfe\x7f\xff\xfe\x00\x00\x1f\xff\xfc\x3f\xff\x80\x01\xff\xff\xff\xe0\x00\xff\xff\xff\x80\x1f\xf8\x00\x7f\xff\xff\xf8\x00\x00\x07\xff\xff\xe0\x00\x00\x07\xff\xff\xff\x80\x00\xff\x80\x0f\xff\xff\xfc\x00\x00\x7f\xff\xfe\x00\x00\x00\x30\x00\x00\x7f\x80\x00\x07\xff\xff\xf0\x00\x00\x03\xff\xc0\x0f\xff\xff\x80\x3f\xff\x80\x03\xff\xff\xfe\x03\xff\xff\xff\x7f\xfc\x1f\xf0\x00\x00", + "\x1f\xf0\x00\x00\x7f\xff\xfe\x02\x00\x00\x03\xff\xff\xff\xd8\x07\xff\xff\xe0\x01\xff\xff\x80\x00\x00\x07\xc0\x00\x0f\xff\xc0\x7f\xf0\x00\x07\xff\xff\x80\x00\x07\xf0\x00\x00\x7f\xfc\x03\xff\xff\xff\xc0\x00\x01\xff\xff\xf9\xff\xfe\x00\x00\x1f\xff\xc0\x00\x00\x03\xfe\x3f\xff\xff\x00\x07\xfe\x00\x00\x03\xc0\x00\x3f\xf8\x00\x10\x03\xfc\x00\x0f\xff\xc0\x00\x7f\xff\xe0\x00\xff\xf0\x00\x00\x7f\xff\xe0\x00\x00\x0f\xff\xff\xff", + "\xff\xff\xff\xf8\x00\x00\x60\x00\x00\x00\xff\xff\xfc\x03\xff\xfc\x00\x00\x3c\x00\x3f\xe0\x7f\xf8\x00\x07\xff\xf8\x0f\xf8\x00\x00\x7f\xff\xff\xfc\x00\x7f\xc2\x00\x03\xff\xff\xfe\x00\x01\xff\xff\xff\xf0\x03\xff\xff\xf0\x18\x07\xc0\x00\x0f\xff\xc0\x00\x00\x7f\xff\xff\x87\xe0\x00\x00\x07\x00\x1f\x80\x04\x07\xff\xe0\x00\x00\x1f\xff\x81\xff\x80\x00\x03\xff\xfc\x00\x00\x07\xff\xff\xff\xc0\x00\x00\x1f\x80\x01\xff\xff\x00\x00\x00", + "\x00\x0f\xfc\x1f\xf8\x00\x0f\xff\xff\xf8\x07\xff\xf1\xfc\x00\x1f\xff\xff\xf0\x00\x0f\xff\xdf\xff\xff\xff\x00\x00\x03\xff\xff\xff\x00\x01\xff\xff\xff\xc0\x10\x0f\xf0\x00\x00\x00\xfc\x00\x1f\x00\x07\x00\x01\xf0\x00\x00\x1f\xe0\x00\x00\x30\x7c\x3f\xff\xe0\x00\xff\xfc\x07\xff\xfc\x00\x3f\xff\xff\xf8\xff\xff\xc1\xfc\x1f\xff\xff\xf8\x00\x01\xff\xfc\x00\x00\x0f\xff\xff\xff\x00\x00\xff\xf8\x0c\x00\x00\x07\xff\xff\x00\x00\x00\x7f\xff", + "\xff\xff\x80\xff\xff\x00\x00\x00\x7f\xff\xff\x00\x1f\xfc\x00\x06\x00\x0f\xf8\x00\x00\x01\x80\x00\x00\x7f\xff\xff\xe0\x3f\xff\xff\xfc\x00\x60\x00\x00\x00\xfe\x00\x00\x07\xff\xff\xf0\x7f\xff\xff\xf8\x00\x00\x80\x00\x00\x0f\xff\xff\xff\xbf\xff\xff\xc0\x07\xff\xfe\x00\x00\x1c\x00\x1f\xfc\x07\x00\x01\xff\xff\x00\x00\x00\x80\x00\x1f\xff\x03\x80\x00\x00\x3f\xff\xff\xf8\x00\x07\xff\xff\xff\x80\x00\x1f\xff\xff\xe0\x1f\xff\xff\xc0\x00\x00", + "\xff\xff\xff\xf8\x00\x00\x00\x7e\x00\x00\x00\x1f\xff\x80\x07\xff\xff\xff\x80\x00\x00\x0f\xff\xff\xc3\xff\xf0\x00\x00\x04\x7f\xc0\x7f\xf0\x00\x3f\xff\x80\x00\x7f\xe0\x00\x03\xff\xc0\x00\x07\xff\x00\x00\x0f\xff\x80\x00\x00\x07\x80\x00\x00\x0f\xff\xff\xff\x01\xff\xff\xff\xc0\x03\xc0\x00\x00\x03\xff\xff\xe0\x00\x0f\xff\xff\xc0\x00\x03\xff\xfe\x00\x03\xff\xf8\x00\x00\x0f\xff\xff\xc0\x01\xff\xe0\x00\x00\xff\xff\xfc\x00\x00\x1f\xff\xff\xff", + "\xff\xf0\x00\x3f\xfc\x00\x00\xff\xff\xff\xe0\x1f\xc3\xfe\x00\x07\xff\xf8\x00\x0f\xf0\x01\xff\xff\xf0\x00\x00\xff\xc0\x0f\xff\xff\x80\x00\x00\xff\xff\xf3\xff\x80\x00\x00\x80\x08\x38\x00\x00\x0f\xff\xf0\x00\x1f\xff\xff\xfc\x00\x0f\x80\x00\x70\x00\x00\x31\xff\xff\xfe\x3f\xff\xf8\x00\x00\x00\x3c\x3f\xf0\x0f\xff\xff\x00\x03\xff\xfb\xff\xff\xff\x00\x0f\xff\xff\xfe\x00\x00\x00\xf0\x00\x00\x00\xff\xff\xfc\x00\x7f\xff\xf0\x00\x01\xff\xff\xfe\x00", + "\xff\xff\xf0\x0f\xf8\x3f\xff\xff\xe0\x00\x03\xff\xfe\x00\x00\x3f\xff\x80\xff\xff\xff\x00\x00\x00\xff\xff\xf8\xff\xff\xf0\x00\x0f\xf1\xff\xff\x00\x00\x00\x0f\xff\xfc\x00\x00\x00\x1f\xf0\x00\x00\x1f\xf0\x03\xff\xff\xff\xe1\xff\xe0\x00\x00\x1f\xff\xc1\xfe\x00\x00\x07\xff\xfc\x00\x00\x00\x1f\xfe\x3f\xc0\x00\x00\x01\xff\xfc\x00\x00\x1f\xff\xff\x0f\xe0\x00\x01\xfc\x00\xfe\x00\x00\x00\x7f\xe0\x00\x1f\xff\xff\xe0\x7f\x00\x0f\xf0\x00\xff\xfe\x00\x00", + "\x00\x7f\xff\xc0\x07\xff\xff\xff\x80\x07\xff\xff\xfe\x00\x00\x00\x7e\x00\x00\x00\x0f\xff\x80\x1f\xff\xfe\x07\xff\xff\xf0\x03\xc7\xff\xff\xfe\x00\x00\x00\x7f\xfe\x00\x00\x1f\xff\xfe\x00\x00\x00\xff\xfc\x00\x1f\xff\xc0\x00\x00\x3f\xff\x00\x1e\x00\x00\x03\xff\xff\xff\x80\x00\x00\x7f\xff\xf8\x03\xff\xfc\x00\x01\xff\xff\xfe\x00\x0f\xff\x02\x00\x07\xff\xff\xfe\x00\x00\x00\xfe\x01\xff\xff\xf7\xff\xff\x19\xff\xff\x00\x00\x07\xff\xc1\xff\x00\x00\x07\xff", + "\x00\x00\x00\x40\x00\x00\x07\xff\xff\xf8\x1f\xff\xff\xc0\x00\x3e\xff\xff\xf0\x00\x00\x00\x7f\xff\xfe\x00\x00\x00\xff\x80\x00\x00\x3f\xf1\xff\xff\xff\xe0\x00\x00\x01\xff\xff\xff\x00\x00\x1f\xff\xf8\x00\x07\xff\xff\xf8\x00\x1f\xff\xc1\xff\xff\xff\xe0\x01\xff\xff\xff\xe0\x00\x00\x07\xff\xff\xff\xcf\xff\xe0\x00\x3f\xe0\xff\xff\xc0\x00\x07\xff\xff\xe0\x01\xff\xfc\x3f\x00\x01\xff\xff\xfe\x00\x01\xff\x0f\xff\xff\xfc\x00\x00\x01\xff\xff\x80\x00\x00\x0f\xff", + "\xff\xff\xf0\xff\xff\xff\xc0\x03\x80\x00\x01\x00\x00\x03\xff\xff\xff\xf1\xff\xff\xff\xe0\x07\xfc\x00\x00\x03\xff\xf0\x00\x00\x00\x7e\x00\x00\x00\x07\x00\x3f\xff\xfc\x00\x0f\xc7\xff\xff\x00\x00\x07\xff\xff\xc0\x00\x00\x03\xff\xfc\x00\x00\xff\xe0\x00\x00\x00\x7f\xf0\x00\x00\xff\xff\xff\xfd\xff\x00\xff\xe0\xff\xff\xe0\x07\xff\xff\xf8\x7f\xff\xfe\x18\x00\x00\x01\xf0\x00\x1f\xff\xfe\x01\xc0\x01\xff\xff\xff\xf8\x00\x01\xfe\xff\xff\xff\x80\x00\x00\x07\xff\xff", + "\xff\xff\xf0\x00\x1f\xff\xff\x00\x00\x3f\xff\xf0\x00\xff\xff\x00\x07\xff\xff\xf8\x03\xff\xff\xe7\xff\xff\xff\x81\x00\x00\x01\xff\x00\x00\x3f\xff\xff\xf8\x00\x00\x00\xf0\x07\xff\xc0\x0f\xf0\x00\x3f\xff\xc0\x00\x7f\xf8\x00\xff\xfc\x00\x00\x1f\xff\x80\x1f\xfc\x00\x00\x01\xff\xff\x00\x00\x7f\xff\xff\xfe\x00\x00\x0f\xff\x80\x00\x00\x0f\xff\xff\xfc\x00\x00\x00\xff\xff\xfc\x00\x0f\xff\x80\x00\x3f\xff\xfe\x00\x00\x3f\xe0\x0f\xff\xff\x00\x00\x01\xff\xf0\x00\x00\x00", + "\xff\xc0\x00\x00\x03\xff\xff\xfc\x00\xff\xff\xfc\x00\x00\x00\x7f\xff\xff\x00\x00\x00\x1f\xe0\x00\x0f\xff\xc0\xf0\x00\x00\x7f\xff\xff\xe0\x00\x20\x1f\xff\xff\xff\x00\x00\x00\x1f\x80\x00\x00\x07\xff\xf1\xff\xff\xff\xc0\x00\x00\x1f\xff\xff\xf0\x00\x3f\xff\xf8\x00\x3f\xff\xff\xfe\x01\xff\xff\xfe\x7f\x9e\x00\x1f\xff\xfc\x00\x7f\xe0\x7f\xff\xff\xe0\x00\x7f\xff\xfe\x00\x00\x01\xff\xff\xff\xf8\x01\xff\xc0\x03\x00\x0f\xff\xf8\x00\x00\x0f\xf0\x0f\xff\x00\x00\x00\x0f\xff", + "\x00\x03\xff\xff\xff\xcf\xff\xf8\x7f\x8f\xff\xff\xfc\x01\xff\xff\xfc\x00\x00\x1f\xff\xff\xff\x80\x00\x00\x01\xff\xff\xe1\xff\xf0\x00\x00\x00\xff\xff\xff\xf8\x03\x80\x00\x3f\x80\x00\x0f\xff\xff\xff\xc0\x00\x00\x02\x7f\xff\xf8\x03\xff\xc0\x00\x00\x3f\xff\x80\x00\x00\x01\xff\xff\xe0\x00\x00\x03\x80\x00\x00\xff\xe0\x7f\xff\xff\xfc\x00\x00\x01\xff\xff\xfc\x00\x00\x00\xff\xff\x80\x00\x07\xfe\x00\x00\x07\xff\xf0\x00\x00\x1f\x80\x00\x00\x3e\x1f\xff\xff\xff\x9f\xff\xff\xff", + "\xff\xff\xfe\x00\x03\xff\xff\xff\x80\x01\xff\xff\xff\xa0\x3f\xff\xf8\x00\x7f\x03\xff\xff\xc0\x00\x0f\xff\xc3\xff\xf8\x00\x03\xff\xff\xff\xc0\x7f\xf0\x1f\xe0\x0f\xff\xff\xc0\x00\x1f\xfe\x0f\xff\xff\xe0\x00\x07\xff\xff\xfc\x00\x00\xfc\x00\x3f\xff\xff\xf0\x00\x00\x00\x3f\xfc\x00\x00\x00\x0f\xff\xc4\x00\x00\xff\xc0\x00\x03\xff\xff\xff\x80\x00\x03\xfc\x0f\xff\xff\xf0\x00\x00\x03\xff\xff\xc0\x07\xff\xff\xf8\x0c\x3f\xff\xf0\x00\x1f\xff\x80\x00\x00\x01\xff\xfe\x00\x00\x3f\xff", + "\x00\x00\x00\x1f\xff\xc3\xff\xff\x80\x00\x00\x3f\xff\xff\xfe\x00\x00\x00\x0f\xe0\x00\x7f\xff\xe0\x0f\xfe\x00\xff\xff\xff\xe0\x03\xff\xf8\x00\x00\x00\x3f\xe0\x00\x00\x01\xff\xff\xe7\xff\xff\xff\xe0\x00\x00\x07\xff\xff\xc0\x00\x1f\xe0\x00\x00\x01\xff\xff\x00\x00\x03\xff\xff\xff\xe0\x00\x00\x1f\xe0\x03\xff\xff\x00\x00\x00\x07\xff\xf0\x3f\x80\x00\x00\x0f\xff\xff\xfe\x00\x00\xff\xff\xff\x00\x00\x3f\xff\xff\x80\x0f\xff\xfe\x01\xff\xff\xff\xf8\x3f\xff\xff\xc0\x00\x00\xff\xff\xff", + "\xff\xff\xff\x80\x00\xff\xff\xff\xf0\x00\x00\x1f\x00\x3f\xff\xfe\x0f\xf0\x1c\x00\xff\xff\xe0\x00\x0f\xc0\x1f\xff\xc0\x00\x00\x01\xff\x80\xf7\xff\xf8\x00\x00\x3f\xff\xc0\x00\x00\x01\xff\xf0\x00\x03\xe3\xfc\x00\x07\xf8\x00\x00\x3f\xff\xff\xfe\x00\x00\x1f\x00\x00\x00\x18\x00\x3f\xff\xff\xf8\x0f\xe0\x00\x00\x00\x60\x00\x07\xff\xff\xfe\x00\x60\xff\xff\xff\xf8\x00\x00\x3f\xff\x80\x00\x00\x3f\xff\xff\xf0\x00\x00\x0f\xf0\x00\xff\xff\xf1\xff\x00\x3f\xff\xff\xff\x01\xff\xe0\x00\x00\x00", + "\xff\xff\xff\xfc\x00\x00\x00\xff\xff\xf0\x01\xff\xff\xf8\x00\x00\xff\xff\xff\xe7\xff\xf8\x01\xf8\x7f\xff\xff\x80\x00\x3f\xff\xfc\x00\x00\x01\xff\xff\xe0\x00\x3f\xc0\x00\x00\x7f\xff\xff\x00\x00\x0f\xff\xff\xff\xc0\x00\x0f\xff\xf1\xff\xff\xff\xf8\x00\x0f\xff\xff\xfc\x00\x00\x07\xff\xff\xff\x80\xff\xff\xf8\x07\xf0\x00\x00\x00\x1f\xff\xff\xff\xc0\x00\xff\xff\xff\xc0\x00\x0e\xff\xff\xff\xc0\x00\x00\x03\xff\xf8\x00\x00\x03\xff\x80\x00\x00\x00\xe0\x00\x00\x0f\xf8\x00\x00\x3f\xff\xff\xff", + "\x3f\x00\x03\xc0\x1f\x00\x00\x00\x0f\xf0\x00\x07\xff\xff\xef\x00\xfe\x00\x7f\xfe\x00\x00\x3f\xf0\x00\x3f\xc0\x00\x00\x07\xfc\x00\x00\x03\xff\xff\xff\x0f\xff\xff\xff\xc0\x07\xf8\x00\x00\xf8\x00\x00\x3f\x9f\xff\xff\xfc\x00\x00\x3f\xff\xc0\x00\x03\xff\xff\xc0\x00\x00\xff\xfc\x00\x1f\xff\xe0\x00\x00\x07\xff\xe0\x07\x00\x00\x00\x7f\xff\xfe\x00\x00\x00\xff\xff\xfe\x00\x00\x0f\xfc\x00\x07\xff\xf0\x00\x00\x00\x7f\x80\x03\xcf\xff\x80\x00\x01\xff\xff\xe0\x3c\x00\x00\x3f\xff\xff\xff\x80\x00\x00", + "\x30\x00\x00\x00\xff\xf8\x00\x00\xff\xfc\x00\x3f\xff\xff\x80\x00\x00\x0f\xcf\xff\xcf\xff\xff\xc0\xff\xff\xff\x80\x00\x00\x01\xff\xff\xff\xf0\x00\x00\x00\x1f\xff\x00\x03\xff\xfc\x00\x00\x00\x07\xff\x80\x00\x7f\xff\xff\xfe\x0f\xff\xc0\x00\x00\x00\x7f\xf0\xbf\xff\xff\xe0\x00\x00\xff\xf8\x00\x00\x01\xff\xff\xf8\x00\x00\x3e\x00\x00\x07\xff\xe0\x00\x00\x00\x80\x00\x03\x80\x01\xff\xff\xff\xf8\x60\x00\x00\x00\xff\xf0\x00\x1f\xff\xff\xc7\xff\xf0\x40\xff\xff\xfe\x00\x00\x07\xff\xdf\xff\x80\x00\x00", + "\xff\xff\xff\x83\xff\xf8\x1f\xff\x1f\xff\xff\x80\x0f\xff\xff\xe0\x00\x00\x00\x3f\xff\xff\xc0\xf8\x00\x00\x78\x00\x1c\x00\x00\x00\x1f\xe0\x00\x00\x00\xff\xff\xe0\x3f\xff\xff\xfe\x00\x00\x03\xff\xff\xfe\x00\x00\x00\x1f\xff\xfc\x00\x7f\xff\x00\x00\x00\x1f\xff\xff\x00\x02\x00\x00\x3f\xff\xfc\x00\x00\x00\xff\xf0\x1f\xfe\xff\xff\xc0\x01\xff\xff\xff\xf0\x00\x00\x00\xff\xff\xfe\x00\x00\x00\x0f\xff\xc0\x00\x00\x7f\x7f\xc0\x00\x00\x01\xff\xff\xfe\x0f\xff\xff\xff\xc0\x00\x0f\x80\x00\x00\x3f\xff\xff\xff", + "\xff\xff\xff\xfe\x00\x00\x00\xff\xf8\x0f\xff\xff\xf0\x00\x00\x07\xff\xff\xfb\xff\xc0\x00\x07\xfc\x07\xe0\x00\x00\x01\xff\xff\xe0\x00\x7f\xff\xff\xf8\x00\x00\x3f\xff\xf8\x00\x00\x00\x0f\xff\xff\x00\x00\x0f\xc0\x00\x00\x3f\xff\xf0\x00\x00\x01\xff\xff\xfe\x1f\xff\xf8\x00\x00\x20\x00\x00\x00\x3f\xff\xbf\xff\x9f\xff\xff\xfc\x3f\xff\xff\xf0\x00\x00\x07\x80\x00\x00\xff\xff\xe7\xff\xff\xff\xf0\x00\x00\x3f\xff\xff\xff\x00\x00\x07\xff\xff\xe0\xff\xff\xff\xe0\x01\xff\xff\xff\xf8\x00\x00\x00\x7f\xff\xff\xff", + "\x00\x00\x00\x1f\xff\xc0\x00\x0f\xff\xc0\x00\x00\x1f\xff\xc0\x00\x1f\xc0\x00\x00\x03\xff\x80\x00\x00\x07\xff\xff\xff\xc0\x00\x00\x00\x80\x00\x3f\xfc\x00\xc0\x00\x0f\xff\xff\x00\x00\x06\x00\x3f\xfc\x1e\x00\x1f\xff\xff\xf0\x00\x3e\x0f\xff\xff\xf0\x00\x00\x3f\xff\xf0\x00\x00\x00\x1f\xff\xc0\x00\x00\xff\xff\xff\xf8\x00\xe0\x00\x00\xff\xff\xff\xfe\x00\x00\x0f\xff\xff\xfe\x3f\xff\xff\xfc\x07\xfe\x00\x00\x00\xc0\x00\x7f\xff\xff\xfe\x00\xff\xff\xff\xfc\x07\xff\xff\xe0\x00\x3f\xe3\xff\xff\xc0\x00\x00\x3f\xff", + "\x00\x00\x00\x0f\xff\xc0\x00\x0f\xf8\x00\x00\x00\xff\xfc\x00\x00\x0f\xff\xff\xfe\x00\x00\x00\x03\xff\x00\xff\xfc\x07\xff\xf0\x1f\xff\xfe\x0f\xff\xff\xfd\xff\xff\xff\xf0\x1f\xff\xf0\x00\x07\xf8\xff\xf8\x00\x00\x00\xff\xff\xc0\x3f\xff\xff\xff\x80\x00\x00\x0f\xff\xff\xff\x00\x00\x03\xff\xff\xf0\x00\x07\xff\xff\x00\x00\x3f\xff\xf0\x01\xff\xff\xc0\x01\xff\xff\xff\x00\x3f\xff\xf8\x1f\xff\xff\xfe\x1f\xff\xff\xff\xc0\x00\x00\x7f\xe0\x00\x07\xff\xff\xfe\x00\x00\x00\x03\xe0\x07\xff\xc0\x03\xfc\x00\x07\xff\xff\xff", + "\xff\xff\xff\x00\x00\x03\xc0\x00\x00\x01\xff\xff\xf8\x00\x00\x00\x0f\xff\xff\xff\x00\x00\x0f\x00\x00\xff\xff\xf8\x80\x00\xf8\x00\x0f\xc0\x00\x00\x00\xe0\x00\x00\x00\xff\xff\xff\xf8\x0f\xff\xff\xfe\x00\x00\x18\x00\x00\x7f\xff\xff\xff\x00\x00\x03\xff\xff\xff\x00\x7f\xff\xff\xfc\x00\x03\xc0\x00\x00\x0f\xff\xff\xff\xf0\x00\x07\xff\xff\x80\x01\xff\xff\xff\xe0\x00\x0f\xff\xfe\x07\xff\xff\xf8\x00\xff\xff\xff\xc0\x00\x00\x03\xe0\x00\x07\xff\xf0\x0f\xff\xf0\x00\x00\xff\xff\xf8\x7f\xc0\x03\xc0\x3f\xff\xe0\x00\x00\x00", + + /* These are zero-terminated strings */ + + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" +}; + +static uschar *hashes[] = { + "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", + "3CDF2936DA2FC556BFA533AB1EB59CE710AC80E5", + "19C1E2048FA7393CFBF2D310AD8209EC11D996E5", + "CA775D8C80FAA6F87FA62BECA6CA6089D63B56E5", + "71AC973D0E4B50AE9E5043FF4D615381120A25A0", + "A6B5B9F854CFB76701C3BDDBF374B3094EA49CBA", + "D87A0EE74E4B9AD72E6847C87BDEEB3D07844380", + "1976B8DD509FE66BF09C9A8D33534D4EF4F63BFD", + "5A78F439B6DB845BB8A558E4CEB106CD7B7FF783", + "F871BCE62436C1E280357416695EE2EF9B83695C", + "62B243D1B780E1D31CF1BA2DE3F01C72AEEA0E47", + "1698994A273404848E56E7FDA4457B5900DE1342", + "056F4CDC02791DA7ED1EB2303314F7667518DEEF", + "9FE2DA967BD8441EEA1C32DF68DDAA9DC1FC8E4B", + "73A31777B4ACE9384EFA8BBEAD45C51A71ABA6DD", + "3F9D7C4E2384EDDABFF5DD8A31E23DE3D03F42AC", + "4814908F72B93FFD011135BEE347DE9A08DA838F", + "0978374B67A412A3102C5AA0B10E1A6596FC68EB", + "44AD6CB618BD935460D46D3F921D87B99AB91C1E", + "02DC989AF265B09CF8485640842128DCF95E9F39", + "67507B8D497B35D6E99FC01976D73F54AECA75CF", + "1EAE0373C1317CB60C36A42A867B716039D441F5", + "9C3834589E5BFFAC9F50950E0199B3EC2620BEC8", + "209F7ABC7F3B878EE46CDF3A1FBB9C21C3474F32", + "05FC054B00D97753A9B3E2DA8FBBA3EE808CEF22", + "0C4980EA3A46C757DFBFC5BAA38AC6C8E72DDCE7", + "96A460D2972D276928B69864445BEA353BDCFFD2", + "F3EF04D8FA8C6FA9850F394A4554C080956FA64B", + "F2A31D875D1D7B30874D416C4D2EA6BAF0FFBAFE", + "F4942D3B9E9588DCFDC6312A84DF75D05F111C20", + "310207DF35B014E4676D30806FA34424813734DD", + "4DA1955B2FA7C7E74E3F47D7360CE530BBF57CA3", + "74C4BC5B26FB4A08602D40CCEC6C6161B6C11478", + "0B103CE297338DFC7395F7715EE47539B556DDB6", + "EFC72D99E3D2311CE14190C0B726BDC68F4B0821", + "660EDAC0A8F4CE33DA0D8DBAE597650E97687250", + "FE0A55A988B3B93946A63EB36B23785A5E6EFC3E", + "0CBDF2A5781C59F907513147A0DE3CC774B54BF3", + "663E40FEE5A44BFCB1C99EA5935A6B5BC9F583B0", + "00162134256952DD9AE6B51EFB159B35C3C138C7", + "CEB88E4736E354416E2010FC1061B3B53B81664B", + "A6A2C4B6BCC41DDC67278F3DF4D8D0B9DD7784EF", + "C23D083CD8820B57800A869F5F261D45E02DC55D", + "E8AC31927B78DDEC41A31CA7A44EB7177165E7AB", + "E864EC5DBAB0F9FF6984AB6AD43A8C9B81CC9F9C", + "CFED6269069417A84D6DE2347220F4B858BCD530", + "D9217BFB46C96348722C3783D29D4B1A3FEDA38C", + "DEC24E5554F79697218D317315FA986229CE3350", + "83A099DF7071437BA5495A5B0BFBFEFE1C0EF7F3", + "AA3198E30891A83E33CE3BFA0587D86A197D4F80", + "9B6ACBEB4989CBEE7015C7D515A75672FFDE3442", + "B021EB08A436B02658EAA7BA3C88D49F1219C035", + "CAE36DAB8AEA29F62E0855D9CB3CD8E7D39094B1", + "02DE8BA699F3C1B0CB5AD89A01F2346E630459D7", + "88021458847DD39B4495368F7254941859FAD44B", + "91A165295C666FE85C2ADBC5A10329DAF0CB81A0", + "4B31312EAF8B506811151A9DBD162961F7548C4B", + "3FE70971B20558F7E9BAC303ED2BC14BDE659A62", + "93FB769D5BF49D6C563685954E2AECC024DC02D6", + "BC8827C3E614D515E83DEA503989DEA4FDA6EA13", + "E83868DBE4A389AB48E61CFC4ED894F32AE112AC", + "55C95459CDE4B33791B4B2BCAAF840930AF3F3BD", + "36BB0E2BA438A3E03214D9ED2B28A4D5C578FCAA", + "3ACBF874199763EBA20F3789DFC59572ACA4CF33", + "86BE037C4D509C9202020767D860DAB039CADACE", + "51B57D7080A87394EEC3EB2E0B242E553F2827C9", + "1EFBFA78866315CE6A71E457F3A750A38FACAB41", + "57D6CB41AEEC20236F365B3A490C61D0CFA39611", + "C532CB64B4BA826372BCCF2B4B5793D5B88BB715", + "15833B5631032663E783686A209C6A2B47A1080E", + "D04F2043C96E10CD83B574B1E1C217052CD4A6B2", + "E8882627C64DB743F7DB8B4413DD033FC63BEB20", + "CD2D32286B8867BC124A0AF2236FC74BE3622199", + "019B70D745375091ED5C7B218445EC986D0F5A82", + "E5FF5FEC1DADBAED02BF2DAD4026BE6A96B3F2AF", + "6F4E23B3F2E2C068D13921FE4E5E053FFED4E146", + "25E179602A575C915067566FBA6DA930E97F8678", + "67DED0E68E235C8A523E051E86108EEB757EFBFD", + "AF78536EA83C822796745556D62A3EE82C7BE098", + "64D7AC52E47834BE72455F6C64325F9C358B610D", + "9D4866BAA3639C13E541F250FFA3D8BC157A491F", + "2E258811961D3EB876F30E7019241A01F9517BEC", + "8E0EBC487146F83BC9077A1630E0FB3AB3C89E63", + "CE8953741FFF3425D2311FBBF4AB481B669DEF70", + "789D1D2DAB52086BD90C0E137E2515ED9C6B59B5", + "B76CE7472700DD68D6328B7AA8437FB051D15745", + "F218669B596C5FFB0B1C14BD03C467FC873230A0", + "1FF3BDBE0D504CB0CDFAB17E6C37ABA6B3CFFDED", + "2F3CBACBB14405A4652ED52793C1814FD8C4FCE0", + "982C8AB6CE164F481915AF59AAED9FFF2A391752", + "5CD92012D488A07ECE0E47901D0E083B6BD93E3F", + "69603FEC02920851D4B3B8782E07B92BB2963009", + "3E90F76437B1EA44CF98A08D83EA24CECF6E6191", + "34C09F107C42D990EB4881D4BF2DDDCAB01563AE", + "474BE0E5892EB2382109BFC5E3C8249A9283B03D", + "A04B4F75051786682483252438F6A75BF4705EC6", + "BE88A6716083EB50ED9416719D6A247661299383", + "C67E38717FEE1A5F65EC6C7C7C42AFC00CD37F04", + "959AC4082388E19E9BE5DE571C047EF10C174A8D", + "BAA7AA7B7753FA0ABDC4A541842B5D238D949F0A", + "351394DCEBC08155D100FCD488578E6AE71D0E9C", + "AB8BE94C5AF60D9477EF1252D604E58E27B2A9EE", + "3429EC74A695FDD3228F152564952308AFE0680A", + "907FA46C029BC67EAA8E4F46E3C2A232F85BD122", + "2644C87D1FBBBC0FC8D65F64BCA2492DA15BAAE4", + "110A3EEB408756E2E81ABAF4C5DCD4D4C6AFCF6D", + "CD4FDC35FAC7E1ADB5DE40F47F256EF74D584959", + "8E6E273208AC256F9ECCF296F3F5A37BC8A0F9F7", + "FE0606100BDBC268DB39B503E0FDFE3766185828", + "6C63C3E58047BCDB35A17F74EEBA4E9B14420809", + "BCC2BD305F0BCDA8CF2D478EF9FE080486CB265F", + "CE5223FD3DD920A3B666481D5625B16457DCB5E8", + "948886776E42E4F5FAE1B2D0C906AC3759E3F8B0", + "4C12A51FCFE242F832E3D7329304B11B75161EFB", + "C54BDD2050504D92F551D378AD5FC72C9ED03932", + "8F53E8FA79EA09FD1B682AF5ED1515ECA965604C", + "2D7E17F6294524CE78B33EAB72CDD08E5FF6E313", + "64582B4B57F782C9302BFE7D07F74AA176627A3A", + "6D88795B71D3E386BBD1EB830FB9F161BA98869F", + "86AD34A6463F12CEE6DE9596ABA72F0DF1397FD1", + "7EB46685A57C0D466152DC339C8122548C757ED1", + "E7A98FB0692684054407CC221ABC60C199D6F52A", + "34DF1306662206FD0A5FC2969A4BEEC4EB0197F7", + "56CF7EBF08D10F0CB9FE7EE3B63A5C3A02BCB450", + "3BAE5CB8226642088DA760A6F78B0CF8EDDEA9F1", + "6475DF681E061FA506672C27CBABFA9AA6DDFF62", + "79D81991FA4E4957C8062753439DBFD47BBB277D", + "BAE224477B20302E881F5249F52EC6C34DA8ECEF", + "EDE4DEB4293CFE4138C2C056B7C46FF821CC0ACC", + + "A9993E364706816ABA3E25717850C26C9CD0D89D", + "84983E441C3BD26EBAAE4AA1F95129E5E54670F1" +}; + +static uschar *atest = "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F"; + +int main(void) +{ +sha1 base; +int j; +int i = 0x01020304; +uschar *ctest = US (&i); +uschar buffer[256]; +uschar digest[20]; +uschar s[41]; +printf("Checking sha1: %s-endian\n\n", (ctest[0] == 0x04)? "little" : "big"); + +for (i = 0; i < sizeof(tests)/sizeof(uschar *); i ++) + { + printf("%d.\nShould be: %s\n", i, hashes[i]); + native_sha1_start(&base); + native_sha1_end(&base, tests[i], (i <= 128)? i : strlen(tests[i]), digest); + for (j = 0; j < 20; j++) sprintf(s+2*j, "%02X", digest[j]); + printf("Computed: %s\n", s); + if (strcmp(s, hashes[i]) != 0) printf("*** No match ***\n"); + printf("\n"); + } + +/* 1 000 000 repetitions of "a" */ + +ctest = malloc(1000000); +memset(ctest, 'a', 1000000); + +printf("1 000 000 repetitions of 'a'\n"); +printf("Should be: %s\n", atest); +native_sha1_start(&base); +native_sha1_end(&base, ctest, 1000000, digest); +for (j = 0; j < 20; j++) sprintf(s+2*j, "%02X", digest[j]); +printf("Computed: %s\n", s); +if (strcmp(s, atest) != 0) printf("*** No match ***\n"); + +} +# endif /*STAND_ALONE*/ /* End of File */