From d51f701e063828f391cd44a0ba75a194f2d9b77e Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Sun, 29 Jul 2018 20:30:19 -0400 Subject: Refactor validat5.cpp and validat6.cpp Also see https://groups.google.com/forum/#\!topic/cryptopp-users/j_aQj6r-PoI --- validat5.cpp | 2825 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 1744 insertions(+), 1081 deletions(-) (limited to 'validat5.cpp') diff --git a/validat5.cpp b/validat5.cpp index 10eed51d..c0dd66b2 100644 --- a/validat5.cpp +++ b/validat5.cpp @@ -1,4 +1,4 @@ -// validat5.cpp - originally written and placed in the public domain by Wei Dai +// validat6.cpp - originally written and placed in the public domain by Wei Dai // CryptoPP::Test namespace added by JW in February 2017. // Source files split in July 2018 to expedite compiles. @@ -10,8 +10,9 @@ #include "cpu.h" #include "validate.h" -#include "asn.h" -#include "oids.h" +#include "aes.h" +#include "crc.h" +#include "adler32.h" #include "md2.h" #include "md4.h" @@ -20,24 +21,21 @@ #include "sha.h" #include "sha3.h" #include "pssr.h" +#include "tiger.h" +#include "blake2.h" #include "ripemd.h" +#include "siphash.h" +#include "poly1305.h" #include "whrlpool.h" -#include "dh.h" -#include "rw.h" -#include "dsa.h" -#include "luc.h" -#include "mqv.h" -#include "rsa.h" -#include "xtr.h" -#include "hmqv.h" -#include "esign.h" -#include "rabin.h" -#include "pubkey.h" -#include "elgamal.h" -#include "xtrcrypt.h" -#include "blumshub.h" -#include "eccrypto.h" +#include "hkdf.h" +#include "scrypt.h" +#include "pwdbased.h" + +#include "cmac.h" +#include "dmac.h" +#include "hmac.h" +#include "ttmac.h" #include #include @@ -55,1307 +53,1972 @@ NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(Test) -class FixedRNG : public RandomNumberGenerator +struct HashTestTuple { -public: - FixedRNG(BufferedTransformation &source) : m_source(source) {} + HashTestTuple(const char *input, const char *output, unsigned int repeatTimes=1) + : input((byte *)input), output((byte *)output), inputLen(strlen(input)), repeatTimes(repeatTimes) {} - void GenerateBlock(byte *output, size_t size) - { - m_source.Get(output, size); - } + HashTestTuple(const char *input, unsigned int inputLen, const char *output, unsigned int repeatTimes) + : input((byte *)input), output((byte *)output), inputLen(inputLen), repeatTimes(repeatTimes) {} -private: - BufferedTransformation &m_source; + const byte *input, *output; + size_t inputLen; + unsigned int repeatTimes; }; -bool ValidateBBS() +bool HashModuleTest(HashTransformation &md, const HashTestTuple *testSet, unsigned int testSetSize) { - std::cout << "\nBlumBlumShub validation suite running...\n\n"; - - Integer p("212004934506826557583707108431463840565872545889679278744389317666981496005411448865750399674653351"); - Integer q("100677295735404212434355574418077394581488455772477016953458064183204108039226017738610663984508231"); - Integer seed("63239752671357255800299643604761065219897634268887145610573595874544114193025997412441121667211431"); - BlumBlumShub bbs(p, q, seed); - bool pass = true, fail; - int j; - - static const byte output1[] = { - 0x49,0xEA,0x2C,0xFD,0xB0,0x10,0x64,0xA0,0xBB,0xB9, - 0x2A,0xF1,0x01,0xDA,0xC1,0x8A,0x94,0xF7,0xB7,0xCE}; - static const byte output2[] = { - 0x74,0x45,0x48,0xAE,0xAC,0xB7,0x0E,0xDF,0xAF,0xD7, - 0xD5,0x0E,0x8E,0x29,0x83,0x75,0x6B,0x27,0x46,0xA1}; + bool pass=true, fail; + SecByteBlock digest(md.DigestSize()); // Coverity finding, also see http://stackoverflow.com/a/34509163/608639. StreamState ss(std::cout); - byte buf[20]; - - bbs.GenerateBlock(buf, 20); - fail = memcmp(output1, buf, 20) != 0; - pass = pass && !fail; - - std::cout << (fail ? "FAILED " : "passed "); - for (j=0;j<20;j++) - std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)buf[j]; - std::cout << std::endl; - - bbs.Seek(10); - bbs.GenerateBlock(buf, 10); - fail = memcmp(output1+10, buf, 10) != 0; - pass = pass && !fail; - - std::cout << (fail ? "FAILED " : "passed "); - for (j=0;j<10;j++) - std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)buf[j]; - std::cout << std::endl; - - bbs.Seek(1234567); - bbs.GenerateBlock(buf, 20); - fail = memcmp(output2, buf, 20) != 0; - pass = pass && !fail; - - std::cout << (fail ? "FAILED " : "passed "); - for (j=0;j<20;j++) - std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)buf[j]; - std::cout << std::endl; - - return pass; -} - -bool SignatureValidate(PK_Signer &priv, PK_Verifier &pub, bool thorough = false) -{ - bool pass = true, fail; - - fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2); - pass = pass && !fail; - - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "signature key validation\n"; - - const byte *message = (byte *)"test message"; - const int messageLen = 12; - - SecByteBlock signature(priv.MaxSignatureLength()); - size_t signatureLength = priv.SignMessage(GlobalRNG(), message, messageLen, signature); - fail = !pub.VerifyMessage(message, messageLen, signature, signatureLength); - pass = pass && !fail; - - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "signature and verification\n"; - - ++signature[0]; - fail = pub.VerifyMessage(message, messageLen, signature, signatureLength); - pass = pass && !fail; - - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "checking invalid signature" << std::endl; - - if (priv.MaxRecoverableLength() > 0) + for (unsigned int i=0; i::Signer rsaPriv(keys); - RSASS::Verifier rsaPub(rsaPriv); - - size_t signatureLength = rsaPriv.SignMessage(GlobalRNG(), (byte *)plain, strlen(plain), out); - CRYPTOPP_ASSERT(signatureLength <= sizeof(out)); - fail = memcmp(signature, out, signatureLength) != 0; - pass = pass && !fail; - - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "signature check against test vector\n"; - - fail = !rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength); - pass = pass && !fail; - - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "verification check against test vector\n"; - - out[10]++; - fail = rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength); - pass = pass && !fail; - - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "invalid signature verification\n"; - } - ///// + HashTestTuple("", "\xcd\xf2\x62\x13\xa1\x50\xdc\x3e\xcb\x61\x0f\x18\xf6\xb3\x8b\x46"), + HashTestTuple("a", "\x86\xbe\x7a\xfa\x33\x9d\x0f\xc7\xcf\xc7\x85\xe7\x2f\x57\x8d\x33"), + HashTestTuple("abc", "\xc1\x4a\x12\x19\x9c\x66\xe4\xba\x84\x63\x6b\x0f\x69\x14\x4c\x77"), + HashTestTuple("message digest", "\x9e\x32\x7b\x3d\x6e\x52\x30\x62\xaf\xc1\x13\x2d\x7d\xf9\xd1\xb8"), + HashTestTuple("abcdefghijklmnopqrstuvwxyz", "\xfd\x2a\xa6\x07\xf7\x1d\xc8\xf5\x10\x71\x49\x22\xb3\x71\x83\x4e"), + HashTestTuple("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\xa1\xaa\x06\x89\xd0\xfa\xfa\x2d\xdc\x22\xe8\x8b\x49\x13\x3a\x06"), + HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xd1\xe9\x59\xeb\x17\x9c\x91\x1f\xae\xa4\x62\x4c\x60\xc5\xc7\x02"), + HashTestTuple("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "\x3f\x45\xef\x19\x47\x32\xc2\xdb\xb2\xc4\xa2\xc7\x69\x79\x5f\xa3"), + HashTestTuple("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "\x4a\x7f\x57\x23\xf9\x54\xeb\xa1\x21\x6c\x9d\x8f\x63\x20\x43\x1f", 15625) + }; + + HashTestTuple testSet160[] = { - FileSource keys(CRYPTOPP_DATA_DIR "TestData/rsa1024.dat", true, new HexDecoder); - RSAES_PKCS1v15_Decryptor rsaPriv(keys); - RSAES_PKCS1v15_Encryptor rsaPub(rsaPriv); - - pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass; - } + HashTestTuple("", "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31"), + HashTestTuple("a", "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe"), + HashTestTuple("abc", "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc"), + HashTestTuple("message digest", "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36"), + HashTestTuple("abcdefghijklmnopqrstuvwxyz", "\xf7\x1c\x27\x10\x9c\x69\x2c\x1b\x56\xbb\xdc\xeb\x5b\x9d\x28\x65\xb3\x70\x8d\xbc"), + HashTestTuple("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x12\xa0\x53\x38\x4a\x9c\x0c\x88\xe4\x05\xa0\x6c\x27\xdc\xf4\x9a\xda\x62\xeb\x2b"), + HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xb0\xe2\x0b\x6e\x31\x16\x64\x02\x86\xed\x3a\x87\xa5\x71\x30\x79\xb2\x1f\x51\x89"), + HashTestTuple("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "\x9b\x75\x2e\x45\x57\x3d\x4b\x39\xf4\xdb\xd3\x32\x3c\xab\x82\xbf\x63\x32\x6b\xfb"), + HashTestTuple("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "\x52\x78\x32\x43\xc1\x69\x7b\xdb\xe1\x6d\x37\xf9\x7f\x68\xf0\x83\x25\xdc\x15\x28", 15625) + }; + + HashTestTuple testSet256[] = { - RSAES >::Decryptor rsaPriv(GlobalRNG(), 512); - RSAES >::Encryptor rsaPub(rsaPriv); - - pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass; - } + HashTestTuple("", "\x02\xba\x4c\x4e\x5f\x8e\xcd\x18\x77\xfc\x52\xd6\x4d\x30\xe3\x7a\x2d\x97\x74\xfb\x1e\x5d\x02\x63\x80\xae\x01\x68\xe3\xc5\x52\x2d"), + HashTestTuple("a", "\xf9\x33\x3e\x45\xd8\x57\xf5\xd9\x0a\x91\xba\xb7\x0a\x1e\xba\x0c\xfb\x1b\xe4\xb0\x78\x3c\x9a\xcf\xcd\x88\x3a\x91\x34\x69\x29\x25"), + HashTestTuple("abc", "\xaf\xbd\x6e\x22\x8b\x9d\x8c\xbb\xce\xf5\xca\x2d\x03\xe6\xdb\xa1\x0a\xc0\xbc\x7d\xcb\xe4\x68\x0e\x1e\x42\xd2\xe9\x75\x45\x9b\x65"), + HashTestTuple("message digest", "\x87\xe9\x71\x75\x9a\x1c\xe4\x7a\x51\x4d\x5c\x91\x4c\x39\x2c\x90\x18\xc7\xc4\x6b\xc1\x44\x65\x55\x4a\xfc\xdf\x54\xa5\x07\x0c\x0e"), + HashTestTuple("abcdefghijklmnopqrstuvwxyz", "\x64\x9d\x30\x34\x75\x1e\xa2\x16\x77\x6b\xf9\xa1\x8a\xcc\x81\xbc\x78\x96\x11\x8a\x51\x97\x96\x87\x82\xdd\x1f\xd9\x7d\x8d\x51\x33"), + HashTestTuple("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x38\x43\x04\x55\x83\xaa\xc6\xc8\xc8\xd9\x12\x85\x73\xe7\xa9\x80\x9a\xfb\x2a\x0f\x34\xcc\xc3\x6e\xa9\xe7\x2f\x16\xf6\x36\x8e\x3f"), + HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\x57\x40\xa4\x08\xac\x16\xb7\x20\xb8\x44\x24\xae\x93\x1c\xbb\x1f\xe3\x63\xd1\xd0\xbf\x40\x17\xf1\xa8\x9f\x7e\xa6\xde\x77\xa0\xb8"), + HashTestTuple("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "\x06\xfd\xcc\x7a\x40\x95\x48\xaa\xf9\x13\x68\xc0\x6a\x62\x75\xb5\x53\xe3\xf0\x99\xbf\x0e\xa4\xed\xfd\x67\x78\xdf\x89\xa8\x90\xdd"), + HashTestTuple("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "\xac\x95\x37\x44\xe1\x0e\x31\x51\x4c\x15\x0d\x4d\x8d\x7b\x67\x73\x42\xe3\x33\x99\x78\x82\x96\xe4\x3a\xe4\x85\x0c\xe4\xf9\x79\x78", 15625) + }; + + HashTestTuple testSet320[] = { - byte *plain = (byte *) - "\x54\x85\x9b\x34\x2c\x49\xea\x2a"; - static const byte encrypted[] = - "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a" - "\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4" - "\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52" - "\x62\x51"; - static const byte oaepSeed[] = - "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2" - "\xf0\x6c\xb5\x8f"; - ByteQueue bq; - bq.Put(oaepSeed, 20); - FixedRNG rng(bq); - - FileSource privFile(CRYPTOPP_DATA_DIR "TestData/rsa400pv.dat", true, new HexDecoder); - FileSource pubFile(CRYPTOPP_DATA_DIR "TestData/rsa400pb.dat", true, new HexDecoder); - RSAES_OAEP_SHA_Decryptor rsaPriv; - rsaPriv.AccessKey().BERDecodePrivateKey(privFile, false, 0); - RSAES_OAEP_SHA_Encryptor rsaPub(pubFile); - - memset(out, 0, 50); - memset(outPlain, 0, 8); - rsaPub.Encrypt(rng, plain, 8, out); - DecodingResult result = rsaPriv.FixedLengthDecrypt(GlobalRNG(), encrypted, outPlain); - fail = !result.isValidCoding || (result.messageLength!=8) || memcmp(out, encrypted, 50) || memcmp(plain, outPlain, 8); - pass = pass && !fail; + HashTestTuple("", "\x22\xd6\x5d\x56\x61\x53\x6c\xdc\x75\xc1\xfd\xf5\xc6\xde\x7b\x41\xb9\xf2\x73\x25\xeb\xc6\x1e\x85\x57\x17\x7d\x70\x5a\x0e\xc8\x80\x15\x1c\x3a\x32\xa0\x08\x99\xb8"), + HashTestTuple("a", "\xce\x78\x85\x06\x38\xf9\x26\x58\xa5\xa5\x85\x09\x75\x79\x92\x6d\xda\x66\x7a\x57\x16\x56\x2c\xfc\xf6\xfb\xe7\x7f\x63\x54\x2f\x99\xb0\x47\x05\xd6\x97\x0d\xff\x5d"), + HashTestTuple("abc", "\xde\x4c\x01\xb3\x05\x4f\x89\x30\xa7\x9d\x09\xae\x73\x8e\x92\x30\x1e\x5a\x17\x08\x5b\xef\xfd\xc1\xb8\xd1\x16\x71\x3e\x74\xf8\x2f\xa9\x42\xd6\x4c\xdb\xc4\x68\x2d"), + HashTestTuple("message digest", "\x3a\x8e\x28\x50\x2e\xd4\x5d\x42\x2f\x68\x84\x4f\x9d\xd3\x16\xe7\xb9\x85\x33\xfa\x3f\x2a\x91\xd2\x9f\x84\xd4\x25\xc8\x8d\x6b\x4e\xff\x72\x7d\xf6\x6a\x7c\x01\x97"), + HashTestTuple("abcdefghijklmnopqrstuvwxyz", "\xca\xbd\xb1\x81\x0b\x92\x47\x0a\x20\x93\xaa\x6b\xce\x05\x95\x2c\x28\x34\x8c\xf4\x3f\xf6\x08\x41\x97\x51\x66\xbb\x40\xed\x23\x40\x04\xb8\x82\x44\x63\xe6\xb0\x09"), + HashTestTuple("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\xd0\x34\xa7\x95\x0c\xf7\x22\x02\x1b\xa4\xb8\x4d\xf7\x69\xa5\xde\x20\x60\xe2\x59\xdf\x4c\x9b\xb4\xa4\x26\x8c\x0e\x93\x5b\xbc\x74\x70\xa9\x69\xc9\xd0\x72\xa1\xac"), + HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xed\x54\x49\x40\xc8\x6d\x67\xf2\x50\xd2\x32\xc3\x0b\x7b\x3e\x57\x70\xe0\xc6\x0c\x8c\xb9\xa4\xca\xfe\x3b\x11\x38\x8a\xf9\x92\x0e\x1b\x99\x23\x0b\x84\x3c\x86\xa4"), + HashTestTuple("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "\x55\x78\x88\xaf\x5f\x6d\x8e\xd6\x2a\xb6\x69\x45\xc6\xd2\xa0\xa4\x7e\xcd\x53\x41\xe9\x15\xeb\x8f\xea\x1d\x05\x24\x95\x5f\x82\x5d\xc7\x17\xe4\xa0\x08\xab\x2d\x42"), + HashTestTuple("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "\xbd\xee\x37\xf4\x37\x1e\x20\x64\x6b\x8b\x0d\x86\x2d\xda\x16\x29\x2a\xe3\x6f\x40\x96\x5e\x8c\x85\x09\xe6\x3d\x1d\xbd\xde\xcc\x50\x3e\x2b\x63\xeb\x92\x45\xbb\x66", 15625) + }; - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "PKCS 2.0 encryption and decryption\n"; - } + bool pass = true; - return pass; -} + std::cout << "\nRIPEMD-128 validation suite running...\n\n"; + RIPEMD128 md128; + pass = HashModuleTest(md128, testSet128, COUNTOF(testSet128)) && pass; -bool ValidateDH() -{ - std::cout << "\nDH validation suite running...\n\n"; + std::cout << "\nRIPEMD-160 validation suite running...\n\n"; + RIPEMD160 md160; + pass = HashModuleTest(md160, testSet160, COUNTOF(testSet160)) && pass; - FileSource f(CRYPTOPP_DATA_DIR "TestData/dh1024.dat", true, new HexDecoder()); - DH dh(f); - return SimpleKeyAgreementValidate(dh); -} + std::cout << "\nRIPEMD-256 validation suite running...\n\n"; + RIPEMD256 md256; + pass = HashModuleTest(md256, testSet256, COUNTOF(testSet256)) && pass; -bool ValidateMQV() -{ - std::cout << "\nMQV validation suite running...\n\n"; + std::cout << "\nRIPEMD-320 validation suite running...\n\n"; + RIPEMD320 md320; + pass = HashModuleTest(md320, testSet320, COUNTOF(testSet320)) && pass; - FileSource f(CRYPTOPP_DATA_DIR "TestData/mqv1024.dat", true, new HexDecoder()); - MQV mqv(f); - return AuthenticatedKeyAgreementValidate(mqv); + return pass; } -bool ValidateHMQV() +#ifdef CRYPTOPP_REMOVED +bool ValidateHAVAL() { - std::cout << "\nHMQV validation suite running...\n\n"; - - //ECHMQV< ECP >::Domain hmqvB(false /*server*/); - ECHMQV256 hmqvB(false); - FileSource f256(CRYPTOPP_DATA_DIR "TestData/hmqv256.dat", true, new HexDecoder()); - FileSource f384(CRYPTOPP_DATA_DIR "TestData/hmqv384.dat", true, new HexDecoder()); - FileSource f512(CRYPTOPP_DATA_DIR "TestData/hmqv512.dat", true, new HexDecoder()); - hmqvB.AccessGroupParameters().BERDecode(f256); - - std::cout << "HMQV with NIST P-256 and SHA-256:" << std::endl; - - if (hmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; - else + HashTestTuple testSet[] = { - std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; - return false; - } + HashTestTuple("", "\xC6\x8F\x39\x91\x3F\x90\x1F\x3D\xDF\x44\xC7\x07\x35\x7A\x7D\x70"), + HashTestTuple("a", "\x4D\xA0\x8F\x51\x4A\x72\x75\xDB\xC4\xCE\xCE\x4A\x34\x73\x85\x98\x39\x83\xA8\x30"), + HashTestTuple("HAVAL", "\x0C\x13\x96\xD7\x77\x26\x89\xC4\x67\x73\xF3\xDA\xAC\xA4\xEF\xA9\x82\xAD\xBF\xB2\xF1\x46\x7E\xEA"), + HashTestTuple("0123456789", "\xBE\xBD\x78\x16\xF0\x9B\xAE\xEC\xF8\x90\x3B\x1B\x9B\xC6\x72\xD9\xFA\x42\x8E\x46\x2B\xA6\x99\xF8\x14\x84\x15\x29"), + HashTestTuple("abcdefghijklmnopqrstuvwxyz", "\xC9\xC7\xD8\xAF\xA1\x59\xFD\x9E\x96\x5C\xB8\x3F\xF5\xEE\x6F\x58\xAE\xDA\x35\x2C\x0E\xFF\x00\x55\x48\x15\x3A\x61\x55\x1C\x38\xEE"), + HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xB4\x5C\xB6\xE6\x2F\x2B\x13\x20\xE4\xF8\xF1\xB0\xB2\x73\xD4\x5A\xDD\x47\xC3\x21\xFD\x23\x99\x9D\xCF\x40\x3A\xC3\x76\x36\xD9\x63") + }; - const OID oid = ASN1::secp256r1(); - ECHMQV< ECP >::Domain hmqvA(oid, true /*client*/); - - if (hmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; - return false; - } - - SecByteBlock sprivA(hmqvA.StaticPrivateKeyLength()), sprivB(hmqvB.StaticPrivateKeyLength()); - SecByteBlock eprivA(hmqvA.EphemeralPrivateKeyLength()), eprivB(hmqvB.EphemeralPrivateKeyLength()); - SecByteBlock spubA(hmqvA.StaticPublicKeyLength()), spubB(hmqvB.StaticPublicKeyLength()); - SecByteBlock epubA(hmqvA.EphemeralPublicKeyLength()), epubB(hmqvB.EphemeralPublicKeyLength()); - SecByteBlock valA(hmqvA.AgreedValueLength()), valB(hmqvB.AgreedValueLength()); - - hmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA); - hmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB); - hmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA); - hmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB); - - memset(valA.begin(), 0x00, valA.size()); - memset(valB.begin(), 0x11, valB.size()); + bool pass=true; - if (!(hmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && hmqvB.Agree(valB, sprivB, eprivB, spubA, epubA))) + std::cout << "\nHAVAL validation suite running...\n\n"; { - std::cout << "FAILED authenticated key agreement failed" << std::endl; - return false; + HAVAL3 md(16); + pass = HashModuleTest(md, testSet+0, 1) && pass; } - - if (memcmp(valA.begin(), valB.begin(), hmqvA.AgreedValueLength())) { - std::cout << "FAILED authenticated agreed values not equal" << std::endl; - return false; + HAVAL3 md(20); + pass = HashModuleTest(md, testSet+1, 1) && pass; } - - std::cout << "passed authenticated key agreement" << std::endl; - - // Now test HMQV with NIST P-384 curve and SHA384 hash - std::cout << std::endl; - std::cout << "HMQV with NIST P-384 and SHA-384:" << std::endl; - - ECHMQV384 hmqvB384(false); - hmqvB384.AccessGroupParameters().BERDecode(f384); - - if (hmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; - else { - std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; - return false; + HAVAL4 md(24); + pass = HashModuleTest(md, testSet+2, 1) && pass; } - - const OID oid384 = ASN1::secp384r1(); - ECHMQV384 hmqvA384(oid384, true /*client*/); - - if (hmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; - else { - std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; - return false; + HAVAL4 md(28); + pass = HashModuleTest(md, testSet+3, 1) && pass; } - - SecByteBlock sprivA384(hmqvA384.StaticPrivateKeyLength()), sprivB384(hmqvB384.StaticPrivateKeyLength()); - SecByteBlock eprivA384(hmqvA384.EphemeralPrivateKeyLength()), eprivB384(hmqvB384.EphemeralPrivateKeyLength()); - SecByteBlock spubA384(hmqvA384.StaticPublicKeyLength()), spubB384(hmqvB384.StaticPublicKeyLength()); - SecByteBlock epubA384(hmqvA384.EphemeralPublicKeyLength()), epubB384(hmqvB384.EphemeralPublicKeyLength()); - SecByteBlock valA384(hmqvA384.AgreedValueLength()), valB384(hmqvB384.AgreedValueLength()); - - hmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384); - hmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384); - hmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384); - hmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384); - - memset(valA384.begin(), 0x00, valA384.size()); - memset(valB384.begin(), 0x11, valB384.size()); - - if (!(hmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && hmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384))) { - std::cout << "FAILED authenticated key agreement failed" << std::endl; - return false; + HAVAL5 md(32); + pass = HashModuleTest(md, testSet+4, 1) && pass; } - - if (memcmp(valA384.begin(), valB384.begin(), hmqvA384.AgreedValueLength())) { - std::cout << "FAILED authenticated agreed values not equal" << std::endl; - return false; + HAVAL5 md(32); + pass = HashModuleTest(md, testSet+5, 1) && pass; } - std::cout << "passed authenticated key agreement" << std::endl; + return pass; +} +#endif - return true; +bool ValidatePanama() +{ + return RunTestDataFile(CRYPTOPP_DATA_DIR "TestVectors/panama.txt"); } -bool ValidateFHMQV() +bool ValidateWhirlpool() { - std::cout << "\nFHMQV validation suite running...\n\n"; + return RunTestDataFile(CRYPTOPP_DATA_DIR "TestVectors/whrlpool.txt"); +} - //ECFHMQV< ECP >::Domain fhmqvB(false /*server*/); - ECFHMQV256 fhmqvB(false); - FileSource f256(CRYPTOPP_DATA_DIR "TestData/fhmqv256.dat", true, new HexDecoder()); - FileSource f384(CRYPTOPP_DATA_DIR "TestData/fhmqv384.dat", true, new HexDecoder()); - FileSource f512(CRYPTOPP_DATA_DIR "TestData/fhmqv512.dat", true, new HexDecoder()); - fhmqvB.AccessGroupParameters().BERDecode(f256); +#ifdef CRYPTOPP_REMOVED +bool ValidateMD5MAC() +{ + const byte keys[2][MD5MAC::KEYLENGTH]={ + {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff}, + {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}}; + + const char *TestVals[7]={ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}; + + const byte output[2][7][MD5MAC::DIGESTSIZE]={ + {{0x1f,0x1e,0xf2,0x37,0x5c,0xc0,0xe0,0x84,0x4f,0x98,0xe7,0xe8,0x11,0xa3,0x4d,0xa8}, + {0x7a,0x76,0xee,0x64,0xca,0x71,0xef,0x23,0x7e,0x26,0x29,0xed,0x94,0x52,0x73,0x65}, + {0xe8,0x01,0x3c,0x11,0xf7,0x20,0x9d,0x13,0x28,0xc0,0xca,0xa0,0x4f,0xd0,0x12,0xa6}, + {0xc8,0x95,0x53,0x4f,0x22,0xa1,0x74,0xbc,0x3e,0x6a,0x25,0xa2,0xb2,0xef,0xd6,0x30}, + {0x91,0x72,0x86,0x7e,0xb6,0x00,0x17,0x88,0x4c,0x6f,0xa8,0xcc,0x88,0xeb,0xe7,0xc9}, + {0x3b,0xd0,0xe1,0x1d,0x5e,0x09,0x4c,0xb7,0x1e,0x35,0x44,0xac,0xa9,0xb8,0xbf,0xa2}, + {0x93,0x37,0x16,0x64,0x44,0xcc,0x95,0x35,0xb7,0xd5,0xb8,0x0f,0x91,0xe5,0x29,0xcb}}, + {{0x2f,0x6e,0x73,0x13,0xbf,0xbb,0xbf,0xcc,0x3a,0x2d,0xde,0x26,0x8b,0x59,0xcc,0x4d}, + {0x69,0xf6,0xca,0xff,0x40,0x25,0x36,0xd1,0x7a,0xe1,0x38,0x03,0x2c,0x0c,0x5f,0xfd}, + {0x56,0xd3,0x2b,0x6c,0x34,0x76,0x65,0xd9,0x74,0xd6,0xf7,0x5c,0x3f,0xc6,0xf0,0x40}, + {0xb8,0x02,0xb2,0x15,0x4e,0x59,0x8b,0x6f,0x87,0x60,0x56,0xc7,0x85,0x46,0x2c,0x0b}, + {0x5a,0xde,0xf4,0xbf,0xf8,0x04,0xbe,0x08,0x58,0x7e,0x94,0x41,0xcf,0x6d,0xbd,0x57}, + {0x18,0xe3,0x49,0xa5,0x24,0x44,0xb3,0x0e,0x5e,0xba,0x5a,0xdd,0xdc,0xd9,0xf1,0x8d}, + {0xf2,0xb9,0x06,0xa5,0xb8,0x4b,0x9b,0x4b,0xbe,0x95,0xed,0x32,0x56,0x4e,0xe7,0xeb}}}; - std::cout << "FHMQV with NIST P-256 and SHA-256:" << std::endl; + // Coverity finding, also see http://stackoverflow.com/a/34509163/608639. + StreamState ss(std::cout); - if (fhmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; - return false; - } + byte digest[MD5MAC::DIGESTSIZE]; + bool pass=true, fail; - const OID oid = ASN1::secp256r1(); - ECFHMQV< ECP >::Domain fhmqvA(oid, true /*client*/); + std::cout << "\nMD5MAC validation suite running...\n"; - if (fhmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; - else + for (int k=0; k<2; k++) { - std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; - return false; + MD5MAC mac(keys[k]); + std::cout << "\nKEY: "; + for (int j=0;j XMACC_MD5; + + const byte keys[2][XMACC_MD5::KEYLENGTH]={ + {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb}, + {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98}}; + + const word32 counters[2]={0xccddeeff, 0x76543210}; + + const char *TestVals[7]={ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}; + + const byte output[2][7][XMACC_MD5::DIGESTSIZE]={ + {{0xcc,0xdd,0xef,0x00,0xfa,0x89,0x54,0x92,0x86,0x32,0xda,0x2a,0x3f,0x29,0xc5,0x52,0xa0,0x0d,0x05,0x13}, + {0xcc,0xdd,0xef,0x01,0xae,0xdb,0x8b,0x7b,0x69,0x71,0xc7,0x91,0x71,0x48,0x9d,0x18,0xe7,0xdf,0x9d,0x5a}, + {0xcc,0xdd,0xef,0x02,0x5e,0x01,0x2e,0x2e,0x4b,0xc3,0x83,0x62,0xc2,0xf4,0xe6,0x18,0x1c,0x44,0xaf,0xca}, + {0xcc,0xdd,0xef,0x03,0x3e,0xa9,0xf1,0xe0,0x97,0x91,0xf8,0xe2,0xbe,0xe0,0xdf,0xf3,0x41,0x03,0xb3,0x5a}, + {0xcc,0xdd,0xef,0x04,0x2e,0x6a,0x8d,0xb9,0x72,0xe3,0xce,0x9f,0xf4,0x28,0x45,0xe7,0xbc,0x80,0xa9,0xc7}, + {0xcc,0xdd,0xef,0x05,0x1a,0xd5,0x40,0x78,0xfb,0x16,0x37,0xfc,0x7a,0x1d,0xce,0xb4,0x77,0x10,0xb2,0xa0}, + {0xcc,0xdd,0xef,0x06,0x13,0x2f,0x11,0x47,0xd7,0x1b,0xb5,0x52,0x36,0x51,0x26,0xb0,0x96,0xd7,0x60,0x81}}, + {{0x76,0x54,0x32,0x11,0xe9,0xcb,0x74,0x32,0x07,0x93,0xfe,0x01,0xdd,0x27,0xdb,0xde,0x6b,0x77,0xa4,0x56}, + {0x76,0x54,0x32,0x12,0xcd,0x55,0x87,0x5c,0xc0,0x35,0x85,0x99,0x44,0x02,0xa5,0x0b,0x8c,0xe7,0x2c,0x68}, + {0x76,0x54,0x32,0x13,0xac,0xfd,0x87,0x50,0xc3,0x8f,0xcd,0x58,0xaa,0xa5,0x7e,0x7a,0x25,0x63,0x26,0xd1}, + {0x76,0x54,0x32,0x14,0xe3,0x30,0xf5,0xdd,0x27,0x2b,0x76,0x22,0x7f,0xaa,0x90,0x73,0x6a,0x48,0xdb,0x00}, + {0x76,0x54,0x32,0x15,0xfc,0x57,0x00,0x20,0x7c,0x9d,0xf6,0x30,0x6f,0xbd,0x46,0x3e,0xfb,0x8a,0x2c,0x60}, + {0x76,0x54,0x32,0x16,0xfb,0x0f,0xd3,0xdf,0x4c,0x4b,0xc3,0x05,0x9d,0x63,0x1e,0xba,0x25,0x2b,0xbe,0x35}, + {0x76,0x54,0x32,0x17,0xc6,0xfe,0xe6,0x5f,0xb1,0x35,0x8a,0xf5,0x32,0x7a,0x80,0xbd,0xb8,0x72,0xee,0xae}}}; - std::cout << "passed authenticated key agreement" << std::endl; + // Coverity finding, also see http://stackoverflow.com/a/34509163/608639. + StreamState ss(std::cout); - // Now test FHMQV with NIST P-384 curve and SHA384 hash - std::cout << std::endl; - std::cout << "FHMQV with NIST P-384 and SHA-384:" << std::endl; + byte digest[XMACC_MD5::DIGESTSIZE]; + bool pass=true, fail; - ECHMQV384 fhmqvB384(false); - fhmqvB384.AccessGroupParameters().BERDecode(f384); + std::cout << "\nXMACC/MD5 validation suite running...\n"; - if (fhmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; - else + for (int k=0; k<2; k++) { - std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; - return false; + XMACC_MD5 mac(keys[k], counters[k]); + std::cout << "\nKEY: "; + for (int j=0;j::Decryptor privC(fc); - DLIES<>::Encryptor pubC(privC); - pass = CryptoSystemValidate(privC, pubC) && pass; - } + // from OpenSSL PKCS #12 Program FAQ v1.77, at http://www.drh-consultancy.demon.co.uk/test.txt + PBKDF_TestTuple testSet[] = { - std::cout << "Generating new encryption key..." << std::endl; - DLIES<>::GroupParameters gp; - gp.GenerateRandomWithKeySize(GlobalRNG(), 128); - DLIES<>::Decryptor decryptor; - decryptor.AccessKey().GenerateRandom(GlobalRNG(), gp); - DLIES<>::Encryptor encryptor(decryptor); - - pass = CryptoSystemValidate(decryptor, encryptor) && pass; + {1, 1, "0073006D006500670000", "0A58CF64530D823F", "8AAAE6297B6CB04642AB5B077851284EB7128F1A2A7FBCA3"}, + {2, 1, "0073006D006500670000", "0A58CF64530D823F", "79993DFE048D3B76"}, + {1, 1, "0073006D006500670000", "642B99AB44FB4B1F", "F3A95FEC48D7711E985CFE67908C5AB79FA3D7C5CAA5D966"}, + {2, 1, "0073006D006500670000", "642B99AB44FB4B1F", "C0A38D64A79BEA1D"}, + {3, 1, "0073006D006500670000", "3D83C0E4546AC140", "8D967D88F6CAA9D714800AB3D48051D63F73A312"}, + {1, 1000, "007100750065006500670000", "05DEC959ACFF72F7", "ED2034E36328830FF09DF1E1A07DD357185DAC0D4F9EB3D4"}, + {2, 1000, "007100750065006500670000", "05DEC959ACFF72F7", "11DEDAD7758D4860"}, + {1, 1000, "007100750065006500670000", "1682C0FC5B3F7EC5", "483DD6E919D7DE2E8E648BA8F862F3FBFBDC2BCB2C02957F"}, + {2, 1000, "007100750065006500670000", "1682C0FC5B3F7EC5", "9D461D1B00355C50"}, + {3, 1000, "007100750065006500670000", "263216FCC2FAB31C", "5EC4C7A80DF652294C3925B6489A7AB857C83476"} + }; + + PKCS12_PBKDF pbkdf; + + std::cout << "\nPKCS #12 PBKDF validation suite running...\n\n"; + pass = TestPBKDF(pbkdf, testSet, COUNTOF(testSet)) && pass; } - return pass; -} -bool ValidateNR() -{ - std::cout << "\nNR validation suite running...\n\n"; - bool pass = true; { - FileSource f(CRYPTOPP_DATA_DIR "TestData/nr2048.dat", true, new HexDecoder); - NR::Signer privS(f); - privS.AccessKey().Precompute(); - NR::Verifier pubS(privS); - - pass = SignatureValidate(privS, pubS) && pass; - } + // from draft-ietf-smime-password-03.txt, at http://www.imc.org/draft-ietf-smime-password + PBKDF_TestTuple testSet[] = { - std::cout << "Generating new signature key..." << std::endl; - NR::Signer privS(GlobalRNG(), 256); - NR::Verifier pubS(privS); + {0, 5, "70617373776f7264", "1234567878563412", "D1DAA78615F287E6"}, + {0, 500, "416C6C206E2D656E746974696573206D75737420636F6D6D756E69636174652077697468206F74686572206E2d656E74697469657320766961206E2D3120656E746974656568656568656573", "1234567878563412","6A8970BF68C92CAEA84A8DF28510858607126380CC47AB2D"} + }; + + PKCS5_PBKDF2_HMAC pbkdf; - pass = SignatureValidate(privS, pubS) && pass; + std::cout << "\nPKCS #5 PBKDF2 validation suite running...\n\n"; + pass = TestPBKDF(pbkdf, testSet, COUNTOF(testSet)) && pass; } + return pass; } -bool ValidateDSA(bool thorough) +struct HKDF_TestTuple { - std::cout << "\nDSA validation suite running...\n\n"; - - bool pass = true; - FileSource fs1(CRYPTOPP_DATA_DIR "TestData/dsa1024.dat", true, new HexDecoder()); - DSA::Signer priv(fs1); - DSA::Verifier pub(priv); - FileSource fs2(CRYPTOPP_DATA_DIR "TestData/dsa1024b.dat", true, new HexDecoder()); - DSA::Verifier pub1(fs2); - CRYPTOPP_ASSERT(pub.GetKey() == pub1.GetKey()); - pass = SignatureValidate(priv, pub, thorough) && pass; - pass = RunTestDataFile(CRYPTOPP_DATA_DIR "TestVectors/dsa.txt", g_nullNameValuePairs, thorough) && pass; - - return pass; -} + const char *hexSecret, *hexSalt, *hexInfo, *hexExpected; + size_t len; +}; -bool ValidateLUC() +bool TestHKDF(KeyDerivationFunction &kdf, const HKDF_TestTuple *testSet, unsigned int testSetSize) { - std::cout << "\nLUC validation suite running...\n\n"; - bool pass=true; + bool pass = true; + for (unsigned int i=0; i::Signer privS(f); - LUC_HMP::Verifier pubS(privS); - bool pass = SignatureValidate(privS, pubS); + kdf.DeriveKey((byte*)&derived[0], derived.size(), (const byte*)&secret[0], secret.size(), params); - std::cout << "\nLUC-IES validation suite running...\n\n"; + bool fail = !VerifyBufsEqual(derived, (const byte*)&expected[0], derived.size()); + pass = pass && !fail; - FileSource fc(CRYPTOPP_DATA_DIR "TestData/lucc512.dat", true, new HexDecoder); - LUC_IES<>::Decryptor privC(fc); - LUC_IES<>::Encryptor pubC(privC); - pass = CryptoSystemValidate(privC, pubC) && pass; + HexEncoder enc(new FileSink(std::cout)); + std::cout << (fail ? "FAILED " : "passed "); + std::cout << " " << tuple.hexSecret << " "; + std::cout << (tuple.hexSalt ? (strlen(tuple.hexSalt) ? tuple.hexSalt : "<0-LEN SALT>") : ""); + std::cout << " "; + std::cout << (tuple.hexInfo ? (strlen(tuple.hexInfo) ? tuple.hexInfo : "<0-LEN INFO>") : ""); + std::cout << " "; + enc.Put(derived, derived.size()); + std::cout << std::endl; + } return pass; } -bool ValidateRabin() +bool ValidateHKDF() { - std::cout << "\nRabin validation suite running...\n\n"; - bool pass=true; + bool pass = true; { - FileSource f(CRYPTOPP_DATA_DIR "TestData/rabi1024.dat", true, new HexDecoder); - RabinSS::Signer priv(f); - RabinSS::Verifier pub(priv); - pass = SignatureValidate(priv, pub) && pass; - } + // SHA-1 from RFC 5869, Appendix A, https://tools.ietf.org/html/rfc5869 + const HKDF_TestTuple testSet[] = { - RabinES >::Decryptor priv(GlobalRNG(), 512); - RabinES >::Encryptor pub(priv); - pass = CryptoSystemValidate(priv, pub) && pass; + // Test Case #4 + {"0b0b0b0b0b0b0b0b0b0b0b", "000102030405060708090a0b0c", "f0f1f2f3f4f5f6f7f8f9", "085a01ea1b10f36933068b56efa5ad81 a4f14b822f5b091568a9cdd4f155fda2 c22e422478d305f3f896", 42}, + // Test Case #5 + {"000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f 202122232425262728292a2b2c2d2e2f 303132333435363738393a3b3c3d3e3f 404142434445464748494a4b4c4d4e4f", "606162636465666768696a6b6c6d6e6f 707172737475767778797a7b7c7d7e7f 808182838485868788898a8b8c8d8e8f 909192939495969798999a9b9c9d9e9f a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf c0c1c2c3c4c5c6c7c8c9cacbcccdcecf d0d1d2d3d4d5d6d7d8d9dadbdcdddedf e0e1e2e3e4e5e6e7e8e9eaebecedeeef f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "0bd770a74d1160f7c9f12cd5912a06eb ff6adcae899d92191fe4305673ba2ffe 8fa3f1a4e5ad79f3f334b3b202b2173c 486ea37ce3d397ed034c7f9dfeb15c5e 927336d0441f4c4300e2cff0d0900b52 d3b4", 82}, + // Test Case #6 + {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "", "0ac1af7002b3d761d1e55298da9d0506 b9ae52057220a306e07b6b87e8df21d0 ea00033de03984d34918", 42}, + // Test Case #7 + {"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", NULLPTR, "", "2c91117204d745f3500d636a62f64f0 ab3bae548aa53d423b0d1f27ebba6f5e5 673a081d70cce7acfc48", 42} + }; + + HKDF hkdf; + + std::cout << "\nRFC 5869 HKDF(SHA-1) validation suite running...\n\n"; + pass = TestHKDF(hkdf, testSet, COUNTOF(testSet)) && pass; } - return pass; -} -bool ValidateRW() -{ - std::cout << "\nRW validation suite running...\n\n"; - - FileSource f(CRYPTOPP_DATA_DIR "TestData/rw1024.dat", true, new HexDecoder); - RWSS::Signer priv(f); - RWSS::Verifier pub(priv); - - return SignatureValidate(priv, pub); -} - -/* -bool ValidateBlumGoldwasser() -{ - std::cout << "\nBlumGoldwasser validation suite running...\n\n"; - - FileSource f(CRYPTOPP_DATA_DIR "TestData/blum512.dat", true, new HexDecoder); - BlumGoldwasserPrivateKey priv(f); - BlumGoldwasserPublicKey pub(priv); - - return CryptoSystemValidate(priv, pub); -} -*/ - -bool ValidateECP() -{ - std::cout << "\nECP validation suite running...\n\n"; - - ECIES::Decryptor cpriv(GlobalRNG(), ASN1::secp192r1()); - ECIES::Encryptor cpub(cpriv); - ByteQueue bq; - cpriv.GetKey().DEREncode(bq); - cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true); - cpub.GetKey().DEREncode(bq); - ECDSA::Signer spriv(bq); - ECDSA::Verifier spub(bq); - ECDH::Domain ecdhc(ASN1::secp192r1()); - ECMQV::Domain ecmqvc(ASN1::secp192r1()); - - spriv.AccessKey().Precompute(); - ByteQueue queue; - spriv.AccessKey().SavePrecomputation(queue); - spriv.AccessKey().LoadPrecomputation(queue); - - bool pass = SignatureValidate(spriv, spub); - cpub.AccessKey().Precompute(); - cpriv.AccessKey().Precompute(); - pass = CryptoSystemValidate(cpriv, cpub) && pass; - pass = SimpleKeyAgreementValidate(ecdhc) && pass; - pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; - - std::cout << "Turning on point compression..." << std::endl; - cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true); - cpub.AccessKey().AccessGroupParameters().SetPointCompression(true); - ecdhc.AccessGroupParameters().SetPointCompression(true); - ecmqvc.AccessGroupParameters().SetPointCompression(true); - pass = CryptoSystemValidate(cpriv, cpub) && pass; - pass = SimpleKeyAgreementValidate(ecdhc) && pass; - pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; - - std::cout << "Testing SEC 2, NIST, and Brainpool recommended curves..." << std::endl; - OID oid; - while (!(oid = DL_GroupParameters_EC::GetNextRecommendedParametersOID(oid)).GetValues().empty()) { - DL_GroupParameters_EC params(oid); - bool fail = !params.Validate(GlobalRNG(), 2); - std::cout << (fail ? "FAILED" : "passed") << " " << std::dec << params.GetCurve().GetField().MaxElementBitLength() << " bits" << std::endl; - pass = pass && !fail; + // SHA-256 from RFC 5869, Appendix A, https://tools.ietf.org/html/rfc5869 + const HKDF_TestTuple testSet[] = + { + // Test Case #1 + {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "000102030405060708090a0b0c", "f0f1f2f3f4f5f6f7f8f9", "3cb25f25faacd57a90434f64d0362f2a 2d2d0a90cf1a5a4c5db02d56ecc4c5bf 34007208d5b887185865", 42}, + // Test Case #2 + {"000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f 202122232425262728292a2b2c2d2e2f 303132333435363738393a3b3c3d3e3f 404142434445464748494a4b4c4d4e4f", "606162636465666768696a6b6c6d6e6f 707172737475767778797a7b7c7d7e7f 808182838485868788898a8b8c8d8e8f 909192939495969798999a9b9c9d9e9f a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf c0c1c2c3c4c5c6c7c8c9cacbcccdcecf d0d1d2d3d4d5d6d7d8d9dadbdcdddedf e0e1e2e3e4e5e6e7e8e9eaebecedeeef f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "b11e398dc80327a1c8e7f78c596a4934 4f012eda2d4efad8a050cc4c19afa97c 59045a99cac7827271cb41c65e590e09 da3275600c2f09b8367793a9aca3db71 cc30c58179ec3e87c14c01d5c1f3434f 1d87", 82}, + // Test Case #3 + {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "", "8da4e775a563c18f715f802a063c5a31 b8a11f5c5ee1879ec3454e5f3c738d2d 9d201395faa4b61a96c8", 42} + }; + + HKDF hkdf; + + std::cout << "\nRFC 5869 HKDF(SHA-256) validation suite running...\n\n"; + pass = TestHKDF(hkdf, testSet, COUNTOF(testSet)) && pass; } - return pass; -} + { + // SHA-512, Crypto++ generated, based on RFC 5869, https://tools.ietf.org/html/rfc5869 + const HKDF_TestTuple testSet[] = + { + // Test Case #0 + {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "000102030405060708090a0b0c", "f0f1f2f3f4f5f6f7f8f9", "832390086CDA71FB47625BB5CEB168E4 C8E26A1A16ED34D9FC7FE92C14815793 38DA362CB8D9F925D7CB", 42}, + // Test Case #0 + {"000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f 202122232425262728292a2b2c2d2e2f 303132333435363738393a3b3c3d3e3f 404142434445464748494a4b4c4d4e4f", "606162636465666768696a6b6c6d6e6f 707172737475767778797a7b7c7d7e7f 808182838485868788898a8b8c8d8e8f 909192939495969798999a9b9c9d9e9f a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf c0c1c2c3c4c5c6c7c8c9cacbcccdcecf d0d1d2d3d4d5d6d7d8d9dadbdcdddedf e0e1e2e3e4e5e6e7e8e9eaebecedeeef f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "CE6C97192805B346E6161E821ED16567 3B84F400A2B514B2FE23D84CD189DDF1 B695B48CBD1C8388441137B3CE28F16A A64BA33BA466B24DF6CFCB021ECFF235 F6A2056CE3AF1DE44D572097A8505D9E 7A93", 82}, + // Test Case #0 + {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "", "F5FA02B18298A72A8C23898A8703472C 6EB179DC204C03425C970E3B164BF90F FF22D04836D0E2343BAC", 42}, + // Test Case #0 + {"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", NULLPTR, "", "1407D46013D98BC6DECEFCFEE55F0F90 B0C7F63D68EB1A80EAF07E953CFC0A3A 5240A155D6E4DAA965BB", 42} + }; + + HKDF hkdf; + + std::cout << "\nRFC 5869 HKDF(SHA-512) validation suite running...\n\n"; + pass = TestHKDF(hkdf, testSet, COUNTOF(testSet)) && pass; + } -bool ValidateEC2N() -{ - std::cout << "\nEC2N validation suite running...\n\n"; - - // DEREncode() changed to Save() at Issue 569. - ECIES::Decryptor cpriv(GlobalRNG(), ASN1::sect193r1()); - ECIES::Encryptor cpub(cpriv); - ByteQueue bq; - cpriv.AccessMaterial().Save(bq); - cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true); - cpub.AccessMaterial().Save(bq); - ECDSA::Signer spriv(bq); - ECDSA::Verifier spub(bq); - ECDH::Domain ecdhc(ASN1::sect193r1()); - ECMQV::Domain ecmqvc(ASN1::sect193r1()); - - spriv.AccessKey().Precompute(); - ByteQueue queue; - spriv.AccessKey().SavePrecomputation(queue); - spriv.AccessKey().LoadPrecomputation(queue); - - bool pass = SignatureValidate(spriv, spub); - pass = CryptoSystemValidate(cpriv, cpub) && pass; - pass = SimpleKeyAgreementValidate(ecdhc) && pass; - pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; - - std::cout << "Turning on point compression..." << std::endl; - cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true); - cpub.AccessKey().AccessGroupParameters().SetPointCompression(true); - ecdhc.AccessGroupParameters().SetPointCompression(true); - ecmqvc.AccessGroupParameters().SetPointCompression(true); - pass = CryptoSystemValidate(cpriv, cpub) && pass; - pass = SimpleKeyAgreementValidate(ecdhc) && pass; - pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; - -#if 0 // TODO: turn this back on when I make EC2N faster for pentanomial basis - std::cout << "Testing SEC 2 recommended curves..." << std::endl; - OID oid; - while (!(oid = DL_GroupParameters_EC::GetNextRecommendedParametersOID(oid)).m_values.empty()) { - DL_GroupParameters_EC params(oid); - bool fail = !params.Validate(GlobalRNG(), 2); - std::cout << (fail ? "FAILED" : "passed") << " " << params.GetCurve().GetField().MaxElementBitLength() << " bits" << std::endl; - pass = pass && !fail; + // Whirlpool, Crypto++ generated, based on RFC 5869, https://tools.ietf.org/html/rfc5869 + const HKDF_TestTuple testSet[] = + { + // Test Case #0 + {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "000102030405060708090a0b0c", "f0f1f2f3f4f5f6f7f8f9", "0D29F74CCD8640F44B0DD9638111C1B5 766EFED752AF358109E2E7C9CD4A28EF 2F90B2AD461FBA0744D4", 42}, + // Test Case #0 + {"000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f 202122232425262728292a2b2c2d2e2f 303132333435363738393a3b3c3d3e3f 404142434445464748494a4b4c4d4e4f", "606162636465666768696a6b6c6d6e6f 707172737475767778797a7b7c7d7e7f 808182838485868788898a8b8c8d8e8f 909192939495969798999a9b9c9d9e9f a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf c0c1c2c3c4c5c6c7c8c9cacbcccdcecf d0d1d2d3d4d5d6d7d8d9dadbdcdddedf e0e1e2e3e4e5e6e7e8e9eaebecedeeef f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "4EBE4FE2DCCEC42661699500BE279A99 3FED90351E19373B3926FAA3A410700B2 BBF77E254CF1451AE6068D64A0904D96 6F4FF25498445A501B88F50D21E3A68A8 90E09445DC5886DD00E7F4F7C58A5121 70", 82}, + // Test Case #0 + {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "", "110632D0F7AEFAC31771FC66C22BB346 2614B81E4B04BA7F2B662E0BD694F564 58615F9A9CB56C57ECF2", 42}, + // Test Case #0 + {"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c" /*key*/, NULLPTR /*salt*/, "" /*info*/, "4089286EBFB23DD8A02F0C9DAA35D538 EB09CD0A8CBAB203F39083AA3E0BD313 E6F91E64F21A187510B0", 42} + }; + + HKDF hkdf; + + std::cout << "\nRFC 5869 HKDF(Whirlpool) validation suite running...\n\n"; + pass = TestHKDF(hkdf, testSet, COUNTOF(testSet)) && pass; } -#endif return pass; } -bool ValidateECDSA() +struct Scrypt_TestTuple { - std::cout << "\nECDSA validation suite running...\n\n"; - - // from Sample Test Vectors for P1363 - GF2NT gf2n(191, 9, 0); - byte a[]="\x28\x66\x53\x7B\x67\x67\x52\x63\x6A\x68\xF5\x65\x54\xE1\x26\x40\x27\x6B\x64\x9E\xF7\x52\x62\x67"; - byte b[]="\x2E\x45\xEF\x57\x1F\x00\x78\x6F\x67\xB0\x08\x1B\x94\x95\xA3\xD9\x54\x62\xF5\xDE\x0A\xA1\x85\xEC"; - EC2N ec(gf2n, PolynomialMod2(a,24), PolynomialMod2(b,24)); - - EC2N::Point P; - bool result = ec.DecodePoint(P, (byte *)"\x04\x36\xB3\xDA\xF8\xA2\x32\x06\xF9\xC4\xF2\x99\xD7\xB2\x1A\x9C\x36\x91\x37\xF2\xC8\x4A\xE1\xAA\x0D" - "\x76\x5B\xE7\x34\x33\xB3\xF9\x5E\x33\x29\x32\xE7\x0E\xA2\x45\xCA\x24\x18\xEA\x0E\xF9\x80\x18\xFB", ec.EncodedPointSize()); - CRYPTOPP_ASSERT(result); CRYPTOPP_UNUSED(result); - - Integer n("40000000000000000000000004a20e90c39067c893bbb9a5H"); - Integer d("340562e1dda332f9d2aec168249b5696ee39d0ed4d03760fH"); - EC2N::Point Q(ec.Multiply(d, P)); - ECDSA::Signer priv(ec, P, n, d); - ECDSA::Verifier pub(priv); - - Integer h("A9993E364706816ABA3E25717850C26C9CD0D89DH"); - Integer k("3eeace72b4919d991738d521879f787cb590aff8189d2b69H"); - static const byte sig[]="\x03\x8e\x5a\x11\xfb\x55\xe4\xc6\x54\x71\xdc\xd4\x99\x84\x52\xb1\xe0\x2d\x8a\xf7\x09\x9b\xb9\x30" - "\x0c\x9a\x08\xc3\x44\x68\xc2\x44\xb4\xe5\xd6\xb2\x1b\x3c\x68\x36\x28\x07\x41\x60\x20\x32\x8b\x6e"; - Integer r(sig, 24); - Integer s(sig+24, 24); + const char * passwd; + const char * salt; + word64 n; + word32 r; + word32 p; + const char * expect; +}; - Integer rOut, sOut; - bool fail, pass=true; +bool TestScrypt(KeyDerivationFunction &pbkdf, const Scrypt_TestTuple *testSet, unsigned int testSetSize) +{ + bool pass = true; - priv.RawSign(k, h, rOut, sOut); - fail = (rOut != r) || (sOut != s); - pass = pass && !fail; + for (unsigned int i=0; i sign; + bool pass = true; - const Integer x("09A4D6792295A7F730FC3F2B49CBC0F62E862272Fh"); - const Integer e("AF2BDBE1AA9B6EC1E2ADE1D694F41FC71A831D0268E9891562113D8A62ADD1BFh"); - const Integer q("4000000000000000000020108A2E0CC0D99F8A5EFh"); - const Integer k("23AF4074C90A02B3FE61D286D5C87F425E6BDD81Bh"); - const Integer &k_out = sign.GenerateRandom(x, q, e); + // https://tools.ietf.org/html/rfc7914 + const Scrypt_TestTuple testSet[] = + { + { "", "", 16, 1, 1, "77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906"}, + { "password", "NaCl", 1024, 8, 16, "fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640"}, + { "pleaseletmein", "SodiumChloride", 16384, 8, 1, "7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887"}, +#ifndef CRYPTOPP_DEBUG + // This one takes too long in debug builds + // { "pleaseletmein", "SodiumChloride", 1048576, 8, 1, "2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049e8a952fbcbf45c6fa77a41a4"} +#endif + }; - bool pass = (k_out == k); + Scrypt pbkdf; - std::cout << (pass ? "passed " : "FAILED "); - std::cout << "deterministic k generation against test vector\n"; + std::cout << "\nRFC 7914 Scrypt validation suite running...\n\n"; + pass = TestScrypt(pbkdf, testSet, COUNTOF(testSet)) && pass; return pass; } -// from http://www.teletrust.de/fileadmin/files/oid/ecgdsa_final.pdf -bool ValidateECGDSA(bool thorough) +struct Poly1305_TestTuples { - std::cout << "\nECGDSA validation suite running...\n\n"; + const char *key, *message, *nonce, *digest; + size_t klen, mlen, nlen, dlen; +}; - bool fail, pass=true; +bool ValidatePoly1305() +{ + std::cout << "\nPoly1305 validation suite running...\n\n"; + bool fail, pass = true; - // 2.4.1 Examples of ECGDSA over GF(p) with the hash function RIPEMD-160 (p. 10) - if (thorough) { - const OID oid = ASN1::brainpoolP192r1(); - DL_GroupParameters_EC params(oid); - Integer x("0x 80F2425E 89B4F585 F27F3536 ED834D68 E3E492DE 08FE84B9"); - ECGDSA::Signer signer(params, x); - ECGDSA::Verifier verifier(signer); - - Integer e("0x 00000000 577EF842 B32FDE45 79727FFF 02F7A280 74ADC4EF"); - Integer k("0x 22C17C2A 367DD85A B8A365ED 06F19C43 F9ED1834 9A9BC044"); - - Integer r, s; - signer.RawSign(k, e, r, s); - - Integer rExp("0x 2D017BE7 F117FF99 4ED6FC63 CA5B4C7A 0430E9FA 095DAFC4"); - Integer sExp("0x C02B5CC5 C51D5411 060BF024 5049F824 839F671D 78A1BBF1"); - - fail = (r != rExp) || (s != sExp); - pass = pass && !fail; - - const byte msg[] = "Example of ECGDSA with the hash function RIPEMD-160"; - const size_t len = strlen((char*)msg); - - byte signature[48]; - r.Encode(signature+0, 24); - s.Encode(signature+24, 24); - - fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); - pass = pass && !fail; - - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "brainpoolP192r1 using RIPEMD-160\n"; - - fail = !SignatureValidate(signer, verifier); + fail = (Poly1305::StaticAlgorithmName() != "Poly1305(AES)"); + std::cout << (fail ? "FAILED " : "passed ") << "algorithm name\n"; pass = pass && !fail; } - // 2.4.1 Examples of ECGDSA over GF(p) with the hash function RIPEMD-160 (p. 13) - if (thorough) + // Test data from http://cr.yp.to/mac/poly1305-20050329.pdf + const Poly1305_TestTuples tests[] = { - const OID oid = ASN1::brainpoolP256r1(); - DL_GroupParameters_EC params(oid); - Integer x("0x 47B3A278 62DEF037 49ACF0D6 00E69F9B 851D01ED AEFA531F 4D168E78 7307F4D8"); - ECGDSA::Signer signer(params, x); - ECGDSA::Verifier verifier(signer); - - Integer e("0x 00000000 00000000 00000000 577EF842 B32FDE45 79727FFF 02F7A280 74ADC4EF"); - Integer k("0x 908E3099 776261A4 558FF7A9 FA6DFFE0 CA6BB3F9 CB35C2E4 E1DC73FD 5E8C08A3"); - - Integer r, s; - signer.RawSign(k, e, r, s); - - Integer rExp("0x 62CCD1D2 91E62F6A 4FFBD966 C66C85AA BA990BB6 AB0C087D BD54A456 CCC84E4C"); - Integer sExp("0x 9119719B 08EEA0D6 BC56E4D1 D37369BC F3768445 EF65CAE4 A37BF6D4 3BD01646"); - - fail = (r != rExp) || (s != sExp); - pass = pass && !fail; - - const byte msg[] = "Example of ECGDSA with the hash function RIPEMD-160"; - const size_t len = strlen((char*)msg); - - byte signature[64]; - r.Encode(signature+0, 32); - s.Encode(signature+32, 32); - - fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); - pass = pass && !fail; - - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "brainpoolP256r1 using RIPEMD-160\n"; - - fail = !SignatureValidate(signer, verifier); + // Appendix B, Test 1 + { + "\xec\x07\x4c\x83\x55\x80\x74\x17\x01\x42\x5b\x62\x32\x35\xad\xd6" // Key + "\x85\x1f\xc4\x0c\x34\x67\xac\x0b\xe0\x5c\xc2\x04\x04\xf3\xf7\x00", + "\xf3\xf6", // Message + "\xfb\x44\x73\x50\xc4\xe8\x68\xc5\x2a\xc3\x27\x5c\xf9\xd4\x32\x7e", // Nonce + "\xf4\xc6\x33\xc3\x04\x4f\xc1\x45\xf8\x4f\x33\x5c\xb8\x19\x53\xde", // Digest + 32, 2, 16, 16 + }, + // Appendix B, Test 2 + { + "\x75\xde\xaa\x25\xc0\x9f\x20\x8e\x1d\xc4\xce\x6b\x5c\xad\x3f\xbf" // Key + "\x61\xee\x09\x21\x8d\x29\xb0\xaa\xed\x7e\x15\x4a\x2c\x55\x09\xcc", + "", // Message + "\x61\xee\x09\x21\x8d\x29\xb0\xaa\xed\x7e\x15\x4a\x2c\x55\x09\xcc", // Nonce + "\xdd\x3f\xab\x22\x51\xf1\x1a\xc7\x59\xf0\x88\x71\x29\xcc\x2e\xe7", // Digest + 32, 0, 16, 16 + }, + // Appendix B, Test 3 + { + "\x6a\xcb\x5f\x61\xa7\x17\x6d\xd3\x20\xc5\xc1\xeb\x2e\xdc\xdc\x74" // Key + "\x48\x44\x3d\x0b\xb0\xd2\x11\x09\xc8\x9a\x10\x0b\x5c\xe2\xc2\x08", + "\x66\x3c\xea\x19\x0f\xfb\x83\xd8\x95\x93\xf3\xf4\x76\xb6\xbc\x24" // Message + "\xd7\xe6\x79\x10\x7e\xa2\x6a\xdb\x8c\xaf\x66\x52\xd0\x65\x61\x36", + "\xae\x21\x2a\x55\x39\x97\x29\x59\x5d\xea\x45\x8b\xc6\x21\xff\x0e", // Nonce + "\x0e\xe1\xc1\x6b\xb7\x3f\x0f\x4f\xd1\x98\x81\x75\x3c\x01\xcd\xbe", // Digest + 32, 32, 16, 16 + }, + // Appendix B, Test 4 + { + "\xe1\xa5\x66\x8a\x4d\x5b\x66\xa5\xf6\x8c\xc5\x42\x4e\xd5\x98\x2d" // Key + "\x12\x97\x6a\x08\xc4\x42\x6d\x0c\xe8\xa8\x24\x07\xc4\xf4\x82\x07", + "\xab\x08\x12\x72\x4a\x7f\x1e\x34\x27\x42\xcb\xed\x37\x4d\x94\xd1" // Message + "\x36\xc6\xb8\x79\x5d\x45\xb3\x81\x98\x30\xf2\xc0\x44\x91\xfa\xf0" + "\x99\x0c\x62\xe4\x8b\x80\x18\xb2\xc3\xe4\xa0\xfa\x31\x34\xcb\x67" + "\xfa\x83\xe1\x58\xc9\x94\xd9\x61\xc4\xcb\x21\x09\x5c\x1b\xf9", + "\x9a\xe8\x31\xe7\x43\x97\x8d\x3a\x23\x52\x7c\x71\x28\x14\x9e\x3a", // Nonce + "\x51\x54\xad\x0d\x2c\xb2\x6e\x01\x27\x4f\xc5\x11\x48\x49\x1f\x1b", // Digest + 32, 63, 16, 16 + } + }; + + unsigned int count = 0; + byte digest[Poly1305::DIGESTSIZE]; + + // Positive tests + for (unsigned int i=0; i poly1305((const byte*)tests[i].key, tests[i].klen); + poly1305.Resynchronize((const byte*)tests[i].nonce, (int)tests[i].nlen); + poly1305.Update((const byte*)tests[i].message, tests[i].mlen); + poly1305.Final(digest); + + fail = !!memcmp(digest, tests[i].digest, tests[i].dlen) != 0; + if (fail) + { + std::cout << "FAILED " << "Poly1305 test set " << count << std::endl; + } + + count++; pass = pass && !fail; } - // 2.4.1 Examples of ECGDSA over GF(p) with the hash function RIPEMD-160 (p. 16) - if (thorough) + // Positive tests + for (unsigned int i=0; i params(oid); - Integer x("0x 48683594 5A3A284F FC52629A D48D8F37 F4B2E993 9C52BC72 362A9961 40192AEF 7D2AAFF0 C73A51C5"); - ECGDSA::Signer signer(params, x); - ECGDSA::Verifier verifier(signer); - - Integer e("0x 00000000 00000000 00000000 00000000 00000000 577EF842 B32FDE45 79727FFF 02F7A280 74ADC4EF"); - Integer k("0x C70BC00A 77AD7872 5D36CEEC 27D6F956 FB546EEF 6DC90E35 31452BD8 7ECE8A4A 7AD730AD C299D81B"); + Poly1305 poly1305((const byte*)tests[i].key, tests[i].klen,(const byte*)tests[i].nonce, (int)tests[i].nlen); + poly1305.Update((const byte*)tests[i].message, tests[i].mlen); + poly1305.Final(digest); - Integer r, s; - signer.RawSign(k, e, r, s); + fail = !!memcmp(digest, tests[i].digest, tests[i].dlen) != 0; + if (fail) + { + std::cout << "FAILED " << "Poly1305 test set " << count << std::endl; + } - Integer rExp("0x 3C925969 FAB22F7A E7B8CC5D 50CB0867 DFDB2CF4 FADA3D49 0DF75D72 F7563186 419494C9 8F9C82A6"); - Integer sExp("0x 06AB5250 B31A8E93 56194894 61733200 E4FD5C12 75C0AB37 E7E41149 5BAAE145 41DF6DE6 66B8CA56"); - - fail = (r != rExp) || (s != sExp); - pass = pass && !fail; - - const byte msg[] = "Example of ECGDSA with the hash function RIPEMD-160"; - const size_t len = strlen((char*)msg); - - byte signature[80]; - r.Encode(signature+0, 40); - s.Encode(signature+40, 40); - - fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); - pass = pass && !fail; - - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "brainpoolP320r1 using RIPEMD-160\n"; - - fail = !SignatureValidate(signer, verifier); + count++; pass = pass && !fail; } - // 2.4.1 Examples of ECGDSA over GF(p) with the hash function SHA-1 (p. 19) + // Negative tests + for (unsigned int i=0; i params(oid); - Integer x("0x 80F2425E 89B4F585 F27F3536 ED834D68 E3E492DE 08FE84B9"); - ECGDSA::Signer signer(params, x); - ECGDSA::Verifier verifier(signer); + Poly1305 poly1305((const byte*)tests[i].key, tests[i].klen); + poly1305.Resynchronize((const byte*)tests[i].nonce, (int)tests[i].nlen); + poly1305.Update((const byte*)tests[i].message, tests[i].mlen); + poly1305.Final(digest); + + unsigned int next = (i+1) % COUNTOF(tests); + fail = !!memcmp(digest, tests[next].digest, tests[next].dlen) == 0; + if (fail) + { + std::cout << "FAILED " << "Poly1305 test set " << count << std::endl; + } + + count++; + pass = pass && !fail; + } - Integer e("0x 00000000 CF00CD42 CAA80DDF 8DDEBDFD 32F2DA15 11B53F29"); - Integer k("0x 22C17C2A 367DD85A B8A365ED 06F19C43 F9ED1834 9A9BC044"); + std::cout << (!pass ? "FAILED " : "passed ") << count << " message authentication codes" << std::endl; - Integer r, s; - signer.RawSign(k, e, r, s); + return pass; +} - Integer rExp("0x 2D017BE7 F117FF99 4ED6FC63 CA5B4C7A 0430E9FA 095DAFC4"); - Integer sExp("0x 18FD604E 5F00F55B 3585C052 8C319A2B 05B8F2DD EE9CF1A6"); +bool ValidateSipHash() +{ + std::cout << "\nSipHash validation suite running...\n\n"; + bool fail, pass = true, pass1=true, pass2=true, pass3=true, pass4=true; - fail = (r != rExp) || (s != sExp); + { + fail = (SipHash<2,4>::StaticAlgorithmName() != "SipHash-2-4"); + std::cout << (fail ? "FAILED " : "passed ") << "SipHash-2-4 algorithm name\n"; pass = pass && !fail; - const byte msg[] = "Example of ECGDSA with the hash function SHA-1"; - const size_t len = strlen((char*)msg); - - byte signature[48]; - r.Encode(signature+0, 24); - s.Encode(signature+24, 24); - - fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); + fail = (SipHash<2,4, false>::DIGESTSIZE != 8); + std::cout << (fail ? "FAILED " : "passed ") << "SipHash-2-4 64-bit digest size\n"; pass = pass && !fail; - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "brainpoolP192r1 using SHA-1\n"; - - fail = !SignatureValidate(signer, verifier); + fail = (SipHash<2,4, true>::DIGESTSIZE != 16); + std::cout << (fail ? "FAILED " : "passed ") << "SipHash-2-4 128-bit digest size\n"; pass = pass && !fail; - } - - // 2.4.1 Examples of ECGDSA over GF(p) with the hash function SHA-224 (p. 23) - { - const OID oid = ASN1::brainpoolP320r1(); - DL_GroupParameters_EC params(oid); - Integer x("0x 48683594 5A3A284F FC52629A D48D8F37 F4B2E993 9C52BC72 362A9961 40192AEF 7D2AAFF0 C73A51C5"); - ECGDSA::Signer signer(params, x); - ECGDSA::Verifier verifier(signer); - - Integer e("0x 00000000 00000000 00000000 92AE8A0E 8D08EADE E9426378 714FF3E0 1957587D 2876FA70 D40E3144"); - Integer k("0x C70BC00A 77AD7872 5D36CEEC 27D6F956 FB546EEF 6DC90E35 31452BD8 7ECE8A4A 7AD730AD C299D81B"); - - Integer r, s; - signer.RawSign(k, e, r, s); - - Integer rExp("0x 3C925969 FAB22F7A E7B8CC5D 50CB0867 DFDB2CF4 FADA3D49 0DF75D72 F7563186 419494C9 8F9C82A6"); - Integer sExp("0x 6EA191CA 0D468AC3 E9568768 9338357C 7D0BACB3 F1D87E0D EC05F635 B7ADB842 75AA0086 60F812CF"); - fail = (r != rExp) || (s != sExp); + fail = (SipHash<4,8>::StaticAlgorithmName() != "SipHash-4-8"); + std::cout << (fail ? "FAILED " : "passed ") << "SipHash-4-8 algorithm name\n"; pass = pass && !fail; - const byte msg[] = "Example of ECGDSA with the hash function SHA-224"; - const size_t len = strlen((char*)msg); - - byte signature[80]; - r.Encode(signature+0, 40); - s.Encode(signature+40, 40); - - fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); + fail = (SipHash<4,8, false>::DIGESTSIZE != 8); + std::cout << (fail ? "FAILED " : "passed ") << "SipHash-4-8 64-bit digest size\n"; pass = pass && !fail; - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "brainpoolP320r1 using SHA-224\n"; - - fail = !SignatureValidate(signer, verifier); + fail = (SipHash<4,8, true>::DIGESTSIZE != 16); + std::cout << (fail ? "FAILED " : "passed ") << "SipHash-4-8 128-bit digest size\n"; pass = pass && !fail; } - // 2.4.1 Examples of ECGDSA over GF(p) with the hash function SHA-256 (p. 27) + // Siphash-2-4, 64-bit MAC { - const OID oid = ASN1::brainpoolP320r1(); - DL_GroupParameters_EC params(oid); - Integer x("0x 48683594 5A3A284F FC52629A D48D8F37 F4B2E993 9C52BC72 362A9961 40192AEF 7D2AAFF0 C73A51C5"); - ECGDSA::Signer signer(params, x); - ECGDSA::Verifier verifier(signer); - - Integer e("0x 00000000 00000000 37ED8AA9 4AE667DB BB753330 E050EB8E 12195807 ECDC4FB1 0E0662B4 22C219D7"); - Integer k("0x C70BC00A 77AD7872 5D36CEEC 27D6F956 FB546EEF 6DC90E35 31452BD8 7ECE8A4A 7AD730AD C299D81B"); - - Integer r, s; - signer.RawSign(k, e, r, s); + const byte key[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; + SipHash<2,4, false> hash(key, 16); + byte digest[SipHash<2,4, false>::DIGESTSIZE]; + + hash.Update((const byte*)"", 0); + hash.Final(digest); + fail = !!memcmp("\x31\x0E\x0E\xDD\x47\xDB\x6F\x72", digest, COUNTOF(digest)); + pass1 = !fail && pass1; + + hash.Update((const byte*)"\x00", 1); + hash.Final(digest); + fail = !!memcmp("\xFD\x67\xDC\x93\xC5\x39\xF8\x74", digest, COUNTOF(digest)); + pass1 = !fail && pass1; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06", 7); + hash.Final(digest); + fail = !!memcmp("\x37\xD1\x01\x8B\xF5\x00\x02\xAB", digest, COUNTOF(digest)); + pass1 = !fail && pass1; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07", 8); + hash.Final(digest); + fail = !!memcmp("\x62\x24\x93\x9A\x79\xF5\xF5\x93", digest, COUNTOF(digest)); + pass1 = !fail && pass1; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07\x08", 9); + hash.Final(digest); + fail = !!memcmp("\xB0\xE4\xA9\x0B\xDF\x82\x00\x9E", digest, COUNTOF(digest)); + pass1 = !fail && pass1; + + std::cout << (pass1 ? "passed " : "FAILED ") << "SipHash-2-4 64-bit MAC\n"; + pass = pass1 && pass; + } - Integer rExp("0x 3C925969 FAB22F7A E7B8CC5D 50CB0867 DFDB2CF4 FADA3D49 0DF75D72 F7563186 419494C9 8F9C82A6"); - Integer sExp("0x 24370797 A9D11717 BBBB2B76 2E08ECD0 7DD7E033 F544E47C BF3C6D16 FD90B51D CC2E4DD8 E6ECD8CD"); + // Siphash-2-4, 128-bit MAC + { + const byte key[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; + SipHash<2,4, true> hash(key, 16); + byte digest[SipHash<2,4, true>::DIGESTSIZE]; + + hash.Update((const byte*)"", 0); + hash.Final(digest); + fail = !!memcmp("\xA3\x81\x7F\x04\xBA\x25\xA8\xE6\x6D\xF6\x72\x14\xC7\x55\x02\x93", digest, COUNTOF(digest)); + pass3 = !fail && pass3; + + hash.Update((const byte*)"\x00", 1); + hash.Final(digest); + fail = !!memcmp("\xDA\x87\xC1\xD8\x6B\x99\xAF\x44\x34\x76\x59\x11\x9B\x22\xFC\x45", digest, COUNTOF(digest)); + pass3 = !fail && pass3; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06", 7); + hash.Final(digest); + fail = !!memcmp("\xA1\xF1\xEB\xBE\xD8\xDB\xC1\x53\xC0\xB8\x4A\xA6\x1F\xF0\x82\x39", digest, COUNTOF(digest)); + pass3 = !fail && pass3; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07", 8); + hash.Final(digest); + fail = !!memcmp("\x3B\x62\xA9\xBA\x62\x58\xF5\x61\x0F\x83\xE2\x64\xF3\x14\x97\xB4", digest, COUNTOF(digest)); + pass3 = !fail && pass3; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07\x08", 9); + hash.Final(digest); + fail = !!memcmp("\x26\x44\x99\x06\x0A\xD9\xBA\xAB\xC4\x7F\x8B\x02\xBB\x6D\x71\xED", digest, COUNTOF(digest)); + pass3 = !fail && pass3; + + std::cout << (pass3 ? "passed " : "FAILED ") << "SipHash-2-4 128-bit MAC\n"; + pass = pass3 && pass; + } - fail = (r != rExp) || (s != sExp); - pass = pass && !fail; + // Siphash-4-8, 64-bit MAC + { + const byte key[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; + SipHash<4, 8, false> hash(key, 16); + byte digest[SipHash<4, 8, false>::DIGESTSIZE]; + + hash.Update((const byte*)"", 0); + hash.Final(digest); + fail = !!memcmp("\x41\xDA\x38\x99\x2B\x05\x79\xC8", digest, COUNTOF(digest)); + pass2 = !fail && pass2; + + hash.Update((const byte*)"\x00", 1); + hash.Final(digest); + fail = !!memcmp("\x51\xB8\x95\x52\xF9\x14\x59\xC8", digest, COUNTOF(digest)); + pass2 = !fail && pass2; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06", 7); + hash.Final(digest); + fail = !!memcmp("\x47\xD7\x3F\x71\x5A\xBE\xFD\x4E", digest, COUNTOF(digest)); + pass2 = !fail && pass2; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07", 8); + hash.Final(digest); + fail = !!memcmp("\x20\xB5\x8B\x9C\x07\x2F\xDB\x50", digest, COUNTOF(digest)); + pass2 = !fail && pass2; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07\x08", 9); + hash.Final(digest); + fail = !!memcmp("\x36\x31\x9A\xF3\x5E\xE1\x12\x53", digest, COUNTOF(digest)); + pass2 = !fail && pass2; + + std::cout << (pass2 ? "passed " : "FAILED ") << "SipHash-4-8 64-bit MAC\n"; + pass = pass2 && pass; + } - const byte msg[] = "Example of ECGDSA with the hash function SHA-256"; - const size_t len = strlen((char*)msg); + // Siphash-4-8, 128-bit MAC + { + const byte key[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; + SipHash<4, 8, true> hash(key, 16); + byte digest[SipHash<4, 8, true>::DIGESTSIZE]; + + hash.Update((const byte*)"", 0); + hash.Final(digest); + fail = !!memcmp("\x1F\x64\xCE\x58\x6D\xA9\x04\xE9\xCF\xEC\xE8\x54\x83\xA7\x0A\x6C", digest, COUNTOF(digest)); + pass4 = !fail && pass4; + + hash.Update((const byte*)"\x00", 1); + hash.Final(digest); + fail = !!memcmp("\x47\x34\x5D\xA8\xEF\x4C\x79\x47\x6A\xF2\x7C\xA7\x91\xC7\xA2\x80", digest, COUNTOF(digest)); + pass4 = !fail && pass4; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06", 7); + hash.Final(digest); + fail = !!memcmp("\xED\x00\xE1\x3B\x18\x4B\xF1\xC2\x72\x6B\x8B\x54\xFF\xD2\xEE\xE0", digest, COUNTOF(digest)); + pass4 = !fail && pass4; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07", 8); + hash.Final(digest); + fail = !!memcmp("\xA7\xD9\x46\x13\x8F\xF9\xED\xF5\x36\x4A\x5A\x23\xAF\xCA\xE0\x63", digest, COUNTOF(digest)); + pass4 = !fail && pass4; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07\x08", 9); + hash.Final(digest); + fail = !!memcmp("\x9E\x73\x14\xB7\x54\x5C\xEC\xA3\x8B\x9A\x55\x49\xE4\xFB\x0B\xE8", digest, COUNTOF(digest)); + pass4 = !fail && pass4; + + std::cout << (pass4 ? "passed " : "FAILED ") << "SipHash-4-8 128-bit MAC\n"; + pass = pass4 && pass; + } - byte signature[80]; - r.Encode(signature+0, 40); - s.Encode(signature+40, 40); + return pass; +} - fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); - pass = pass && !fail; +struct BLAKE2_TestTuples +{ + const char *key, *message, *digest; + size_t klen, mlen, dlen; +}; - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "brainpoolP320r1 using SHA-256\n"; +bool ValidateBLAKE2s() +{ + std::cout << "\nBLAKE2s validation suite running...\n\n"; + bool fail, pass = true; - fail = !SignatureValidate(signer, verifier); + { + fail = strcmp(BLAKE2s::StaticAlgorithmName(), "BLAKE2s") != 0; + std::cout << (fail ? "FAILED " : "passed ") << "algorithm name\n"; pass = pass && !fail; } - // 2.4.1 Examples of ECGDSA over GF(p) with the hash function SHA-384 (p. 34) + const BLAKE2_TestTuples tests[] = { + { + NULLPTR, + NULLPTR, + "\x8F\x38", + 0, 0, 2 + }, + { + NULLPTR, + NULLPTR, + "\x36\xE9\xD2\x46", + 0, 0, 4 + }, + { + NULLPTR, + NULLPTR, + "\xEF\x2A\x8B\x78\xDD\x80\xDA\x9C", + 0, 0, 8 + }, + { + NULLPTR, + NULLPTR, + "\x64\x55\x0D\x6F\xFE\x2C\x0A\x01\xA1\x4A\xBA\x1E\xAD\xE0\x20\x0C", + 0, 0, 16 + }, + { + NULLPTR, + NULLPTR, + "\x69\x21\x7A\x30\x79\x90\x80\x94\xE1\x11\x21\xD0\x42\x35\x4A\x7C\x1F\x55\xB6\x48\x2C\xA1\xA5\x1E\x1B\x25\x0D\xFD\x1E\xD0\xEE\xF9", + 0, 0, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x25\xEC\xB2\xF6\xA7\x81\x82\x57\x5D\x4B\xD7\x02\x72\x6D\xE1\x82\xBB\x1E\x21\xA8\x5D\x51\x34\xAD\xA2\x25\x8D\x7E\x21\x38\x03\xA7", + 0, 15, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xD4\x1C\x69\x87\x29\x7E\xDE\x4F\x08\x9B\x66\x9B\xC7\x0E\x62\xB9\xFA\xFA\x1C\x37\xCC\x31\x29\x22\xE0\xEA\x63\xE2\xE5\x85\xAA\x9F", + 0, 16, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xE0\xAD\xF2\xCC\x1F\x1F\x55\x3A\xE6\xC3\xCD\x3D\xF7\x68\xEA\x66\x9C\x32\xBE\x1D\x37\xF9\xA2\x61\xD4\x4F\x45\x26\x69\xD0\xD3\xA4", + 0, 17, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x10\x42\x65\x1C\x86\x15\xC4\x87\x69\x41\x19\x1F\xB6\xD5\xC5\x1D\xEB\x4C\xA1\x8C\xAF\xEF\xEB\x79\x69\x62\x87\x0D\x6A\x5D\xEE\x20", + 0, 31, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEA\xB1\xC5\xDD\xDF\xB5\x7C\x48\xC5\xB0\xB3\xF5\xBE\x5B\x47\x6D\xBB\xF5\xA3\x5C\x21\xD3\xDD\x94\x13\xA1\x04\xB8\x14\xF9\x2D\x4B", + 0, 32, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x7E\x82\x07\x49\x14\x62\x11\x96\xC5\xE8\xF3\xCB\x0F\x21\x7B\x37\xAE\x9B\x64\x58\xF4\x66\x01\xB9\x21\x23\xAC\x48\x64\x30\x83\x8F", + 0, 33, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x90\xB5\xA2\x5E\x8E\xA8\xA0\xC8\x74\x85\xAE\x18\x08\x9D\x92\xEB\x14\x5A\x5D\x4E\x2C\x60\x7B\xCB\x4B\x94\xD1\x0F\xAE\x59\x33\xC1", + 0, 63, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x71\x27\x28\x45\x9E\x67\xD7\xED\xB7\xAE\xFA\x88\xFF\x5C\x7E\x7B\x5D\xA9\x94\xA1\xC3\xB1\x7B\x64\xFB\xC1\x4E\x47\xCA\xDA\x45\xDD", + 0, 64, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x58\x72\x3B\xB1\xBE\x18\x33\x12\x31\x5E\x6E\xF7\xF2\xB1\x84\x60\x97\x2C\x19\xD3\x01\xAF\x42\x00\xAB\xDB\x04\x26\xFC\xB0\xC1\xF8", + 0, 65, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\x9A\xD4\x81\xEF\x81\x6C\xAC\xB6\x59\x35\x8E\x6D\x6B\x73\xF1\xE5\xAC\x71\xD6\x6E\x8B\x12\x6B\x73\xD9\xD9\x7D\x2F\xA7\xA4\x61\xB4", + 15, 0, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x61\x8C\xBE\x19\x4B\x28\xDC\xA3\x8B\xE5\x1A\x79\x37\x45\xB4\x66\x3D\xF1\x9D\xB5\x8F\xFF\xEF\xC4\x5D\x37\x82\x25\x93\xEB\xE2\x93", + 15, 15, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xF3\xEC\x81\x61\x44\x5C\x6E\x2E\xE6\x52\x6A\xCA\x5F\xD9\x25\x74\x2A\x33\xB9\x1F\xEF\x0F\x7E\x54\x4F\x50\xC2\xFB\x04\x3C\x52\xD2", + 15, 16, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xF4\x81\x43\x6E\x2F\x4C\x5D\x09\x21\x73\x24\xDA\xA6\x23\x9E\xFD\xF8\x82\xCE\x0E\x3E\x4C\xB4\x17\xCC\x27\xCD\x1A\xAE\x90\x9B\x94", + 15, 17, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x99\x5E\x74\x8E\x96\xFE\xC0\x39\x5B\x73\xA3\xC0\x4E\xC7\xF7\xBE\x89\x83\xCD\x18\x24\x60\x60\x7B\xBC\xF5\x50\xF5\x84\xD1\x71\x6B", + 15, 31, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x21\x6E\xB9\xE2\xE4\xAF\x94\x5F\x6A\xA3\xD2\xCA\x25\x72\xFB\x8F\xDB\x95\x2F\xAC\x1C\x69\xC1\x26\x28\x31\x63\x16\x25\xA5\x2C\xF8", + 15, 32, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xE3\x71\x9F\xD8\xAE\x68\xC8\xC4\x5D\x17\xDD\x21\x33\xBB\xE1\x61\x51\x22\xC2\x3B\x00\x6E\xDD\x66\x7E\x2A\x0A\x6B\x77\xA9\x0B\x8D", + 15, 33, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xD3\xF8\x5F\x1B\xBE\x9C\x53\xCB\x7F\x5F\x5F\x62\x4D\x06\x36\x8F\xF8\x15\xA7\xF5\xEB\x77\xC6\xC5\xB4\x81\x15\x01\x82\x8D\x9D\x40", + 15, 63, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xBF\xA3\xDA\x09\xF9\xDE\x1B\xE6\x57\x4B\x55\x82\x85\x69\x79\xA1\x89\xD6\xF4\x15\x8B\x03\xFA\xAC\x6E\x00\x80\x26\xF1\x6B\xA1\x28", + 15, 64, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x77\x45\xEA\x51\x24\x46\x53\x19\x6F\xE4\xED\x6B\x54\x5C\x9B\x95\x88\xF5\xD4\x2B\x4C\x3E\xE6\xB7\xA1\xA3\x9F\xC4\x3A\x27\x1E\x45", + 15, 65, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\xFD\x61\x6D\xA6\x8E\xEF\x10\x24\x16\xC7\xBD\x7D\xC8\xCA\xF8\x2B\x3D\x92\x7B\xCB\xDD\x06\x8E\x7C\xCA\xA7\x72\x76\xCE\x6C\x8C\xD4", + 16, 0, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x10\x18\x97\x28\xFB\x05\x1D\xA0\xA8\xD6\x8F\x1C\xAD\x81\xFC\x7C\xA2\x6D\x41\x4B\xAA\x0C\x2A\x95\xB7\xF4\xEF\x9A\x67\xB5\x26\x5F", + 16, 15, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x9E\x3B\x50\xF3\xB5\xF4\xC9\xB3\x57\x03\x74\xF1\xB3\xA0\x4B\x3C\xC1\x71\xB4\x30\x42\xE4\x65\x90\xE5\xE2\x8A\x4D\xBA\xCD\xB1\x9F", + 16, 16, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x69\x70\x88\xAB\x61\x39\x46\xEA\x3B\xEB\x98\x98\x78\xCD\x8E\xF1\xB5\x7E\x81\xFC\x42\x7D\x46\xB8\xDA\x85\xD2\xEB\xB8\x56\xE4\xAC", + 16, 17, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xD2\xDA\xAC\x63\x09\xF1\x81\xBB\xCC\x06\x0D\xCC\xB8\xFA\x67\x08\x14\xD4\x6A\x50\xD7\x4F\xBF\x3B\x4A\x2E\x39\x4D\x45\x55\x27\x2F", + 16, 31, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEB\xB0\xF3\x27\xC3\xC4\x35\x97\x4F\x89\x73\x5A\x4D\xEB\xBB\x4C\x7C\xE9\x0C\x3E\x13\xEB\x07\x83\x74\x67\x0A\x86\xA7\xF4\xA8\x73", + 16, 32, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xC8\x96\xC3\x3A\x26\x77\x02\x84\x5D\x95\x1B\x0D\x9F\x5C\x07\xC5\x6D\x21\x5D\x7E\x20\xF1\x2F\xE0\x45\xE3\x50\x42\x9D\x58\xB0\xEA", + 16, 33, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x8A\x3C\x9F\xA4\xAC\x78\x82\xA7\x08\x76\xB9\xE1\xED\x22\x9B\x43\x45\xF4\xD4\x01\x76\xC4\xED\x5D\xA4\x5A\x41\xDE\x28\xB8\x09\x6C", + 16, 63, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x2D\x0C\x97\xBE\xD2\xF2\x13\x40\xB9\xC8\x15\x91\x6A\x55\x86\x7A\x43\xB1\xFD\xC7\x04\x08\x1B\x58\x37\x09\x12\x80\x40\x99\x7C\xED", + 16, 64, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xF7\xC0\x08\xE1\x31\x52\x9B\x71\x87\x51\xCF\xFF\x8B\x08\xA3\x14\x32\x08\x06\x8C\x22\xAD\x83\x97\x71\x95\xC5\x2C\xFC\x66\xA4\xAD", + 16, 65, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\xD0\xCE\x8E\x8D\xA0\xBA\xA4\x26\x0E\xD3\x1F\xD1\x7B\x78\xE6\x18\x15\xC6\xFF\xD8\x5A\xDB\x41\x8A\xE7\x36\xF0\xE7\xB9\x87\x2B\x6A", + 17, 0, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xCB\xE4\x63\xEB\x6B\x24\x6C\x08\x55\x84\x36\x30\x8E\xFA\xC1\x6B\x97\x43\xD7\x1F\x1F\x3E\x96\xBA\x7E\x87\xF2\x42\x3E\xF5\x69\x5E", + 17, 15, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEF\x39\x55\x9D\x92\x20\xDC\xB6\x8C\x21\x79\xD6\x7C\x51\xB7\x36\xAC\x4E\xFC\xA1\xDE\x66\xC7\xED\x40\xBF\x23\x15\xD1\x25\x82\x4B", + 17, 16, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xE3\x3E\x44\x7B\xA2\x7F\x69\x21\x09\x57\x79\x72\xE7\x4B\xE0\xC7\xCD\x54\xDC\xCD\x55\x60\x75\x61\x82\x66\xD7\x5B\x6F\x60\xDD\x73", + 17, 17, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xA9\xC4\x29\x2F\x5B\x49\x9A\xE0\x71\xE7\xFD\x65\x98\x53\x42\xC0\xC0\xF1\x75\xBC\xB5\x7B\x5C\xA1\x61\xFC\x8B\x45\x44\x54\xEC\x06", + 17, 31, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x29\x60\xBD\x05\x28\xEA\xF1\xA9\x43\xEF\x2D\x87\xC7\xB5\x27\x47\x33\xBA\xC8\x0C\x9F\x1C\xF5\x72\x62\x4C\xA7\x9E\x10\x23\x66\x76", + 17, 32, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xE2\xF1\x33\x23\x9D\xD8\xBC\x60\x1F\xB7\xD8\x21\xF5\x13\x98\xE2\x5C\x24\x0E\xC0\x60\x18\xB4\x0B\x93\xF1\x04\x25\xC5\xEC\x20\x14", + 17, 33, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEB\x4F\x8D\xB3\xF5\x03\x72\x55\x72\xCE\xF3\x91\x22\xCD\xEA\x5A\xC4\x9A\xD0\x42\xE1\xC4\x62\x90\xCE\x11\x9E\xFD\x11\xDB\xCA\x23", + 17, 63, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xB5\x9A\xA7\x74\xDA\xB8\xDE\x5C\xBB\xC3\x5A\xFC\xF0\xD7\xAF\x51\x1E\x0F\x05\x45\xDB\xDA\xB7\xA4\xA6\x52\xB2\x9E\x0E\x23\x14\x3D", + 17, 64, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x69\xA2\x95\x6C\x87\xED\x22\x76\x0A\x53\x75\x6D\x28\xF4\xCD\xC5\xF7\xF9\x88\x51\x73\xA7\xD9\x44\x0C\x96\xB1\x5F\xE5\x57\xFE\xE3", + 17, 65, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\x39\x4A\xB9\x85\xDD\xFF\x59\x59\x84\x5A\xF7\x54\xD6\xFC\x19\xFB\x94\x0E\xAE\xA4\xEA\x70\x54\x3E\x0D\x7E\x9D\xC7\x8A\x22\x77\x3B", + 31, 0, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x1B\x46\x57\xC0\x48\x26\x7B\xC6\x17\xEC\xD5\x76\x89\xEE\x81\xE5\x5B\xE0\xAC\xCE\xB7\x5D\x33\x2A\xAF\xB6\xE2\xF6\xC0\xBB\x93\xE6", + 31, 15, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x53\xB3\x3A\x58\x98\xD2\x0D\x25\x61\x5A\x0C\xF5\x74\x7F\x44\x2F\x51\x70\x31\x66\x5E\x41\x5E\xBC\xF5\xF0\x03\x12\x98\x12\x90\xCC", + 31, 16, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x0B\x2C\x2A\x74\x72\x12\x18\xE1\xCE\xCD\x8A\x7E\xFC\xCE\x8D\x57\xBE\x42\x1A\xCC\xA2\x20\x24\x33\xC5\x1E\x31\x54\x1F\xB6\x45\xBD", + 31, 17, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEF\x13\x95\xD4\x42\xC9\x9A\x04\xFE\xF0\x11\xE9\x72\xA9\x37\x74\x3E\x14\xC4\x4C\x58\x0C\xAC\x81\x4A\x75\x73\x35\x05\xC0\x81\x32", + 31, 31, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x0D\x35\xCF\x7F\x82\x08\x1E\x1B\xE9\x1E\x75\xE1\x96\x05\x9F\xBD\x63\x94\x8E\xE0\x71\xEF\x53\xDE\x79\xC6\x68\x21\xD6\x8A\x5A\xE4", + 31, 32, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x74\x0D\xCB\x50\x59\x59\xB9\x48\x52\x2B\x0B\x2A\x1F\xFC\x4F\x12\xF5\x9F\x49\x11\xED\x43\x61\xA6\x38\x8D\xF9\x35\x5C\xCD\x18\xBB", + 31, 33, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xDD\x48\xE5\xE8\x86\x8E\x61\xFF\x8A\x85\xC6\x5A\xB8\x5A\x32\xD2\x2A\x9C\xA2\xC8\xDC\xB9\xD6\x0A\x44\xD3\xF1\xB4\x8B\x5B\xD3\x80", + 31, 63, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x81\xEF\xAD\x79\x16\xE4\x29\x02\xDB\x89\x8D\xF2\xA4\x6D\xB4\xC4\x2A\x8C\xC6\x7E\xDE\x9B\xF7\x63\xB2\x10\xED\x15\xED\x0A\x0E\x3C", + 31, 64, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEB\x54\xC4\x8A\x8F\x92\x53\x4D\xDF\x1D\x78\xCA\x98\x38\xF9\x10\xE4\x05\xCD\x6D\xB6\x82\x3B\x76\xB7\x82\x3A\xD2\x20\x77\xD4\x89", + 31, 65, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\x18\xE3\xCE\x19\x98\x7B\xA5\x0B\x30\xDD\x14\x4C\x16\xF2\x26\x55\xEB\xA3\x14\x09\xD6\x62\x10\xBC\x38\xBB\xC1\x4B\x5D\xAB\x05\x19", + 32, 0, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x10\x9D\x6C\xB3\x37\x9C\x9E\x2B\xC9\x1C\xF9\x79\x7A\x46\xEA\xFA\x78\x5C\xA1\x54\x83\xBD\xC2\x67\x31\xFA\x66\xAC\x5D\x4C\xE7\xAB", + 32, 15, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x76\x83\x9A\x8F\xBC\x20\x81\xD6\x09\x5C\x97\x46\xD3\xD6\xA4\xC4\xC1\x17\x8E\x3B\x14\xFC\xFD\x8F\x72\x20\xEF\xC6\x0B\xD3\xFF\x42", + 32, 16, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEA\x0C\x05\xE6\x8F\xD6\xA6\xA1\xD9\xFC\xDA\x3C\xCB\x49\x02\xA5\xF9\x5D\x80\x9E\x89\xF6\xA2\x15\x74\x48\x84\x87\x77\x47\x6D\xBB", + 32, 17, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x98\x79\xD8\x91\x48\xB3\x12\x10\xE8\x49\x73\x38\x1B\xFA\x6C\xCA\x85\x59\xF9\xF9\xFE\xD3\xF2\x98\x9E\x9D\x5C\xE8\x1E\x59\xB3\x46", + 32, 31, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xC7\x41\x7E\x23\xDD\x7D\xB0\x84\xCA\x64\x26\x5A\xE0\x98\xD7\xF2\x29\xE4\x4C\x88\xC9\xF9\x15\x00\x19\x73\xC7\xCF\x95\xF5\x30\x68", + 32, 32, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x0F\xDA\x45\x55\xAC\x8F\xB0\x17\x1D\xF2\x41\x54\xFB\x41\x26\x16\x0C\x00\x84\x49\x3D\x54\xAE\x9F\x13\xD4\xE5\x11\x2B\x42\xB5\xF5", + 32, 33, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xF1\x1B\x54\x05\xCE\x3A\xEB\xA1\x1B\x49\x99\x43\xBF\x2C\x73\x10\x0E\x35\x6B\xEA\x40\xAC\xE5\xBC\xD8\xD5\xB0\xAE\xB2\x8E\xFB\x05", + 32, 63, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEA\xAF\xA4\xBE\xD6\x9D\x98\x73\x5E\xDF\xFC\x35\xFD\xB8\x26\x18\xAC\x15\x9E\x2B\xB2\xF9\x36\xEC\x51\x58\x1E\xD8\x53\xB7\x11\x10", + 32, 64, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xC3\x0A\xE0\xAB\xFA\x38\x3C\x3F\xBC\x44\xD3\x2A\x4F\xC8\xFA\x86\xF2\x15\x9E\x83\x75\x65\xE4\x78\x63\xED\xEF\x31\x79\xEC\x00\x21", + 32, 65, 32 + } + }; + + byte digest[BLAKE2s::DIGESTSIZE]; + for (unsigned int i=0; i params(oid); - Integer x("0x 92006A98 8AF96D91 57AADCF8 62716962 7CE2ECC4 C58ECE5C 1A0A8642 11AB764C 04236FA0 160857A7 8E71CCAE 4D79D52E 5A69A457 8AF50658 1F598FA9 B4F7DA68"); - ECGDSA::Signer signer(params, x); - ECGDSA::Verifier verifier(signer); - - Integer e("0x 00000000 00000000 00000000 00000000 68FEAB7D 8BF8A779 4466E447 5959946B 2136C084 A86090CA 8070C980 68B1250D 88213190 6B7E0CB8 475F9054 E9290C2E"); - Integer k("0x 6942B01D 5901BEC1 506BB874 9618E22E C0FCD7F3 5159D51E D53BA77A 78752128 A58232AD 8E0E021A FDE1477F F4C74FDF FE88AE2D 15D89B56 F6D73C03 77631D2B"); + // the condition is written in a way which for non-default digest sizes + // tests the BLAKE2_Base(bool treeMode, unsigned int digestSize) constructor. + // See https://github.com/weidai11/cryptopp/issues/415 + if (tests[i].dlen < BLAKE2s::DIGESTSIZE && tests[i].key == NULLPTR) + { + BLAKE2s blake2s(false, (unsigned int)tests[i].dlen); + blake2s.Update((const byte*)tests[i].message, tests[i].mlen); + blake2s.Final(digest); + } + else + { + BLAKE2s blake2s((const byte*)tests[i].key, tests[i].klen, NULLPTR, 0, NULLPTR, 0, false, (unsigned int)tests[i].dlen); + blake2s.Update((const byte*)tests[i].message, tests[i].mlen); + blake2s.Final(digest); + } + + fail = !!memcmp(digest, tests[i].digest, tests[i].dlen) != 0; + if (fail) + { + std::cout << "FAILED " << "BLAKE2s test set " << i << std::endl; + } - Integer r, s; - signer.RawSign(k, e, r, s); - - Integer rExp("0x 0104918B 2B32B1A5 49BD43C3 0092953B 4164CA01 A1A97B5B 0756EA06 3AC16B41 B88A1BAB 4538CD7D 8466180B 3E3F5C86 46AC4A45 F564E9B6 8FEE72ED 00C7AC48"); - Integer sExp("0x 3D233E9F D9EB152E 889F4F7C F325B464 0894E5EA 44C51443 54305CD4 BF70D234 8257C2DB E06C5544 92CE9FDD 6861A565 77B53E5E E80E6062 31A4CF06 8FA1EC21"); - - fail = (r != rExp) || (s != sExp); pass = pass && !fail; + } - const byte msg[] = "Example of ECGDSA with the hash function SHA-384"; - const size_t len = strlen((char*)msg); - - byte signature[128]; - r.Encode(signature+0, 64); - s.Encode(signature+64, 64); + std::cout << (!pass ? "FAILED " : "passed ") << COUNTOF(tests) << " hashes and keyed hashes" << std::endl; - fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); - pass = pass && !fail; + return pass; +} - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "brainpoolP512r1 using SHA-384\n"; +bool ValidateBLAKE2b() +{ + std::cout << "\nBLAKE2b validation suite running...\n\n"; + bool fail, pass = true; - fail = !SignatureValidate(signer, verifier); + { + fail = strcmp(BLAKE2b::StaticAlgorithmName(), "BLAKE2b") != 0; + std::cout << (fail ? "FAILED " : "passed ") << "algorithm name\n"; pass = pass && !fail; } - // 2.4.1 Examples of ECGDSA over GF(p) with the hash function SHA-512 (p. 38) + const BLAKE2_TestTuples tests[] = { + { + NULLPTR, + NULLPTR, + "\x12\x71\xCF\x25", + 0, 0, 4 + }, + { + NULLPTR, + NULLPTR, + "\xE4\xA6\xA0\x57\x74\x79\xB2\xB4", + 0, 0, 8 + }, + { + NULLPTR, + NULLPTR, + "\xCA\xE6\x69\x41\xD9\xEF\xBD\x40\x4E\x4D\x88\x75\x8E\xA6\x76\x70", + 0, 0, 16 + }, + { + NULLPTR, + NULLPTR, + "\x0E\x57\x51\xC0\x26\xE5\x43\xB2\xE8\xAB\x2E\xB0\x60\x99\xDA\xA1\xD1\xE5\xDF\x47\x77\x8F\x77\x87\xFA\xAB\x45\xCD\xF1\x2F\xE3\xA8", + 0, 0, 32 + }, + { + NULLPTR, + NULLPTR, + "\x78\x6A\x02\xF7\x42\x01\x59\x03\xC6\xC6\xFD\x85\x25\x52\xD2\x72\x91\x2F\x47\x40\xE1\x58\x47\x61\x8A\x86\xE2\x17\xF7\x1F\x54\x19\xD2\x5E\x10\x31\xAF\xEE\x58\x53\x13\x89\x64\x44\x93\x4E\xB0\x4B\x90\x3A\x68\x5B\x14\x48\xB7\x55\xD5\x6F\x70\x1A\xFE\x9B\xE2\xCE", + 0, 0, 64 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x2A\xF7\xA1\x34\x71\x1C\x5A\x03\xCE\xC8\xFC\xA9\x88\xD9\x9C\x8B\x99\x9A\x95\x33\x0D\xC9\x37\xBE\xE3\x3B\xB3\x0B\xAD\x1B\xE3\x7E\x4F\x66\x81\xF1\xE8\x0E\x64\xA1\x9D\xFC\x86\x83\xF1\xFE\x32\x5D\xAA\xDD\xB8\x1B\xA7\xA3\x88\x3F\x71\x1F\x04\x14\x08\x91\x16\x39", + 0, 31, 64 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x49\x9A\x63\x97\x86\x14\xB9\x50\xCC\x1D\xA0\xAB\x63\xAF\x3B\xC3\xFF\xBC\x63\xA2\x91\xE5\x2A\xD7\xA8\x11\xD6\xD4\x23\x32\x52\xCF\xA9\xD6\x5A\x19\x51\xBA\x20\xF1\x74\xEF\x7D\x82\x38\xFB\x85\x20\x82\x16\x0B\xC7\x3C\xD0\xD2\x72\x45\x75\x38\x5C\xE4\x17\xB1\xAA", + 0, 32, 64 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xA5\x5B\x85\xDD\x70\x10\xE5\x04\xD3\xB5\x10\xEF\x08\xE1\x95\x40\x19\x69\x82\x87\x44\xFD\xBF\x5B\xE8\xE2\xBB\xE3\x57\x8F\x24\x0B\xFB\x92\xD1\x50\x98\xAC\x06\xED\xC2\xBB\x93\x04\x54\x84\x35\x23\x83\xA1\xB0\x47\x91\x99\x0C\x4C\xA6\xFD\x73\x8D\xE5\x78\xA5\x5E", + 0, 33, 64 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xB8\xBC\xDA\xB9\x66\xE2\x5A\x76\x72\x38\x55\xD9\x5A\x4E\x8C\x4F\xA9\xEC\x8C\xFF\x0B\x18\x38\x98\x5C\x8C\x90\xBC\x46\x56\x24\xD7\x96\xAB\x26\x2B\x49\x14\xD0\xEE\x91\x69\x9A\x0C\xC3\xE6\xCA\x14\x55\x37\xDA\xF6\x59\x4A\x31\x78\x67\x49\x89\x0E\x84\xDC\xE7\x5D", + 0, 63, 64 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xA1\xD7\x6B\x3B\xB7\xCE\x56\x22\xD1\x13\x94\xDF\xF4\xA2\x04\xEF\x75\x85\xAF\x93\x63\x55\xBF\xCE\xAF\x01\x25\xCA\x17\x65\xC3\xD2\x6E\x67\x71\x95\x33\x18\xE7\xE4\xC1\xFA\xE0\xE6\x24\x8A\xE9\x56\xB7\x63\xE2\xBF\x8F\xB3\xA7\xD4\xD7\xFD\x1A\xC1\xAB\x1F\x17\x77", + 0, 64, 64 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xF3\x26\x82\x25\x97\xE1\x91\x53\xF8\x57\xC6\xD9\x57\x46\x09\xDF\x1E\x05\x81\xF6\x23\xEE\x8B\xBC\xFA\xA1\x9F\x21\xB6\xF3\x1D\xAD\x9F\x4E\x47\x0B\xE6\x3C\x5E\x28\xE9\x11\x1D\xAA\x52\xF2\x6B\x1A\x61\xCF\x61\x1C\xB0\x7D\xE5\x79\x14\x79\x79\xA6\x08\xDF\x76\x4B", + 0, 65, 64 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x6A\x3F\x90\x50\x84\x5D\x84\xB7\xA2\x43\xF3\xEE\x2C\x7A\x10\x50\xC4\x4C\x5E\x39\xF4\xB8\xCC\x1D\xB3\xF1\x39\x82\x77\x22\x10\x92\x36\x21\xA0\xBA\x13\xCC\x4F\xA3\x1C\x4F\xEC\x1A\x15\x29\x20\x20\x3E\x1A\x06\xEA\xF4\xFF\xCB\x44\x72\x52\x3B\xE5\xE0\x08\x79\x92", + 0, 127, 64 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xC2\xB8\x8C\x5F\xBD\x61\x0F\xAB\x04\xD3\x40\xAD\x88\x74\x02\x6B\x27\x33\x5C\x6F\x8C\xE5\x93\xC3\x2F\x1A\xE5\xE8\x42\xA6\x07\xCB\xB7\x73\x88\xF3\xF5\xFF\xDC\xBF\xCC\x87\x8F\x56\x1F\xF2\x30\x37\x02\xBE\xC3\x1D\xA7\x8F\x12\x56\x35\x03\x50\xC6\x1E\xD8\xBD\x84", + 0, 128, 64 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xAD\xE2\x77\xD8\x19\xA7\xBE\xF1\x4E\x47\x92\xDF\x4B\xFD\x1E\x7B\xDE\xC8\x41\x54\x31\xF6\x18\x79\x8B\x7F\x9A\x23\x3C\x6F\xA0\x56\xE6\xB3\x85\xBE\x76\x78\x88\x58\x86\x47\xEB\x48\xC5\x20\x62\xF3\x40\xA5\xB2\xB3\x3F\x33\x18\x3A\x12\xA8\xE9\x9A\x74\x9B\xE8\x8F", + 0, 129, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\x55\xD9\xFB\xF8\x8E\x42\x80\xBF\xE2\x75\xB8\xA7\xA1\xFA\xAD\x7D\xEA\x4B\x65\xB3\xDF\xA2\x92\xE1\xB0\x43\xB6\x36\x74\xB4\xC7\x87\x5D\x68\x02\x21\x39\x49\x0B\x69\x70\xC8\x80\x14\x82\x26\x77\x3D\x2D\x97\xAD\x01\x67\x55\x7D\x54\x62\xA0\x88\x0C\xB3\xFA\x69\x85", + 31, 0, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xBA\xD4\xD2\x86\x9D\x23\x5A\xBD\x76\x77\x0A\xD4\x28\xFD\x31\x8B\x34\xD6\xAA\x7A\x22\xB7\x2E\x8E\x09\x55\x79\xF9\xE9\xB4\x0D\xB7\xA8\x05\x0E\xAB\x17\xD9\xFC\x97\x97\xA0\x61\x40\xC6\x35\x61\xC1\x9A\x91\xF5\x69\x41\xA1\x3D\x3F\xFE\x8B\xEA\xC8\xC4\xE4\xDD\xD7", + 31, 31, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x24\x4C\x4F\xD1\x8D\x4B\xEC\xE4\x7E\x45\x25\x33\x75\xBE\x95\xCB\x5D\x20\xA0\xE7\x62\xB4\x81\x62\x74\x12\xFD\x86\x09\x4A\xBB\x35\x6B\x26\xF8\xE4\x5A\x8F\x38\xD2\xA1\x10\x89\xC1\x93\xDB\xB0\xB2\xA7\xD8\xE0\x83\x3D\xE6\x76\x18\xF6\xFE\x1A\x14\xBC\x9E\x63\xEF", + 31, 32, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x91\x58\xD9\x2B\xF2\x81\x65\xA2\xDE\x73\x9E\x9D\x15\x04\xFB\x9C\x47\x76\x04\xA3\x51\xE6\x84\xEF\x1C\xF0\xF5\xF1\x1B\x5F\xE5\x78\x39\x3D\x23\xCA\x3C\x95\xAB\xB1\xD7\xC1\xE9\x10\x4A\x6C\x51\x46\x6C\x19\x02\x48\x75\xD5\x23\x76\xCF\xCC\x64\x02\x15\xC2\xCF\xD6", + 31, 33, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEA\xFA\xD7\x50\xFD\x93\x65\xB6\xA7\x29\x75\x07\x17\x80\xF7\xE2\xE2\xF9\x60\xF3\x9C\x9F\x06\xFC\x13\x16\x79\x66\x7A\x3A\x92\xE2\x75\x79\x71\x89\x34\x5C\x6F\x85\x76\x31\xCF\x7A\x76\xB4\x52\xF5\xDC\xC7\x39\x2A\x39\x1A\x26\xD6\x74\xEA\xF4\xC7\x44\x53\xF6\x43", + 31, 63, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x5C\x55\x87\x5A\xCA\xF3\x78\x11\x33\x91\x5C\x40\x3C\xE8\xDB\x74\xEA\x68\x4D\x76\x44\x91\x6A\x03\x72\xF7\xAA\x0B\x09\x0A\xAD\xC1\x14\xDF\xC0\x52\x83\x0C\x5A\x75\x2B\x25\x0D\x6F\x7F\x94\xBE\x48\x93\xA2\x19\xED\x2E\x4C\x4C\x47\xA3\xF4\xD0\xBD\x9D\x51\x4A\xDA", + 31, 64, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xA2\x3C\xB9\x96\xBC\x40\x61\x12\xF7\x5A\xE7\xBE\x2F\x04\xBB\xCF\x4F\x6D\x65\x65\xF8\x65\xA6\xF6\x88\x5D\x56\x57\x79\xA3\x11\x33\x37\xD1\x72\x84\xEE\x75\x56\x4E\x00\x52\xF1\x88\x07\xC6\xD6\x4D\xFB\x55\xF0\x25\x39\x70\x51\x35\x1A\x73\x85\x6D\x6B\x26\x7A\x79", + 31, 65, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x22\xEA\xC1\x75\x7B\xBF\x13\xA1\x91\x8B\x46\x89\x2A\xEC\xEB\x07\x6F\x3F\xF4\x70\x68\x8F\xD3\x6D\xE5\x5B\xB9\x03\x69\x38\xF3\x11\x2E\x1E\x6E\x24\xD9\x60\xB7\x4E\xB1\xD4\x67\x38\xBD\x1B\x45\x7C\xF9\x29\xFC\xBB\x4C\x23\x78\xE3\xE5\xFE\x4A\x2D\xED\xDA\x29\x05", + 31, 127, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x9C\xAE\xD2\x2D\x53\x1B\x52\x07\x39\x4F\xE4\x9F\xE4\x8D\x55\x2C\xC6\x00\x6D\x61\xA5\x83\xA5\xE7\x10\x3B\x34\xFD\x24\xBD\x4E\xE1\xD0\xC2\x02\x8A\xE2\x86\x57\xF3\xAC\x31\xBD\x51\xDE\xEB\x54\xFD\xEB\x84\x80\x2C\x79\x16\x28\x98\x1E\x3C\x83\x87\xDE\x14\x83\x34", + 31, 128, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xF3\x73\x96\x41\x7B\xEF\x67\xF3\x97\xF5\xCD\x8D\xFD\x79\xAA\xBC\xC7\x95\x70\x48\xC8\xC3\x89\xFE\xEC\x7B\xDB\x23\x43\x1E\xFA\x85\x51\x75\x4E\x04\xB3\xF3\xCB\xA6\x46\x58\x2A\x3E\x22\xBE\xFF\x85\x12\xC9\x2B\xE7\xA7\x93\x78\x47\xF5\xFD\xB8\x43\xAF\xBD\x11\x9A", + 31, 129, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\x0C\xAB\xE4\x02\x57\xEB\xAC\x85\xBC\xD6\x13\xBD\x40\x56\x58\xEC\x0B\x7F\x32\xB4\xDB\xBE\x6A\x31\x57\x60\x25\xC4\xFA\xBB\x3E\xDB\x55\x63\xE8\xD1\x27\x19\xB9\xEE\x9C\x7B\xE0\x0D\x8F\x09\xA4\x66\x5C\x32\x34\x34\xC8\x7F\x66\x00\xB7\x0B\x7B\x9C\x32\x74\xFC\x40", + 32, 0, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xA8\x09\x82\xFC\x9A\x5B\xC7\xC5\xF0\x37\x26\x7B\x86\x5D\x35\xA2\x2E\x4D\x79\xCE\xBE\x99\x56\xD6\x56\xBB\xCA\x48\x4C\xFB\x47\xD9\xF4\xBE\xA2\x7A\x3A\xA3\xA7\x91\x34\x8B\x23\xB4\x84\xD1\x66\x8A\xBC\x0F\x4E\xE4\xF1\x70\x8E\xFB\x1A\x95\x12\x2B\x2F\xFF\x49\x87", + 32, 31, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xE0\xD6\xF6\x98\xC1\x50\xBB\xBF\xC1\x65\x47\x20\xC3\x2A\xD6\xE4\x1E\x3B\x31\xC0\xBA\xCF\x7C\xF8\xF8\xA5\xDB\x17\xCF\x4B\x84\x98\x02\x2D\x23\xF6\x18\x78\x8E\x10\xE2\xD3\x53\x5D\x43\x37\x8E\x3F\x9D\x68\xD2\x99\xBB\xC8\x04\xA7\xF4\xCA\xD2\x5C\x0C\x99\xA8\xF4", + 32, 32, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x43\x62\x70\x1E\xFE\x4C\x12\x39\x03\x01\x04\xA8\x5E\xB5\x55\xE6\xE9\xE5\x55\x6A\xCE\x80\x18\x1D\x81\xA6\xBA\x87\x92\xAB\xFC\x0C\x54\x83\x09\xD2\x45\xFD\xA6\xBC\x1A\x7E\x79\x45\x74\x06\xCC\x77\x3D\x18\x77\x8C\x0D\x38\x03\xC2\x76\x2B\x91\x6F\xF7\xE8\xCA\x61", + 32, 33, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x08\x1C\xBA\x80\x31\x39\xDF\x39\x37\xBE\x58\xB7\x22\xB3\x3E\x17\x9D\xBF\xE3\xCC\x02\x3C\x60\x2B\x1A\xB8\xEF\x77\x40\x32\x5A\x23\x8F\x48\x3F\x48\x64\x5E\x35\xA6\xBE\xB5\xBE\x1E\x3C\x35\x19\x15\xDE\x87\x41\xFF\xBB\xC4\x65\xB0\xDD\x4A\x5A\x88\x96\x47\xF5\x48", + 32, 63, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xA5\x35\x83\xFB\x6B\x15\x35\x70\x70\x23\x1A\x21\xC3\xBC\x97\x6C\x9C\x59\xDA\x51\xE4\xC4\x11\xDE\x3F\x04\x4E\x0F\x11\x8B\x9F\x1D\xA5\x26\x12\xBC\x2C\x54\x03\x67\x03\x0D\xD5\xB3\xFB\x34\x67\xE7\x02\xC6\x6F\xD9\x31\x1E\xA6\x5C\xBC\xA3\xFE\x86\x2D\x12\x45\xD7", + 32, 64, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xD9\x1C\xA9\xC0\xE9\x06\xEF\x1E\xDE\xD4\x84\x42\x89\xCD\x7A\xFF\x96\x92\x3E\x43\xAE\xAC\xC6\xDA\xD5\x2E\x55\x3E\x9A\xAA\x10\x86\x2E\xE9\xE4\xEF\x56\xDF\x9D\xD2\x70\x84\x5A\xF7\xD7\xD6\x58\x99\xE9\x01\xCC\x70\xBE\x98\xE0\x20\x3E\xCB\xCB\xCD\x4A\xD0\xA7\x81", + 32, 65, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xC5\x0E\x8C\x76\x05\x2D\xA7\x43\x90\x73\x8D\x38\xB0\x6C\x9D\x83\x2C\x14\xB1\x2C\x61\x42\x19\xC9\x82\xC5\x90\xB6\xB6\xCE\x78\xFD\x73\x9A\x2A\x79\x27\xA6\xBA\xAF\xEF\xCE\x68\x1D\x00\x53\x49\x2E\x89\x1E\x4C\x13\x12\x77\x9A\x78\xA5\x0F\x2A\xE7\x73\x78\xE2\x0A", + 32, 127, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x17\xB1\x1E\x2B\xB1\xDF\x49\xFA\x9A\xD0\xD1\x6E\x79\x33\x2A\x62\xA2\x11\x3B\x5E\xE0\xEF\xA2\x49\x44\x6C\x70\xD2\x69\x69\x7F\x69\xC3\xB4\x0B\x21\x1E\x76\x43\x58\x81\x8E\xA1\x2F\x73\x75\xDB\xC3\x22\xF3\x9C\xB7\x03\x56\x49\x8C\xDE\x60\x5A\xB7\x52\x7A\xA1\x53", + 32, 128, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xE4\xF6\xE4\x01\x8A\xA6\xD0\x8D\xCF\x81\x1D\x38\x60\x5C\xB6\xF5\x83\xAA\xB2\x1F\xC0\xC8\x77\xA5\xA4\x77\xE0\x65\x55\xB7\x34\xFC\x7C\x40\x53\x6A\xEC\x32\x7D\x2A\xA3\xE8\xD0\x31\x91\xA8\x15\x11\x58\xE8\x51\xF7\xA0\xDB\xCA\x8A\x71\x6D\x5B\x19\x7B\x78\xDA\xF7", + 32, 129, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\x0D\x19\x8F\xB3\x01\xE3\x83\x7D\xF1\xB9\x98\xEE\x48\x47\xF5\x1D\x91\x01\xEB\x91\x4A\x85\xFA\x6A\x7E\xBA\x7C\xDB\x12\x69\x45\xD7\x15\x6F\xF2\xF5\x05\x81\x27\xA0\x4A\xE4\xE8\xCF\x43\xD8\x76\x8A\x64\xFE\x9D\x97\x61\xE1\x0B\xC1\xBE\x45\xF9\xFA\x1C\xEB\x4B\xB6", + 33, 0, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x0E\xC6\xDC\x77\xF3\x78\x55\xDE\xF9\x10\x48\x37\x28\xC6\xC1\x93\x0D\x65\x6B\x51\x20\x78\x48\x90\x10\x01\x1B\x9D\xFC\xDB\xB2\x6E\x6D\xD9\xAC\xF5\x1A\xBE\xEF\xBF\xAF\x46\x99\x61\x65\x53\x50\xA6\x08\x09\x90\x8E\x77\x36\x33\x80\xC1\xD7\x7E\xD2\x59\x8A\xA9\x51", + 33, 31, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x44\x66\x17\xF1\x0A\xDD\x2A\xCC\x5C\x23\xAF\x6D\x1B\xF8\xE6\x99\x6B\x69\x41\x82\xFD\x7D\x1D\xBD\x83\x44\xF7\x80\x1D\x96\x8F\xF6\xB5\x4A\xA2\x60\x72\x06\x7D\x06\xA6\x11\x87\x44\x27\xAF\x2D\x04\xA7\x8E\xF0\x90\x72\x7F\xED\x05\x90\x36\x27\xD9\x37\xBF\xDF\x9B", + 33, 32, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xA8\xAE\x4B\x1B\x9C\x20\x5F\xF3\xE8\xBC\xA5\xD0\x8B\xB0\x10\x1F\xB9\xFB\x10\xB5\x29\xB2\xA0\x72\x43\xD8\x75\x08\xF5\x65\x3C\xA8\xB2\x93\x92\x2F\x85\xB2\xE6\xC2\xAF\x72\x30\xDF\x50\x5F\x1F\x60\xFD\x4A\xC5\x02\x4D\xDF\x01\xBD\x83\x4F\xC7\x9A\x9E\x15\xAA\x8B", + 33, 33, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x88\x18\xC9\xDB\x3A\xD3\x29\x7F\xC3\xC0\x6A\x27\x62\x50\x06\x72\x74\x7D\x60\xAF\x53\xA8\xB0\x4D\xF2\xE2\x9E\x50\xF8\xE8\xFD\x93\x21\x11\x4D\x69\x42\xA0\xD8\x60\xFA\xDD\xEE\x95\x59\xED\x51\x5B\x29\xA9\x19\x4B\xE5\xE5\x5B\x88\x63\x06\x05\xBF\x6E\x57\x3E\xE2", + 33, 63, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x35\xEC\xD6\x75\x45\x34\xAD\x71\x93\x99\xE8\xC0\xB0\x2F\x0D\xE2\x79\xB1\x7A\x5E\xA3\x54\x59\x3F\x1B\x73\x92\xC4\xAD\x18\xEE\x56\xE1\xE6\x76\x6D\x7B\xCC\x62\xE8\x9C\x38\x56\x7B\xC4\x0A\xE4\x89\x7C\x66\x84\x8C\xB3\x99\xDE\x2E\x60\xDD\x48\xA0\x08\x0A\xDE\xA0", + 33, 64, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xBA\x5D\xDD\x7B\xE8\x47\xB7\x2D\x90\x17\x52\x66\xDD\x17\x54\xFC\x69\x59\x9D\x43\x1B\x3C\x6D\xE8\x08\x3B\xB2\xEA\xA5\x8C\xDE\xE9\x71\x69\xF5\x62\x22\x14\x67\xC9\xAC\xC2\xB7\xEA\xEA\xAF\x10\x17\xDA\xD8\x52\xFA\x45\x65\x9F\x5E\xAE\x38\xB7\xCF\x01\xD2\x66\x53", + 33, 65, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x9B\x61\x94\x75\x04\x23\x28\xED\xAF\x0C\x9B\x50\x58\xEB\x5F\xD0\x8F\x78\x16\xA7\x81\xA6\x29\xA1\xEC\x50\xA7\xE6\x41\x53\xE2\x3B\x38\x84\x28\x4C\xE7\x33\x25\xA5\xF2\xB4\xEB\x0C\x7A\x40\xEA\xA0\x39\x54\x76\x7D\x94\xDA\xE7\x2B\x67\x68\x60\xF1\xD2\x8A\x05\xA5", + 33, 127, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x9C\x18\x11\x0D\x2C\x8D\xE4\x07\x0D\x7F\x99\xB5\x0F\x88\x55\x7C\xBB\xB8\x4C\x8D\xE3\x42\x04\x32\x2C\xF0\x77\x79\xBE\x35\xE2\xEA\x0B\x4B\xA1\x44\x69\xDA\xA6\xFB\xBD\x40\xD6\x66\x5A\x99\x4E\x9E\x7B\x32\x20\xB8\xC7\x34\x3F\xCA\x66\x5C\x86\x2A\x60\x1A\x69\x74", + 33, 128, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xCB\xEC\x77\x51\x9F\xD7\xAC\x67\xEE\xB7\x8D\xAC\xB8\x1E\xE2\x8D\x3E\x17\x61\x29\xC0\x39\xF5\xDD\xB4\x5A\xC6\x8A\xBB\x40\x55\x81\x03\x7E\x58\x43\x9E\xDD\x36\x08\x04\x96\xCD\xC1\x95\xCF\xF1\x71\x20\x81\x66\x10\x89\xE3\x88\x22\xB8\x5E\x65\xA4\xC8\x8E\xAA\x2A", + 33, 129, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\x31\xD7\x85\x5E\xBC\xAA\x40\xE2\xEF\xA6\xD4\x35\xC7\x9E\x37\x1E\x80\xBD\x1E\x37\x72\xE6\xEF\xD6\xB1\x41\x1A\xE5\xF8\xB2\x92\x1A\xE0\xAD\x11\xBF\xF0\x57\xD5\x9A\xF8\xC4\x4C\x11\x88\x64\xDA\x88\x45\x3C\xCC\xF7\xCB\x44\x9E\x34\x23\xA3\x9D\x6D\x11\x98\x0B\xAC", + 63, 0, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x3E\x7E\xA0\x5E\x1B\x64\x0D\x9F\x5B\xDA\xF9\xB8\x56\x4E\x2D\xEC\x99\x5E\xDC\xF3\xAF\x26\xE1\x19\x4E\x1B\xC2\xA6\xDA\x2D\x41\x8A\xDD\xC2\x12\xA6\x54\x6C\x90\x98\x74\x27\x29\xF6\x2D\x94\x55\xA6\x92\x95\x4C\x8E\xD3\x23\x72\x06\xEF\x92\x38\x99\xA6\x9E\xE2\x14", + 63, 31, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x79\xA5\x33\xEA\x9A\xBC\xBF\xB9\x48\x23\xDF\x8F\x27\x7E\x96\x4A\xB9\x2D\xA7\x3D\xEE\x9E\xBE\x97\x5E\x1B\xC1\x4A\xD0\x19\xF8\xF8\xF4\x6D\x0C\x59\x94\xB3\x6C\x2E\xCA\x18\xD7\xEF\x20\x98\x21\x77\x7E\x07\xEB\x4F\x51\x0C\x82\xCE\xD3\x3F\x48\x82\xBC\x98\x3C\xBA", + 63, 32, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xF8\x34\x86\xBD\x50\xEC\xB7\x32\x3A\xCC\x9A\x93\x6B\xA6\x45\x3D\xD5\x77\x42\xC7\x88\xC1\x34\xEB\x17\xE4\x0C\x41\xB0\xDD\x4F\xC9\x83\x29\x38\x26\x64\x1C\x21\xC9\xD1\x8A\xA5\xFC\x9F\x64\x5E\xE8\x11\x17\x41\x0C\xE6\xEB\x8C\x73\x93\xF6\xB2\xEB\xEF\xC7\xB8\xBE", + 63, 33, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x9B\xDF\x77\xB9\xC0\x1F\xC9\xC5\xAA\x6B\x52\x8B\x30\x77\xE5\x1C\xD0\x09\x79\x44\x45\x6D\xB6\x1A\xFF\x1B\xEE\x54\xD1\xE9\x8D\x84\xB9\x53\x5F\x50\x50\x75\x58\x69\x7C\x5C\xEE\x86\xCC\x19\x4D\x3D\x8A\x4F\xCD\x93\x48\xEF\xAE\xBF\x95\x12\x72\x88\x45\xCB\x00\xD3", + 63, 63, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x79\x8A\xB1\xD6\x8A\x88\x62\x00\xF4\x20\xA6\xC6\x5D\x63\x7D\x2D\xEB\x91\xB9\xDA\x63\xA9\xFF\xC4\x6A\x49\x19\x30\x73\xE2\xDE\x95\x7B\x9A\xEE\x23\xAE\x58\xD9\x58\x91\xFE\x43\x9D\x82\x0B\x95\x50\xE1\x58\x1D\xA6\x93\x70\x84\x4A\x70\xE5\xC2\xED\x28\x39\x5C\x29", + 63, 64, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xD2\x0E\x26\xF0\xDE\xB8\x75\xEF\xD0\xB9\xD3\x29\x2D\x1F\x94\x46\x62\xB5\x9A\x55\xFB\xAB\x4C\x13\xFF\xB9\x62\x82\x90\x93\x04\xE6\x8B\xA5\x32\x9A\x50\xB9\x2D\xAE\x79\x6B\xC3\xE1\x3E\x58\xE1\x5F\xAB\x9B\xA7\x07\x95\x52\x8B\x60\x5C\x64\x0C\xEB\x15\x93\x16\x2A", + 63, 65, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x60\x41\x21\xAA\x32\x6A\x49\x68\xDF\xBA\xAE\x5A\xF2\x43\xE6\xA6\x7B\xB7\x4A\x4C\x0D\xD6\xE7\x32\x71\x1E\x24\xCC\x14\xD0\x5F\x5A\x94\x0A\x21\x4F\xBB\x68\xA1\x43\x78\xC8\x71\x8C\x5C\x4E\xB8\x19\x91\xA6\x5B\x1E\x59\x87\x86\xB7\x6F\x5D\xB8\xCB\xF2\xEC\x7C\x50", + 63, 127, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x5A\xC4\xD5\xD9\xA5\x67\x38\x66\x0B\x18\x67\xF7\xD8\xD3\x4E\x82\x6C\xFA\xC1\x91\x40\x73\x60\xE7\xCA\x0E\x71\x7D\x30\xC8\x55\x88\x25\x83\xCF\xB2\x55\xCA\x9B\xE9\x61\x53\x73\xCF\xB1\xB8\x40\x3F\xC1\x37\xB2\x20\xEB\x4F\x03\xC5\x15\x48\x94\xE6\xAE\xDB\xA4\x60", + 63, 128, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x0A\x3E\x43\x52\x9D\x71\xDA\x38\x49\xBC\x64\x93\xA9\x43\x78\x1E\xB2\x5B\x79\xE9\xF5\x3F\x1A\xFE\xEB\x41\xBE\x41\x33\xDA\x6B\x31\x2E\xC5\xBD\xD6\xC2\x96\xE2\x4C\xA1\x2C\x05\xA8\x52\x86\x4C\x8F\xEE\x73\x6F\x71\x71\x6D\x5B\x60\xE1\x1C\xAC\x7D\x2F\xC6\x23\x55", + 63, 129, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\xD9\x38\xD6\xD9\x8F\x0B\xD9\x87\x39\xA6\x59\x19\xD2\xB3\xC9\x14\x9A\x4F\xCE\x6C\x98\xB0\x6A\xF4\xF9\x58\x58\x31\x35\x0B\x57\x47\xC2\xF6\xA7\x82\xA3\x39\x61\xA8\x1B\x62\x59\x7A\x2E\xB1\xE9\xC0\xA5\x80\x3D\xA7\xC5\xD3\x93\x4B\xB2\x0A\x6E\x88\xBA\xA4\xAE\x02", + 64, 0, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xE9\x47\xAF\x37\x5E\x3D\xBF\x30\x27\x8E\x29\xE6\x39\x0A\x48\x77\x3F\xB0\x0E\x80\x86\xDF\x3B\x98\x8A\x11\x97\xA7\x3C\xBE\x9C\x4A\x23\xAC\x25\x28\xF5\xD0\x9F\xBA\xFC\xDE\xCD\x88\x85\x30\x00\x00\xA3\xC2\x51\xCF\x9A\x41\x88\x00\x02\xA6\xB5\x46\xD2\x58\xB1\xB6", + 64, 31, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x64\x24\x6B\xA8\x6C\x93\x07\xE2\x62\xC2\x35\xD6\xD9\xA7\xD1\xCD\xFA\xCE\x0A\x12\xB0\x5E\x57\x1C\xBC\x61\xDF\xFB\x59\x6C\x95\xAD\x04\xEF\x02\xCD\x89\xDD\x39\x80\x7D\x78\x3E\x55\x32\x3C\x53\x32\xF3\x91\xFE\x16\x0C\xF9\xF4\x41\xBB\x9E\xF7\xBA\xE6\x0A\xB7\x6F", + 64, 32, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xB0\x09\xE7\x5A\xBA\x9F\xED\xBE\x3C\xA4\x6A\x93\xF8\x9A\x79\x3A\x01\x8F\x06\xC6\x4A\xA6\xED\xC5\xDD\x21\xDF\x3C\x87\xD4\xBD\xC1\x0E\x29\x3E\x3F\x3B\x6A\x16\x7B\x41\xB8\xB7\x79\xC9\xB2\x16\xD0\xC2\xC2\xF8\xA7\x68\x9B\xB2\x93\x2B\x0A\x43\x58\xC0\x76\xE0\x40", + 64, 33, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x62\x47\x33\xE4\x70\xCC\xBE\x7A\x64\xE1\xBC\xF4\x37\x0E\x61\x92\xCC\x78\xA0\x1B\x26\x11\x39\x82\x36\x29\x76\xFA\x0A\x2A\x99\x52\xE5\xDC\x08\xB5\xFF\xBC\xEA\x5F\xE7\xDD\x48\xF7\x77\x36\x49\x58\x46\xA3\x53\x38\xCB\xFD\x96\x39\x2C\xDB\x01\x94\x4E\x8D\xCC\xD9", + 64, 63, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x76\x31\x38\x1F\x2B\x49\xCF\x26\xCA\x9B\xD9\x8F\x48\x09\x67\x50\x6F\x0E\xC3\x26\xC3\x44\x05\xC1\xE5\x8F\x58\x20\x80\xE0\x2F\x47\xAE\xC9\xF4\x5C\x8C\x48\x41\xA5\xF8\xBA\xD3\x24\x60\x64\xBE\x6C\x23\x15\xC8\x36\xC1\x91\xE4\x4A\x76\x8F\x2A\x8D\xBC\x22\x42\x14", + 64, 64, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x97\x13\x7E\x8C\x18\x22\x5B\x6B\xBC\x61\xF3\x9A\xB4\x10\x77\x91\x43\x80\x05\x9D\x13\x1D\xDC\xA7\x95\x1B\x41\x95\x4D\x49\x6A\xFF\x51\xE1\x03\x87\xCF\x61\x86\x21\x64\x7F\xD6\x4D\x4C\x5A\x49\xC5\xC7\x47\x18\x6F\xDB\x87\xBA\x22\xD3\x4C\xB3\x85\x76\x01\x64\x9D", + 64, 65, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xB9\x5F\x66\xD3\x80\xDC\x88\xBF\x0F\x75\xB8\xA7\x0F\x93\xAB\xBB\x46\x34\x8C\x38\xD0\x71\x1F\x83\xAC\x80\x4A\x2C\x68\xFD\xCD\x3C\x82\x31\x83\x3B\x25\xE0\xC4\x5C\xCF\xD7\x4A\x33\x9D\x27\x2E\xC0\x2F\x44\x39\x7C\x9F\xBA\x54\x07\x0B\xA3\x5C\x71\x39\xA0\x9A\x11", + 64, 127, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x59\xB3\xCE\x2E\x95\xDB\x70\x0A\xA7\x34\xC1\x50\x70\xCA\x57\xDE\x3C\x37\x6C\xB7\x22\xF8\x99\x60\x6E\xE4\x0E\x67\xBF\x7C\x10\xC6\x7C\x16\xDE\x7A\xEF\x06\x02\x13\x3E\x57\x75\xE3\x9A\x4D\x88\xAE\x1C\x32\x07\xEC\x57\x77\x11\x53\x47\x07\x79\x9C\xA8\x60\x30\x96", + 64, 128, 64 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x43\x06\xF9\x3E\x7C\xFB\xDE\x72\x5F\x83\x3E\x39\xCD\x07\x57\x89\x9B\xCD\x81\x0F\x83\x51\x56\x18\x19\xB4\x6F\xFD\xA4\x61\x86\x2E\x68\x9C\x55\x5A\xF4\xBC\x88\x46\x04\x5C\xDD\x27\xC6\xE0\x0C\x81\x07\x7C\xC5\x90\x0B\x25\x2D\xF1\xD1\x40\x01\xD8\x39\x69\x3C\x2E", + 64, 129, 64 + } + }; + + byte digest[BLAKE2b::DIGESTSIZE]; + for (unsigned int i=0; i params(oid); - Integer x("0x 92006A98 8AF96D91 57AADCF8 62716962 7CE2ECC4 C58ECE5C 1A0A8642 11AB764C 04236FA0 160857A7 8E71CCAE 4D79D52E 5A69A457 8AF50658 1F598FA9 B4F7DA68"); - ECGDSA::Signer signer(params, x); - ECGDSA::Verifier verifier(signer); - - Integer e("0x 1A95EF81 D213BD3B 8191E7FE 7F5BFD43 F51E3EE5 A4FD3D08 4A7C9BB5 411F4649 746AEBC6 623D4DEA 7E02DC5A 85E24AF2 96B5A555 AD470413 71E4BF64 380F3E34"); - Integer k("0x 6942B01D 5901BEC1 506BB874 9618E22E C0FCD7F3 5159D51E D53BA77A 78752128 A58232AD 8E0E021A FDE1477F F4C74FDF FE88AE2D 15D89B56 F6D73C03 77631D2B"); + // the condition is written in a way which for non-default digest sizes + // tests the BLAKE2_Base(bool treeMode, unsigned int digestSize) constructor. + // See https://github.com/weidai11/cryptopp/issues/415 + if (tests[i].dlen < BLAKE2b::DIGESTSIZE && tests[i].key == NULLPTR) + { + BLAKE2b blake2b(false, (unsigned int)tests[i].dlen); + blake2b.Update((const byte*)tests[i].message, tests[i].mlen); + blake2b.Final(digest); + } + else + { + BLAKE2b blake2b((const byte*)tests[i].key, tests[i].klen, NULLPTR, 0, NULLPTR, 0, false, (unsigned int)tests[i].dlen); + blake2b.Update((const byte*)tests[i].message, tests[i].mlen); + blake2b.Final(digest); + } + + fail = !!memcmp(digest, tests[i].digest, tests[i].dlen) != 0; + if (fail) + { + std::cout << "FAILED " << "BLAKE2b test set " << i << std::endl; + } - Integer r, s; - signer.RawSign(k, e, r, s); - - Integer rExp("0x 0104918B 2B32B1A5 49BD43C3 0092953B 4164CA01 A1A97B5B 0756EA06 3AC16B41 B88A1BAB 4538CD7D 8466180B 3E3F5C86 46AC4A45 F564E9B6 8FEE72ED 00C7AC48"); - Integer sExp("0x 17A011F8 DD7B5665 2B27AA6D 6E7BDF3C 7C23B5FA 32910FBA A107E627 0E1CA8A7 A263F661 8E6098A0 D6CD6BA1 C03544C5 425875EC B3418AF5 A3EE3F32 143E48D2"); - - fail = (r != rExp) || (s != sExp); - pass = pass && !fail; - - const byte msg[] = "Example of ECGDSA with the hash function SHA-512"; - const size_t len = strlen((char*)msg); - - byte signature[128]; - r.Encode(signature+0, 64); - s.Encode(signature+64, 64); - - fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); - pass = pass && !fail; - - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "brainpoolP512r1 using SHA-512\n"; - - fail = !SignatureValidate(signer, verifier); pass = pass && !fail; } + std::cout << (!pass ? "FAILED " : "passed ") << COUNTOF(tests) << " hashes and keyed hashes" << std::endl; + return pass; } -bool ValidateESIGN() +bool ValidateSM3() { - std::cout << "\nESIGN validation suite running...\n\n"; - - bool pass = true, fail; - - static const char plain[] = "test"; - static const byte signature[] = - "\xA3\xE3\x20\x65\xDE\xDA\xE7\xEC\x05\xC1\xBF\xCD\x25\x79\x7D\x99\xCD\xD5\x73\x9D\x9D\xF3\xA4\xAA\x9A\xA4\x5A\xC8\x23\x3D\x0D\x37" - "\xFE\xBC\x76\x3F\xF1\x84\xF6\x59\x14\x91\x4F\x0C\x34\x1B\xAE\x9A\x5C\x2E\x2E\x38\x08\x78\x77\xCB\xDC\x3C\x7E\xA0\x34\x44\x5B\x0F" - "\x67\xD9\x35\x2A\x79\x47\x1A\x52\x37\x71\xDB\x12\x67\xC1\xB6\xC6\x66\x73\xB3\x40\x2E\xD6\xF2\x1A\x84\x0A\xB6\x7B\x0F\xEB\x8B\x88" - "\xAB\x33\xDD\xE4\x83\x21\x90\x63\x2D\x51\x2A\xB1\x6F\xAB\xA7\x5C\xFD\x77\x99\xF2\xE1\xEF\x67\x1A\x74\x02\x37\x0E\xED\x0A\x06\xAD" - "\xF4\x15\x65\xB8\xE1\xD1\x45\xAE\x39\x19\xB4\xFF\x5D\xF1\x45\x7B\xE0\xFE\x72\xED\x11\x92\x8F\x61\x41\x4F\x02\x00\xF2\x76\x6F\x7C" - "\x79\xA2\xE5\x52\x20\x5D\x97\x5E\xFE\x39\xAE\x21\x10\xFB\x35\xF4\x80\x81\x41\x13\xDD\xE8\x5F\xCA\x1E\x4F\xF8\x9B\xB2\x68\xFB\x28"; - - FileSource keys(CRYPTOPP_DATA_DIR "TestData/esig1536.dat", true, new HexDecoder); - ESIGN::Signer signer(keys); - ESIGN::Verifier verifier(signer); - - fail = !SignatureValidate(signer, verifier); - pass = pass && !fail; - - fail = !verifier.VerifyMessage((byte *)plain, strlen(plain), signature, verifier.SignatureLength()); - pass = pass && !fail; - - std::cout << (fail ? "FAILED " : "passed "); - std::cout << "verification check against test vector\n"; - - std::cout << "Generating signature key from seed..." << std::endl; - signer.AccessKey().GenerateRandom(GlobalRNG(), MakeParameters("Seed", ConstByteArrayParameter((const byte *)"test", 4))("KeySize", 3*512)); - verifier = signer; - - fail = !SignatureValidate(signer, verifier); - pass = pass && !fail; - - return pass; + return RunTestDataFile(CRYPTOPP_DATA_DIR "TestVectors/sm3.txt"); } NAMESPACE_END // Test -- cgit v1.2.1