/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */
/*======================================================================
Copyright (C) 2004,2005,2009,2011,2012 Walter Doekes
  <walter+tthsum@wjd.nu>
This file is part of tthsum.

tthsum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

tthsum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with tthsum.  If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include "tiger.h"

#include "base32.h"
#include "test.h"
#include <stdlib.h>
#include <string.h>


static int help_cmp_base32_bin(const char* name, const uint64_t* input,
	unsigned input_len, const char* base32) {
    uint64_t res[3];
    char base32buf[40];
    tiger((uint64_t*)input, input_len, res);
    uint64tobase32(base32buf, res, 3);
    TEST_PASS3(strcmp(base32buf, base32) == 0,
	    "Tiger hash result for \"%s\" is wrong! "
	    "Expected \"%s\", got \"%s\".", name, base32, base32buf);
    if (input_len != 0) {
	tiger_bp(((const char*)input)[0], (const char*)input + 1,
		input_len - 1, res);
	uint64tobase32(base32buf, res, 3);
	TEST_PASS1(strcmp(base32buf, base32) == 0,
		"Tiger BP hash result for \"%s\" is wrong!", name);
    }
    return 0;
}
    
static int help_cmp_base32(const char* input, const char* base32) {
    unsigned input_len = strlen(input);
    uint64_t buf64[32];
    if (input_len > 8*32)
	abort();
    memcpy(buf64, input, input_len); /* force 64 bit alignment */
    return help_cmp_base32_bin(input, buf64, input_len, base32);
}

static int test_tiger192_nessie_1a() {
    /* echo -n '3293AC630C13F0245F92BBB1766E16167A4E58492DDE73F3' |
     * perl -e 'use MIME::Base32 "RFC";$bin=<>;$bin=~s/([0-9A-Fa-f]{2})/chr
     *  hex $1/eg;print MIME::Base32::encode($bin)."\n";' */
    return help_cmp_base32("",
	    "GKJ2YYYMCPYCIX4SXOYXM3QWCZ5E4WCJFXPHH4Y")
	 + help_cmp_base32("a",
	    "O67PX3ZOP34KWLWI7E57LB5H7RQT4JD7L4SHQCI")
	 + help_cmp_base32("abc",
	    "FKVRJBHIYFMPFP5YYX7UDNL2KJISSEY4SV5V7EY")
	 + help_cmp_base32("message digest",
	    "3GA7RS3YEANJKDOPGBEHKHSEDRIX7SQ2UVNCT5Q")
	 + help_cmp_base32("abcdefghijklmnopqrstuvwxyz",
	    "C4KKI4XO4V6TABAECK74YVIDFIFRCYBP6N5652I")
	 + help_cmp_base32("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnl"
	    "mnomnopnopq", "B557TIM3TRMPFN3BBX36QTYKYOTRYYY6PNJ7PDQ");
}

static int test_tiger192_nessie_1b() {
    int ret = 0;
    char buf[2048];
    char *p;
    int i = 0;

    /* A..Z a..z 0..9 */
    p = buf;
    for (i = 'A'; i <= 'Z'; ++i)
	*p++ = (char)i;
    for (i = 'a'; i <= 'z'; ++i)
	*p++ = (char)i;
    for (i = '0'; i <= '9'; ++i)
	*p++ = (char)i;
    *p = '\0';
    ret += help_cmp_base32(buf, "RXHKNAFBOWB64UBLUOFDYNUGKGEQ766M3RE2RTA");

    /* 8 * (1..0) */
    p = buf;
    for (i = 0; i < 8; ++i) {
	int j;
	for (j = '1'; j <= '9'; ++j)
	    *p++ = (char)j;
	*p++ = (char)'0';
    }
    *p = '\0';
    ret += help_cmp_base32(buf, "DQKHSVJJ7WPSA6UVR6CMKLYR5CD7UDFL37MRX7I");

    /* 1M * 'a' */
    p = (char*)malloc(1000000);
    memset(p, 'a', 1000000);
    ret += help_cmp_base32_bin("one million times 'a'", (const uint64_t*)p,
	    1000000, "NWYOE4U4X2WZHVYVY2T5GYYC5GZ45YGSXQYUWQI");
    free(p);

    return ret;
}

static int test_tiger192_ross_and_eli() {
    return help_cmp_base32("",
	    "GKJ2YYYMCPYCIX4SXOYXM3QWCZ5E4WCJFXPHH4Y")
	 + help_cmp_base32("abc",
	    "FKVRJBHIYFMPFP5YYX7UDNL2KJISSEY4SV5V7EY")
	 + help_cmp_base32("Tiger",
	    "3UACGB4Z6UAJ73DN5PEDRO3KE7PSXHLPCEGHSNY")
	 + help_cmp_base32("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr"
	    "stuvwxyz0123456789+-", "64OILA4QFL5YPHW74YIPQLANI6DKHJJUKBCINNI")
	 + help_cmp_base32("ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopq"
	    "rstuvwxyz+0123456789", "JDHOWYYIXB6UN2K5MVQRFTPRRWLZCX4XMVSYSVY")
	 + help_cmp_base32("Tiger - A Fast New Hash Function, by Ross An"
	    "derson and Eli Biham", "RKDGQKIEBJAQY4U22I7VVWTRCYB3HTOTK7SMCXQ")
	 + help_cmp_base32("Tiger - A Fast New Hash Function, by Ross An"
	    "derson and Eli Biham, proceedings of Fast Software Encrypti"
	    "on 3, Cambridge, 1996.", "MMNL3UID5OND2JC3NX6U255SK76HIOKQDUKWRXI")
	 + help_cmp_base32("Tiger - A Fast New Hash Function, by Ross An"
	    "derson and Eli Biham, proceedings of Fast Software Encrypti"
	    "on 3, Cambridge.", "ZZK2NL6VSH26XLCUP74E7CJCP6JTDWVQWYI4RCI")
	 + help_cmp_base32("message digest", 
	    "3GA7RS3YEANJKDOPGBEHKHSEDRIX7SQ2UVNCT5Q")
	 + help_cmp_base32("12345678901234567890123456789012345678901234"
	    "567890123456789012345678901234567890",
	    "DQKHSVJJ7WPSA6UVR6CMKLYR5CD7UDFL37MRX7I")
	 + help_cmp_base32("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr"
	    "stuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm"
	    "nopqrstuvwxyz0123456789+-",
	    "YVADJZNUH24AAWCIU7QK42VMO3SP6WIK44K72JI");
}

static int test_tiger192_0to255() {
    char name[256];
    uint64_t buf64[32];
    char *buf = (char*)&buf64[0]; /* char[256] */
    const char *results[256] = {
	"LWPNACQDBZRYXW3VHJVCJ64QBZNGHOHHHZWCLNQ",
	"MWYOD2RWZIL63YXQKXTH5LLHWHBIFII2LOR2RYA",
	"VN73RUQ44PMNTO27DLY7F6QNHQTXSBQWBW4NEJQ",
	"7YXJ2Q7XJMMZ3ENZFEOXHTH4UC7KL4DI7OREJ7Y",
	"HX3NM4X6TWVLEFJD5MCHAXMKRNZLPCYAVVDF2HA",
	"4BLSINJ74KMVPQ7I325KEHIMFXKJZSRCDEOVVUY",
	"IBLN3P4CVZ2KWVTSBXVPA6NMULYHN3IENUCE3ZI",
	"QAP3TPQ2TLDTG6UBGRNTQRPE47ATV4P3VW3TOIY",
	"IMAVMVD2QJESZKCZHBJQI5EPMXZNJJ7CMZFOFMI",
	"7RBVCN6NMUWXECQR5X2HVPSGQC5EVVN5QEGJQNI",
	"ECUBIPPUP5LRL6QJAX7G7HI5FNNS2TRG7KMJGCY",
	"4SRAMMAZ7PADJXVQDYVJKKLAIIYZZPADTWTJVEI",
	"WXYPUVYMJTLJUPDIISF6ILEGLPPXP3LIXE4HLZY",
	"QAV6N2RM5BVAWNY7ENKJISYZZMZDDL37WTYA76A",
	"27AIQY5V4XR5NG2UASQRMMK2NGHBFDV27BRWW4A",
	"LRJIRSYOJZJTAVV2KKJUIDM343Z4IYJDHPY62UI",
	"RDJ2STZYEDSAQ7NGTWF34LHUCVDGAY3QTRCQYTI",
	"YB5UWFK7T52YAXM5BBYIP7G5FDIIVHICEGJEI7Q",
	"5ZDT4VU76PQJFT4JS2ZRZZTF5J6WCUQNILRHHFI",
	"4E625AEYCOOPZ2TVLUQGB4IH4PDVQHW7T5FTXBI",
	"WSFJYCPSNM3ZVIUPXR2QWUGO62OQ2DXDP73WL5Y",
	"K5FACRLDOMAU6QLZZWQUKQPC4PC2DTO2T6OQOHA",
	"6LRIGHS3WSXQLEKMJOTBXOGWADI66BY4LXYCE2I",
	"W6AIUW3CLDF6OGHNVE4JPDDJ2P74IWRCF2O36TA",
	"3DSOA5W546EVBVI6VSPZPUWRSFVASECGLVC2KXA",
	"J3PM7KXB32MLPYCW4ZGKEQADIIV343YEQEU3ETA",
	"BXRIHNNESU7KV3DPH7PFBV4HLSHOK75HTPOHB7A",
	"5TOUXIMTNW46N6B6FPL7HHJDSJ5BUF5S2UVIMSI",
	"XYIYSNDA4SLFT567H6Z32XR6TIYZ7BP5GSLOE3A",
	"V3ANUDZMYBSGGJOMAMYZUDQIB5ULI2ZT7AMSBVQ",
	"RASP2OMYJ5VFF777DEAW4J6FSSJBIUQIMNZ7F3Q",
	"RNSZFL53ALRCPKSFDNOP3SBBXBBELU2LS27U6EY",
	"SYG7TQ2J5RTBT7ZX4PYPJAZODHGGUTSNNCLCMUI",
	"6TRLPKTSXR6W4DHW3IIJJPXPVKOFKYIDE7DCSAA",
	"AX6RXAGKJR6BJ7S36CWL2DVD3LSJRXBZDXHSE5Y",
	"YXUV7FJYTDDIGVNVSFIHXNYU6DS5VOMYTUEDSAA",
	"WLKOFBWPP2UKW3WNMUGJ4SGKENEX5LPFKSC5WHQ",
	"TVIWK7QRYVH734QF3O2DKCL2FPDPSPCL5DLBQCY",
	"HRVOHEITK2RUHLRRCNZV6B747NPAI2WNI6YA7OY",
	"MZBUFTPMZAS62NAKP77C4VYQPXILL4SMESZMH4A",
	"J337ZIJ442CNQHPE6VTNFCL45NAH7OZ532A72ZA",
	"KRUJ73HNMPZJPMJ42SKLQXTIM2APJ54N47WIDVI",
	"V5BUXW64P34QXYB6ICQDH4LORJL3IGCA4HUKWWI",
	"UMW3M6HUJEC4DCLI6XMJRSTZSLV6FZGMGMMLS3A",
	"33U5KGNBFLH3RIETLI3I23TMOXXO5ZXSWDK5DEI",
	"ZPDUQY2HFUOJ2I6FE32JBC6U2QRU4AGLZSM2T2I",
	"NQRIUHKIOHUAFYBVZG5RNRIYONKIIH5WXY6GTNQ",
	"ZKTVLRK2VBU6MM6LHRWZHJLBSRFMOQMBKTRLB4A",
	"U2BV67AMNSUPJJCXQ65PU52HRLU23W7PXQYFFUY",
	"4QDHKWKX5QQ3U2TEWXJ2V4YXJHHZRX4S6GY77YA",
	"BQWUURFIAPN2TG32IZ2VHSJJHNDKKOCVRPLX3VA",
	"6BHQCGYJ2J22DBKSRTAEB23RSZE4QRY2Q6ZFTMY",
	"HWULK77VF7FOPQZGG3WGZADQQGE45WARHRON4HQ",
	"NRWIROHBRX24WIXNWYNC2PWXI5A2OCF4IZLW7NY",
	"FVEO4K7YLXRDI5KL5TZ4N5NQ4YUYRNN7ESXKLOY",
	"BULXALO4UB4O2HGFDOK56KPKCBJ45F7WSOK4MEY",
	"TWGCVUZH3ZB5K6BNL4QIQH2KRRBTXIM27SGBLLI",
	"EJ52IGNXMDM5CDN3BFMF5XKHLLBHGT6UKOPYE5I",
	"F5JCBKBI56KOGJ55KHKN6XCYMCPYVE5Z7YA775Q",
	"B3WZ7EPBUM5FBOHJCPN2BNPCJDJGHYP4OLDKISI",
	"OZVXA7UZT7Z4KHXACFUFCO5A3TX6VMRC3UPWT5Q",
	"QXTHCBUU47BWUI2A3JVDOHAFMBCQ6PKE2NNNTDA",
	"2QA7TMJ5HHBEI56AVZUXDRYFYY6AM7ZJKCGCTSI",
	"EEW7RHCXCVJHANCKZSYZAJ5QWJVRAT5A7O7A7ZA",
	"HPW6OZ5KJJ2QPW7P7A6RXQZ7M7V2TRSJIUDGEJY",
	"PH7ND647C7CJQAII5BQFYEGZ4F3KZD7E62TFAZA",
	"JDM3OYRKW74JNDWZEYSV66HIZZDB4TERML76RNY",
	"MY4MQOBXFF5T6U5Q7ASMBB6ZUC4NT7DCMVUDXDY",
	"C5CCDT3NGMP7KGJE7CKG5ASEKVOJAIGTRYY3NWY",
	"APSCV62776NZYN4UUPN6ZGP2PY7XGBPPA66ST3Y",
	"ZSX4NDKLH3MITXE7FDFZEJMARJAKVDQNLSRUH7Y",
	"5ASPSO2AEIARRBXPYVCTTVGV2UMGHLNDFH5U4IQ",
	"PTYNYANTEZUHKMHUEBALUDIM5EYXIRK6RKMQ2FA",
	"PKHGDFDZ6T24IGHMAQMANBIOM4R4UVVPXQ6TFTA",
	"BA6FZKIPJMUWYQQEAVM4QKLBJHKO5OVV54WLQLI",
	"GWA3PLBS7KFATBX5CTZHP6YQNYISXEWRRTLITPI",
	"EWHIELM4YHWKRNK5SJN2GYN2FWP4E6XRQHYTRNA",
	"VBWB5CFGIUK7UKA2IYWUM5CYEMKJJ4LOQNO7Q4Y",
	"O3T7A37JXCZYRWYBF6FUXYX3GQ7ZLEJ63XSHUJY",
	"AATYWTSWSDTST3DRDC236Y6J2HVRE2EWBCJ4U5I",
	"RXTQ4ZFDDOQ26T24EPHXOTGKGL7JKLLWYP65DNY",
	"XPVHFSCAOSN2XLYUCX7KYNBUCG4JKFNYPBEKBGQ",
	"Y3B4ZLA3GOG7CF5GD3HZUKAOTOTQS6CMOK3WO4I",
	"V2MBH32EFHVOOPVJ7W26EPJGHLY3XB4SRT27ASA",
	"NBSHZV577OHFGDJIZBTILKGS6ZL64TGWJ3OX4ZQ",
	"VKGDLMHHI2XVMQ27NRYRVUCCHFTOURMQQ5AJOEY",
	"VLK4BVPJQCZJXSEJQXCUI4L3QH2YZW4SHI2GRYA",
	"6YESTUKHQHPEJ2TAPKX4BUS7UG3O6PDKUD4LHVY",
	"YSAIPXDV5RB2KSSZH4SODM2ZXN24LANGLQYXBUA",
	"CHITOL557WP7KFDBDKZA2MN2MLYYQVWI22XDVVY",
	"6KUAO24QC7W233WUD5AJZHRS5M54BEHK5CPYKXI",
	"OAX2I7S32NPDIS23Q7AAQIIGGNZANSW5HVGVAFA",
	"XHQD73LVFJLAYOYDMXW7LP6E3R7KYXSLXOJXHDI",
	"HSCMKK7VCB32LAM7K3S2LQOAMIERQFLZHEZCBRY",
	"7DWMUKFFEVMU4E4LKXAGMF5AMPPXJ7RUNHMYHAI",
	"CCA4HOXOYCW7JGAMF2TFSOYJA3OL5XSIAV2UO5A",
	"WUKS4OO6BP7ITAWXQP6E6DFXCYHLFVU7N45T4WY",
	"NJVXMC73DFS4OKWHSP44AL5CDMHRYNF5EZALW2Y",
	"DZW4X6ULVDMWYKIQC5UKNI4UGPK22WSQ4CLQOMA",
	"OMZCFU5AGM2R7L6WRROORJGYGO5HIIGUIEB4W2Y",
	"4TGX3JM3EFPR32VI7O5IKDZMDJ7UYPKJL7TIASQ",
	"PPTYY6IHCNKFOVGUY6FJGGFMUSVALDC4ENKACMI",
	"W4ODQCNFAS7C6V5OTYS33TBZEHOGMXDFFCPKKWQ",
	"FOGKHGLXKNPLNEXPX4G6ZWUJOGUGAT37ZOXHLXI",
	"HTCIWUPEYXPE6DBKXYF6N3SLMPGFMSUHYAMUHTI",
	"CV5M355VT7BFSZXZPAZAOVKDMSECQQHHEUPNNQI",
	"32Q47LWPDDJWCHGNAULRGGQW3W6JPIJJALOYXKY",
	"FLJOTEF46ZEBFBG7IS4WCYZGQ7BOMTP24KXBNQQ",
	"QOHTUOZIUUFBFNLQOSIKMYEA3T5AEMHFQO3OWFA",
	"ZCZAGFISDTP3HKI3YDW7CGEG6KB463CIB5EYMJY",
	"FMH3ATYQBPU22UNX2ZGHMZI3VNFX2MOR3EMVOEI",
	"WZEVWYSW75DE5RAJUQEYWYRORPN3CABUCGCU7VY",
	"C5A2PCKHFYQODTEJQ2NCI57E6KAHYIQYF2S3EII",
	"A6W4QLFT6JZYTIJLNOOCWJUL3X6R3FDY3HW2BVY",
	"3G6WOYH3QGNIUPHOOUYD7AQI7SR6COFVC7NLSNA",
	"T7HSDKJDNQWBFBQ72IHR7MK2DB6NP3TYEH3SXZY",
	"OPIWK5U3GTNG6FIUMTTBCFOQ4CNGN6GQ7ICJOJQ",
	"ORMAX6UI52QDYDVOOIXYDGL6IAGZZQS7UAYR36Q",
	"4PDKG2MCBYTHZE4NE5VILCJIAQGHYJNIEZIB3RY",
	"YIFNSDNQXC7OAM25A2JFTGIQMCLJ53E7SOPEZJY",
	"6N2G6TGWUGOMCN6F7TEPMCSMBJ7VNWLRSC32TQQ",
	"MOR3PHVPHXZVDAEWARSQLHAK33QG2RIXTJLCQTY",
	"MBVP3AZ5BATCRVMGOJAD5ZW3GSHG62GYZUMUP6A",
	"OVT6VDQQZPZRF6CHRN6FDWD3AC3M6PPIFMB5ZZY",
	"3PG4FONYLCPWY5QWWVNQLGZ3HY4NS6U6NXY7FGQ",
	"CXMZBH4NNFUJ47TYUDNZFAMUUWLCHZZFHKU5IAA",
	"3Y4VRHOMBRSUQZ4UHAAZI24YRCZUOUTCPHFBLPI",
	"GT5HY5HOM7A7SLAL4HH5JMXUNIKP7OMZMBESL5Q",
	"32RM6ILFACIWWHX4JGFYI5U5CD6CUTYFDHR5POI",
	"DGD6BKKGH3AQUVA7DDOZWS2LRPYTCG5C23GNLKA",
	"KAQ2LYN7TEYGNVIVRGTWRL4FDSS7GPIRVRRY3KY",
	"RY4HR4SOJ32AV72H7CEFIIXV243JAEZCRVXFNGA",
	"YDS3SGLNKTO2XBRYTXRT6CQFC5RPCTWY4VIR6VA",
	"TOZ7PTUDBNRYA2P4PUAOWH3ARMW7ADF3R4R5XZQ",
	"2VN5HKX2D4YH3IQMMILR5OU3KSVZFUU6YLGSNIY",
	"AHDZC2W5Y6YBQNKPIJQLYXUJ3IWCTAZPBF24SGQ",
	"G7YYLV7LIVZSYBBAKYZ4R6BUWXO7KHZ7KVPPKRI",
	"QGC3IZH4PMI64TRRC24QESZKGUEXJMLFE6LCRUI",
	"MAO56LXX4CO7KHF3VRBXN6ROPZYA3F6OU5HEOZA",
	"NXJZ3LLKNFIGECW3KK4FLRFYJXR656BBRUZGGOA",
	"YRUYD3AKI3SIVIH5JTQV425AVNCS363J4YGK5QY",
	"WBZK3JBTM5J7OQ62IPALVEV3X66UY54RM427YJA",
	"YYF7KUUYFKY5O6QO7HXAQA5TZVVMZKJEPKKUC3Q",
	"AAM2ABFELIJXLKNODF4AHLNHSOMIKTKPT742OZI",
	"3YUIDE5QJGJVRXXX47FZFFDVPFQ4UZFPEQWBXHQ",
	"HK7TEYEMKYVUHFUB25XJC2ZRBKBHLHRFUHKORMA",
	"MGF5LPUOV2QUETHAAKGHYXQYXEKD7GG4HP2UN5Y",
	"EKNBK6YSSIDDZTUZKW2S6QJRX3WQRBPAZXNJDDQ",
	"HWWBBJ3Y2V7T73HZVQ7G2YPBTZEIPCKGZHJHGWQ",
	"TUSLJITDCZP7K3IEZHD6PH5ZJN7TFQOUIIXAOMQ",
	"E7VYSFDMRIGE5OULOWP67BCEA5IKCQLTUTVTNWA",
	"XYJETXKBVW57IIUABPGKJI46XREQSTZUFMDNFGQ",
	"PTYB2XTVSY7XRYNLNARPN6NAZOCGBVTLVOZUYXY",
	"WVAE3KBQLN2WWLOE4YFU447H7PRALW3IMWIEL3A",
	"RJC52KLP336OETVMOHIYMSM5IWD5FY2C77HTZEI",
	"7SEPD75TGIFSJQOYC232N4YCYRXC7NC7SLVR73Y",
	"DJ6AGOILGDVFL5ZJGRUU7JTCEJFWPSU6MYHH6RI",
	"CTNJSYU245C6H3UIQVY5RMNJ3OPBWHMB4V76OJQ",
	"OGORC6O2MB6IDTKYUILD6W2AY3RRDQBACL6JVPQ",
	"IJ4336JAXNGBHTHNBYNQ7TS6O4V6POP7UHARAZY",
	"U7EFYE2KTRCPB4DRU6EB4F2JGOANBN7RMHLJ4YI",
	"IHKFGKRUUBEWCPAAQJKUOM5ZFG3FP3GHWHGNQRA",
	"TODCDW4LPZS2NWK5DRIBA3J5G2GCHIO2PIIVXGA",
	"LRLOEZ3HQRTTPTIK3MMEUJCOIBNRDJM4KD4R2BQ",
	"IDPALYFIHCRENOVNATHEF6CWEDWEVDGVFSU2MWI",
	"2MBXSFC6RFO674PVSF7FIVW7JIZJUCNFRZ3TMPY",
	"HLMYUQO5K6FQGCU6TKVG7G55XQ6P6W5UGJTPZMY",
	"IYG2OE2T5QEKYYH7U4PWQEKAMGNU4XOO3X3E2JA",
	"KZLRXQ3K5KXF7HEIBMMNGZWXXF2NTNKKKCBZURA",
	"THSWZB6CU6TYPB6YEODWJI6GPTARSN3O2OWFTNQ",
	"6TOHWP2AIVPZSFU7S5KOBTX3H7TOQG7YCSWMKCI",
	"ZXTONTTSRYXGLT2JC75OMWFUVBDSLLYGMYKT72Y",
	"MRIZWQYCM7QE2A4UOJB2XLQ6T3FRDQ7SP7JEZ2I",
	"PZTTS46DJG2PMYTLOHDRR3DOKNGHOWINXBHWE7Q",
	"W2OFMNVOWMDAL5WKJJTRX2BYXM5KBHH3OUKEGQY",
	"JJCDGWPQ3LB34AWD2XX3UEN23P2XXJZ2YXPHWEA",
	"3F5FSYBRDWYQMEFEFSUAUG44A3QUQLVOHZNOODQ",
	"E4OHMFFQFIOYB4K7DHVGBXYC54SXF3QO3C3Y3FI",
	"ZA6NHVBVUIIRDY6BCXWOBWQD5TASWUV3KZNDI4Y",
	"YJCMEZZ2JGFJUW2Y2Y2WOO42KIAYXHHLTX6EPYI",
	"XD6JPM6DMKD6NTPPFEFOB57EOBUDMJP4LBD7ZFQ",
	"OZBHUSVBAVJZBYOVUHVMKBALFYXP345BGQ4XSSQ",
	"4QA33HZMJJPNT4XSXCJTKYKJ6V7DMQ73225Q2TY",
	"F5SLLM6AXAVPOAULYDB2TLY3J32GJZ5ZNTQNFUY",
	"VWXRK7F3R2ZLMCEUMK3QN6Y7BXI4O2UC7V3OKJA",
	"HYIRWDFF6PDAJDEWDWCJAOVER4ZAHC4MGXF7VXA",
	"OARGE3NPDEUZCF5LKXLCLP47IAPEKKH62HDHK3Y",
	"2FEP6FOWAMLPZE43I64EE6LYWVP7MUBHCBEODAA",
	"IYNG4VYBO32ADGEQ4GQH3AAKY2UGILZDY5TG6GY",
	"MELMIUEKN24DJIPKRPM4XYWCTED5KBIILWZBHUQ",
	"D7F6NJVK53BPIZHZFYIANJJ3VDI56ZX3ID4QDWA",
	"JEUJXOTM77T7SLFBA2L3Q6I7MQP5HUZL7CFKS7Y",
	"ORDNK5DB6T5IHQJE4NLS5DF7VZU2FTV3H565SEI",
	"HTJD4F42BZ64RNWGMMJVM7LTW4VRKW4JHZGFDHI",
	"G7QTMS6DLMKVEOOMFS4A2YWWEEXGOR67SDCTZCQ",
	"KDF4GLZP4WGFGTNPVIEZTOYMMBBS5HIIJUTFUDI",
	"FWQBOAZMVQLA4E5BMEVLK6DRWOMEXDZ7BVARFTA",
	"6RSPTN2DJSEJUY2VBLSRIUWH3VG2TZBZWBR7IZA",
	"6IARIZQCKVK7HLJSHXBWELEIAUKMGLP273ZIXOQ",
	"NB7CEN3VJPU7ZBCITQAXNHZKINMLIGW7ANVYFZA",
	"RJC44IPNNHRCFEXLBT7LZ455NRU45XWPF4DKDBI",
	"5MOCB7SLPFJSVM553DHRRVRJSBV7EGPHE3C36QA",
	"7DJXLJEVKAM7XHQPPPKSNMBWXT3COBEL7XFRITI",
	"6BBPKU43LJ2RLSRZBOKGMPEBX536DSPHWOIV6EA",
	"PI4E3BDUPERN6CXYMK5X3UQMWORLAMMP4VPUZWA",
	"YZWIPSJZQNMJZJO47DRZ2ZLXUSD2RSXJ6F4BJBA",
	"4HIQKOIHLZOWZNJF36BHTIHGFPYLDYOMIS5HPEY",
	"EB4HKLKAQP7ZEHWLNYLBJSDAIPD5GCH6F22W5UY",
	"2GR57JDXL3TCEYOUTHGXRAY2ZKO3A3G2NQ3GRHA",
	"AZ635YQX5IHUIJ5IKYZVV4EVYDBIOTBOYJHECGI",
	"DN32SZO6SEU7SEHU23ZNPKWFBEA6ADNT2BWF2QQ",
	"2XJ5TSJ7UKK7MJPBO4NBBW5FXPLNFISJ7EPER7I",
	"JB55WLFKIR3PLVAK6BGG65LVG56JQX224MJ6G2Y",
	"4MW7ZSNBX4LSURKHSIYAEEFFGPUJOMRVG4QJALY",
	"XT3ASJ6DIECY5VYWHLV7CPVERVXNFBGUW3VQ3HI",
	"QQNEFKUIIPKFQM6Y4XSKAHYD3OAT75ZHXW6366A",
	"EUXMMGHHGC6HZ7UGMFNJZCOSXYTA7PDM3UUWEFY",
	"5MYSTBUSOYXB6W5XUTPYD2A3XEHA2JJTEKSGPMI",
	"72XGOD2IY7MFXK3URTCMBEVAPIRP44ZUOERJXGI",
	"DOF4GVPB3UQFM2FXKX5XZPEL3MYVIJG53QQEXFY",
	"NZQZPSB3Y4NY5R6NZSDZZEYNFJW77OGVC63JQ6A",
	"4LKYFNQQUE2JBDR5MZ74KX54RHSWGBWCQVMKSKY",
	"XH5YMKIQHK6COXGT4JBY5IO5SQTS6IZ4PDIFZII",
	"TZPF64R4YI6QL3ZN2UW3Z3YJQOIG5ACDZ47WDPA",
	"S5PGNXT2WOIMIZDU3DHAIWVDJ25NWGUU3VEPDII",
	"ZTCDIG52EXSTQSNXMFZVYXIB5MX2CCMEZEAWGTY",
	"GTUJMZY2CSZQ3WX6A23BCGRBCBY3GLQ4VVL67RY",
	"BOOXD4JIXX6WRN6BQU6JDZ76PEMDHN24UF4EAEA",
	"75JXVY2ZT4JJNWRKSTVYOY3UDRSYOEIX2QYL3TQ",
	"4EVUFPLLBEXNBX7DC65LR3ELULPDXYKAQO2RRFI",
	"3RC2GTPP5M4RAZAOI5ZTTFJFOIE7I4THW6JP5HY",
	"ISM2YBQKIDZMLDARHCN75AAWVAVD5ISHIA7PJAI",
	"BLB4GRYDVNHZNGZJRP4I53IR2JYXA66OLSWK6SA",
	"YO3ZP3NESLRUOJWJ2Z2ZCMTXR53DA3RSCMJSWFY",
	"FC4BPAJVHCW4D6GDYVQCIA34S5YESFTXSWPVIAY",
	"VQWALTQ2VV66M75RRCRG4ZEFBBHER6TLHQ6VG3I",
	"FCGJCN4WPOTGMZBBLMDKG5SJLIRT7HPFWOYAIJY",
	"XABLN2BETS3DMOFSDWSMBCNBN4AECT75GTQZ6GA",
	"5YBTJHDV6AILPCSIPTHMNADWKE645GX3N4MHZXA",
	"N6F6BY5IP7IJNT2X7TRRY3SCZ4ATZ5VHGZ7EFQQ",
	"JAAEWOBNORJASTMJ3JUFMZFZCVLF7ECHPTORUXY",
	"HX6GPU5GUAT5MJKE5O63XWYAFA4ZX5KY6RKRP2Q",
	"G42Q47J2JYQO5L6CDRH2ODBHUIEAG6XHLMHSFIQ",
	"QEIE7IKMSAI5UIVDJRMYMPFDHBEU7YRZF2BYGVI",
	"G3VSBYIRM76QI4I36PQ36JGJXHNABSOLRZRN4QA",
	"BBXWENR7SUAV2OPOWT3BEZWQEQETQFMVHHAOZ5Y",
	"O72GHKBQVOD2SM2UH5DWLSBROAPDO77WCFPLMJY",
	"SSIRRW6I47HUQLBCJU47HROY52OWN6VGKYERCPA",
	"PUMGP24L3C3BK6OLUNN75H6TNTXGO47BJYQLYQY",
	"GD2TAVFT3EMTPGL32ZQAFBZ7T65QAKJ4QFFYNAA",
	"7XPTUXVFHWNKGNK6SU4DJBBXR23NOWIEO4LZGNY",
	"V66BL34FLEWONDE4Z6WCE6OOE4SXJ2A767VGJBI",
	"DZ4DTF7KCDSBBUXQV3ENXBV3QBNVCJNURAL6VFY",
	"Z63ZRRF5CFJ2JODAZ7DUFFGGIIIO26XHC2BYCEA",
	"SCIIV6BFYPFII5GNTWGEEAPBUEXJOYYP67LOGVA",
	"UMC6OJR6MLYN6ZWWL2XM5CQC7TROEI4P67C4PJQ"
    };
    int i;
    name[255] = '\0';
    for (i = 0; i < 256; ++i) {
	/* Avoid snprintf because it's not C90 */
	sprintf(name, "<characters 0..%d, length %d>", i, i + 1);
	buf[i] = (char)i;
	if (help_cmp_base32_bin(name, buf64, i + 1, results[i]))
	    return 1;
    }
    return 0;
}	

static int test_tiger192_alignment() {
    uint64_t res[3];
    char buf[127];

    memset(buf, (int)'A', 127);
    tiger_bp(0x00, buf, 127, res);
    TEST_PASS3(res[0] == _ULL(0x007bbdabb402654c)
	    && res[1] == _ULL(0xaa7aefd7cb812b2d)
	    && res[2] == _ULL(0x1df2166aea456fca),
	    "Tiger BP hash result for \"<127*A>\" is wrong! "
	    "Expected 007bbdabb402654c aa7aefd7cb812b2d 1df2166aea456fca, "
	    "got %016" PRIx64 " %016" PRIx64 " %016" PRIx64 ".\n",
	    res[0], res[1], res[2]);

    /* The ARM fails on this second one when unaligned access is attempted on the
     * last int64. It rotates some values and ends up with 8*A instead of 7*A+LF.
     */
    buf[126] = '\n';
    tiger_bp(0x00, buf, 127, res);
    TEST_PASS3(res[0] == _ULL(0x8dfae2bea717c033)
	    && res[1] == _ULL(0x91fc74dffb9eba48)
	    && res[2] == _ULL(0xe62d12fd8ef213af),
	    "Tiger BP hash result for \"<126*A+LF>\" is wrong! "
	    "Expected 8dfae2bea717c033 91fc74dffb9eba48 e62d12fd8ef213af, "
	    "got %016" PRIx64 " %016" PRIx64 " %016" PRIx64 ".\n",
	    res[0], res[1], res[2]);

    return 0;
}

static int test_tiger192_abelarm_o3() {
    uint64_t res[3];
    uint64_t const out[] = {
	_ULL(0x60d56f0949e7560f), _ULL(0xcf62a9d35ea20959),
	_ULL(0xd4f5836a7ce76166), /* 0..124 (len=125) */
	_ULL(0x6baec4efc36d6da1), _ULL(0xf87ff3d2852f0250),
	_ULL(0xfbdb48ea8c361c38), /* 0..125 (len=126) */
	_ULL(0xa950e3ff469b7cc2), _ULL(0xd2e5105a998e1647),
	_ULL(0x7dc3bc1a875015b5), /* 0..126 (len=127) */
	_ULL(0xaa322e0262d43ccd), _ULL(0x85e408a00248ee64),
	_ULL(0x327f3eec7f32687e)  /* 0..127 (len=128) */
    };
    char buf[128];
    int i, j;
    int failures = 0;

    /* A different ARM (abel@debian) fails on this one with -O3 optimization
     * when an uint64_t pointer is pointing to unaligned memory. */
    for (i = 0; i < 128; ++i)
	buf[i] = (char)i;
    for (i = 0, j = 125; j <= 128 /* i < 4 * 3 */; i += 3, ++j) {
	tiger_bp(0x00, buf, j, res);
	if (res[0] != out[i] || res[1] != out[i+1] || res[2] != out[i+2]) {
	    fprintf(stderr, ">>> %s:%i: Tiger BP hash result for \"<\\x00.."
			    "\\x%hhx is wrong! Expected %016" PRIx64 " %016"
			    PRIx64 " %016" PRIx64 ", got %016" PRIx64 " %016"
			    PRIx64 " %016" PRIx64 ".\n", __FILE__, __LINE__,
			    j - 1, out[i], out[i+1], out[i+2], res[0], res[1],
			    res[2]);
	    ++failures;
	}
    }
    if (failures)
	return 1;

    return 0;
}


TESTS(tiger_test)
    TEST(test_tiger192_nessie_1a);
    TEST(test_tiger192_nessie_1b);
    TEST(test_tiger192_ross_and_eli);
    TEST(test_tiger192_0to255);
    TEST(test_tiger192_alignment);
    TEST(test_tiger192_abelarm_o3);
ENDTESTS
