cout << "Hello World!" << endl; // 张鲁夺 :: 个人博客,幸福着你的幸福!


基于SHA3的HMAC算法实现

作者:鲁夺,2016年5月29日,原创文章,转载请注明出处!

原文:http://zhangluduo.com/article/3a601d71/


HMAC算法定 义如下:
This definition is taken from RFC 2104:

where
H is a cryptographic hash function,
K is the secret key,
m is the message to be authenticated,
K’ is another secret key, derived from the original key K (by padding K to the right with extra zeroes to the input block size of the hash function, or by hashing K if it is longer than that block size),
|| denotes concatenation,
⊕ denotes exclusive or (XOR),
opad is the outer padding (0x5c5c5c…5c5c, one-block-long hexadecimal constant), and ipad is the inner padding (0×363636…3636, one-block-long hexadecimal constant).

// (关于SHA3: http://baike.baidu.com/view/9418874.htm)
// https://en.wikipedia.org/wiki/Hash-based_message_authentication_code
// 在最新的CryptoPP_5.6.2算法库中已实现了SHA3-224,SHA3-256,SHA3-384,SHA3-512.
// 由于继承关系,这些类不能使用HAMC模板直接实例化,若是想实现HMAC运算只好自已动手了。
// 以下程序的实现标准基于RFC 2104, 以下test vectors来自于一个国外的网站
//
// http://www.di-mgt.com.au/hmac_sha3_testvectors.html
//
// Key=0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
// Data="Hi There"
// HMAC-SHA-3-224=b73d595a2ba9af815e9f2b4e53e78581ebd34a80b3bbaac4e702c4cc
// HMAC-SHA-3-256=9663d10c73ee294054dc9faf95647cb99731d12210ff7075fb3d3395abfb9821
// HMAC-SHA-3-384=892dfdf5d51e4679bf320cd16d4c9dc6f749744608e003add7fba894acff87361efa4e5799be06b6461f43b60ae97048
// HMAC-SHA-3-512=8852c63be8cfc21541a4ee5e5a9a852fc2f7a9adec2ff3a13718ab4ed81aaea0b87b7eb397323548e261a64e7fc75198f6663a11b22cd957f7c8ec858a1c7755
//
//
// Key="Jefe"
// Data= "what do ya want for nothing?"
// HMAC-SHA-3-224=e824fec96c074f22f99235bb942da1982664ab692ca8501053cbd414
// HMAC-SHA-3-256=aa9aed448c7abc8b5e326ffa6a01cdedf7b4b831881468c044ba8dd4566369a1
// HMAC-SHA-3-384=5af5c9a77a23a6a93d80649e562ab77f4f3552e3c5caffd93bdf8b3cfc6920e3023fc26775d9df1f3c94613146ad2c9d
// HMAC-SHA-3-512=c2962e5bbe1238007852f79d814dbbecd4682e6f097d37a363587c03bfa2eb0859d8d9c701e04cececfd3dd7bfd438f20b8b648e01bf8c11d26824b96cebbdcb
//
//
// Key=r20 aa
// Data=r50 dd
// HMAC-SHA-3-224=770df38c99d6e2bacd68056dcfe07d4c89ae20b2686a6185e1faa449
// HMAC-SHA-3-256=95f43e50f8df80a21977d51a8db3ba572dcd71db24687e6f86f47c1139b26260
// HMAC-SHA-3-384=4243c29f2201992ff96441e3b91ff81d8c601d706fbc83252684a4bc51101ca9b2c06ddd03677303c502ac5331752a3c
// HMAC-SHA-3-512=eb0ed9580e0ec11fc66cbb646b1be904eaff6da4556d9334f65ee4b2c85739157bae9027c51505e49d1bb81cfa55e6822db55262d5a252c088a29a5e95b84a66
//
//
// Key=0102030405060708090a0b0c0d0e0f10111213141516171819
// Data=r50 cd
// HMAC-SHA-3-224=305a8f2dfb94bad28861a03cbc4d590febe775c58cb4961c28428a0b
// HMAC-SHA-3-256=6331ba9b4af5804a68725b3663eb74814494b63c6093e35fb320a85d507936fd
// HMAC-SHA-3-384=b730724d3d4090cda1be799f63acbbe389fef7792fc18676fa5453aab398664650ed029c3498bbe8056f06c658e1e693
// HMAC-SHA-3-512=b46193bb59f4f696bf702597616da91e2a4558a593f4b015e69141ba81e1e50ea580834c2b87f87baa25a3a03bfc9bb389847f2dc820beae69d30c4bb75369cb
//
//
// Key=r131 aa
// Data=54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374
// HMAC-SHA-3-224=e7a52dfa45f95a217c100066b239aa8ad519be9b35d667268b1b57ff
// HMAC-SHA-3-256=b4d0cdee7ec2ba81a88b86918958312300a15622377929a054a9ce3ae1fac2b6
// HMAC-SHA-3-384=d62482ef601d7847439b55236e9679388ffcd53c62cd126f39be6ea63de762e26cd5974cb9a8de401b786b5555040f6f
// HMAC-SHA-3-512=d05888a6ebf8460423ea7bc85ea4ffda847b32df32291d2ce115fd187707325c7ce4f71880d91008084ce24a38795d20e6a28328a0f0712dc38253370da3ebb5
//
//
// Key=r147 aa
// Data=54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374
// HMAC-SHA-3-224=4dc9ce183281ce751bfc55667c074a077e0751bf40c53f9e6a83250f
// HMAC-SHA-3-256=ea68d6571dcb4669fd97c5953269c74126a102b1f97af6bdba5533cde51e8acc
// HMAC-SHA-3-384=0c0817f74b182baeb933e4e7074a0cb1c619dce7f11549ec9505d2d6c82959d451bd31654f58ebd569ac6323dc62d408
// HMAC-SHA-3-512=0f01da58d52a7e4ef3386bf7edb66625ff5c25385c3887d3ac9918c0828ba80c0db2de5bca3398f9694f7fd51535203a9e1f73ac4d9019383b5520bc26d2d654
//
//
// Key=r131 aa
// Data=5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e
// HMAC-SHA-3-224=ba13009405a929f398b348885caa5419191bb948ada32194afc84104
// HMAC-SHA-3-256=1fdc8cb4e27d07c10d897dec39c217792a6e64fa9c63a77ce42ad106ef284e02
// HMAC-SHA-3-384=4860ea191ac34994cf88957afe5a836ef36e4cc1a66d75bf77defb7576122d75f60660e4cf731c6effac06402787e2b9
// HMAC-SHA-3-512=2c6b9748d35c4c8db0b4407dd2ed2381f133bdbd1dfaa69e30051eb6badfcca64299b88ae05fdbd3dd3dd7fe627e42e39e48b0fe8c7f1e85f2dbd52c2d753572
//
//
// Key=r147 aa
// Data=5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e
// HMAC-SHA-3-224=92649468be236c3c72c189909c063b13f994be05749dc91310db639e
// HMAC-SHA-3-256=fdaa10a0299aecff9bb411cf2d7748a4022e4a26be3fb5b11b33d8c2b7ef5484
// HMAC-SHA-3-384=fe9357e3cfa538eb0373a2ce8f1e26ad6590afdaf266f1300522e8896d27e73f654d0631c8fa598d4bb82af6b744f4f5
// HMAC-SHA-3-512=6adc502f14e27812402fc81a807b28bf8a53c87bea7a1df6256bf66f5de1a4cb741407ad15ab8abc136846057f881969fbb159c321c904bfb557b77afb7778c8
//
/* 基于CryptoPP5.6.2实现的HMAC, 作者: 张鲁夺 */

struct HmacTestTuple
{
    HmacTestTuple(
        const char *input, unsigned int repeatTimesI, bool inputAsc,
        const char *key, unsigned int repeatTimesK, bool keyAsc,
        const char *output
        ): 
    input((byte *)input), repeatTimesI(repeatTimesI), inputLen(strlen(input)), inputAsc(inputAsc),
        key((byte *)key), repeatTimesK(repeatTimesK), keyLen(strlen(key)), keyAsc(keyAsc),
        output((byte *)output)
    { }

    const byte *input;
    unsigned int repeatTimesI;
    size_t inputLen;
    bool inputAsc;

    const byte *key;
    unsigned int repeatTimesK;
    size_t keyLen;
    bool keyAsc;

    const byte *output; 
};

void HmacModuleTest_Manual(
                           HashTransformation &md, const HmacTestTuple *testSet, unsigned int testSetSize)
{
    for (unsigned int i=0; i blockLen)
        {
            SecByteBlock digest(blockLen);
            md.Update(key, keyLen);
            md.Final(digest);
            md.Restart();

            memcpy(key, digest, digestLen);
            keyLen = digestLen;
        }

        for ( int i = 0; i < keyLen; i++ )
        {
            ipad[i] ^= key[i];
            opad[i] ^= key[i];
        }

        SecByteBlock Ldigest(blockLen);

        {
            md.Update(ipad, blockLen);
            /* can be loop */ md.Update(text, textLen);
            md.Final(Ldigest);
            md.Restart();
        }

        {
            md.Update(opad, blockLen);
            md.Update(Ldigest, digestLen);
            md.Final(Ldigest);
        }

        delete ipad, ipad = NULL;
        delete opad, opad = NULL;

        delete key, key = NULL;
        delete text, text = NULL;

        //
        // compare
        //

        bool fail = memcmp(Ldigest, testSet[i].output, digestLen) == 0 ? false : true;

        // output test result
        cout << (fail ? "FAILED   " : "passed   ");

        // output message authentication code
        cout << "0x";
        for (int j = 0; j < digestLen; j++)
            cout << setw(2) << setfill('0') << hex << (int)Ldigest[j];

        // output message
        if (testSet[i].inputAsc)
            cout << "   \"" << (char *)testSet[i].input << '\"';
        else
        {
            cout << "   0x";
            for (int k = 0; k < testSet[i].inputLen; k++)
                cout << setw(2) << setfill('0') << hex << (int)testSet[i].input[k];
        }

        // output repeat times of message
        if (testSet[i].repeatTimesI != 1)
            cout << " repeated " << dec << testSet[i].repeatTimesI << " times";

        // output key
        if (testSet[i].keyAsc)
            cout << "   \"" << (char *)testSet[i].key << '\"';
        else
        {
            cout << "   0x";
            for (int k = 0; k < testSet[i].keyLen; k++)
                cout << setw(2) << setfill('0') << hex << (int)testSet[i].key[k];
        }

        // output repeat times of key
        if (testSet[i].repeatTimesK != 1)
            cout << " repeated " << dec << testSet[i].repeatTimesK << " times";

        cout  << endl;
    }
}

class SHA3_224X: public SHA3_224 { public: unsigned int BlockSize() const { return r(); } };
class SHA3_256X: public SHA3_256 { public: unsigned int BlockSize() const { return r(); } };
class SHA3_384X: public SHA3_384 { public: unsigned int BlockSize() const { return r(); } };
class SHA3_512X: public SHA3_512 { public: unsigned int BlockSize() const { return r(); } };

void HMAC_SHA3_Test()
{
    HmacTestTuple testSet224[] = 
    {
        HmacTestTuple("Hi There", 1, true, "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 1, false, "\xb7\x3d\x59\x5a\x2b\xa9\xaf\x81\x5e\x9f\x2b\x4e\x53\xe7\x85\x81\xeb\xd3\x4a\x80\xb3\xbb\xaa\xc4\xe7\x02\xc4\xcc"),
        HmacTestTuple("what do ya want for nothing?", 1, true, "Jefe", 1, true, "\xe8\x24\xfe\xc9\x6c\x07\x4f\x22\xf9\x92\x35\xbb\x94\x2d\xa1\x98\x26\x64\xab\x69\x2c\xa8\x50\x10\x53\xcb\xd4\x14"),
        HmacTestTuple("\xdd", 50, false, "\xaa", 20, false, "\x77\x0d\xf3\x8c\x99\xd6\xe2\xba\xcd\x68\x05\x6d\xcf\xe0\x7d\x4c\x89\xae\x20\xb2\x68\x6a\x61\x85\xe1\xfa\xa4\x49"),
        HmacTestTuple("\xcd", 50, false, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", 1, false, "\x30\x5a\x8f\x2d\xfb\x94\xba\xd2\x88\x61\xa0\x3c\xbc\x4d\x59\x0f\xeb\xe7\x75\xc5\x8c\xb4\x96\x1c\x28\x42\x8a\x0b"),
        HmacTestTuple("\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74", 1, false, "\xaa", 131, false, "\xe7\xa5\x2d\xfa\x45\xf9\x5a\x21\x7c\x10\x00\x66\xb2\x39\xaa\x8a\xd5\x19\xbe\x9b\x35\xd6\x67\x26\x8b\x1b\x57\xff"),
        HmacTestTuple("\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74", 1, false, "\xaa", 147, false, "\x4d\xc9\xce\x18\x32\x81\xce\x75\x1b\xfc\x55\x66\x7c\x07\x4a\x07\x7e\x07\x51\xbf\x40\xc5\x3f\x9e\x6a\x83\x25\x0f"),
        HmacTestTuple("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e", 1, false, "\xaa", 131, false, "\xba\x13\x00\x94\x05\xa9\x29\xf3\x98\xb3\x48\x88\x5c\xaa\x54\x19\x19\x1b\xb9\x48\xad\xa3\x21\x94\xaf\xc8\x41\x04"),
        HmacTestTuple("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e", 1, false, "\xaa", 147, false, "\x92\x64\x94\x68\xbe\x23\x6c\x3c\x72\xc1\x89\x90\x9c\x06\x3b\x13\xf9\x94\xbe\x05\x74\x9d\xc9\x13\x10\xdb\x63\x9e"),
    };

    HmacTestTuple testSet256[] = 
    {
        HmacTestTuple("Hi There", 1, true, "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 1, false, "\x96\x63\xd1\x0c\x73\xee\x29\x40\x54\xdc\x9f\xaf\x95\x64\x7c\xb9\x97\x31\xd1\x22\x10\xff\x70\x75\xfb\x3d\x33\x95\xab\xfb\x98\x21"),
        HmacTestTuple("what do ya want for nothing?", 1, true, "Jefe", 1, true, "\xaa\x9a\xed\x44\x8c\x7a\xbc\x8b\x5e\x32\x6f\xfa\x6a\x01\xcd\xed\xf7\xb4\xb8\x31\x88\x14\x68\xc0\x44\xba\x8d\xd4\x56\x63\x69\xa1"),
        HmacTestTuple("\xdd", 50, false, "\xaa", 20, false, "\x95\xf4\x3e\x50\xf8\xdf\x80\xa2\x19\x77\xd5\x1a\x8d\xb3\xba\x57\x2d\xcd\x71\xdb\x24\x68\x7e\x6f\x86\xf4\x7c\x11\x39\xb2\x62\x60"),
        HmacTestTuple("\xcd", 50, false, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", 1, false, "\x63\x31\xba\x9b\x4a\xf5\x80\x4a\x68\x72\x5b\x36\x63\xeb\x74\x81\x44\x94\xb6\x3c\x60\x93\xe3\x5f\xb3\x20\xa8\x5d\x50\x79\x36\xfd"),
        HmacTestTuple("\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74", 1, false, "\xaa", 131, false, "\xb4\xd0\xcd\xee\x7e\xc2\xba\x81\xa8\x8b\x86\x91\x89\x58\x31\x23\x00\xa1\x56\x22\x37\x79\x29\xa0\x54\xa9\xce\x3a\xe1\xfa\xc2\xb6"),
        HmacTestTuple("\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74", 1, false, "\xaa", 147, false, "\xea\x68\xd6\x57\x1d\xcb\x46\x69\xfd\x97\xc5\x95\x32\x69\xc7\x41\x26\xa1\x02\xb1\xf9\x7a\xf6\xbd\xba\x55\x33\xcd\xe5\x1e\x8a\xcc"),
        HmacTestTuple("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e", 1, false, "\xaa", 131, false, "\x1f\xdc\x8c\xb4\xe2\x7d\x07\xc1\x0d\x89\x7d\xec\x39\xc2\x17\x79\x2a\x6e\x64\xfa\x9c\x63\xa7\x7c\xe4\x2a\xd1\x06\xef\x28\x4e\x02"),
        HmacTestTuple("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e", 1, false, "\xaa", 147, false, "\xfd\xaa\x10\xa0\x29\x9a\xec\xff\x9b\xb4\x11\xcf\x2d\x77\x48\xa4\x02\x2e\x4a\x26\xbe\x3f\xb5\xb1\x1b\x33\xd8\xc2\xb7\xef\x54\x84"),
    };
    HmacTestTuple testSet384[] = 
    {
        HmacTestTuple("Hi There", 1, true, "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 1, false, "\x89\x2d\xfd\xf5\xd5\x1e\x46\x79\xbf\x32\x0c\xd1\x6d\x4c\x9d\xc6\xf7\x49\x74\x46\x08\xe0\x03\xad\xd7\xfb\xa8\x94\xac\xff\x87\x36\x1e\xfa\x4e\x57\x99\xbe\x06\xb6\x46\x1f\x43\xb6\x0a\xe9\x70\x48"),
        HmacTestTuple("what do ya want for nothing?", 1, true, "Jefe", 1, true, "\x5a\xf5\xc9\xa7\x7a\x23\xa6\xa9\x3d\x80\x64\x9e\x56\x2a\xb7\x7f\x4f\x35\x52\xe3\xc5\xca\xff\xd9\x3b\xdf\x8b\x3c\xfc\x69\x20\xe3\x02\x3f\xc2\x67\x75\xd9\xdf\x1f\x3c\x94\x61\x31\x46\xad\x2c\x9d"),
        HmacTestTuple("\xdd", 50, false, "\xaa", 20, false, "\x42\x43\xc2\x9f\x22\x01\x99\x2f\xf9\x64\x41\xe3\xb9\x1f\xf8\x1d\x8c\x60\x1d\x70\x6f\xbc\x83\x25\x26\x84\xa4\xbc\x51\x10\x1c\xa9\xb2\xc0\x6d\xdd\x03\x67\x73\x03\xc5\x02\xac\x53\x31\x75\x2a\x3c"),
        HmacTestTuple("\xcd", 50, false, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", 1, false, "\xb7\x30\x72\x4d\x3d\x40\x90\xcd\xa1\xbe\x79\x9f\x63\xac\xbb\xe3\x89\xfe\xf7\x79\x2f\xc1\x86\x76\xfa\x54\x53\xaa\xb3\x98\x66\x46\x50\xed\x02\x9c\x34\x98\xbb\xe8\x05\x6f\x06\xc6\x58\xe1\xe6\x93"),
        HmacTestTuple("\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74", 1, false, "\xaa", 131, false, "\xd6\x24\x82\xef\x60\x1d\x78\x47\x43\x9b\x55\x23\x6e\x96\x79\x38\x8f\xfc\xd5\x3c\x62\xcd\x12\x6f\x39\xbe\x6e\xa6\x3d\xe7\x62\xe2\x6c\xd5\x97\x4c\xb9\xa8\xde\x40\x1b\x78\x6b\x55\x55\x04\x0f\x6f"),
        HmacTestTuple("\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74", 1, false, "\xaa", 147, false, "\x0c\x08\x17\xf7\x4b\x18\x2b\xae\xb9\x33\xe4\xe7\x07\x4a\x0c\xb1\xc6\x19\xdc\xe7\xf1\x15\x49\xec\x95\x05\xd2\xd6\xc8\x29\x59\xd4\x51\xbd\x31\x65\x4f\x58\xeb\xd5\x69\xac\x63\x23\xdc\x62\xd4\x08"),
        HmacTestTuple("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e", 1, false, "\xaa", 131, false, "\x48\x60\xea\x19\x1a\xc3\x49\x94\xcf\x88\x95\x7a\xfe\x5a\x83\x6e\xf3\x6e\x4c\xc1\xa6\x6d\x75\xbf\x77\xde\xfb\x75\x76\x12\x2d\x75\xf6\x06\x60\xe4\xcf\x73\x1c\x6e\xff\xac\x06\x40\x27\x87\xe2\xb9"),
        HmacTestTuple("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e", 1, false, "\xaa", 147, false, "\xfe\x93\x57\xe3\xcf\xa5\x38\xeb\x03\x73\xa2\xce\x8f\x1e\x26\xad\x65\x90\xaf\xda\xf2\x66\xf1\x30\x05\x22\xe8\x89\x6d\x27\xe7\x3f\x65\x4d\x06\x31\xc8\xfa\x59\x8d\x4b\xb8\x2a\xf6\xb7\x44\xf4\xf5"),
    };
    HmacTestTuple testSet512[] = 
    {
        HmacTestTuple("Hi There", 1, true, "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 1, false, "\x88\x52\xc6\x3b\xe8\xcf\xc2\x15\x41\xa4\xee\x5e\x5a\x9a\x85\x2f\xc2\xf7\xa9\xad\xec\x2f\xf3\xa1\x37\x18\xab\x4e\xd8\x1a\xae\xa0\xb8\x7b\x7e\xb3\x97\x32\x35\x48\xe2\x61\xa6\x4e\x7f\xc7\x51\x98\xf6\x66\x3a\x11\xb2\x2c\xd9\x57\xf7\xc8\xec\x85\x8a\x1c\x77\x55"),
        HmacTestTuple("what do ya want for nothing?", 1, true, "Jefe", 1, true, "\xc2\x96\x2e\x5b\xbe\x12\x38\x00\x78\x52\xf7\x9d\x81\x4d\xbb\xec\xd4\x68\x2e\x6f\x09\x7d\x37\xa3\x63\x58\x7c\x03\xbf\xa2\xeb\x08\x59\xd8\xd9\xc7\x01\xe0\x4c\xec\xec\xfd\x3d\xd7\xbf\xd4\x38\xf2\x0b\x8b\x64\x8e\x01\xbf\x8c\x11\xd2\x68\x24\xb9\x6c\xeb\xbd\xcb"),
        HmacTestTuple("\xdd", 50, false, "\xaa", 20, false, "\xeb\x0e\xd9\x58\x0e\x0e\xc1\x1f\xc6\x6c\xbb\x64\x6b\x1b\xe9\x04\xea\xff\x6d\xa4\x55\x6d\x93\x34\xf6\x5e\xe4\xb2\xc8\x57\x39\x15\x7b\xae\x90\x27\xc5\x15\x05\xe4\x9d\x1b\xb8\x1c\xfa\x55\xe6\x82\x2d\xb5\x52\x62\xd5\xa2\x52\xc0\x88\xa2\x9a\x5e\x95\xb8\x4a\x66"),
        HmacTestTuple("\xcd", 50, false, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", 1, false, "\xb4\x61\x93\xbb\x59\xf4\xf6\x96\xbf\x70\x25\x97\x61\x6d\xa9\x1e\x2a\x45\x58\xa5\x93\xf4\xb0\x15\xe6\x91\x41\xba\x81\xe1\xe5\x0e\xa5\x80\x83\x4c\x2b\x87\xf8\x7b\xaa\x25\xa3\xa0\x3b\xfc\x9b\xb3\x89\x84\x7f\x2d\xc8\x20\xbe\xae\x69\xd3\x0c\x4b\xb7\x53\x69\xcb"),
        HmacTestTuple("\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74", 1, false, "\xaa", 131, false, "\xd0\x58\x88\xa6\xeb\xf8\x46\x04\x23\xea\x7b\xc8\x5e\xa4\xff\xda\x84\x7b\x32\xdf\x32\x29\x1d\x2c\xe1\x15\xfd\x18\x77\x07\x32\x5c\x7c\xe4\xf7\x18\x80\xd9\x10\x08\x08\x4c\xe2\x4a\x38\x79\x5d\x20\xe6\xa2\x83\x28\xa0\xf0\x71\x2d\xc3\x82\x53\x37\x0d\xa3\xeb\xb5"),
        HmacTestTuple("\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74", 1, false, "\xaa", 147, false, "\x0f\x01\xda\x58\xd5\x2a\x7e\x4e\xf3\x38\x6b\xf7\xed\xb6\x66\x25\xff\x5c\x25\x38\x5c\x38\x87\xd3\xac\x99\x18\xc0\x82\x8b\xa8\x0c\x0d\xb2\xde\x5b\xca\x33\x98\xf9\x69\x4f\x7f\xd5\x15\x35\x20\x3a\x9e\x1f\x73\xac\x4d\x90\x19\x38\x3b\x55\x20\xbc\x26\xd2\xd6\x54"),
        HmacTestTuple("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e", 1, false, "\xaa", 131, false, "\x2c\x6b\x97\x48\xd3\x5c\x4c\x8d\xb0\xb4\x40\x7d\xd2\xed\x23\x81\xf1\x33\xbd\xbd\x1d\xfa\xa6\x9e\x30\x05\x1e\xb6\xba\xdf\xcc\xa6\x42\x99\xb8\x8a\xe0\x5f\xdb\xd3\xdd\x3d\xd7\xfe\x62\x7e\x42\xe3\x9e\x48\xb0\xfe\x8c\x7f\x1e\x85\xf2\xdb\xd5\x2c\x2d\x75\x35\x72"),
        HmacTestTuple("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e", 1, false, "\xaa", 147, false, "\x6a\xdc\x50\x2f\x14\xe2\x78\x12\x40\x2f\xc8\x1a\x80\x7b\x28\xbf\x8a\x53\xc8\x7b\xea\x7a\x1d\xf6\x25\x6b\xf6\x6f\x5d\xe1\xa4\xcb\x74\x14\x07\xad\x15\xab\x8a\xbc\x13\x68\x46\x05\x7f\x88\x19\x69\xfb\xb1\x59\xc3\x21\xc9\x04\xbf\xb5\x57\xb7\x7a\xfb\x77\x78\xc8"),
    };

    {
        SHA3_224X md;
        HmacModuleTest_Manual(md, testSet224, sizeof(testSet224) / sizeof(testSet224[0])); 
    }

    {
        SHA3_256X md;
        HmacModuleTest_Manual(md, testSet256, sizeof(testSet256) / sizeof(testSet256[0])); 
    }

    {
        SHA3_384X md;
        HmacModuleTest_Manual(md, testSet384, sizeof(testSet384) / sizeof(testSet384[0])); 
    }

    {
        SHA3_512X md;
        HmacModuleTest_Manual(md, testSet512, sizeof(testSet512) / sizeof(testSet512[0]));
    }
}
//
// 程序执行结果如下: 
//
// passed   0xb73d595a2ba9af815e9f2b4e53e78581ebd34a80b3bbaac4e702c4cc   "Hi There"   0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
// passed   0xe824fec96c074f22f99235bb942da1982664ab692ca8501053cbd414   "what do ya want for nothing?"   "Jefe"
// passed   0x770df38c99d6e2bacd68056dcfe07d4c89ae20b2686a6185e1faa449   0xdd repeated 50 times   0xaa repeated 20 times
// passed   0x305a8f2dfb94bad28861a03cbc4d590febe775c58cb4961c28428a0b   0xcd repeated 50 times   0x0102030405060708090a0b0c0d0e0f10111213141516171819
// passed   0xe7a52dfa45f95a217c100066b239aa8ad519be9b35d667268b1b57ff   0x54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374   0xaa repeated 131 times
// passed   0x4dc9ce183281ce751bfc55667c074a077e0751bf40c53f9e6a83250f   0x54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374   0xaa repeated 147 times
// passed   0xba13009405a929f398b348885caa5419191bb948ada32194afc84104   0x5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e   0xaa repeated 131 times
// passed   0x92649468be236c3c72c189909c063b13f994be05749dc91310db639e   0x5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e   0xaa repeated 147 times
// passed   0x9663d10c73ee294054dc9faf95647cb99731d12210ff7075fb3d3395abfb9821   "Hi There"   0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
// passed   0xaa9aed448c7abc8b5e326ffa6a01cdedf7b4b831881468c044ba8dd4566369a1   "what do ya want for nothing?"   "Jefe"
// passed   0x95f43e50f8df80a21977d51a8db3ba572dcd71db24687e6f86f47c1139b26260   0xdd repeated 50 times   0xaa repeated 20 times
// passed   0x6331ba9b4af5804a68725b3663eb74814494b63c6093e35fb320a85d507936fd   0xcd repeated 50 times   0x0102030405060708090a0b0c0d0e0f10111213141516171819
// passed   0xb4d0cdee7ec2ba81a88b86918958312300a15622377929a054a9ce3ae1fac2b6   0x54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374   0xaa repeated 131 times
// passed   0xea68d6571dcb4669fd97c5953269c74126a102b1f97af6bdba5533cde51e8acc   0x54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374   0xaa repeated 147 times
// passed   0x1fdc8cb4e27d07c10d897dec39c217792a6e64fa9c63a77ce42ad106ef284e02   0x5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e   0xaa repeated 131 times
// passed   0xfdaa10a0299aecff9bb411cf2d7748a4022e4a26be3fb5b11b33d8c2b7ef5484   0x5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e   0xaa repeated 147 times
// passed   0x892dfdf5d51e4679bf320cd16d4c9dc6f749744608e003add7fba894acff87361efa4e5799be06b6461f43b60ae97048   "Hi There"   0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
// passed   0x5af5c9a77a23a6a93d80649e562ab77f4f3552e3c5caffd93bdf8b3cfc6920e3023fc26775d9df1f3c94613146ad2c9d   "what do ya want for nothing?"   "Jefe"
// passed   0x4243c29f2201992ff96441e3b91ff81d8c601d706fbc83252684a4bc51101ca9b2c06ddd03677303c502ac5331752a3c   0xdd repeated 50 times   0xaa repeated 20 times
// passed   0xb730724d3d4090cda1be799f63acbbe389fef7792fc18676fa5453aab398664650ed029c3498bbe8056f06c658e1e693   0xcd repeated 50 times   0x0102030405060708090a0b0c0d0e0f10111213141516171819
// passed   0xd62482ef601d7847439b55236e9679388ffcd53c62cd126f39be6ea63de762e26cd5974cb9a8de401b786b5555040f6f   0x54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374   0xaa repeated 131 times
// passed   0x0c0817f74b182baeb933e4e7074a0cb1c619dce7f11549ec9505d2d6c82959d451bd31654f58ebd569ac6323dc62d408   0x54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374   0xaa repeated 147 times
// passed   0x4860ea191ac34994cf88957afe5a836ef36e4cc1a66d75bf77defb7576122d75f60660e4cf731c6effac06402787e2b9   0x5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e   0xaa repeated 131 times
// passed   0xfe9357e3cfa538eb0373a2ce8f1e26ad6590afdaf266f1300522e8896d27e73f654d0631c8fa598d4bb82af6b744f4f5   0x5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e   0xaa repeated 147 times
// passed   0x8852c63be8cfc21541a4ee5e5a9a852fc2f7a9adec2ff3a13718ab4ed81aaea0b87b7eb397323548e261a64e7fc75198f6663a11b22cd957f7c8ec858a1c7755   "Hi There"   0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
// passed   0xc2962e5bbe1238007852f79d814dbbecd4682e6f097d37a363587c03bfa2eb0859d8d9c701e04cececfd3dd7bfd438f20b8b648e01bf8c11d26824b96cebbdcb   "what do ya want for nothing?"   "Jefe"
// passed   0xeb0ed9580e0ec11fc66cbb646b1be904eaff6da4556d9334f65ee4b2c85739157bae9027c51505e49d1bb81cfa55e6822db55262d5a252c088a29a5e95b84a66   0xdd repeated 50 times   0xaa repeated 20 times
// passed   0xb46193bb59f4f696bf702597616da91e2a4558a593f4b015e69141ba81e1e50ea580834c2b87f87baa25a3a03bfc9bb389847f2dc820beae69d30c4bb75369cb   0xcd repeated 50 times   0x0102030405060708090a0b0c0d0e0f10111213141516171819
// passed   0xd05888a6ebf8460423ea7bc85ea4ffda847b32df32291d2ce115fd187707325c7ce4f71880d91008084ce24a38795d20e6a28328a0f0712dc38253370da3ebb5   0x54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374   0xaa repeated 131 times
// passed   0x0f01da58d52a7e4ef3386bf7edb66625ff5c25385c3887d3ac9918c0828ba80c0db2de5bca3398f9694f7fd51535203a9e1f73ac4d9019383b5520bc26d2d654   0x54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374   0xaa repeated 147 times
// passed   0x2c6b9748d35c4c8db0b4407dd2ed2381f133bdbd1dfaa69e30051eb6badfcca64299b88ae05fdbd3dd3dd7fe627e42e39e48b0fe8c7f1e85f2dbd52c2d753572   0x5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e   0xaa repeated 131 times
// passed   0x6adc502f14e27812402fc81a807b28bf8a53c87bea7a1df6256bf66f5de1a4cb741407ad15ab8abc136846057f881969fbb159c321c904bfb557b77afb7778c8   0x5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e   0xaa repeated 147 times

Copyright © 2015 Zhang Luduo.

All rights reserved.