From 1eed98f629b5a1295143be2a911d589b3307951f Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Sun, 18 Jun 2006 01:37:50 +0000 Subject: [PATCH] added libtomcrypt-1.13 --- Doxyfile | 2 +- TODO | 6 +- changes | 15 +- crypt.tex | 20 +- demos/multi.c | 32 +- demos/small.c | 2 +- demos/timing.c | 7 + demos/tv_gen.c | 6 +- doc/crypt.pdf | Bin 646735 -> 647443 bytes makefile | 31 +- makefile.icc | 29 +- makefile.msvc | 29 +- makefile.shared | 31 +- src/ciphers/anubis.c | 3116 ++++++++--------- src/hashes/helper/hash_filehandle.c | 1 + src/hashes/helper/hash_memory.c | 1 + src/hashes/helper/hash_memory_multi.c | 1 + src/headers/tomcrypt.h | 4 +- src/headers/tomcrypt_argchk.h | 9 + src/headers/tomcrypt_cipher.h | 34 +- src/headers/tomcrypt_custom.h | 3 + src/headers/tomcrypt_math.h | 15 +- src/headers/tomcrypt_pk.h | 2 +- src/math/fp/ltc_ecc_fp_mulmod.c | 96 +- src/math/gmp_desc.c | 16 +- src/math/ltm_desc.c | 11 +- src/math/tfm_desc.c | 21 +- src/misc/base64/base64_encode.c | 1 + src/misc/crypt/crypt.c | 3 + src/misc/zeromem.c | 2 +- src/modes/cbc/cbc_getiv.c | 1 + src/modes/cfb/cfb_getiv.c | 1 + src/modes/ctr/ctr_getiv.c | 1 + src/modes/f8/f8_decrypt.c | 43 + src/modes/f8/f8_done.c | 42 + src/modes/f8/f8_encrypt.c | 68 + src/modes/f8/f8_getiv.c | 46 + src/modes/f8/f8_setiv.c | 52 + src/modes/f8/f8_start.c | 91 + src/modes/f8/f8_test_mode.c | 75 + src/modes/lrw/lrw_getiv.c | 1 + src/modes/ofb/ofb_getiv.c | 1 + src/pk/asn1/der/bit/der_decode_bit_string.c | 1 + src/pk/asn1/der/bit/der_encode_bit_string.c | 1 + src/pk/asn1/der/boolean/der_encode_boolean.c | 1 + src/pk/asn1/der/ia5/der_decode_ia5_string.c | 1 + src/pk/asn1/der/ia5/der_encode_ia5_string.c | 1 + src/pk/asn1/der/integer/der_encode_integer.c | 1 + .../der_encode_object_identifier.c | 1 + .../asn1/der/octet/der_decode_octet_string.c | 1 + .../asn1/der/octet/der_encode_octet_string.c | 1 + .../der_decode_printable_string.c | 1 + .../der_encode_printable_string.c | 1 + .../der/sequence/der_encode_sequence_ex.c | 1 + .../short_integer/der_encode_short_integer.c | 1 + src/pk/asn1/der/utctime/der_encode_utctime.c | 1 + src/pk/dsa/dsa_decrypt_key.c | 1 + src/pk/dsa/dsa_free.c | 2 +- src/pk/dsa/dsa_shared_secret.c | 1 + src/pk/ecc/ecc_decrypt_key.c | 1 + src/pk/ecc/ecc_free.c | 2 +- src/pk/ecc/ecc_shared_secret.c | 1 + src/pk/ecc/ecc_sizes.c | 4 +- src/pk/ecc/ltc_ecc_points.c | 2 +- src/pk/ecc/ltc_ecc_projective_add_point.c | 10 +- src/pk/katja/katja_encrypt_key.c | 1 + src/pk/katja/katja_exptmod.c | 1 + src/pk/pkcs1/pkcs_1_oaep_decode.c | 1 + src/pk/pkcs1/pkcs_1_oaep_encode.c | 1 + src/pk/pkcs1/pkcs_1_pss_encode.c | 1 + src/pk/rsa/rsa_encrypt_key.c | 1 + src/pk/rsa/rsa_exptmod.c | 1 + src/pk/rsa/rsa_free.c | 2 +- src/pk/rsa/rsa_sign_hash.c | 1 + src/prngs/fortuna.c | 22 +- src/prngs/rc4.c | 1 + src/prngs/sober128.c | 1 + src/prngs/yarrow.c | 1 + testprof/der_tests.c | 48 +- testprof/makefile | 2 +- testprof/makefile.icc | 2 +- testprof/makefile.msvc | 2 +- testprof/makefile.shared | 2 +- testprof/modes_test.c | 4 + testprof/{test.c => test_driver.c} | 0 testprof/tomcrypt_test.h | 2 +- testprof/x86_prof.c | 20 +- 87 files changed, 2390 insertions(+), 1733 deletions(-) create mode 100644 src/modes/f8/f8_decrypt.c create mode 100644 src/modes/f8/f8_done.c create mode 100644 src/modes/f8/f8_encrypt.c create mode 100644 src/modes/f8/f8_getiv.c create mode 100644 src/modes/f8/f8_setiv.c create mode 100644 src/modes/f8/f8_start.c create mode 100644 src/modes/f8/f8_test_mode.c rename testprof/{test.c => test_driver.c} (100%) diff --git a/Doxyfile b/Doxyfile index f172aa1..7c7e195 100644 --- a/Doxyfile +++ b/Doxyfile @@ -23,7 +23,7 @@ PROJECT_NAME = LibTomCrypt # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 1.12 +PROJECT_NUMBER = 1.13 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/TODO b/TODO index 253469f..ce7fce1 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,2 @@ -- document new math function count_lsb_bits -- add BOOLEAN type to the ASN world - -- ECC fixed point accelerator -- look into X9.63 support [in addition to the LTC style ecc_encrypt_key() not replacing] +- long term, start moving macros like CTR over to LTC_CTR to make LTC a bit more "drop-in-able". diff --git a/changes b/changes index 0222e1b..2bfe328 100644 --- a/changes +++ b/changes @@ -1,3 +1,14 @@ +June 17th, 2005 +v1.13 -- Fixed to fortuna_start() to clean up state if an error occurs. Not really useful at this stage (sha256 can't fail) but useful + if I ever make fortuna pluggable + -- Mike Marin submitted a whole bunch of patches for fixing up the libs on traditional UNIX platforms. Go AIX! Thanks! + -- One of bugs found in the multi demo highlights that at least with gcc you need to pass integers with a UL prefix to ensure + they're unsigned long + -- Updated the FP ECC code to use affine points. It's teh fast. + -- Made it so many functions which return CRYPT_BUFFER_OVERFLOW now also indicate the required buffer size, note that not all functions + do this (most do though). + -- Added F8 chaining mode. It's super neato. + May 29th, 2006 v1.12 -- Fixed OID encoder/decoder/length to properly handle the first two parts of an OID, matches 2002 X.690 now. -- [Wesley Shields] Allows both GMP/LTM and TFM to be defined now. @@ -1453,6 +1464,6 @@ v0.02 -- Changed RC5 to only allow 12 to 24 rounds v0.01 -- We will call this the first version. /* $Source: /cvs/libtom/libtomcrypt/changes,v $ */ -/* $Revision: 1.206 $ */ -/* $Date: 2006/05/29 11:21:25 $ */ +/* $Revision: 1.213 $ */ +/* $Date: 2006/06/18 01:42:59 $ */ diff --git a/crypt.tex b/crypt.tex index 78537c0..81ddaae 100644 --- a/crypt.tex +++ b/crypt.tex @@ -47,7 +47,7 @@ \def\gap{\vspace{0.5ex}} \makeindex \begin{document} -\title{LibTomCrypt \\ Version 1.12} +\title{LibTomCrypt \\ Version 1.13} \author{Tom St Denis \\ \\ tomstdenis@gmail.com \\ @@ -280,8 +280,7 @@ There are 32 and 64-bit cyclic rotations as well: \section{Functions with Variable Length Output} Certain functions such as (for example) ``rsa\_export()'' give an output that is variable length. To prevent buffer overflows you -must pass it the length of the buffer\footnote{Extensive error checking is not in place but it will be in future releases so it is a good idea to follow through with these guidelines.} where -the output will be stored. For example: +must pass it the length of the buffer where the output will be stored. For example: \begin{small} \begin{verbatim} #include @@ -313,6 +312,9 @@ In the above example if the size of the RSA public key was more than 1024 bytes indicating a buffer overflow would have occurred. If the function succeeds it stores the length of the output back into ``x'' so that the calling application will know how many bytes were used. +As of v1.13, most functions will update your length on failure to indicate the size required by the function. Not all functions +support this so please check the source before you rely on it doing that. + \section{Functions that need a PRNG} \index{Pseudo Random Number Generator} \index{PRNG} Certain functions such as ``rsa\_make\_key()'' require a Pseudo Random Number Generator (PRNG). These functions do not setup @@ -5018,6 +5020,14 @@ typedef struct { */ int (*mulmod)(void *a, void *b, void *c, void *d); + /** Modular squaring + @param a The first source + @param b The modulus + @param c The destination (a*a mod b) + @return CRYPT_OK on success + */ + int (*sqrmod)(void *a, void *b, void *c); + /** Modular inversion @param a The value to invert @param b The modulus @@ -5231,5 +5241,5 @@ Since the function is given the entire RSA key (for private keys only) CRT is po \end{document} % $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $ -% $Revision: 1.71 $ -% $Date: 2006/05/29 11:19:08 $ +% $Revision: 1.74 $ +% $Date: 2006/06/18 01:35:41 $ diff --git a/demos/multi.c b/demos/multi.c index 33d17a2..424a190 100644 --- a/demos/multi.c +++ b/demos/multi.c @@ -13,21 +13,21 @@ int main(void) /* HASH testing */ len = sizeof(buf[0]); - hash_memory(find_hash("sha256"), "hello", 5, buf[0], &len); + hash_memory(find_hash("sha256"), (unsigned char*)"hello", 5, buf[0], &len); len2 = sizeof(buf[0]); - hash_memory_multi(find_hash("sha256"), buf[1], &len2, "hello", 5, NULL); + hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"hello", 5, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); - hash_memory_multi(find_hash("sha256"), buf[1], &len2, "he", 2, "llo", 3, NULL); + hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL, 0); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); - hash_memory_multi(find_hash("sha256"), buf[1], &len2, "h", 1, "e", 1, "l", 1, "l", 1, "o", 1, NULL); + hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; @@ -35,21 +35,21 @@ int main(void) /* HMAC */ len = sizeof(buf[0]); - hmac_memory(find_hash("sha256"), key, 16, "hello", 5, buf[0], &len); + hmac_memory(find_hash("sha256"), key, 16, (unsigned char*)"hello", 5, buf[0], &len); len2 = sizeof(buf[0]); - hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, "hello", 5, NULL); + hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); - hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, "he", 2, "llo", 3, NULL); + hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); - hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, "h", 1, "e", 1, "l", 1, "l", 1, "o", 1, NULL); + hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; @@ -57,21 +57,21 @@ int main(void) /* OMAC */ len = sizeof(buf[0]); - omac_memory(find_cipher("aes"), key, 16, "hello", 5, buf[0], &len); + omac_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len); len2 = sizeof(buf[0]); - omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, "hello", 5, NULL); + omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); - omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, "he", 2, "llo", 3, NULL); + omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); - omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, "h", 1, "e", 1, "l", 1, "l", 1, "o", 1, NULL); + omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; @@ -79,21 +79,21 @@ int main(void) /* PMAC */ len = sizeof(buf[0]); - pmac_memory(find_cipher("aes"), key, 16, "hello", 5, buf[0], &len); + pmac_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len); len2 = sizeof(buf[0]); - pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, "hello", 5, NULL); + pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); - pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, "he", 2, "llo", 3, NULL); + pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); - pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, "h", 1, "e", 1, "l", 1, "l", 1, "o", 1, NULL); + pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; diff --git a/demos/small.c b/demos/small.c index f320424..8d43821 100644 --- a/demos/small.c +++ b/demos/small.c @@ -1,4 +1,4 @@ -// small demo app that just includes a cipher/hash/prng +/* small demo app that just includes a cipher/hash/prng */ #include int main(void) diff --git a/demos/timing.c b/demos/timing.c index 8313332..fc76842 100644 --- a/demos/timing.c +++ b/demos/timing.c @@ -16,6 +16,13 @@ reg_algs(); extern ltc_math_descriptor EXT_MATH_LIB; ltc_mp = EXT_MATH_LIB; #endif +time_cipher(); +time_hash(); +time_encmacs(); +time_rsa(); +time_ecc(); +time_ecc(); +return 0; time_keysched(); time_cipher(); time_cipher2(); diff --git a/demos/tv_gen.c b/demos/tv_gen.c index eae4898..4d4db06 100644 --- a/demos/tv_gen.c +++ b/demos/tv_gen.c @@ -685,9 +685,9 @@ void ecc_gen(void) while (mp_cmp(k, order) == LTC_MP_LT) { ltc_mp.ecc_ptmul(k, G, R, modulus, 1); - mp_tohex(k, str); fprintf(out, "%s, ", str); - mp_tohex(R->x, str); fprintf(out, "%s, ", str); - mp_tohex(R->y, str); fprintf(out, "%s\n", str); + mp_tohex(k, (char*)str); fprintf(out, "%s, ", (char*)str); + mp_tohex(R->x, (char*)str); fprintf(out, "%s, ", (char*)str); + mp_tohex(R->y, (char*)str); fprintf(out, "%s\n", (char*)str); mp_mul_d(k, 3, k); } } diff --git a/doc/crypt.pdf b/doc/crypt.pdf index 316030b42d56af437e1953f12c11328aff900b98..feae4a718738106f448a91812839d76029c7287e 100644 GIT binary patch delta 81677 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%0A*&I7L+nu_j5hiCf3nqe$nUPHJ+H;kC_qaqa^PuU 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≧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 delta 80869 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 UUTei5l!K{dF-=Vi2TQU42d$ohrvLx| diff --git a/makefile b/makefile index b460814..e55c666 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ # Modified by Clay Culver # The version -VERSION=1.12 +VERSION=1.13 # Compiler and Linker Names #CC=gcc @@ -150,18 +150,19 @@ src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o \ src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o \ src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o \ src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \ -src/modes/ecb/ecb_start.o src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o \ -src/modes/lrw/lrw_encrypt.o src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o \ -src/modes/lrw/lrw_setiv.o src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o \ -src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o src/modes/ofb/ofb_encrypt.o \ -src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ -src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \ -src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \ -src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \ -src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/ia5/der_decode_ia5_string.o \ -src/pk/asn1/der/ia5/der_encode_ia5_string.o src/pk/asn1/der/ia5/der_length_ia5_string.o \ -src/pk/asn1/der/integer/der_decode_integer.o src/pk/asn1/der/integer/der_encode_integer.o \ -src/pk/asn1/der/integer/der_length_integer.o \ +src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o src/modes/f8/f8_encrypt.o \ +src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o src/modes/f8/f8_test_mode.o \ +src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o src/modes/lrw/lrw_encrypt.o \ +src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o src/modes/lrw/lrw_setiv.o \ +src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \ +src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \ +src/modes/ofb/ofb_start.o src/pk/asn1/der/bit/der_decode_bit_string.o \ +src/pk/asn1/der/bit/der_encode_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \ +src/pk/asn1/der/boolean/der_decode_boolean.o src/pk/asn1/der/boolean/der_encode_boolean.o \ +src/pk/asn1/der/boolean/der_length_boolean.o src/pk/asn1/der/choice/der_decode_choice.o \ +src/pk/asn1/der/ia5/der_decode_ia5_string.o src/pk/asn1/der/ia5/der_encode_ia5_string.o \ +src/pk/asn1/der/ia5/der_length_ia5_string.o src/pk/asn1/der/integer/der_decode_integer.o \ +src/pk/asn1/der/integer/der_encode_integer.o src/pk/asn1/der/integer/der_length_integer.o \ src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \ src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ src/pk/asn1/der/object_identifier/der_length_object_identifier.o \ @@ -366,5 +367,5 @@ zipup: no_oops docs # $Source: /cvs/libtom/libtomcrypt/makefile,v $ -# $Revision: 1.123 $ -# $Date: 2006/05/25 10:33:01 $ +# $Revision: 1.126 $ +# $Date: 2006/06/16 23:52:08 $ diff --git a/makefile.icc b/makefile.icc index dcc06cc..9fd0928 100644 --- a/makefile.icc +++ b/makefile.icc @@ -142,18 +142,19 @@ src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o \ src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o \ src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o \ src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \ -src/modes/ecb/ecb_start.o src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o \ -src/modes/lrw/lrw_encrypt.o src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o \ -src/modes/lrw/lrw_setiv.o src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o \ -src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o src/modes/ofb/ofb_encrypt.o \ -src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ -src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \ -src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \ -src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \ -src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/ia5/der_decode_ia5_string.o \ -src/pk/asn1/der/ia5/der_encode_ia5_string.o src/pk/asn1/der/ia5/der_length_ia5_string.o \ -src/pk/asn1/der/integer/der_decode_integer.o src/pk/asn1/der/integer/der_encode_integer.o \ -src/pk/asn1/der/integer/der_length_integer.o \ +src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o src/modes/f8/f8_encrypt.o \ +src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o src/modes/f8/f8_test_mode.o \ +src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o src/modes/lrw/lrw_encrypt.o \ +src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o src/modes/lrw/lrw_setiv.o \ +src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \ +src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \ +src/modes/ofb/ofb_start.o src/pk/asn1/der/bit/der_decode_bit_string.o \ +src/pk/asn1/der/bit/der_encode_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \ +src/pk/asn1/der/boolean/der_decode_boolean.o src/pk/asn1/der/boolean/der_encode_boolean.o \ +src/pk/asn1/der/boolean/der_length_boolean.o src/pk/asn1/der/choice/der_decode_choice.o \ +src/pk/asn1/der/ia5/der_decode_ia5_string.o src/pk/asn1/der/ia5/der_encode_ia5_string.o \ +src/pk/asn1/der/ia5/der_length_ia5_string.o src/pk/asn1/der/integer/der_decode_integer.o \ +src/pk/asn1/der/integer/der_encode_integer.o src/pk/asn1/der/integer/der_length_integer.o \ src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \ src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ src/pk/asn1/der/object_identifier/der_length_object_identifier.o \ @@ -276,6 +277,6 @@ install: library install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) # $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $ -# $Revision: 1.56 $ -# $Date: 2006/05/25 10:33:01 $ +# $Revision: 1.58 $ +# $Date: 2006/06/16 23:52:08 $ diff --git a/makefile.msvc b/makefile.msvc index 3e351c7..fa310e0 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -52,18 +52,19 @@ src/modes/cfb/cfb_getiv.obj src/modes/cfb/cfb_setiv.obj src/modes/cfb/cfb_start. src/modes/ctr/ctr_decrypt.obj src/modes/ctr/ctr_done.obj src/modes/ctr/ctr_encrypt.obj \ src/modes/ctr/ctr_getiv.obj src/modes/ctr/ctr_setiv.obj src/modes/ctr/ctr_start.obj \ src/modes/ecb/ecb_decrypt.obj src/modes/ecb/ecb_done.obj src/modes/ecb/ecb_encrypt.obj \ -src/modes/ecb/ecb_start.obj src/modes/lrw/lrw_decrypt.obj src/modes/lrw/lrw_done.obj \ -src/modes/lrw/lrw_encrypt.obj src/modes/lrw/lrw_getiv.obj src/modes/lrw/lrw_process.obj \ -src/modes/lrw/lrw_setiv.obj src/modes/lrw/lrw_start.obj src/modes/lrw/lrw_test.obj \ -src/modes/ofb/ofb_decrypt.obj src/modes/ofb/ofb_done.obj src/modes/ofb/ofb_encrypt.obj \ -src/modes/ofb/ofb_getiv.obj src/modes/ofb/ofb_setiv.obj src/modes/ofb/ofb_start.obj \ -src/pk/asn1/der/bit/der_decode_bit_string.obj src/pk/asn1/der/bit/der_encode_bit_string.obj \ -src/pk/asn1/der/bit/der_length_bit_string.obj src/pk/asn1/der/boolean/der_decode_boolean.obj \ -src/pk/asn1/der/boolean/der_encode_boolean.obj src/pk/asn1/der/boolean/der_length_boolean.obj \ -src/pk/asn1/der/choice/der_decode_choice.obj src/pk/asn1/der/ia5/der_decode_ia5_string.obj \ -src/pk/asn1/der/ia5/der_encode_ia5_string.obj src/pk/asn1/der/ia5/der_length_ia5_string.obj \ -src/pk/asn1/der/integer/der_decode_integer.obj src/pk/asn1/der/integer/der_encode_integer.obj \ -src/pk/asn1/der/integer/der_length_integer.obj \ +src/modes/ecb/ecb_start.obj src/modes/f8/f8_decrypt.obj src/modes/f8/f8_done.obj src/modes/f8/f8_encrypt.obj \ +src/modes/f8/f8_getiv.obj src/modes/f8/f8_setiv.obj src/modes/f8/f8_start.obj src/modes/f8/f8_test_mode.obj \ +src/modes/lrw/lrw_decrypt.obj src/modes/lrw/lrw_done.obj src/modes/lrw/lrw_encrypt.obj \ +src/modes/lrw/lrw_getiv.obj src/modes/lrw/lrw_process.obj src/modes/lrw/lrw_setiv.obj \ +src/modes/lrw/lrw_start.obj src/modes/lrw/lrw_test.obj src/modes/ofb/ofb_decrypt.obj src/modes/ofb/ofb_done.obj \ +src/modes/ofb/ofb_encrypt.obj src/modes/ofb/ofb_getiv.obj src/modes/ofb/ofb_setiv.obj \ +src/modes/ofb/ofb_start.obj src/pk/asn1/der/bit/der_decode_bit_string.obj \ +src/pk/asn1/der/bit/der_encode_bit_string.obj src/pk/asn1/der/bit/der_length_bit_string.obj \ +src/pk/asn1/der/boolean/der_decode_boolean.obj src/pk/asn1/der/boolean/der_encode_boolean.obj \ +src/pk/asn1/der/boolean/der_length_boolean.obj src/pk/asn1/der/choice/der_decode_choice.obj \ +src/pk/asn1/der/ia5/der_decode_ia5_string.obj src/pk/asn1/der/ia5/der_encode_ia5_string.obj \ +src/pk/asn1/der/ia5/der_length_ia5_string.obj src/pk/asn1/der/integer/der_decode_integer.obj \ +src/pk/asn1/der/integer/der_encode_integer.obj src/pk/asn1/der/integer/der_length_integer.obj \ src/pk/asn1/der/object_identifier/der_decode_object_identifier.obj \ src/pk/asn1/der/object_identifier/der_encode_object_identifier.obj \ src/pk/asn1/der/object_identifier/der_length_object_identifier.obj \ @@ -134,5 +135,5 @@ timing: demos/timing.c library cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib $(EXTRALIBS) # $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $ -# $Revision: 1.34 $ -# $Date: 2006/05/25 10:33:01 $ +# $Revision: 1.36 $ +# $Date: 2006/06/16 23:52:08 $ diff --git a/makefile.shared b/makefile.shared index 6f01bc8..4bef699 100644 --- a/makefile.shared +++ b/makefile.shared @@ -6,7 +6,7 @@ # Tom St Denis # The version -VERSION=0:112 +VERSION=0:113 # Compiler and Linker Names CC=libtool --mode=compile --tag=CC gcc @@ -147,18 +147,19 @@ src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o \ src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o \ src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o \ src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \ -src/modes/ecb/ecb_start.o src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o \ -src/modes/lrw/lrw_encrypt.o src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o \ -src/modes/lrw/lrw_setiv.o src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o \ -src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o src/modes/ofb/ofb_encrypt.o \ -src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ -src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \ -src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \ -src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \ -src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/ia5/der_decode_ia5_string.o \ -src/pk/asn1/der/ia5/der_encode_ia5_string.o src/pk/asn1/der/ia5/der_length_ia5_string.o \ -src/pk/asn1/der/integer/der_decode_integer.o src/pk/asn1/der/integer/der_encode_integer.o \ -src/pk/asn1/der/integer/der_length_integer.o \ +src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o src/modes/f8/f8_encrypt.o \ +src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o src/modes/f8/f8_test_mode.o \ +src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o src/modes/lrw/lrw_encrypt.o \ +src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o src/modes/lrw/lrw_setiv.o \ +src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \ +src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \ +src/modes/ofb/ofb_start.o src/pk/asn1/der/bit/der_decode_bit_string.o \ +src/pk/asn1/der/bit/der_encode_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \ +src/pk/asn1/der/boolean/der_decode_boolean.o src/pk/asn1/der/boolean/der_encode_boolean.o \ +src/pk/asn1/der/boolean/der_length_boolean.o src/pk/asn1/der/choice/der_decode_choice.o \ +src/pk/asn1/der/ia5/der_decode_ia5_string.o src/pk/asn1/der/ia5/der_encode_ia5_string.o \ +src/pk/asn1/der/ia5/der_length_ia5_string.o src/pk/asn1/der/integer/der_decode_integer.o \ +src/pk/asn1/der/integer/der_encode_integer.o src/pk/asn1/der/integer/der_length_integer.o \ src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \ src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ src/pk/asn1/der/object_identifier/der_length_object_identifier.o \ @@ -264,5 +265,5 @@ timing: library testprof/$(LIBTEST) $(TIMINGS) gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(EXTRALIBS) # $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $ -# $Revision: 1.55 $ -# $Date: 2006/05/25 10:33:01 $ +# $Revision: 1.58 $ +# $Date: 2006/06/16 23:52:08 $ diff --git a/src/ciphers/anubis.c b/src/ciphers/anubis.c index c23ad66..3cd8bcf 100644 --- a/src/ciphers/anubis.c +++ b/src/ciphers/anubis.c @@ -1,1558 +1,1558 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com - */ - -/** - @file anubis.c - Anubis implementation derived from public domain source - Authors: Paulo S.L.M. Barreto and Vincent Rijmen. -*/ - -#include "tomcrypt.h" - -#ifdef ANUBIS - -const struct ltc_cipher_descriptor anubis_desc = { - "anubis", - 19, - 16, 40, 16, 12, - &anubis_setup, - &anubis_ecb_encrypt, - &anubis_ecb_decrypt, - &anubis_test, - &anubis_done, - &anubis_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - -#define MIN_N 4 -#define MAX_N 10 -#define MIN_ROUNDS (8 + MIN_N) -#define MAX_ROUNDS (8 + MAX_N) -#define MIN_KEYSIZEB (4*MIN_N) -#define MAX_KEYSIZEB (4*MAX_N) -#define BLOCKSIZE 128 -#define BLOCKSIZEB (BLOCKSIZE/8) - - -/* - * Though Anubis is endianness-neutral, the encryption tables are listed - * in BIG-ENDIAN format, which is adopted throughout this implementation - * (but little-endian notation would be equally suitable if consistently - * employed). - */ -#if defined(ANUBIS_TWEAK) - -static const ulong32 T0[256] = { - 0xba69d2bbU, 0x54a84de5U, 0x2f5ebce2U, 0x74e8cd25U, - 0x53a651f7U, 0xd3bb6bd0U, 0xd2b96fd6U, 0x4d9a29b3U, - 0x50a05dfdU, 0xac458acfU, 0x8d070e09U, 0xbf63c6a5U, - 0x70e0dd3dU, 0x52a455f1U, 0x9a29527bU, 0x4c982db5U, - 0xeac98f46U, 0xd5b773c4U, 0x97336655U, 0xd1bf63dcU, - 0x3366ccaaU, 0x51a259fbU, 0x5bb671c7U, 0xa651a2f3U, - 0xdea15ffeU, 0x48903dadU, 0xa84d9ad7U, 0x992f5e71U, - 0xdbab4be0U, 0x3264c8acU, 0xb773e695U, 0xfce5d732U, - 0xe3dbab70U, 0x9e214263U, 0x913f7e41U, 0x9b2b567dU, - 0xe2d9af76U, 0xbb6bd6bdU, 0x4182199bU, 0x6edca579U, - 0xa557aef9U, 0xcb8b0b80U, 0x6bd6b167U, 0x95376e59U, - 0xa15fbee1U, 0xf3fbeb10U, 0xb17ffe81U, 0x0204080cU, - 0xcc851792U, 0xc49537a2U, 0x1d3a744eU, 0x14285078U, - 0xc39b2bb0U, 0x63c69157U, 0xdaa94fe6U, 0x5dba69d3U, - 0x5fbe61dfU, 0xdca557f2U, 0x7dfae913U, 0xcd871394U, - 0x7ffee11fU, 0x5ab475c1U, 0x6cd8ad75U, 0x5cb86dd5U, - 0xf7f3fb08U, 0x264c98d4U, 0xffe3db38U, 0xedc79354U, - 0xe8cd874aU, 0x9d274e69U, 0x6fdea17fU, 0x8e010203U, - 0x19326456U, 0xa05dbae7U, 0xf0fde71aU, 0x890f1e11U, - 0x0f1e3c22U, 0x070e1c12U, 0xaf4386c5U, 0xfbebcb20U, - 0x08102030U, 0x152a547eU, 0x0d1a342eU, 0x04081018U, - 0x01020406U, 0x64c88d45U, 0xdfa35bf8U, 0x76ecc529U, - 0x79f2f90bU, 0xdda753f4U, 0x3d7af48eU, 0x162c5874U, - 0x3f7efc82U, 0x376edcb2U, 0x6ddaa973U, 0x3870e090U, - 0xb96fdeb1U, 0x73e6d137U, 0xe9cf834cU, 0x356ad4beU, - 0x55aa49e3U, 0x71e2d93bU, 0x7bf6f107U, 0x8c050a0fU, - 0x72e4d531U, 0x880d1a17U, 0xf6f1ff0eU, 0x2a54a8fcU, - 0x3e7cf884U, 0x5ebc65d9U, 0x274e9cd2U, 0x468c0589U, - 0x0c183028U, 0x65ca8943U, 0x68d0bd6dU, 0x61c2995bU, - 0x03060c0aU, 0xc19f23bcU, 0x57ae41efU, 0xd6b17fceU, - 0xd9af43ecU, 0x58b07dcdU, 0xd8ad47eaU, 0x66cc8549U, - 0xd7b37bc8U, 0x3a74e89cU, 0xc88d078aU, 0x3c78f088U, - 0xfae9cf26U, 0x96316253U, 0xa753a6f5U, 0x982d5a77U, - 0xecc59752U, 0xb86ddab7U, 0xc7933ba8U, 0xae4182c3U, - 0x69d2b96bU, 0x4b9631a7U, 0xab4b96ddU, 0xa94f9ed1U, - 0x67ce814fU, 0x0a14283cU, 0x478e018fU, 0xf2f9ef16U, - 0xb577ee99U, 0x224488ccU, 0xe5d7b364U, 0xeec19f5eU, - 0xbe61c2a3U, 0x2b56acfaU, 0x811f3e21U, 0x1224486cU, - 0x831b362dU, 0x1b366c5aU, 0x0e1c3824U, 0x23468ccaU, - 0xf5f7f304U, 0x458a0983U, 0x214284c6U, 0xce811f9eU, - 0x499239abU, 0x2c58b0e8U, 0xf9efc32cU, 0xe6d1bf6eU, - 0xb671e293U, 0x2850a0f0U, 0x172e5c72U, 0x8219322bU, - 0x1a34685cU, 0x8b0b161dU, 0xfee1df3eU, 0x8a09121bU, - 0x09122436U, 0xc98f038cU, 0x87132635U, 0x4e9c25b9U, - 0xe1dfa37cU, 0x2e5cb8e4U, 0xe4d5b762U, 0xe0dda77aU, - 0xebcb8b40U, 0x903d7a47U, 0xa455aaffU, 0x1e3c7844U, - 0x85172e39U, 0x60c09d5dU, 0x00000000U, 0x254a94deU, - 0xf4f5f702U, 0xf1ffe31cU, 0x94356a5fU, 0x0b162c3aU, - 0xe7d3bb68U, 0x75eac923U, 0xefc39b58U, 0x3468d0b8U, - 0x3162c4a6U, 0xd4b577c2U, 0xd0bd67daU, 0x86112233U, - 0x7efce519U, 0xad478ec9U, 0xfde7d334U, 0x2952a4f6U, - 0x3060c0a0U, 0x3b76ec9aU, 0x9f234665U, 0xf8edc72aU, - 0xc6913faeU, 0x13264c6aU, 0x060c1814U, 0x050a141eU, - 0xc59733a4U, 0x11224466U, 0x77eec12fU, 0x7cf8ed15U, - 0x7af4f501U, 0x78f0fd0dU, 0x366cd8b4U, 0x1c387048U, - 0x3972e496U, 0x59b279cbU, 0x18306050U, 0x56ac45e9U, - 0xb37bf68dU, 0xb07dfa87U, 0x244890d8U, 0x204080c0U, - 0xb279f28bU, 0x9239724bU, 0xa35bb6edU, 0xc09d27baU, - 0x44880d85U, 0x62c49551U, 0x10204060U, 0xb475ea9fU, - 0x84152a3fU, 0x43861197U, 0x933b764dU, 0xc2992fb6U, - 0x4a9435a1U, 0xbd67cea9U, 0x8f030605U, 0x2d5ab4eeU, - 0xbc65caafU, 0x9c254a6fU, 0x6ad4b561U, 0x40801d9dU, - 0xcf831b98U, 0xa259b2ebU, 0x801d3a27U, 0x4f9e21bfU, - 0x1f3e7c42U, 0xca890f86U, 0xaa4992dbU, 0x42841591U, -}; - -static const ulong32 T1[256] = { - 0x69babbd2U, 0xa854e54dU, 0x5e2fe2bcU, 0xe87425cdU, - 0xa653f751U, 0xbbd3d06bU, 0xb9d2d66fU, 0x9a4db329U, - 0xa050fd5dU, 0x45accf8aU, 0x078d090eU, 0x63bfa5c6U, - 0xe0703dddU, 0xa452f155U, 0x299a7b52U, 0x984cb52dU, - 0xc9ea468fU, 0xb7d5c473U, 0x33975566U, 0xbfd1dc63U, - 0x6633aaccU, 0xa251fb59U, 0xb65bc771U, 0x51a6f3a2U, - 0xa1defe5fU, 0x9048ad3dU, 0x4da8d79aU, 0x2f99715eU, - 0xabdbe04bU, 0x6432acc8U, 0x73b795e6U, 0xe5fc32d7U, - 0xdbe370abU, 0x219e6342U, 0x3f91417eU, 0x2b9b7d56U, - 0xd9e276afU, 0x6bbbbdd6U, 0x82419b19U, 0xdc6e79a5U, - 0x57a5f9aeU, 0x8bcb800bU, 0xd66b67b1U, 0x3795596eU, - 0x5fa1e1beU, 0xfbf310ebU, 0x7fb181feU, 0x04020c08U, - 0x85cc9217U, 0x95c4a237U, 0x3a1d4e74U, 0x28147850U, - 0x9bc3b02bU, 0xc6635791U, 0xa9dae64fU, 0xba5dd369U, - 0xbe5fdf61U, 0xa5dcf257U, 0xfa7d13e9U, 0x87cd9413U, - 0xfe7f1fe1U, 0xb45ac175U, 0xd86c75adU, 0xb85cd56dU, - 0xf3f708fbU, 0x4c26d498U, 0xe3ff38dbU, 0xc7ed5493U, - 0xcde84a87U, 0x279d694eU, 0xde6f7fa1U, 0x018e0302U, - 0x32195664U, 0x5da0e7baU, 0xfdf01ae7U, 0x0f89111eU, - 0x1e0f223cU, 0x0e07121cU, 0x43afc586U, 0xebfb20cbU, - 0x10083020U, 0x2a157e54U, 0x1a0d2e34U, 0x08041810U, - 0x02010604U, 0xc864458dU, 0xa3dff85bU, 0xec7629c5U, - 0xf2790bf9U, 0xa7ddf453U, 0x7a3d8ef4U, 0x2c167458U, - 0x7e3f82fcU, 0x6e37b2dcU, 0xda6d73a9U, 0x703890e0U, - 0x6fb9b1deU, 0xe67337d1U, 0xcfe94c83U, 0x6a35bed4U, - 0xaa55e349U, 0xe2713bd9U, 0xf67b07f1U, 0x058c0f0aU, - 0xe47231d5U, 0x0d88171aU, 0xf1f60effU, 0x542afca8U, - 0x7c3e84f8U, 0xbc5ed965U, 0x4e27d29cU, 0x8c468905U, - 0x180c2830U, 0xca654389U, 0xd0686dbdU, 0xc2615b99U, - 0x06030a0cU, 0x9fc1bc23U, 0xae57ef41U, 0xb1d6ce7fU, - 0xafd9ec43U, 0xb058cd7dU, 0xadd8ea47U, 0xcc664985U, - 0xb3d7c87bU, 0x743a9ce8U, 0x8dc88a07U, 0x783c88f0U, - 0xe9fa26cfU, 0x31965362U, 0x53a7f5a6U, 0x2d98775aU, - 0xc5ec5297U, 0x6db8b7daU, 0x93c7a83bU, 0x41aec382U, - 0xd2696bb9U, 0x964ba731U, 0x4babdd96U, 0x4fa9d19eU, - 0xce674f81U, 0x140a3c28U, 0x8e478f01U, 0xf9f216efU, - 0x77b599eeU, 0x4422cc88U, 0xd7e564b3U, 0xc1ee5e9fU, - 0x61bea3c2U, 0x562bfaacU, 0x1f81213eU, 0x24126c48U, - 0x1b832d36U, 0x361b5a6cU, 0x1c0e2438U, 0x4623ca8cU, - 0xf7f504f3U, 0x8a458309U, 0x4221c684U, 0x81ce9e1fU, - 0x9249ab39U, 0x582ce8b0U, 0xeff92cc3U, 0xd1e66ebfU, - 0x71b693e2U, 0x5028f0a0U, 0x2e17725cU, 0x19822b32U, - 0x341a5c68U, 0x0b8b1d16U, 0xe1fe3edfU, 0x098a1b12U, - 0x12093624U, 0x8fc98c03U, 0x13873526U, 0x9c4eb925U, - 0xdfe17ca3U, 0x5c2ee4b8U, 0xd5e462b7U, 0xdde07aa7U, - 0xcbeb408bU, 0x3d90477aU, 0x55a4ffaaU, 0x3c1e4478U, - 0x1785392eU, 0xc0605d9dU, 0x00000000U, 0x4a25de94U, - 0xf5f402f7U, 0xfff11ce3U, 0x35945f6aU, 0x160b3a2cU, - 0xd3e768bbU, 0xea7523c9U, 0xc3ef589bU, 0x6834b8d0U, - 0x6231a6c4U, 0xb5d4c277U, 0xbdd0da67U, 0x11863322U, - 0xfc7e19e5U, 0x47adc98eU, 0xe7fd34d3U, 0x5229f6a4U, - 0x6030a0c0U, 0x763b9aecU, 0x239f6546U, 0xedf82ac7U, - 0x91c6ae3fU, 0x26136a4cU, 0x0c061418U, 0x0a051e14U, - 0x97c5a433U, 0x22116644U, 0xee772fc1U, 0xf87c15edU, - 0xf47a01f5U, 0xf0780dfdU, 0x6c36b4d8U, 0x381c4870U, - 0x723996e4U, 0xb259cb79U, 0x30185060U, 0xac56e945U, - 0x7bb38df6U, 0x7db087faU, 0x4824d890U, 0x4020c080U, - 0x79b28bf2U, 0x39924b72U, 0x5ba3edb6U, 0x9dc0ba27U, - 0x8844850dU, 0xc4625195U, 0x20106040U, 0x75b49feaU, - 0x15843f2aU, 0x86439711U, 0x3b934d76U, 0x99c2b62fU, - 0x944aa135U, 0x67bda9ceU, 0x038f0506U, 0x5a2deeb4U, - 0x65bcafcaU, 0x259c6f4aU, 0xd46a61b5U, 0x80409d1dU, - 0x83cf981bU, 0x59a2ebb2U, 0x1d80273aU, 0x9e4fbf21U, - 0x3e1f427cU, 0x89ca860fU, 0x49aadb92U, 0x84429115U, -}; - -static const ulong32 T2[256] = { - 0xd2bbba69U, 0x4de554a8U, 0xbce22f5eU, 0xcd2574e8U, - 0x51f753a6U, 0x6bd0d3bbU, 0x6fd6d2b9U, 0x29b34d9aU, - 0x5dfd50a0U, 0x8acfac45U, 0x0e098d07U, 0xc6a5bf63U, - 0xdd3d70e0U, 0x55f152a4U, 0x527b9a29U, 0x2db54c98U, - 0x8f46eac9U, 0x73c4d5b7U, 0x66559733U, 0x63dcd1bfU, - 0xccaa3366U, 0x59fb51a2U, 0x71c75bb6U, 0xa2f3a651U, - 0x5ffedea1U, 0x3dad4890U, 0x9ad7a84dU, 0x5e71992fU, - 0x4be0dbabU, 0xc8ac3264U, 0xe695b773U, 0xd732fce5U, - 0xab70e3dbU, 0x42639e21U, 0x7e41913fU, 0x567d9b2bU, - 0xaf76e2d9U, 0xd6bdbb6bU, 0x199b4182U, 0xa5796edcU, - 0xaef9a557U, 0x0b80cb8bU, 0xb1676bd6U, 0x6e599537U, - 0xbee1a15fU, 0xeb10f3fbU, 0xfe81b17fU, 0x080c0204U, - 0x1792cc85U, 0x37a2c495U, 0x744e1d3aU, 0x50781428U, - 0x2bb0c39bU, 0x915763c6U, 0x4fe6daa9U, 0x69d35dbaU, - 0x61df5fbeU, 0x57f2dca5U, 0xe9137dfaU, 0x1394cd87U, - 0xe11f7ffeU, 0x75c15ab4U, 0xad756cd8U, 0x6dd55cb8U, - 0xfb08f7f3U, 0x98d4264cU, 0xdb38ffe3U, 0x9354edc7U, - 0x874ae8cdU, 0x4e699d27U, 0xa17f6fdeU, 0x02038e01U, - 0x64561932U, 0xbae7a05dU, 0xe71af0fdU, 0x1e11890fU, - 0x3c220f1eU, 0x1c12070eU, 0x86c5af43U, 0xcb20fbebU, - 0x20300810U, 0x547e152aU, 0x342e0d1aU, 0x10180408U, - 0x04060102U, 0x8d4564c8U, 0x5bf8dfa3U, 0xc52976ecU, - 0xf90b79f2U, 0x53f4dda7U, 0xf48e3d7aU, 0x5874162cU, - 0xfc823f7eU, 0xdcb2376eU, 0xa9736ddaU, 0xe0903870U, - 0xdeb1b96fU, 0xd13773e6U, 0x834ce9cfU, 0xd4be356aU, - 0x49e355aaU, 0xd93b71e2U, 0xf1077bf6U, 0x0a0f8c05U, - 0xd53172e4U, 0x1a17880dU, 0xff0ef6f1U, 0xa8fc2a54U, - 0xf8843e7cU, 0x65d95ebcU, 0x9cd2274eU, 0x0589468cU, - 0x30280c18U, 0x894365caU, 0xbd6d68d0U, 0x995b61c2U, - 0x0c0a0306U, 0x23bcc19fU, 0x41ef57aeU, 0x7fced6b1U, - 0x43ecd9afU, 0x7dcd58b0U, 0x47ead8adU, 0x854966ccU, - 0x7bc8d7b3U, 0xe89c3a74U, 0x078ac88dU, 0xf0883c78U, - 0xcf26fae9U, 0x62539631U, 0xa6f5a753U, 0x5a77982dU, - 0x9752ecc5U, 0xdab7b86dU, 0x3ba8c793U, 0x82c3ae41U, - 0xb96b69d2U, 0x31a74b96U, 0x96ddab4bU, 0x9ed1a94fU, - 0x814f67ceU, 0x283c0a14U, 0x018f478eU, 0xef16f2f9U, - 0xee99b577U, 0x88cc2244U, 0xb364e5d7U, 0x9f5eeec1U, - 0xc2a3be61U, 0xacfa2b56U, 0x3e21811fU, 0x486c1224U, - 0x362d831bU, 0x6c5a1b36U, 0x38240e1cU, 0x8cca2346U, - 0xf304f5f7U, 0x0983458aU, 0x84c62142U, 0x1f9ece81U, - 0x39ab4992U, 0xb0e82c58U, 0xc32cf9efU, 0xbf6ee6d1U, - 0xe293b671U, 0xa0f02850U, 0x5c72172eU, 0x322b8219U, - 0x685c1a34U, 0x161d8b0bU, 0xdf3efee1U, 0x121b8a09U, - 0x24360912U, 0x038cc98fU, 0x26358713U, 0x25b94e9cU, - 0xa37ce1dfU, 0xb8e42e5cU, 0xb762e4d5U, 0xa77ae0ddU, - 0x8b40ebcbU, 0x7a47903dU, 0xaaffa455U, 0x78441e3cU, - 0x2e398517U, 0x9d5d60c0U, 0x00000000U, 0x94de254aU, - 0xf702f4f5U, 0xe31cf1ffU, 0x6a5f9435U, 0x2c3a0b16U, - 0xbb68e7d3U, 0xc92375eaU, 0x9b58efc3U, 0xd0b83468U, - 0xc4a63162U, 0x77c2d4b5U, 0x67dad0bdU, 0x22338611U, - 0xe5197efcU, 0x8ec9ad47U, 0xd334fde7U, 0xa4f62952U, - 0xc0a03060U, 0xec9a3b76U, 0x46659f23U, 0xc72af8edU, - 0x3faec691U, 0x4c6a1326U, 0x1814060cU, 0x141e050aU, - 0x33a4c597U, 0x44661122U, 0xc12f77eeU, 0xed157cf8U, - 0xf5017af4U, 0xfd0d78f0U, 0xd8b4366cU, 0x70481c38U, - 0xe4963972U, 0x79cb59b2U, 0x60501830U, 0x45e956acU, - 0xf68db37bU, 0xfa87b07dU, 0x90d82448U, 0x80c02040U, - 0xf28bb279U, 0x724b9239U, 0xb6eda35bU, 0x27bac09dU, - 0x0d854488U, 0x955162c4U, 0x40601020U, 0xea9fb475U, - 0x2a3f8415U, 0x11974386U, 0x764d933bU, 0x2fb6c299U, - 0x35a14a94U, 0xcea9bd67U, 0x06058f03U, 0xb4ee2d5aU, - 0xcaafbc65U, 0x4a6f9c25U, 0xb5616ad4U, 0x1d9d4080U, - 0x1b98cf83U, 0xb2eba259U, 0x3a27801dU, 0x21bf4f9eU, - 0x7c421f3eU, 0x0f86ca89U, 0x92dbaa49U, 0x15914284U, -}; - -static const ulong32 T3[256] = { - 0xbbd269baU, 0xe54da854U, 0xe2bc5e2fU, 0x25cde874U, - 0xf751a653U, 0xd06bbbd3U, 0xd66fb9d2U, 0xb3299a4dU, - 0xfd5da050U, 0xcf8a45acU, 0x090e078dU, 0xa5c663bfU, - 0x3ddde070U, 0xf155a452U, 0x7b52299aU, 0xb52d984cU, - 0x468fc9eaU, 0xc473b7d5U, 0x55663397U, 0xdc63bfd1U, - 0xaacc6633U, 0xfb59a251U, 0xc771b65bU, 0xf3a251a6U, - 0xfe5fa1deU, 0xad3d9048U, 0xd79a4da8U, 0x715e2f99U, - 0xe04babdbU, 0xacc86432U, 0x95e673b7U, 0x32d7e5fcU, - 0x70abdbe3U, 0x6342219eU, 0x417e3f91U, 0x7d562b9bU, - 0x76afd9e2U, 0xbdd66bbbU, 0x9b198241U, 0x79a5dc6eU, - 0xf9ae57a5U, 0x800b8bcbU, 0x67b1d66bU, 0x596e3795U, - 0xe1be5fa1U, 0x10ebfbf3U, 0x81fe7fb1U, 0x0c080402U, - 0x921785ccU, 0xa23795c4U, 0x4e743a1dU, 0x78502814U, - 0xb02b9bc3U, 0x5791c663U, 0xe64fa9daU, 0xd369ba5dU, - 0xdf61be5fU, 0xf257a5dcU, 0x13e9fa7dU, 0x941387cdU, - 0x1fe1fe7fU, 0xc175b45aU, 0x75add86cU, 0xd56db85cU, - 0x08fbf3f7U, 0xd4984c26U, 0x38dbe3ffU, 0x5493c7edU, - 0x4a87cde8U, 0x694e279dU, 0x7fa1de6fU, 0x0302018eU, - 0x56643219U, 0xe7ba5da0U, 0x1ae7fdf0U, 0x111e0f89U, - 0x223c1e0fU, 0x121c0e07U, 0xc58643afU, 0x20cbebfbU, - 0x30201008U, 0x7e542a15U, 0x2e341a0dU, 0x18100804U, - 0x06040201U, 0x458dc864U, 0xf85ba3dfU, 0x29c5ec76U, - 0x0bf9f279U, 0xf453a7ddU, 0x8ef47a3dU, 0x74582c16U, - 0x82fc7e3fU, 0xb2dc6e37U, 0x73a9da6dU, 0x90e07038U, - 0xb1de6fb9U, 0x37d1e673U, 0x4c83cfe9U, 0xbed46a35U, - 0xe349aa55U, 0x3bd9e271U, 0x07f1f67bU, 0x0f0a058cU, - 0x31d5e472U, 0x171a0d88U, 0x0efff1f6U, 0xfca8542aU, - 0x84f87c3eU, 0xd965bc5eU, 0xd29c4e27U, 0x89058c46U, - 0x2830180cU, 0x4389ca65U, 0x6dbdd068U, 0x5b99c261U, - 0x0a0c0603U, 0xbc239fc1U, 0xef41ae57U, 0xce7fb1d6U, - 0xec43afd9U, 0xcd7db058U, 0xea47add8U, 0x4985cc66U, - 0xc87bb3d7U, 0x9ce8743aU, 0x8a078dc8U, 0x88f0783cU, - 0x26cfe9faU, 0x53623196U, 0xf5a653a7U, 0x775a2d98U, - 0x5297c5ecU, 0xb7da6db8U, 0xa83b93c7U, 0xc38241aeU, - 0x6bb9d269U, 0xa731964bU, 0xdd964babU, 0xd19e4fa9U, - 0x4f81ce67U, 0x3c28140aU, 0x8f018e47U, 0x16eff9f2U, - 0x99ee77b5U, 0xcc884422U, 0x64b3d7e5U, 0x5e9fc1eeU, - 0xa3c261beU, 0xfaac562bU, 0x213e1f81U, 0x6c482412U, - 0x2d361b83U, 0x5a6c361bU, 0x24381c0eU, 0xca8c4623U, - 0x04f3f7f5U, 0x83098a45U, 0xc6844221U, 0x9e1f81ceU, - 0xab399249U, 0xe8b0582cU, 0x2cc3eff9U, 0x6ebfd1e6U, - 0x93e271b6U, 0xf0a05028U, 0x725c2e17U, 0x2b321982U, - 0x5c68341aU, 0x1d160b8bU, 0x3edfe1feU, 0x1b12098aU, - 0x36241209U, 0x8c038fc9U, 0x35261387U, 0xb9259c4eU, - 0x7ca3dfe1U, 0xe4b85c2eU, 0x62b7d5e4U, 0x7aa7dde0U, - 0x408bcbebU, 0x477a3d90U, 0xffaa55a4U, 0x44783c1eU, - 0x392e1785U, 0x5d9dc060U, 0x00000000U, 0xde944a25U, - 0x02f7f5f4U, 0x1ce3fff1U, 0x5f6a3594U, 0x3a2c160bU, - 0x68bbd3e7U, 0x23c9ea75U, 0x589bc3efU, 0xb8d06834U, - 0xa6c46231U, 0xc277b5d4U, 0xda67bdd0U, 0x33221186U, - 0x19e5fc7eU, 0xc98e47adU, 0x34d3e7fdU, 0xf6a45229U, - 0xa0c06030U, 0x9aec763bU, 0x6546239fU, 0x2ac7edf8U, - 0xae3f91c6U, 0x6a4c2613U, 0x14180c06U, 0x1e140a05U, - 0xa43397c5U, 0x66442211U, 0x2fc1ee77U, 0x15edf87cU, - 0x01f5f47aU, 0x0dfdf078U, 0xb4d86c36U, 0x4870381cU, - 0x96e47239U, 0xcb79b259U, 0x50603018U, 0xe945ac56U, - 0x8df67bb3U, 0x87fa7db0U, 0xd8904824U, 0xc0804020U, - 0x8bf279b2U, 0x4b723992U, 0xedb65ba3U, 0xba279dc0U, - 0x850d8844U, 0x5195c462U, 0x60402010U, 0x9fea75b4U, - 0x3f2a1584U, 0x97118643U, 0x4d763b93U, 0xb62f99c2U, - 0xa135944aU, 0xa9ce67bdU, 0x0506038fU, 0xeeb45a2dU, - 0xafca65bcU, 0x6f4a259cU, 0x61b5d46aU, 0x9d1d8040U, - 0x981b83cfU, 0xebb259a2U, 0x273a1d80U, 0xbf219e4fU, - 0x427c3e1fU, 0x860f89caU, 0xdb9249aaU, 0x91158442U, -}; - -static const ulong32 T4[256] = { - 0xbabababaU, 0x54545454U, 0x2f2f2f2fU, 0x74747474U, - 0x53535353U, 0xd3d3d3d3U, 0xd2d2d2d2U, 0x4d4d4d4dU, - 0x50505050U, 0xacacacacU, 0x8d8d8d8dU, 0xbfbfbfbfU, - 0x70707070U, 0x52525252U, 0x9a9a9a9aU, 0x4c4c4c4cU, - 0xeaeaeaeaU, 0xd5d5d5d5U, 0x97979797U, 0xd1d1d1d1U, - 0x33333333U, 0x51515151U, 0x5b5b5b5bU, 0xa6a6a6a6U, - 0xdedededeU, 0x48484848U, 0xa8a8a8a8U, 0x99999999U, - 0xdbdbdbdbU, 0x32323232U, 0xb7b7b7b7U, 0xfcfcfcfcU, - 0xe3e3e3e3U, 0x9e9e9e9eU, 0x91919191U, 0x9b9b9b9bU, - 0xe2e2e2e2U, 0xbbbbbbbbU, 0x41414141U, 0x6e6e6e6eU, - 0xa5a5a5a5U, 0xcbcbcbcbU, 0x6b6b6b6bU, 0x95959595U, - 0xa1a1a1a1U, 0xf3f3f3f3U, 0xb1b1b1b1U, 0x02020202U, - 0xccccccccU, 0xc4c4c4c4U, 0x1d1d1d1dU, 0x14141414U, - 0xc3c3c3c3U, 0x63636363U, 0xdadadadaU, 0x5d5d5d5dU, - 0x5f5f5f5fU, 0xdcdcdcdcU, 0x7d7d7d7dU, 0xcdcdcdcdU, - 0x7f7f7f7fU, 0x5a5a5a5aU, 0x6c6c6c6cU, 0x5c5c5c5cU, - 0xf7f7f7f7U, 0x26262626U, 0xffffffffU, 0xededededU, - 0xe8e8e8e8U, 0x9d9d9d9dU, 0x6f6f6f6fU, 0x8e8e8e8eU, - 0x19191919U, 0xa0a0a0a0U, 0xf0f0f0f0U, 0x89898989U, - 0x0f0f0f0fU, 0x07070707U, 0xafafafafU, 0xfbfbfbfbU, - 0x08080808U, 0x15151515U, 0x0d0d0d0dU, 0x04040404U, - 0x01010101U, 0x64646464U, 0xdfdfdfdfU, 0x76767676U, - 0x79797979U, 0xddddddddU, 0x3d3d3d3dU, 0x16161616U, - 0x3f3f3f3fU, 0x37373737U, 0x6d6d6d6dU, 0x38383838U, - 0xb9b9b9b9U, 0x73737373U, 0xe9e9e9e9U, 0x35353535U, - 0x55555555U, 0x71717171U, 0x7b7b7b7bU, 0x8c8c8c8cU, - 0x72727272U, 0x88888888U, 0xf6f6f6f6U, 0x2a2a2a2aU, - 0x3e3e3e3eU, 0x5e5e5e5eU, 0x27272727U, 0x46464646U, - 0x0c0c0c0cU, 0x65656565U, 0x68686868U, 0x61616161U, - 0x03030303U, 0xc1c1c1c1U, 0x57575757U, 0xd6d6d6d6U, - 0xd9d9d9d9U, 0x58585858U, 0xd8d8d8d8U, 0x66666666U, - 0xd7d7d7d7U, 0x3a3a3a3aU, 0xc8c8c8c8U, 0x3c3c3c3cU, - 0xfafafafaU, 0x96969696U, 0xa7a7a7a7U, 0x98989898U, - 0xececececU, 0xb8b8b8b8U, 0xc7c7c7c7U, 0xaeaeaeaeU, - 0x69696969U, 0x4b4b4b4bU, 0xababababU, 0xa9a9a9a9U, - 0x67676767U, 0x0a0a0a0aU, 0x47474747U, 0xf2f2f2f2U, - 0xb5b5b5b5U, 0x22222222U, 0xe5e5e5e5U, 0xeeeeeeeeU, - 0xbebebebeU, 0x2b2b2b2bU, 0x81818181U, 0x12121212U, - 0x83838383U, 0x1b1b1b1bU, 0x0e0e0e0eU, 0x23232323U, - 0xf5f5f5f5U, 0x45454545U, 0x21212121U, 0xcecececeU, - 0x49494949U, 0x2c2c2c2cU, 0xf9f9f9f9U, 0xe6e6e6e6U, - 0xb6b6b6b6U, 0x28282828U, 0x17171717U, 0x82828282U, - 0x1a1a1a1aU, 0x8b8b8b8bU, 0xfefefefeU, 0x8a8a8a8aU, - 0x09090909U, 0xc9c9c9c9U, 0x87878787U, 0x4e4e4e4eU, - 0xe1e1e1e1U, 0x2e2e2e2eU, 0xe4e4e4e4U, 0xe0e0e0e0U, - 0xebebebebU, 0x90909090U, 0xa4a4a4a4U, 0x1e1e1e1eU, - 0x85858585U, 0x60606060U, 0x00000000U, 0x25252525U, - 0xf4f4f4f4U, 0xf1f1f1f1U, 0x94949494U, 0x0b0b0b0bU, - 0xe7e7e7e7U, 0x75757575U, 0xefefefefU, 0x34343434U, - 0x31313131U, 0xd4d4d4d4U, 0xd0d0d0d0U, 0x86868686U, - 0x7e7e7e7eU, 0xadadadadU, 0xfdfdfdfdU, 0x29292929U, - 0x30303030U, 0x3b3b3b3bU, 0x9f9f9f9fU, 0xf8f8f8f8U, - 0xc6c6c6c6U, 0x13131313U, 0x06060606U, 0x05050505U, - 0xc5c5c5c5U, 0x11111111U, 0x77777777U, 0x7c7c7c7cU, - 0x7a7a7a7aU, 0x78787878U, 0x36363636U, 0x1c1c1c1cU, - 0x39393939U, 0x59595959U, 0x18181818U, 0x56565656U, - 0xb3b3b3b3U, 0xb0b0b0b0U, 0x24242424U, 0x20202020U, - 0xb2b2b2b2U, 0x92929292U, 0xa3a3a3a3U, 0xc0c0c0c0U, - 0x44444444U, 0x62626262U, 0x10101010U, 0xb4b4b4b4U, - 0x84848484U, 0x43434343U, 0x93939393U, 0xc2c2c2c2U, - 0x4a4a4a4aU, 0xbdbdbdbdU, 0x8f8f8f8fU, 0x2d2d2d2dU, - 0xbcbcbcbcU, 0x9c9c9c9cU, 0x6a6a6a6aU, 0x40404040U, - 0xcfcfcfcfU, 0xa2a2a2a2U, 0x80808080U, 0x4f4f4f4fU, - 0x1f1f1f1fU, 0xcacacacaU, 0xaaaaaaaaU, 0x42424242U, -}; - -static const ulong32 T5[256] = { - 0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U, - 0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U, - 0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U, - 0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U, - 0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U, - 0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U, - 0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U, - 0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U, - 0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U, - 0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U, - 0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U, - 0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U, - 0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U, - 0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U, - 0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U, - 0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U, - 0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U, - 0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U, - 0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U, - 0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U, - 0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U, - 0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U, - 0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U, - 0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U, - 0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU, - 0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU, - 0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU, - 0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU, - 0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU, - 0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU, - 0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU, - 0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU, - 0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU, - 0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU, - 0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU, - 0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU, - 0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU, - 0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU, - 0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU, - 0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU, - 0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U, - 0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U, - 0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U, - 0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U, - 0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U, - 0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U, - 0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U, - 0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U, - 0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U, - 0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U, - 0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U, - 0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U, - 0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U, - 0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U, - 0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U, - 0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U, - 0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU, - 0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU, - 0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU, - 0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU, - 0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU, - 0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU, - 0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU, - 0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU, -}; - -/** - * The round constants. - */ -static const ulong32 rc[] = { - 0xba542f74U, 0x53d3d24dU, 0x50ac8dbfU, 0x70529a4cU, - 0xead597d1U, 0x33515ba6U, 0xde48a899U, 0xdb32b7fcU, - 0xe39e919bU, 0xe2bb416eU, 0xa5cb6b95U, 0xa1f3b102U, - 0xccc41d14U, 0xc363da5dU, 0x5fdc7dcdU, 0x7f5a6c5cU, - 0xf726ffedU, 0xe89d6f8eU, 0x19a0f089U, -}; - - - -#else - - -static const ulong32 T0[256] = { - 0xa753a6f5U, 0xd3bb6bd0U, 0xe6d1bf6eU, 0x71e2d93bU, - 0xd0bd67daU, 0xac458acfU, 0x4d9a29b3U, 0x79f2f90bU, - 0x3a74e89cU, 0xc98f038cU, 0x913f7e41U, 0xfce5d732U, - 0x1e3c7844U, 0x478e018fU, 0x54a84de5U, 0xbd67cea9U, - 0x8c050a0fU, 0xa557aef9U, 0x7af4f501U, 0xfbebcb20U, - 0x63c69157U, 0xb86ddab7U, 0xdda753f4U, 0xd4b577c2U, - 0xe5d7b364U, 0xb37bf68dU, 0xc59733a4U, 0xbe61c2a3U, - 0xa94f9ed1U, 0x880d1a17U, 0x0c183028U, 0xa259b2ebU, - 0x3972e496U, 0xdfa35bf8U, 0x2952a4f6U, 0xdaa94fe6U, - 0x2b56acfaU, 0xa84d9ad7U, 0xcb8b0b80U, 0x4c982db5U, - 0x4b9631a7U, 0x224488ccU, 0xaa4992dbU, 0x244890d8U, - 0x4182199bU, 0x70e0dd3dU, 0xa651a2f3U, 0xf9efc32cU, - 0x5ab475c1U, 0xe2d9af76U, 0xb07dfa87U, 0x366cd8b4U, - 0x7dfae913U, 0xe4d5b762U, 0x3366ccaaU, 0xffe3db38U, - 0x60c09d5dU, 0x204080c0U, 0x08102030U, 0x8b0b161dU, - 0x5ebc65d9U, 0xab4b96ddU, 0x7ffee11fU, 0x78f0fd0dU, - 0x7cf8ed15U, 0x2c58b0e8U, 0x57ae41efU, 0xd2b96fd6U, - 0xdca557f2U, 0x6ddaa973U, 0x7efce519U, 0x0d1a342eU, - 0x53a651f7U, 0x94356a5fU, 0xc39b2bb0U, 0x2850a0f0U, - 0x274e9cd2U, 0x060c1814U, 0x5fbe61dfU, 0xad478ec9U, - 0x67ce814fU, 0x5cb86dd5U, 0x55aa49e3U, 0x48903dadU, - 0x0e1c3824U, 0x52a455f1U, 0xeac98f46U, 0x42841591U, - 0x5bb671c7U, 0x5dba69d3U, 0x3060c0a0U, 0x58b07dcdU, - 0x51a259fbU, 0x59b279cbU, 0x3c78f088U, 0x4e9c25b9U, - 0x3870e090U, 0x8a09121bU, 0x72e4d531U, 0x14285078U, - 0xe7d3bb68U, 0xc6913faeU, 0xdea15ffeU, 0x50a05dfdU, - 0x8e010203U, 0x9239724bU, 0xd1bf63dcU, 0x77eec12fU, - 0x933b764dU, 0x458a0983U, 0x9a29527bU, 0xce811f9eU, - 0x2d5ab4eeU, 0x03060c0aU, 0x62c49551U, 0xb671e293U, - 0xb96fdeb1U, 0xbf63c6a5U, 0x96316253U, 0x6bd6b167U, - 0x3f7efc82U, 0x070e1c12U, 0x1224486cU, 0xae4182c3U, - 0x40801d9dU, 0x3468d0b8U, 0x468c0589U, 0x3e7cf884U, - 0xdbab4be0U, 0xcf831b98U, 0xecc59752U, 0xcc851792U, - 0xc19f23bcU, 0xa15fbee1U, 0xc09d27baU, 0xd6b17fceU, - 0x1d3a744eU, 0xf4f5f702U, 0x61c2995bU, 0x3b76ec9aU, - 0x10204060U, 0xd8ad47eaU, 0x68d0bd6dU, 0xa05dbae7U, - 0xb17ffe81U, 0x0a14283cU, 0x69d2b96bU, 0x6cd8ad75U, - 0x499239abU, 0xfae9cf26U, 0x76ecc529U, 0xc49537a2U, - 0x9e214263U, 0x9b2b567dU, 0x6edca579U, 0x992f5e71U, - 0xc2992fb6U, 0xb773e695U, 0x982d5a77U, 0xbc65caafU, - 0x8f030605U, 0x85172e39U, 0x1f3e7c42U, 0xb475ea9fU, - 0xf8edc72aU, 0x11224466U, 0x2e5cb8e4U, 0x00000000U, - 0x254a94deU, 0x1c387048U, 0x2a54a8fcU, 0x3d7af48eU, - 0x050a141eU, 0x4f9e21bfU, 0x7bf6f107U, 0xb279f28bU, - 0x3264c8acU, 0x903d7a47U, 0xaf4386c5U, 0x19326456U, - 0xa35bb6edU, 0xf7f3fb08U, 0x73e6d137U, 0x9d274e69U, - 0x152a547eU, 0x74e8cd25U, 0xeec19f5eU, 0xca890f86U, - 0x9f234665U, 0x0f1e3c22U, 0x1b366c5aU, 0x75eac923U, - 0x86112233U, 0x84152a3fU, 0x9c254a6fU, 0x4a9435a1U, - 0x97336655U, 0x1a34685cU, 0x65ca8943U, 0xf6f1ff0eU, - 0xedc79354U, 0x09122436U, 0xbb6bd6bdU, 0x264c98d4U, - 0x831b362dU, 0xebcb8b40U, 0x6fdea17fU, 0x811f3e21U, - 0x04081018U, 0x6ad4b561U, 0x43861197U, 0x01020406U, - 0x172e5c72U, 0xe1dfa37cU, 0x87132635U, 0xf5f7f304U, - 0x8d070e09U, 0xe3dbab70U, 0x23468ccaU, 0x801d3a27U, - 0x44880d85U, 0x162c5874U, 0x66cc8549U, 0x214284c6U, - 0xfee1df3eU, 0xd5b773c4U, 0x3162c4a6U, 0xd9af43ecU, - 0x356ad4beU, 0x18306050U, 0x0204080cU, 0x64c88d45U, - 0xf2f9ef16U, 0xf1ffe31cU, 0x56ac45e9U, 0xcd871394U, - 0x8219322bU, 0xc88d078aU, 0xba69d2bbU, 0xf0fde71aU, - 0xefc39b58U, 0xe9cf834cU, 0xe8cd874aU, 0xfde7d334U, - 0x890f1e11U, 0xd7b37bc8U, 0xc7933ba8U, 0xb577ee99U, - 0xa455aaffU, 0x2f5ebce2U, 0x95376e59U, 0x13264c6aU, - 0x0b162c3aU, 0xf3fbeb10U, 0xe0dda77aU, 0x376edcb2U, -}; - -static const ulong32 T1[256] = { - 0x53a7f5a6U, 0xbbd3d06bU, 0xd1e66ebfU, 0xe2713bd9U, - 0xbdd0da67U, 0x45accf8aU, 0x9a4db329U, 0xf2790bf9U, - 0x743a9ce8U, 0x8fc98c03U, 0x3f91417eU, 0xe5fc32d7U, - 0x3c1e4478U, 0x8e478f01U, 0xa854e54dU, 0x67bda9ceU, - 0x058c0f0aU, 0x57a5f9aeU, 0xf47a01f5U, 0xebfb20cbU, - 0xc6635791U, 0x6db8b7daU, 0xa7ddf453U, 0xb5d4c277U, - 0xd7e564b3U, 0x7bb38df6U, 0x97c5a433U, 0x61bea3c2U, - 0x4fa9d19eU, 0x0d88171aU, 0x180c2830U, 0x59a2ebb2U, - 0x723996e4U, 0xa3dff85bU, 0x5229f6a4U, 0xa9dae64fU, - 0x562bfaacU, 0x4da8d79aU, 0x8bcb800bU, 0x984cb52dU, - 0x964ba731U, 0x4422cc88U, 0x49aadb92U, 0x4824d890U, - 0x82419b19U, 0xe0703dddU, 0x51a6f3a2U, 0xeff92cc3U, - 0xb45ac175U, 0xd9e276afU, 0x7db087faU, 0x6c36b4d8U, - 0xfa7d13e9U, 0xd5e462b7U, 0x6633aaccU, 0xe3ff38dbU, - 0xc0605d9dU, 0x4020c080U, 0x10083020U, 0x0b8b1d16U, - 0xbc5ed965U, 0x4babdd96U, 0xfe7f1fe1U, 0xf0780dfdU, - 0xf87c15edU, 0x582ce8b0U, 0xae57ef41U, 0xb9d2d66fU, - 0xa5dcf257U, 0xda6d73a9U, 0xfc7e19e5U, 0x1a0d2e34U, - 0xa653f751U, 0x35945f6aU, 0x9bc3b02bU, 0x5028f0a0U, - 0x4e27d29cU, 0x0c061418U, 0xbe5fdf61U, 0x47adc98eU, - 0xce674f81U, 0xb85cd56dU, 0xaa55e349U, 0x9048ad3dU, - 0x1c0e2438U, 0xa452f155U, 0xc9ea468fU, 0x84429115U, - 0xb65bc771U, 0xba5dd369U, 0x6030a0c0U, 0xb058cd7dU, - 0xa251fb59U, 0xb259cb79U, 0x783c88f0U, 0x9c4eb925U, - 0x703890e0U, 0x098a1b12U, 0xe47231d5U, 0x28147850U, - 0xd3e768bbU, 0x91c6ae3fU, 0xa1defe5fU, 0xa050fd5dU, - 0x018e0302U, 0x39924b72U, 0xbfd1dc63U, 0xee772fc1U, - 0x3b934d76U, 0x8a458309U, 0x299a7b52U, 0x81ce9e1fU, - 0x5a2deeb4U, 0x06030a0cU, 0xc4625195U, 0x71b693e2U, - 0x6fb9b1deU, 0x63bfa5c6U, 0x31965362U, 0xd66b67b1U, - 0x7e3f82fcU, 0x0e07121cU, 0x24126c48U, 0x41aec382U, - 0x80409d1dU, 0x6834b8d0U, 0x8c468905U, 0x7c3e84f8U, - 0xabdbe04bU, 0x83cf981bU, 0xc5ec5297U, 0x85cc9217U, - 0x9fc1bc23U, 0x5fa1e1beU, 0x9dc0ba27U, 0xb1d6ce7fU, - 0x3a1d4e74U, 0xf5f402f7U, 0xc2615b99U, 0x763b9aecU, - 0x20106040U, 0xadd8ea47U, 0xd0686dbdU, 0x5da0e7baU, - 0x7fb181feU, 0x140a3c28U, 0xd2696bb9U, 0xd86c75adU, - 0x9249ab39U, 0xe9fa26cfU, 0xec7629c5U, 0x95c4a237U, - 0x219e6342U, 0x2b9b7d56U, 0xdc6e79a5U, 0x2f99715eU, - 0x99c2b62fU, 0x73b795e6U, 0x2d98775aU, 0x65bcafcaU, - 0x038f0506U, 0x1785392eU, 0x3e1f427cU, 0x75b49feaU, - 0xedf82ac7U, 0x22116644U, 0x5c2ee4b8U, 0x00000000U, - 0x4a25de94U, 0x381c4870U, 0x542afca8U, 0x7a3d8ef4U, - 0x0a051e14U, 0x9e4fbf21U, 0xf67b07f1U, 0x79b28bf2U, - 0x6432acc8U, 0x3d90477aU, 0x43afc586U, 0x32195664U, - 0x5ba3edb6U, 0xf3f708fbU, 0xe67337d1U, 0x279d694eU, - 0x2a157e54U, 0xe87425cdU, 0xc1ee5e9fU, 0x89ca860fU, - 0x239f6546U, 0x1e0f223cU, 0x361b5a6cU, 0xea7523c9U, - 0x11863322U, 0x15843f2aU, 0x259c6f4aU, 0x944aa135U, - 0x33975566U, 0x341a5c68U, 0xca654389U, 0xf1f60effU, - 0xc7ed5493U, 0x12093624U, 0x6bbbbdd6U, 0x4c26d498U, - 0x1b832d36U, 0xcbeb408bU, 0xde6f7fa1U, 0x1f81213eU, - 0x08041810U, 0xd46a61b5U, 0x86439711U, 0x02010604U, - 0x2e17725cU, 0xdfe17ca3U, 0x13873526U, 0xf7f504f3U, - 0x078d090eU, 0xdbe370abU, 0x4623ca8cU, 0x1d80273aU, - 0x8844850dU, 0x2c167458U, 0xcc664985U, 0x4221c684U, - 0xe1fe3edfU, 0xb7d5c473U, 0x6231a6c4U, 0xafd9ec43U, - 0x6a35bed4U, 0x30185060U, 0x04020c08U, 0xc864458dU, - 0xf9f216efU, 0xfff11ce3U, 0xac56e945U, 0x87cd9413U, - 0x19822b32U, 0x8dc88a07U, 0x69babbd2U, 0xfdf01ae7U, - 0xc3ef589bU, 0xcfe94c83U, 0xcde84a87U, 0xe7fd34d3U, - 0x0f89111eU, 0xb3d7c87bU, 0x93c7a83bU, 0x77b599eeU, - 0x55a4ffaaU, 0x5e2fe2bcU, 0x3795596eU, 0x26136a4cU, - 0x160b3a2cU, 0xfbf310ebU, 0xdde07aa7U, 0x6e37b2dcU, -}; - -static const ulong32 T2[256] = { - 0xa6f5a753U, 0x6bd0d3bbU, 0xbf6ee6d1U, 0xd93b71e2U, - 0x67dad0bdU, 0x8acfac45U, 0x29b34d9aU, 0xf90b79f2U, - 0xe89c3a74U, 0x038cc98fU, 0x7e41913fU, 0xd732fce5U, - 0x78441e3cU, 0x018f478eU, 0x4de554a8U, 0xcea9bd67U, - 0x0a0f8c05U, 0xaef9a557U, 0xf5017af4U, 0xcb20fbebU, - 0x915763c6U, 0xdab7b86dU, 0x53f4dda7U, 0x77c2d4b5U, - 0xb364e5d7U, 0xf68db37bU, 0x33a4c597U, 0xc2a3be61U, - 0x9ed1a94fU, 0x1a17880dU, 0x30280c18U, 0xb2eba259U, - 0xe4963972U, 0x5bf8dfa3U, 0xa4f62952U, 0x4fe6daa9U, - 0xacfa2b56U, 0x9ad7a84dU, 0x0b80cb8bU, 0x2db54c98U, - 0x31a74b96U, 0x88cc2244U, 0x92dbaa49U, 0x90d82448U, - 0x199b4182U, 0xdd3d70e0U, 0xa2f3a651U, 0xc32cf9efU, - 0x75c15ab4U, 0xaf76e2d9U, 0xfa87b07dU, 0xd8b4366cU, - 0xe9137dfaU, 0xb762e4d5U, 0xccaa3366U, 0xdb38ffe3U, - 0x9d5d60c0U, 0x80c02040U, 0x20300810U, 0x161d8b0bU, - 0x65d95ebcU, 0x96ddab4bU, 0xe11f7ffeU, 0xfd0d78f0U, - 0xed157cf8U, 0xb0e82c58U, 0x41ef57aeU, 0x6fd6d2b9U, - 0x57f2dca5U, 0xa9736ddaU, 0xe5197efcU, 0x342e0d1aU, - 0x51f753a6U, 0x6a5f9435U, 0x2bb0c39bU, 0xa0f02850U, - 0x9cd2274eU, 0x1814060cU, 0x61df5fbeU, 0x8ec9ad47U, - 0x814f67ceU, 0x6dd55cb8U, 0x49e355aaU, 0x3dad4890U, - 0x38240e1cU, 0x55f152a4U, 0x8f46eac9U, 0x15914284U, - 0x71c75bb6U, 0x69d35dbaU, 0xc0a03060U, 0x7dcd58b0U, - 0x59fb51a2U, 0x79cb59b2U, 0xf0883c78U, 0x25b94e9cU, - 0xe0903870U, 0x121b8a09U, 0xd53172e4U, 0x50781428U, - 0xbb68e7d3U, 0x3faec691U, 0x5ffedea1U, 0x5dfd50a0U, - 0x02038e01U, 0x724b9239U, 0x63dcd1bfU, 0xc12f77eeU, - 0x764d933bU, 0x0983458aU, 0x527b9a29U, 0x1f9ece81U, - 0xb4ee2d5aU, 0x0c0a0306U, 0x955162c4U, 0xe293b671U, - 0xdeb1b96fU, 0xc6a5bf63U, 0x62539631U, 0xb1676bd6U, - 0xfc823f7eU, 0x1c12070eU, 0x486c1224U, 0x82c3ae41U, - 0x1d9d4080U, 0xd0b83468U, 0x0589468cU, 0xf8843e7cU, - 0x4be0dbabU, 0x1b98cf83U, 0x9752ecc5U, 0x1792cc85U, - 0x23bcc19fU, 0xbee1a15fU, 0x27bac09dU, 0x7fced6b1U, - 0x744e1d3aU, 0xf702f4f5U, 0x995b61c2U, 0xec9a3b76U, - 0x40601020U, 0x47ead8adU, 0xbd6d68d0U, 0xbae7a05dU, - 0xfe81b17fU, 0x283c0a14U, 0xb96b69d2U, 0xad756cd8U, - 0x39ab4992U, 0xcf26fae9U, 0xc52976ecU, 0x37a2c495U, - 0x42639e21U, 0x567d9b2bU, 0xa5796edcU, 0x5e71992fU, - 0x2fb6c299U, 0xe695b773U, 0x5a77982dU, 0xcaafbc65U, - 0x06058f03U, 0x2e398517U, 0x7c421f3eU, 0xea9fb475U, - 0xc72af8edU, 0x44661122U, 0xb8e42e5cU, 0x00000000U, - 0x94de254aU, 0x70481c38U, 0xa8fc2a54U, 0xf48e3d7aU, - 0x141e050aU, 0x21bf4f9eU, 0xf1077bf6U, 0xf28bb279U, - 0xc8ac3264U, 0x7a47903dU, 0x86c5af43U, 0x64561932U, - 0xb6eda35bU, 0xfb08f7f3U, 0xd13773e6U, 0x4e699d27U, - 0x547e152aU, 0xcd2574e8U, 0x9f5eeec1U, 0x0f86ca89U, - 0x46659f23U, 0x3c220f1eU, 0x6c5a1b36U, 0xc92375eaU, - 0x22338611U, 0x2a3f8415U, 0x4a6f9c25U, 0x35a14a94U, - 0x66559733U, 0x685c1a34U, 0x894365caU, 0xff0ef6f1U, - 0x9354edc7U, 0x24360912U, 0xd6bdbb6bU, 0x98d4264cU, - 0x362d831bU, 0x8b40ebcbU, 0xa17f6fdeU, 0x3e21811fU, - 0x10180408U, 0xb5616ad4U, 0x11974386U, 0x04060102U, - 0x5c72172eU, 0xa37ce1dfU, 0x26358713U, 0xf304f5f7U, - 0x0e098d07U, 0xab70e3dbU, 0x8cca2346U, 0x3a27801dU, - 0x0d854488U, 0x5874162cU, 0x854966ccU, 0x84c62142U, - 0xdf3efee1U, 0x73c4d5b7U, 0xc4a63162U, 0x43ecd9afU, - 0xd4be356aU, 0x60501830U, 0x080c0204U, 0x8d4564c8U, - 0xef16f2f9U, 0xe31cf1ffU, 0x45e956acU, 0x1394cd87U, - 0x322b8219U, 0x078ac88dU, 0xd2bbba69U, 0xe71af0fdU, - 0x9b58efc3U, 0x834ce9cfU, 0x874ae8cdU, 0xd334fde7U, - 0x1e11890fU, 0x7bc8d7b3U, 0x3ba8c793U, 0xee99b577U, - 0xaaffa455U, 0xbce22f5eU, 0x6e599537U, 0x4c6a1326U, - 0x2c3a0b16U, 0xeb10f3fbU, 0xa77ae0ddU, 0xdcb2376eU, -}; - -static const ulong32 T3[256] = { - 0xf5a653a7U, 0xd06bbbd3U, 0x6ebfd1e6U, 0x3bd9e271U, - 0xda67bdd0U, 0xcf8a45acU, 0xb3299a4dU, 0x0bf9f279U, - 0x9ce8743aU, 0x8c038fc9U, 0x417e3f91U, 0x32d7e5fcU, - 0x44783c1eU, 0x8f018e47U, 0xe54da854U, 0xa9ce67bdU, - 0x0f0a058cU, 0xf9ae57a5U, 0x01f5f47aU, 0x20cbebfbU, - 0x5791c663U, 0xb7da6db8U, 0xf453a7ddU, 0xc277b5d4U, - 0x64b3d7e5U, 0x8df67bb3U, 0xa43397c5U, 0xa3c261beU, - 0xd19e4fa9U, 0x171a0d88U, 0x2830180cU, 0xebb259a2U, - 0x96e47239U, 0xf85ba3dfU, 0xf6a45229U, 0xe64fa9daU, - 0xfaac562bU, 0xd79a4da8U, 0x800b8bcbU, 0xb52d984cU, - 0xa731964bU, 0xcc884422U, 0xdb9249aaU, 0xd8904824U, - 0x9b198241U, 0x3ddde070U, 0xf3a251a6U, 0x2cc3eff9U, - 0xc175b45aU, 0x76afd9e2U, 0x87fa7db0U, 0xb4d86c36U, - 0x13e9fa7dU, 0x62b7d5e4U, 0xaacc6633U, 0x38dbe3ffU, - 0x5d9dc060U, 0xc0804020U, 0x30201008U, 0x1d160b8bU, - 0xd965bc5eU, 0xdd964babU, 0x1fe1fe7fU, 0x0dfdf078U, - 0x15edf87cU, 0xe8b0582cU, 0xef41ae57U, 0xd66fb9d2U, - 0xf257a5dcU, 0x73a9da6dU, 0x19e5fc7eU, 0x2e341a0dU, - 0xf751a653U, 0x5f6a3594U, 0xb02b9bc3U, 0xf0a05028U, - 0xd29c4e27U, 0x14180c06U, 0xdf61be5fU, 0xc98e47adU, - 0x4f81ce67U, 0xd56db85cU, 0xe349aa55U, 0xad3d9048U, - 0x24381c0eU, 0xf155a452U, 0x468fc9eaU, 0x91158442U, - 0xc771b65bU, 0xd369ba5dU, 0xa0c06030U, 0xcd7db058U, - 0xfb59a251U, 0xcb79b259U, 0x88f0783cU, 0xb9259c4eU, - 0x90e07038U, 0x1b12098aU, 0x31d5e472U, 0x78502814U, - 0x68bbd3e7U, 0xae3f91c6U, 0xfe5fa1deU, 0xfd5da050U, - 0x0302018eU, 0x4b723992U, 0xdc63bfd1U, 0x2fc1ee77U, - 0x4d763b93U, 0x83098a45U, 0x7b52299aU, 0x9e1f81ceU, - 0xeeb45a2dU, 0x0a0c0603U, 0x5195c462U, 0x93e271b6U, - 0xb1de6fb9U, 0xa5c663bfU, 0x53623196U, 0x67b1d66bU, - 0x82fc7e3fU, 0x121c0e07U, 0x6c482412U, 0xc38241aeU, - 0x9d1d8040U, 0xb8d06834U, 0x89058c46U, 0x84f87c3eU, - 0xe04babdbU, 0x981b83cfU, 0x5297c5ecU, 0x921785ccU, - 0xbc239fc1U, 0xe1be5fa1U, 0xba279dc0U, 0xce7fb1d6U, - 0x4e743a1dU, 0x02f7f5f4U, 0x5b99c261U, 0x9aec763bU, - 0x60402010U, 0xea47add8U, 0x6dbdd068U, 0xe7ba5da0U, - 0x81fe7fb1U, 0x3c28140aU, 0x6bb9d269U, 0x75add86cU, - 0xab399249U, 0x26cfe9faU, 0x29c5ec76U, 0xa23795c4U, - 0x6342219eU, 0x7d562b9bU, 0x79a5dc6eU, 0x715e2f99U, - 0xb62f99c2U, 0x95e673b7U, 0x775a2d98U, 0xafca65bcU, - 0x0506038fU, 0x392e1785U, 0x427c3e1fU, 0x9fea75b4U, - 0x2ac7edf8U, 0x66442211U, 0xe4b85c2eU, 0x00000000U, - 0xde944a25U, 0x4870381cU, 0xfca8542aU, 0x8ef47a3dU, - 0x1e140a05U, 0xbf219e4fU, 0x07f1f67bU, 0x8bf279b2U, - 0xacc86432U, 0x477a3d90U, 0xc58643afU, 0x56643219U, - 0xedb65ba3U, 0x08fbf3f7U, 0x37d1e673U, 0x694e279dU, - 0x7e542a15U, 0x25cde874U, 0x5e9fc1eeU, 0x860f89caU, - 0x6546239fU, 0x223c1e0fU, 0x5a6c361bU, 0x23c9ea75U, - 0x33221186U, 0x3f2a1584U, 0x6f4a259cU, 0xa135944aU, - 0x55663397U, 0x5c68341aU, 0x4389ca65U, 0x0efff1f6U, - 0x5493c7edU, 0x36241209U, 0xbdd66bbbU, 0xd4984c26U, - 0x2d361b83U, 0x408bcbebU, 0x7fa1de6fU, 0x213e1f81U, - 0x18100804U, 0x61b5d46aU, 0x97118643U, 0x06040201U, - 0x725c2e17U, 0x7ca3dfe1U, 0x35261387U, 0x04f3f7f5U, - 0x090e078dU, 0x70abdbe3U, 0xca8c4623U, 0x273a1d80U, - 0x850d8844U, 0x74582c16U, 0x4985cc66U, 0xc6844221U, - 0x3edfe1feU, 0xc473b7d5U, 0xa6c46231U, 0xec43afd9U, - 0xbed46a35U, 0x50603018U, 0x0c080402U, 0x458dc864U, - 0x16eff9f2U, 0x1ce3fff1U, 0xe945ac56U, 0x941387cdU, - 0x2b321982U, 0x8a078dc8U, 0xbbd269baU, 0x1ae7fdf0U, - 0x589bc3efU, 0x4c83cfe9U, 0x4a87cde8U, 0x34d3e7fdU, - 0x111e0f89U, 0xc87bb3d7U, 0xa83b93c7U, 0x99ee77b5U, - 0xffaa55a4U, 0xe2bc5e2fU, 0x596e3795U, 0x6a4c2613U, - 0x3a2c160bU, 0x10ebfbf3U, 0x7aa7dde0U, 0xb2dc6e37U, -}; - -static const ulong32 T4[256] = { - 0xa7a7a7a7U, 0xd3d3d3d3U, 0xe6e6e6e6U, 0x71717171U, - 0xd0d0d0d0U, 0xacacacacU, 0x4d4d4d4dU, 0x79797979U, - 0x3a3a3a3aU, 0xc9c9c9c9U, 0x91919191U, 0xfcfcfcfcU, - 0x1e1e1e1eU, 0x47474747U, 0x54545454U, 0xbdbdbdbdU, - 0x8c8c8c8cU, 0xa5a5a5a5U, 0x7a7a7a7aU, 0xfbfbfbfbU, - 0x63636363U, 0xb8b8b8b8U, 0xddddddddU, 0xd4d4d4d4U, - 0xe5e5e5e5U, 0xb3b3b3b3U, 0xc5c5c5c5U, 0xbebebebeU, - 0xa9a9a9a9U, 0x88888888U, 0x0c0c0c0cU, 0xa2a2a2a2U, - 0x39393939U, 0xdfdfdfdfU, 0x29292929U, 0xdadadadaU, - 0x2b2b2b2bU, 0xa8a8a8a8U, 0xcbcbcbcbU, 0x4c4c4c4cU, - 0x4b4b4b4bU, 0x22222222U, 0xaaaaaaaaU, 0x24242424U, - 0x41414141U, 0x70707070U, 0xa6a6a6a6U, 0xf9f9f9f9U, - 0x5a5a5a5aU, 0xe2e2e2e2U, 0xb0b0b0b0U, 0x36363636U, - 0x7d7d7d7dU, 0xe4e4e4e4U, 0x33333333U, 0xffffffffU, - 0x60606060U, 0x20202020U, 0x08080808U, 0x8b8b8b8bU, - 0x5e5e5e5eU, 0xababababU, 0x7f7f7f7fU, 0x78787878U, - 0x7c7c7c7cU, 0x2c2c2c2cU, 0x57575757U, 0xd2d2d2d2U, - 0xdcdcdcdcU, 0x6d6d6d6dU, 0x7e7e7e7eU, 0x0d0d0d0dU, - 0x53535353U, 0x94949494U, 0xc3c3c3c3U, 0x28282828U, - 0x27272727U, 0x06060606U, 0x5f5f5f5fU, 0xadadadadU, - 0x67676767U, 0x5c5c5c5cU, 0x55555555U, 0x48484848U, - 0x0e0e0e0eU, 0x52525252U, 0xeaeaeaeaU, 0x42424242U, - 0x5b5b5b5bU, 0x5d5d5d5dU, 0x30303030U, 0x58585858U, - 0x51515151U, 0x59595959U, 0x3c3c3c3cU, 0x4e4e4e4eU, - 0x38383838U, 0x8a8a8a8aU, 0x72727272U, 0x14141414U, - 0xe7e7e7e7U, 0xc6c6c6c6U, 0xdedededeU, 0x50505050U, - 0x8e8e8e8eU, 0x92929292U, 0xd1d1d1d1U, 0x77777777U, - 0x93939393U, 0x45454545U, 0x9a9a9a9aU, 0xcecececeU, - 0x2d2d2d2dU, 0x03030303U, 0x62626262U, 0xb6b6b6b6U, - 0xb9b9b9b9U, 0xbfbfbfbfU, 0x96969696U, 0x6b6b6b6bU, - 0x3f3f3f3fU, 0x07070707U, 0x12121212U, 0xaeaeaeaeU, - 0x40404040U, 0x34343434U, 0x46464646U, 0x3e3e3e3eU, - 0xdbdbdbdbU, 0xcfcfcfcfU, 0xececececU, 0xccccccccU, - 0xc1c1c1c1U, 0xa1a1a1a1U, 0xc0c0c0c0U, 0xd6d6d6d6U, - 0x1d1d1d1dU, 0xf4f4f4f4U, 0x61616161U, 0x3b3b3b3bU, - 0x10101010U, 0xd8d8d8d8U, 0x68686868U, 0xa0a0a0a0U, - 0xb1b1b1b1U, 0x0a0a0a0aU, 0x69696969U, 0x6c6c6c6cU, - 0x49494949U, 0xfafafafaU, 0x76767676U, 0xc4c4c4c4U, - 0x9e9e9e9eU, 0x9b9b9b9bU, 0x6e6e6e6eU, 0x99999999U, - 0xc2c2c2c2U, 0xb7b7b7b7U, 0x98989898U, 0xbcbcbcbcU, - 0x8f8f8f8fU, 0x85858585U, 0x1f1f1f1fU, 0xb4b4b4b4U, - 0xf8f8f8f8U, 0x11111111U, 0x2e2e2e2eU, 0x00000000U, - 0x25252525U, 0x1c1c1c1cU, 0x2a2a2a2aU, 0x3d3d3d3dU, - 0x05050505U, 0x4f4f4f4fU, 0x7b7b7b7bU, 0xb2b2b2b2U, - 0x32323232U, 0x90909090U, 0xafafafafU, 0x19191919U, - 0xa3a3a3a3U, 0xf7f7f7f7U, 0x73737373U, 0x9d9d9d9dU, - 0x15151515U, 0x74747474U, 0xeeeeeeeeU, 0xcacacacaU, - 0x9f9f9f9fU, 0x0f0f0f0fU, 0x1b1b1b1bU, 0x75757575U, - 0x86868686U, 0x84848484U, 0x9c9c9c9cU, 0x4a4a4a4aU, - 0x97979797U, 0x1a1a1a1aU, 0x65656565U, 0xf6f6f6f6U, - 0xededededU, 0x09090909U, 0xbbbbbbbbU, 0x26262626U, - 0x83838383U, 0xebebebebU, 0x6f6f6f6fU, 0x81818181U, - 0x04040404U, 0x6a6a6a6aU, 0x43434343U, 0x01010101U, - 0x17171717U, 0xe1e1e1e1U, 0x87878787U, 0xf5f5f5f5U, - 0x8d8d8d8dU, 0xe3e3e3e3U, 0x23232323U, 0x80808080U, - 0x44444444U, 0x16161616U, 0x66666666U, 0x21212121U, - 0xfefefefeU, 0xd5d5d5d5U, 0x31313131U, 0xd9d9d9d9U, - 0x35353535U, 0x18181818U, 0x02020202U, 0x64646464U, - 0xf2f2f2f2U, 0xf1f1f1f1U, 0x56565656U, 0xcdcdcdcdU, - 0x82828282U, 0xc8c8c8c8U, 0xbabababaU, 0xf0f0f0f0U, - 0xefefefefU, 0xe9e9e9e9U, 0xe8e8e8e8U, 0xfdfdfdfdU, - 0x89898989U, 0xd7d7d7d7U, 0xc7c7c7c7U, 0xb5b5b5b5U, - 0xa4a4a4a4U, 0x2f2f2f2fU, 0x95959595U, 0x13131313U, - 0x0b0b0b0bU, 0xf3f3f3f3U, 0xe0e0e0e0U, 0x37373737U, -}; - -static const ulong32 T5[256] = { - 0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U, - 0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U, - 0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U, - 0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U, - 0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U, - 0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U, - 0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U, - 0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U, - 0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U, - 0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U, - 0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U, - 0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U, - 0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U, - 0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U, - 0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U, - 0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U, - 0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U, - 0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U, - 0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U, - 0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U, - 0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U, - 0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U, - 0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U, - 0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U, - 0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU, - 0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU, - 0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU, - 0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU, - 0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU, - 0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU, - 0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU, - 0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU, - 0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU, - 0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU, - 0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU, - 0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU, - 0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU, - 0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU, - 0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU, - 0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU, - 0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U, - 0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U, - 0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U, - 0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U, - 0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U, - 0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U, - 0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U, - 0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U, - 0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U, - 0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U, - 0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U, - 0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U, - 0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U, - 0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U, - 0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U, - 0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U, - 0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU, - 0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU, - 0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU, - 0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU, - 0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU, - 0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU, - 0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU, - 0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU, -}; - -/** - * The round constants. - */ -static const ulong32 rc[] = { - 0xa7d3e671U, 0xd0ac4d79U, 0x3ac991fcU, 0x1e4754bdU, - 0x8ca57afbU, 0x63b8ddd4U, 0xe5b3c5beU, 0xa9880ca2U, - 0x39df29daU, 0x2ba8cb4cU, 0x4b22aa24U, 0x4170a6f9U, - 0x5ae2b036U, 0x7de433ffU, 0x6020088bU, 0x5eab7f78U, - 0x7c2c57d2U, 0xdc6d7e0dU, 0x5394c328U, -}; - -#endif - - /** - Initialize the Anubis block cipher - @param key The symmetric key you wish to pass - @param keylen The key length in bytes - @param num_rounds The number of rounds desired (0 for default) - @param skey The key in as scheduled by this function. - @return CRYPT_OK if successful - */ -#ifdef LTC_CLEAN_STACK -static int _anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) -#else -int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) -#endif -{ - int N, R, i, pos, r; - ulong32 kappa[MAX_N]; - ulong32 inter[MAX_N]; - ulong32 v, K0, K1, K2, K3; - - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(skey != NULL); - - /* Valid sizes (in bytes) are 16, 20, 24, 28, 32, 36, and 40. */ - if ((keylen & 3) || (keylen < 16) || (keylen > 40)) { - return CRYPT_INVALID_KEYSIZE; - } - skey->anubis.keyBits = keylen*8; - - /* - * determine the N length parameter: - * (N.B. it is assumed that the key length is valid!) - */ - N = skey->anubis.keyBits >> 5; - - /* - * determine number of rounds from key size: - */ - skey->anubis.R = R = 8 + N; - - if (num_rounds != 0 && num_rounds != skey->anubis.R) { - return CRYPT_INVALID_ROUNDS; - } - - /* - * map cipher key to initial key state (mu): - */ - for (i = 0, pos = 0; i < N; i++, pos += 4) { - kappa[i] = - (key[pos ] << 24) ^ - (key[pos + 1] << 16) ^ - (key[pos + 2] << 8) ^ - (key[pos + 3] ); - } - - /* - * generate R + 1 round keys: - */ - for (r = 0; r <= R; r++) { - /* - * generate r-th round key K^r: - */ - K0 = T4[(kappa[N - 1] >> 24) ]; - K1 = T4[(kappa[N - 1] >> 16) & 0xff]; - K2 = T4[(kappa[N - 1] >> 8) & 0xff]; - K3 = T4[(kappa[N - 1] ) & 0xff]; - for (i = N - 2; i >= 0; i--) { - K0 = T4[(kappa[i] >> 24) ] ^ - (T5[(K0 >> 24) ] & 0xff000000U) ^ - (T5[(K0 >> 16) & 0xff] & 0x00ff0000U) ^ - (T5[(K0 >> 8) & 0xff] & 0x0000ff00U) ^ - (T5[(K0 ) & 0xff] & 0x000000ffU); - K1 = T4[(kappa[i] >> 16) & 0xff] ^ - (T5[(K1 >> 24) ] & 0xff000000U) ^ - (T5[(K1 >> 16) & 0xff] & 0x00ff0000U) ^ - (T5[(K1 >> 8) & 0xff] & 0x0000ff00U) ^ - (T5[(K1 ) & 0xff] & 0x000000ffU); - K2 = T4[(kappa[i] >> 8) & 0xff] ^ - (T5[(K2 >> 24) ] & 0xff000000U) ^ - (T5[(K2 >> 16) & 0xff] & 0x00ff0000U) ^ - (T5[(K2 >> 8) & 0xff] & 0x0000ff00U) ^ - (T5[(K2 ) & 0xff] & 0x000000ffU); - K3 = T4[(kappa[i] ) & 0xff] ^ - (T5[(K3 >> 24) ] & 0xff000000U) ^ - (T5[(K3 >> 16) & 0xff] & 0x00ff0000U) ^ - (T5[(K3 >> 8) & 0xff] & 0x0000ff00U) ^ - (T5[(K3 ) & 0xff] & 0x000000ffU); - } - /* - -- this is the code to use with the large U tables: - K0 = K1 = K2 = K3 = 0; - for (i = 0; i < N; i++) { - K0 ^= U[i][(kappa[i] >> 24) ]; - K1 ^= U[i][(kappa[i] >> 16) & 0xff]; - K2 ^= U[i][(kappa[i] >> 8) & 0xff]; - K3 ^= U[i][(kappa[i] ) & 0xff]; - } - */ - skey->anubis.roundKeyEnc[r][0] = K0; - skey->anubis.roundKeyEnc[r][1] = K1; - skey->anubis.roundKeyEnc[r][2] = K2; - skey->anubis.roundKeyEnc[r][3] = K3; - - /* - * compute kappa^{r+1} from kappa^r: - */ - if (r == R) { - break; - } - for (i = 0; i < N; i++) { - int j = i; - inter[i] = T0[(kappa[j--] >> 24) ]; if (j < 0) j = N - 1; - inter[i] ^= T1[(kappa[j--] >> 16) & 0xff]; if (j < 0) j = N - 1; - inter[i] ^= T2[(kappa[j--] >> 8) & 0xff]; if (j < 0) j = N - 1; - inter[i] ^= T3[(kappa[j ] ) & 0xff]; - } - kappa[0] = inter[0] ^ rc[r]; - for (i = 1; i < N; i++) { - kappa[i] = inter[i]; - } - } - - /* - * generate inverse key schedule: K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r}): - */ - for (i = 0; i < 4; i++) { - skey->anubis.roundKeyDec[0][i] = skey->anubis.roundKeyEnc[R][i]; - skey->anubis.roundKeyDec[R][i] = skey->anubis.roundKeyEnc[0][i]; - } - for (r = 1; r < R; r++) { - for (i = 0; i < 4; i++) { - v = skey->anubis.roundKeyEnc[R - r][i]; - skey->anubis.roundKeyDec[r][i] = - T0[T4[(v >> 24) ] & 0xff] ^ - T1[T4[(v >> 16) & 0xff] & 0xff] ^ - T2[T4[(v >> 8) & 0xff] & 0xff] ^ - T3[T4[(v ) & 0xff] & 0xff]; - } - } - - return CRYPT_OK; -} - -#ifdef LTC_CLEAN_STACK -int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) -{ - int err; - err = _anubis_setup(key, keylen, num_rounds, skey); - burn_stack(sizeof(int) * 5 + sizeof(ulong32) * (MAX_N + MAX_N + 5)); - return err; -} -#endif - - -static void anubis_crypt(const unsigned char *plaintext, unsigned char *ciphertext, - ulong32 roundKey[18 + 1][4], int R) { - int i, pos, r; - ulong32 state[4]; - ulong32 inter[4]; - - /* - * map plaintext block to cipher state (mu) - * and add initial round key (sigma[K^0]): - */ - for (i = 0, pos = 0; i < 4; i++, pos += 4) { - state[i] = - (plaintext[pos ] << 24) ^ - (plaintext[pos + 1] << 16) ^ - (plaintext[pos + 2] << 8) ^ - (plaintext[pos + 3] ) ^ - roundKey[0][i]; - } - - /* - * R - 1 full rounds: - */ - for (r = 1; r < R; r++) { - inter[0] = - T0[(state[0] >> 24) ] ^ - T1[(state[1] >> 24) ] ^ - T2[(state[2] >> 24) ] ^ - T3[(state[3] >> 24) ] ^ - roundKey[r][0]; - inter[1] = - T0[(state[0] >> 16) & 0xff] ^ - T1[(state[1] >> 16) & 0xff] ^ - T2[(state[2] >> 16) & 0xff] ^ - T3[(state[3] >> 16) & 0xff] ^ - roundKey[r][1]; - inter[2] = - T0[(state[0] >> 8) & 0xff] ^ - T1[(state[1] >> 8) & 0xff] ^ - T2[(state[2] >> 8) & 0xff] ^ - T3[(state[3] >> 8) & 0xff] ^ - roundKey[r][2]; - inter[3] = - T0[(state[0] ) & 0xff] ^ - T1[(state[1] ) & 0xff] ^ - T2[(state[2] ) & 0xff] ^ - T3[(state[3] ) & 0xff] ^ - roundKey[r][3]; - state[0] = inter[0]; - state[1] = inter[1]; - state[2] = inter[2]; - state[3] = inter[3]; - } - - /* - * last round: - */ - inter[0] = - (T0[(state[0] >> 24) ] & 0xff000000U) ^ - (T1[(state[1] >> 24) ] & 0x00ff0000U) ^ - (T2[(state[2] >> 24) ] & 0x0000ff00U) ^ - (T3[(state[3] >> 24) ] & 0x000000ffU) ^ - roundKey[R][0]; - inter[1] = - (T0[(state[0] >> 16) & 0xff] & 0xff000000U) ^ - (T1[(state[1] >> 16) & 0xff] & 0x00ff0000U) ^ - (T2[(state[2] >> 16) & 0xff] & 0x0000ff00U) ^ - (T3[(state[3] >> 16) & 0xff] & 0x000000ffU) ^ - roundKey[R][1]; - inter[2] = - (T0[(state[0] >> 8) & 0xff] & 0xff000000U) ^ - (T1[(state[1] >> 8) & 0xff] & 0x00ff0000U) ^ - (T2[(state[2] >> 8) & 0xff] & 0x0000ff00U) ^ - (T3[(state[3] >> 8) & 0xff] & 0x000000ffU) ^ - roundKey[R][2]; - inter[3] = - (T0[(state[0] ) & 0xff] & 0xff000000U) ^ - (T1[(state[1] ) & 0xff] & 0x00ff0000U) ^ - (T2[(state[2] ) & 0xff] & 0x0000ff00U) ^ - (T3[(state[3] ) & 0xff] & 0x000000ffU) ^ - roundKey[R][3]; - - /* - * map cipher state to ciphertext block (mu^{-1}): - */ - for (i = 0, pos = 0; i < 4; i++, pos += 4) { - ulong32 w = inter[i]; - ciphertext[pos ] = (unsigned char)(w >> 24); - ciphertext[pos + 1] = (unsigned char)(w >> 16); - ciphertext[pos + 2] = (unsigned char)(w >> 8); - ciphertext[pos + 3] = (unsigned char)(w ); - } -} - -/** - Encrypts a block of text with Anubis - @param pt The input plaintext (16 bytes) - @param ct The output ciphertext (16 bytes) - @param skey The key as scheduled - @return CRYPT_OK if successful -*/ -int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) -{ - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); - LTC_ARGCHK(skey != NULL); - anubis_crypt(pt, ct, skey->anubis.roundKeyEnc, skey->anubis.R); - return CRYPT_OK; -} - -/** - Decrypts a block of text with Anubis - @param ct The input ciphertext (16 bytes) - @param pt The output plaintext (16 bytes) - @param skey The key as scheduled - @return CRYPT_OK if successful -*/ -int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) -{ - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); - LTC_ARGCHK(skey != NULL); - anubis_crypt(ct, pt, skey->anubis.roundKeyDec, skey->anubis.R); - return CRYPT_OK; -} - -/** - Performs a self-test of the Anubis block cipher - @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled -*/ -int anubis_test(void) -{ -#if !defined(LTC_TEST) - return CRYPT_NOP; -#else - static const struct test { - int keylen; - unsigned char pt[16], ct[16], key[40]; - } tests[] = { -#ifndef ANUBIS_TWEAK - /**** ORIGINAL ANUBIS ****/ - /* 128 bit keys */ -{ - 16, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xF0, 0x68, 0x60, 0xFC, 0x67, 0x30, 0xE8, 0x18, - 0xF1, 0x32, 0xC7, 0x8A, 0xF4, 0x13, 0x2A, 0xFE }, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}, { - 16, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xA8, 0x66, 0x84, 0x80, 0x07, 0x74, 0x5C, 0x89, - 0xFC, 0x5E, 0xB5, 0xBA, 0xD4, 0xFE, 0x32, 0x6D }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } -}, - - /* 160-bit keys */ -{ - 20, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xBD, 0x5E, 0x32, 0xBE, 0x51, 0x67, 0xA8, 0xE2, - 0x72, 0xD7, 0x95, 0x0F, 0x83, 0xC6, 0x8C, 0x31 }, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 } -}, { - 20, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x4C, 0x1F, 0x86, 0x2E, 0x11, 0xEB, 0xCE, 0xEB, - 0xFE, 0xB9, 0x73, 0xC9, 0xDF, 0xEF, 0x7A, 0xDB }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01 } -}, - - /* 192-bit keys */ -{ - 24, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x17, 0xAC, 0x57, 0x44, 0x9D, 0x59, 0x61, 0x66, - 0xD0, 0xC7, 0x9E, 0x04, 0x7C, 0xC7, 0x58, 0xF0 }, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}, { - 24, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x71, 0x52, 0xB4, 0xEB, 0x1D, 0xAA, 0x36, 0xFD, - 0x57, 0x14, 0x5F, 0x57, 0x04, 0x9F, 0x70, 0x74 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } -}, - - /* 224-bit keys */ -{ - 28, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xA2, 0xF0, 0xA6, 0xB9, 0x17, 0x93, 0x2A, 0x3B, - 0xEF, 0x08, 0xE8, 0x7A, 0x58, 0xD6, 0xF8, 0x53 }, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 } -}, { - 28, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xF0, 0xCA, 0xFC, 0x78, 0x8B, 0x4B, 0x4E, 0x53, - 0x8B, 0xC4, 0x32, 0x6A, 0xF5, 0xB9, 0x1B, 0x5F }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01 } -}, - - /* 256-bit keys */ -{ - 32, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xE0, 0x86, 0xAC, 0x45, 0x6B, 0x3C, 0xE5, 0x13, - 0xED, 0xF5, 0xDF, 0xDD, 0xD6, 0x3B, 0x71, 0x93 }, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}, { - 32, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x50, 0x01, 0xB9, 0xF5, 0x21, 0xC1, 0xC1, 0x29, - 0x00, 0xD5, 0xEC, 0x98, 0x2B, 0x9E, 0xE8, 0x21 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } -}, - - /* 288-bit keys */ -{ - 36, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xE8, 0xF4, 0xAF, 0x2B, 0x21, 0xA0, 0x87, 0x9B, - 0x41, 0x95, 0xB9, 0x71, 0x75, 0x79, 0x04, 0x7C }, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 } -}, { - 36, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xE6, 0xA6, 0xA5, 0xBC, 0x8B, 0x63, 0x6F, 0xE2, - 0xBD, 0xA7, 0xA7, 0x53, 0xAB, 0x40, 0x22, 0xE0 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01 } -}, - - /* 320-bit keys */ -{ - 40, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x17, 0x04, 0xD7, 0x2C, 0xC6, 0x85, 0x76, 0x02, - 0x4B, 0xCC, 0x39, 0x80, 0xD8, 0x22, 0xEA, 0xA4 }, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}, { - 40, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x7A, 0x41, 0xE6, 0x7D, 0x4F, 0xD8, 0x64, 0xF0, - 0x44, 0xA8, 0x3C, 0x73, 0x81, 0x7E, 0x53, 0xD8 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } -} -#else - /**** Tweaked ANUBIS ****/ - /* 128 bit keys */ -{ - 16, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xB8, 0x35, 0xBD, 0xC3, 0x34, 0x82, 0x9D, 0x83, - 0x71, 0xBF, 0xA3, 0x71, 0xE4, 0xB3, 0xC4, 0xFD }, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}, { - 16, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xE6, 0x14, 0x1E, 0xAF, 0xEB, 0xE0, 0x59, 0x3C, - 0x48, 0xE1, 0xCD, 0xF2, 0x1B, 0xBA, 0xA1, 0x89 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } -}, - - /* 160-bit keys */ -{ - 20, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x97, 0x59, 0x79, 0x4B, 0x5C, 0xA0, 0x70, 0x73, - 0x24, 0xEF, 0xB3, 0x58, 0x67, 0xCA, 0xD4, 0xB3 }, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 } -}, { - 20, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xB8, 0x0D, 0xFB, 0x9B, 0xE4, 0xA1, 0x58, 0x87, - 0xB3, 0x76, 0xD5, 0x02, 0x18, 0x95, 0xC1, 0x2E }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01 } -}, - - /* 192-bit keys */ -{ - 24, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x7D, 0x62, 0x3B, 0x52, 0xC7, 0x4C, 0x64, 0xD8, - 0xEB, 0xC7, 0x2D, 0x57, 0x97, 0x85, 0x43, 0x8F }, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}, { - 24, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xB1, 0x0A, 0x59, 0xDD, 0x5D, 0x5D, 0x8D, 0x67, - 0xEC, 0xEE, 0x4A, 0xC4, 0xBE, 0x4F, 0xA8, 0x4F }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } -}, - - /* 224-bit keys */ -{ - 28, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x68, 0x9E, 0x05, 0x94, 0x6A, 0x94, 0x43, 0x8F, - 0xE7, 0x8E, 0x37, 0x3D, 0x24, 0x97, 0x92, 0xF5 }, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 } -}, { - 28, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xDD, 0xB7, 0xB0, 0xB4, 0xE9, 0xB4, 0x9B, 0x9C, - 0x38, 0x20, 0x25, 0x0B, 0x47, 0xC2, 0x1F, 0x89 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01 } -}, - - /* 256-bit keys */ -{ - 32, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x96, 0x00, 0xF0, 0x76, 0x91, 0x69, 0x29, 0x87, - 0xF5, 0xE5, 0x97, 0xDB, 0xDB, 0xAF, 0x1B, 0x0A }, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}, { - 32, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x69, 0x9C, 0xAF, 0xDD, 0x94, 0xC7, 0xBC, 0x60, - 0x44, 0xFE, 0x02, 0x05, 0x8A, 0x6E, 0xEF, 0xBD }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } -}, - - /* 288-bit keys */ -{ - 36, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x0F, 0xC7, 0xA2, 0xC0, 0x11, 0x17, 0xAC, 0x43, - 0x52, 0x5E, 0xDF, 0x6C, 0xF3, 0x96, 0x33, 0x6C }, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 } -}, { - 36, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xAD, 0x08, 0x4F, 0xED, 0x55, 0xA6, 0x94, 0x3E, - 0x7E, 0x5E, 0xED, 0x05, 0xA1, 0x9D, 0x41, 0xB4 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01 } -}, - - /* 320-bit keys */ -{ - 40, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xFE, 0xE2, 0x0E, 0x2A, 0x9D, 0xC5, 0x83, 0xBA, - 0xA3, 0xA6, 0xD6, 0xA6, 0xF2, 0xE8, 0x06, 0xA5 }, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}, { - 40, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x86, 0x3D, 0xCC, 0x4A, 0x60, 0x34, 0x9C, 0x28, - 0xA7, 0xDA, 0xA4, 0x3B, 0x0A, 0xD7, 0xFD, 0xC7 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } -} -#endif -}; - int x, y; - unsigned char buf[2][16]; - symmetric_key skey; - - for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { - anubis_setup(tests[x].key, tests[x].keylen, 0, &skey); - anubis_ecb_encrypt(tests[x].pt, buf[0], &skey); - anubis_ecb_decrypt(buf[0], buf[1], &skey); - if (memcmp(buf[0], tests[x].ct, 16) || memcmp(buf[1], tests[x].pt, 16)) { - return CRYPT_FAIL_TESTVECTOR; - } - - for (y = 0; y < 1000; y++) anubis_ecb_encrypt(buf[0], buf[0], &skey); - for (y = 0; y < 1000; y++) anubis_ecb_decrypt(buf[0], buf[0], &skey); - if (memcmp(buf[0], tests[x].ct, 16)) { - return CRYPT_FAIL_TESTVECTOR; - } - - } - return CRYPT_OK; -#endif -} - -/** Terminate the context - @param skey The scheduled key -*/ -void anubis_done(symmetric_key *skey) -{ -} - -/** - Gets suitable key size - @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. - @return CRYPT_OK if the input key size is acceptable. -*/ -int anubis_keysize(int *keysize) -{ - LTC_ARGCHK(keysize != NULL); - if (*keysize >= 40) { - *keysize = 40; - } else if (*keysize >= 36) { - *keysize = 36; - } else if (*keysize >= 32) { - *keysize = 32; - } else if (*keysize >= 28) { - *keysize = 28; - } else if (*keysize >= 24) { - *keysize = 24; - } else if (*keysize >= 20) { - *keysize = 20; - } else if (*keysize >= 16) { - *keysize = 16; - } else { - return CRYPT_INVALID_KEYSIZE; - } - return CRYPT_OK; -} - -#endif - - -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ + +/** + @file anubis.c + Anubis implementation derived from public domain source + Authors: Paulo S.L.M. Barreto and Vincent Rijmen. +*/ + +#include "tomcrypt.h" + +#ifdef ANUBIS + +const struct ltc_cipher_descriptor anubis_desc = { + "anubis", + 19, + 16, 40, 16, 12, + &anubis_setup, + &anubis_ecb_encrypt, + &anubis_ecb_decrypt, + &anubis_test, + &anubis_done, + &anubis_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +#define MIN_N 4 +#define MAX_N 10 +#define MIN_ROUNDS (8 + MIN_N) +#define MAX_ROUNDS (8 + MAX_N) +#define MIN_KEYSIZEB (4*MIN_N) +#define MAX_KEYSIZEB (4*MAX_N) +#define BLOCKSIZE 128 +#define BLOCKSIZEB (BLOCKSIZE/8) + + +/* + * Though Anubis is endianness-neutral, the encryption tables are listed + * in BIG-ENDIAN format, which is adopted throughout this implementation + * (but little-endian notation would be equally suitable if consistently + * employed). + */ +#if defined(ANUBIS_TWEAK) + +static const ulong32 T0[256] = { + 0xba69d2bbU, 0x54a84de5U, 0x2f5ebce2U, 0x74e8cd25U, + 0x53a651f7U, 0xd3bb6bd0U, 0xd2b96fd6U, 0x4d9a29b3U, + 0x50a05dfdU, 0xac458acfU, 0x8d070e09U, 0xbf63c6a5U, + 0x70e0dd3dU, 0x52a455f1U, 0x9a29527bU, 0x4c982db5U, + 0xeac98f46U, 0xd5b773c4U, 0x97336655U, 0xd1bf63dcU, + 0x3366ccaaU, 0x51a259fbU, 0x5bb671c7U, 0xa651a2f3U, + 0xdea15ffeU, 0x48903dadU, 0xa84d9ad7U, 0x992f5e71U, + 0xdbab4be0U, 0x3264c8acU, 0xb773e695U, 0xfce5d732U, + 0xe3dbab70U, 0x9e214263U, 0x913f7e41U, 0x9b2b567dU, + 0xe2d9af76U, 0xbb6bd6bdU, 0x4182199bU, 0x6edca579U, + 0xa557aef9U, 0xcb8b0b80U, 0x6bd6b167U, 0x95376e59U, + 0xa15fbee1U, 0xf3fbeb10U, 0xb17ffe81U, 0x0204080cU, + 0xcc851792U, 0xc49537a2U, 0x1d3a744eU, 0x14285078U, + 0xc39b2bb0U, 0x63c69157U, 0xdaa94fe6U, 0x5dba69d3U, + 0x5fbe61dfU, 0xdca557f2U, 0x7dfae913U, 0xcd871394U, + 0x7ffee11fU, 0x5ab475c1U, 0x6cd8ad75U, 0x5cb86dd5U, + 0xf7f3fb08U, 0x264c98d4U, 0xffe3db38U, 0xedc79354U, + 0xe8cd874aU, 0x9d274e69U, 0x6fdea17fU, 0x8e010203U, + 0x19326456U, 0xa05dbae7U, 0xf0fde71aU, 0x890f1e11U, + 0x0f1e3c22U, 0x070e1c12U, 0xaf4386c5U, 0xfbebcb20U, + 0x08102030U, 0x152a547eU, 0x0d1a342eU, 0x04081018U, + 0x01020406U, 0x64c88d45U, 0xdfa35bf8U, 0x76ecc529U, + 0x79f2f90bU, 0xdda753f4U, 0x3d7af48eU, 0x162c5874U, + 0x3f7efc82U, 0x376edcb2U, 0x6ddaa973U, 0x3870e090U, + 0xb96fdeb1U, 0x73e6d137U, 0xe9cf834cU, 0x356ad4beU, + 0x55aa49e3U, 0x71e2d93bU, 0x7bf6f107U, 0x8c050a0fU, + 0x72e4d531U, 0x880d1a17U, 0xf6f1ff0eU, 0x2a54a8fcU, + 0x3e7cf884U, 0x5ebc65d9U, 0x274e9cd2U, 0x468c0589U, + 0x0c183028U, 0x65ca8943U, 0x68d0bd6dU, 0x61c2995bU, + 0x03060c0aU, 0xc19f23bcU, 0x57ae41efU, 0xd6b17fceU, + 0xd9af43ecU, 0x58b07dcdU, 0xd8ad47eaU, 0x66cc8549U, + 0xd7b37bc8U, 0x3a74e89cU, 0xc88d078aU, 0x3c78f088U, + 0xfae9cf26U, 0x96316253U, 0xa753a6f5U, 0x982d5a77U, + 0xecc59752U, 0xb86ddab7U, 0xc7933ba8U, 0xae4182c3U, + 0x69d2b96bU, 0x4b9631a7U, 0xab4b96ddU, 0xa94f9ed1U, + 0x67ce814fU, 0x0a14283cU, 0x478e018fU, 0xf2f9ef16U, + 0xb577ee99U, 0x224488ccU, 0xe5d7b364U, 0xeec19f5eU, + 0xbe61c2a3U, 0x2b56acfaU, 0x811f3e21U, 0x1224486cU, + 0x831b362dU, 0x1b366c5aU, 0x0e1c3824U, 0x23468ccaU, + 0xf5f7f304U, 0x458a0983U, 0x214284c6U, 0xce811f9eU, + 0x499239abU, 0x2c58b0e8U, 0xf9efc32cU, 0xe6d1bf6eU, + 0xb671e293U, 0x2850a0f0U, 0x172e5c72U, 0x8219322bU, + 0x1a34685cU, 0x8b0b161dU, 0xfee1df3eU, 0x8a09121bU, + 0x09122436U, 0xc98f038cU, 0x87132635U, 0x4e9c25b9U, + 0xe1dfa37cU, 0x2e5cb8e4U, 0xe4d5b762U, 0xe0dda77aU, + 0xebcb8b40U, 0x903d7a47U, 0xa455aaffU, 0x1e3c7844U, + 0x85172e39U, 0x60c09d5dU, 0x00000000U, 0x254a94deU, + 0xf4f5f702U, 0xf1ffe31cU, 0x94356a5fU, 0x0b162c3aU, + 0xe7d3bb68U, 0x75eac923U, 0xefc39b58U, 0x3468d0b8U, + 0x3162c4a6U, 0xd4b577c2U, 0xd0bd67daU, 0x86112233U, + 0x7efce519U, 0xad478ec9U, 0xfde7d334U, 0x2952a4f6U, + 0x3060c0a0U, 0x3b76ec9aU, 0x9f234665U, 0xf8edc72aU, + 0xc6913faeU, 0x13264c6aU, 0x060c1814U, 0x050a141eU, + 0xc59733a4U, 0x11224466U, 0x77eec12fU, 0x7cf8ed15U, + 0x7af4f501U, 0x78f0fd0dU, 0x366cd8b4U, 0x1c387048U, + 0x3972e496U, 0x59b279cbU, 0x18306050U, 0x56ac45e9U, + 0xb37bf68dU, 0xb07dfa87U, 0x244890d8U, 0x204080c0U, + 0xb279f28bU, 0x9239724bU, 0xa35bb6edU, 0xc09d27baU, + 0x44880d85U, 0x62c49551U, 0x10204060U, 0xb475ea9fU, + 0x84152a3fU, 0x43861197U, 0x933b764dU, 0xc2992fb6U, + 0x4a9435a1U, 0xbd67cea9U, 0x8f030605U, 0x2d5ab4eeU, + 0xbc65caafU, 0x9c254a6fU, 0x6ad4b561U, 0x40801d9dU, + 0xcf831b98U, 0xa259b2ebU, 0x801d3a27U, 0x4f9e21bfU, + 0x1f3e7c42U, 0xca890f86U, 0xaa4992dbU, 0x42841591U, +}; + +static const ulong32 T1[256] = { + 0x69babbd2U, 0xa854e54dU, 0x5e2fe2bcU, 0xe87425cdU, + 0xa653f751U, 0xbbd3d06bU, 0xb9d2d66fU, 0x9a4db329U, + 0xa050fd5dU, 0x45accf8aU, 0x078d090eU, 0x63bfa5c6U, + 0xe0703dddU, 0xa452f155U, 0x299a7b52U, 0x984cb52dU, + 0xc9ea468fU, 0xb7d5c473U, 0x33975566U, 0xbfd1dc63U, + 0x6633aaccU, 0xa251fb59U, 0xb65bc771U, 0x51a6f3a2U, + 0xa1defe5fU, 0x9048ad3dU, 0x4da8d79aU, 0x2f99715eU, + 0xabdbe04bU, 0x6432acc8U, 0x73b795e6U, 0xe5fc32d7U, + 0xdbe370abU, 0x219e6342U, 0x3f91417eU, 0x2b9b7d56U, + 0xd9e276afU, 0x6bbbbdd6U, 0x82419b19U, 0xdc6e79a5U, + 0x57a5f9aeU, 0x8bcb800bU, 0xd66b67b1U, 0x3795596eU, + 0x5fa1e1beU, 0xfbf310ebU, 0x7fb181feU, 0x04020c08U, + 0x85cc9217U, 0x95c4a237U, 0x3a1d4e74U, 0x28147850U, + 0x9bc3b02bU, 0xc6635791U, 0xa9dae64fU, 0xba5dd369U, + 0xbe5fdf61U, 0xa5dcf257U, 0xfa7d13e9U, 0x87cd9413U, + 0xfe7f1fe1U, 0xb45ac175U, 0xd86c75adU, 0xb85cd56dU, + 0xf3f708fbU, 0x4c26d498U, 0xe3ff38dbU, 0xc7ed5493U, + 0xcde84a87U, 0x279d694eU, 0xde6f7fa1U, 0x018e0302U, + 0x32195664U, 0x5da0e7baU, 0xfdf01ae7U, 0x0f89111eU, + 0x1e0f223cU, 0x0e07121cU, 0x43afc586U, 0xebfb20cbU, + 0x10083020U, 0x2a157e54U, 0x1a0d2e34U, 0x08041810U, + 0x02010604U, 0xc864458dU, 0xa3dff85bU, 0xec7629c5U, + 0xf2790bf9U, 0xa7ddf453U, 0x7a3d8ef4U, 0x2c167458U, + 0x7e3f82fcU, 0x6e37b2dcU, 0xda6d73a9U, 0x703890e0U, + 0x6fb9b1deU, 0xe67337d1U, 0xcfe94c83U, 0x6a35bed4U, + 0xaa55e349U, 0xe2713bd9U, 0xf67b07f1U, 0x058c0f0aU, + 0xe47231d5U, 0x0d88171aU, 0xf1f60effU, 0x542afca8U, + 0x7c3e84f8U, 0xbc5ed965U, 0x4e27d29cU, 0x8c468905U, + 0x180c2830U, 0xca654389U, 0xd0686dbdU, 0xc2615b99U, + 0x06030a0cU, 0x9fc1bc23U, 0xae57ef41U, 0xb1d6ce7fU, + 0xafd9ec43U, 0xb058cd7dU, 0xadd8ea47U, 0xcc664985U, + 0xb3d7c87bU, 0x743a9ce8U, 0x8dc88a07U, 0x783c88f0U, + 0xe9fa26cfU, 0x31965362U, 0x53a7f5a6U, 0x2d98775aU, + 0xc5ec5297U, 0x6db8b7daU, 0x93c7a83bU, 0x41aec382U, + 0xd2696bb9U, 0x964ba731U, 0x4babdd96U, 0x4fa9d19eU, + 0xce674f81U, 0x140a3c28U, 0x8e478f01U, 0xf9f216efU, + 0x77b599eeU, 0x4422cc88U, 0xd7e564b3U, 0xc1ee5e9fU, + 0x61bea3c2U, 0x562bfaacU, 0x1f81213eU, 0x24126c48U, + 0x1b832d36U, 0x361b5a6cU, 0x1c0e2438U, 0x4623ca8cU, + 0xf7f504f3U, 0x8a458309U, 0x4221c684U, 0x81ce9e1fU, + 0x9249ab39U, 0x582ce8b0U, 0xeff92cc3U, 0xd1e66ebfU, + 0x71b693e2U, 0x5028f0a0U, 0x2e17725cU, 0x19822b32U, + 0x341a5c68U, 0x0b8b1d16U, 0xe1fe3edfU, 0x098a1b12U, + 0x12093624U, 0x8fc98c03U, 0x13873526U, 0x9c4eb925U, + 0xdfe17ca3U, 0x5c2ee4b8U, 0xd5e462b7U, 0xdde07aa7U, + 0xcbeb408bU, 0x3d90477aU, 0x55a4ffaaU, 0x3c1e4478U, + 0x1785392eU, 0xc0605d9dU, 0x00000000U, 0x4a25de94U, + 0xf5f402f7U, 0xfff11ce3U, 0x35945f6aU, 0x160b3a2cU, + 0xd3e768bbU, 0xea7523c9U, 0xc3ef589bU, 0x6834b8d0U, + 0x6231a6c4U, 0xb5d4c277U, 0xbdd0da67U, 0x11863322U, + 0xfc7e19e5U, 0x47adc98eU, 0xe7fd34d3U, 0x5229f6a4U, + 0x6030a0c0U, 0x763b9aecU, 0x239f6546U, 0xedf82ac7U, + 0x91c6ae3fU, 0x26136a4cU, 0x0c061418U, 0x0a051e14U, + 0x97c5a433U, 0x22116644U, 0xee772fc1U, 0xf87c15edU, + 0xf47a01f5U, 0xf0780dfdU, 0x6c36b4d8U, 0x381c4870U, + 0x723996e4U, 0xb259cb79U, 0x30185060U, 0xac56e945U, + 0x7bb38df6U, 0x7db087faU, 0x4824d890U, 0x4020c080U, + 0x79b28bf2U, 0x39924b72U, 0x5ba3edb6U, 0x9dc0ba27U, + 0x8844850dU, 0xc4625195U, 0x20106040U, 0x75b49feaU, + 0x15843f2aU, 0x86439711U, 0x3b934d76U, 0x99c2b62fU, + 0x944aa135U, 0x67bda9ceU, 0x038f0506U, 0x5a2deeb4U, + 0x65bcafcaU, 0x259c6f4aU, 0xd46a61b5U, 0x80409d1dU, + 0x83cf981bU, 0x59a2ebb2U, 0x1d80273aU, 0x9e4fbf21U, + 0x3e1f427cU, 0x89ca860fU, 0x49aadb92U, 0x84429115U, +}; + +static const ulong32 T2[256] = { + 0xd2bbba69U, 0x4de554a8U, 0xbce22f5eU, 0xcd2574e8U, + 0x51f753a6U, 0x6bd0d3bbU, 0x6fd6d2b9U, 0x29b34d9aU, + 0x5dfd50a0U, 0x8acfac45U, 0x0e098d07U, 0xc6a5bf63U, + 0xdd3d70e0U, 0x55f152a4U, 0x527b9a29U, 0x2db54c98U, + 0x8f46eac9U, 0x73c4d5b7U, 0x66559733U, 0x63dcd1bfU, + 0xccaa3366U, 0x59fb51a2U, 0x71c75bb6U, 0xa2f3a651U, + 0x5ffedea1U, 0x3dad4890U, 0x9ad7a84dU, 0x5e71992fU, + 0x4be0dbabU, 0xc8ac3264U, 0xe695b773U, 0xd732fce5U, + 0xab70e3dbU, 0x42639e21U, 0x7e41913fU, 0x567d9b2bU, + 0xaf76e2d9U, 0xd6bdbb6bU, 0x199b4182U, 0xa5796edcU, + 0xaef9a557U, 0x0b80cb8bU, 0xb1676bd6U, 0x6e599537U, + 0xbee1a15fU, 0xeb10f3fbU, 0xfe81b17fU, 0x080c0204U, + 0x1792cc85U, 0x37a2c495U, 0x744e1d3aU, 0x50781428U, + 0x2bb0c39bU, 0x915763c6U, 0x4fe6daa9U, 0x69d35dbaU, + 0x61df5fbeU, 0x57f2dca5U, 0xe9137dfaU, 0x1394cd87U, + 0xe11f7ffeU, 0x75c15ab4U, 0xad756cd8U, 0x6dd55cb8U, + 0xfb08f7f3U, 0x98d4264cU, 0xdb38ffe3U, 0x9354edc7U, + 0x874ae8cdU, 0x4e699d27U, 0xa17f6fdeU, 0x02038e01U, + 0x64561932U, 0xbae7a05dU, 0xe71af0fdU, 0x1e11890fU, + 0x3c220f1eU, 0x1c12070eU, 0x86c5af43U, 0xcb20fbebU, + 0x20300810U, 0x547e152aU, 0x342e0d1aU, 0x10180408U, + 0x04060102U, 0x8d4564c8U, 0x5bf8dfa3U, 0xc52976ecU, + 0xf90b79f2U, 0x53f4dda7U, 0xf48e3d7aU, 0x5874162cU, + 0xfc823f7eU, 0xdcb2376eU, 0xa9736ddaU, 0xe0903870U, + 0xdeb1b96fU, 0xd13773e6U, 0x834ce9cfU, 0xd4be356aU, + 0x49e355aaU, 0xd93b71e2U, 0xf1077bf6U, 0x0a0f8c05U, + 0xd53172e4U, 0x1a17880dU, 0xff0ef6f1U, 0xa8fc2a54U, + 0xf8843e7cU, 0x65d95ebcU, 0x9cd2274eU, 0x0589468cU, + 0x30280c18U, 0x894365caU, 0xbd6d68d0U, 0x995b61c2U, + 0x0c0a0306U, 0x23bcc19fU, 0x41ef57aeU, 0x7fced6b1U, + 0x43ecd9afU, 0x7dcd58b0U, 0x47ead8adU, 0x854966ccU, + 0x7bc8d7b3U, 0xe89c3a74U, 0x078ac88dU, 0xf0883c78U, + 0xcf26fae9U, 0x62539631U, 0xa6f5a753U, 0x5a77982dU, + 0x9752ecc5U, 0xdab7b86dU, 0x3ba8c793U, 0x82c3ae41U, + 0xb96b69d2U, 0x31a74b96U, 0x96ddab4bU, 0x9ed1a94fU, + 0x814f67ceU, 0x283c0a14U, 0x018f478eU, 0xef16f2f9U, + 0xee99b577U, 0x88cc2244U, 0xb364e5d7U, 0x9f5eeec1U, + 0xc2a3be61U, 0xacfa2b56U, 0x3e21811fU, 0x486c1224U, + 0x362d831bU, 0x6c5a1b36U, 0x38240e1cU, 0x8cca2346U, + 0xf304f5f7U, 0x0983458aU, 0x84c62142U, 0x1f9ece81U, + 0x39ab4992U, 0xb0e82c58U, 0xc32cf9efU, 0xbf6ee6d1U, + 0xe293b671U, 0xa0f02850U, 0x5c72172eU, 0x322b8219U, + 0x685c1a34U, 0x161d8b0bU, 0xdf3efee1U, 0x121b8a09U, + 0x24360912U, 0x038cc98fU, 0x26358713U, 0x25b94e9cU, + 0xa37ce1dfU, 0xb8e42e5cU, 0xb762e4d5U, 0xa77ae0ddU, + 0x8b40ebcbU, 0x7a47903dU, 0xaaffa455U, 0x78441e3cU, + 0x2e398517U, 0x9d5d60c0U, 0x00000000U, 0x94de254aU, + 0xf702f4f5U, 0xe31cf1ffU, 0x6a5f9435U, 0x2c3a0b16U, + 0xbb68e7d3U, 0xc92375eaU, 0x9b58efc3U, 0xd0b83468U, + 0xc4a63162U, 0x77c2d4b5U, 0x67dad0bdU, 0x22338611U, + 0xe5197efcU, 0x8ec9ad47U, 0xd334fde7U, 0xa4f62952U, + 0xc0a03060U, 0xec9a3b76U, 0x46659f23U, 0xc72af8edU, + 0x3faec691U, 0x4c6a1326U, 0x1814060cU, 0x141e050aU, + 0x33a4c597U, 0x44661122U, 0xc12f77eeU, 0xed157cf8U, + 0xf5017af4U, 0xfd0d78f0U, 0xd8b4366cU, 0x70481c38U, + 0xe4963972U, 0x79cb59b2U, 0x60501830U, 0x45e956acU, + 0xf68db37bU, 0xfa87b07dU, 0x90d82448U, 0x80c02040U, + 0xf28bb279U, 0x724b9239U, 0xb6eda35bU, 0x27bac09dU, + 0x0d854488U, 0x955162c4U, 0x40601020U, 0xea9fb475U, + 0x2a3f8415U, 0x11974386U, 0x764d933bU, 0x2fb6c299U, + 0x35a14a94U, 0xcea9bd67U, 0x06058f03U, 0xb4ee2d5aU, + 0xcaafbc65U, 0x4a6f9c25U, 0xb5616ad4U, 0x1d9d4080U, + 0x1b98cf83U, 0xb2eba259U, 0x3a27801dU, 0x21bf4f9eU, + 0x7c421f3eU, 0x0f86ca89U, 0x92dbaa49U, 0x15914284U, +}; + +static const ulong32 T3[256] = { + 0xbbd269baU, 0xe54da854U, 0xe2bc5e2fU, 0x25cde874U, + 0xf751a653U, 0xd06bbbd3U, 0xd66fb9d2U, 0xb3299a4dU, + 0xfd5da050U, 0xcf8a45acU, 0x090e078dU, 0xa5c663bfU, + 0x3ddde070U, 0xf155a452U, 0x7b52299aU, 0xb52d984cU, + 0x468fc9eaU, 0xc473b7d5U, 0x55663397U, 0xdc63bfd1U, + 0xaacc6633U, 0xfb59a251U, 0xc771b65bU, 0xf3a251a6U, + 0xfe5fa1deU, 0xad3d9048U, 0xd79a4da8U, 0x715e2f99U, + 0xe04babdbU, 0xacc86432U, 0x95e673b7U, 0x32d7e5fcU, + 0x70abdbe3U, 0x6342219eU, 0x417e3f91U, 0x7d562b9bU, + 0x76afd9e2U, 0xbdd66bbbU, 0x9b198241U, 0x79a5dc6eU, + 0xf9ae57a5U, 0x800b8bcbU, 0x67b1d66bU, 0x596e3795U, + 0xe1be5fa1U, 0x10ebfbf3U, 0x81fe7fb1U, 0x0c080402U, + 0x921785ccU, 0xa23795c4U, 0x4e743a1dU, 0x78502814U, + 0xb02b9bc3U, 0x5791c663U, 0xe64fa9daU, 0xd369ba5dU, + 0xdf61be5fU, 0xf257a5dcU, 0x13e9fa7dU, 0x941387cdU, + 0x1fe1fe7fU, 0xc175b45aU, 0x75add86cU, 0xd56db85cU, + 0x08fbf3f7U, 0xd4984c26U, 0x38dbe3ffU, 0x5493c7edU, + 0x4a87cde8U, 0x694e279dU, 0x7fa1de6fU, 0x0302018eU, + 0x56643219U, 0xe7ba5da0U, 0x1ae7fdf0U, 0x111e0f89U, + 0x223c1e0fU, 0x121c0e07U, 0xc58643afU, 0x20cbebfbU, + 0x30201008U, 0x7e542a15U, 0x2e341a0dU, 0x18100804U, + 0x06040201U, 0x458dc864U, 0xf85ba3dfU, 0x29c5ec76U, + 0x0bf9f279U, 0xf453a7ddU, 0x8ef47a3dU, 0x74582c16U, + 0x82fc7e3fU, 0xb2dc6e37U, 0x73a9da6dU, 0x90e07038U, + 0xb1de6fb9U, 0x37d1e673U, 0x4c83cfe9U, 0xbed46a35U, + 0xe349aa55U, 0x3bd9e271U, 0x07f1f67bU, 0x0f0a058cU, + 0x31d5e472U, 0x171a0d88U, 0x0efff1f6U, 0xfca8542aU, + 0x84f87c3eU, 0xd965bc5eU, 0xd29c4e27U, 0x89058c46U, + 0x2830180cU, 0x4389ca65U, 0x6dbdd068U, 0x5b99c261U, + 0x0a0c0603U, 0xbc239fc1U, 0xef41ae57U, 0xce7fb1d6U, + 0xec43afd9U, 0xcd7db058U, 0xea47add8U, 0x4985cc66U, + 0xc87bb3d7U, 0x9ce8743aU, 0x8a078dc8U, 0x88f0783cU, + 0x26cfe9faU, 0x53623196U, 0xf5a653a7U, 0x775a2d98U, + 0x5297c5ecU, 0xb7da6db8U, 0xa83b93c7U, 0xc38241aeU, + 0x6bb9d269U, 0xa731964bU, 0xdd964babU, 0xd19e4fa9U, + 0x4f81ce67U, 0x3c28140aU, 0x8f018e47U, 0x16eff9f2U, + 0x99ee77b5U, 0xcc884422U, 0x64b3d7e5U, 0x5e9fc1eeU, + 0xa3c261beU, 0xfaac562bU, 0x213e1f81U, 0x6c482412U, + 0x2d361b83U, 0x5a6c361bU, 0x24381c0eU, 0xca8c4623U, + 0x04f3f7f5U, 0x83098a45U, 0xc6844221U, 0x9e1f81ceU, + 0xab399249U, 0xe8b0582cU, 0x2cc3eff9U, 0x6ebfd1e6U, + 0x93e271b6U, 0xf0a05028U, 0x725c2e17U, 0x2b321982U, + 0x5c68341aU, 0x1d160b8bU, 0x3edfe1feU, 0x1b12098aU, + 0x36241209U, 0x8c038fc9U, 0x35261387U, 0xb9259c4eU, + 0x7ca3dfe1U, 0xe4b85c2eU, 0x62b7d5e4U, 0x7aa7dde0U, + 0x408bcbebU, 0x477a3d90U, 0xffaa55a4U, 0x44783c1eU, + 0x392e1785U, 0x5d9dc060U, 0x00000000U, 0xde944a25U, + 0x02f7f5f4U, 0x1ce3fff1U, 0x5f6a3594U, 0x3a2c160bU, + 0x68bbd3e7U, 0x23c9ea75U, 0x589bc3efU, 0xb8d06834U, + 0xa6c46231U, 0xc277b5d4U, 0xda67bdd0U, 0x33221186U, + 0x19e5fc7eU, 0xc98e47adU, 0x34d3e7fdU, 0xf6a45229U, + 0xa0c06030U, 0x9aec763bU, 0x6546239fU, 0x2ac7edf8U, + 0xae3f91c6U, 0x6a4c2613U, 0x14180c06U, 0x1e140a05U, + 0xa43397c5U, 0x66442211U, 0x2fc1ee77U, 0x15edf87cU, + 0x01f5f47aU, 0x0dfdf078U, 0xb4d86c36U, 0x4870381cU, + 0x96e47239U, 0xcb79b259U, 0x50603018U, 0xe945ac56U, + 0x8df67bb3U, 0x87fa7db0U, 0xd8904824U, 0xc0804020U, + 0x8bf279b2U, 0x4b723992U, 0xedb65ba3U, 0xba279dc0U, + 0x850d8844U, 0x5195c462U, 0x60402010U, 0x9fea75b4U, + 0x3f2a1584U, 0x97118643U, 0x4d763b93U, 0xb62f99c2U, + 0xa135944aU, 0xa9ce67bdU, 0x0506038fU, 0xeeb45a2dU, + 0xafca65bcU, 0x6f4a259cU, 0x61b5d46aU, 0x9d1d8040U, + 0x981b83cfU, 0xebb259a2U, 0x273a1d80U, 0xbf219e4fU, + 0x427c3e1fU, 0x860f89caU, 0xdb9249aaU, 0x91158442U, +}; + +static const ulong32 T4[256] = { + 0xbabababaU, 0x54545454U, 0x2f2f2f2fU, 0x74747474U, + 0x53535353U, 0xd3d3d3d3U, 0xd2d2d2d2U, 0x4d4d4d4dU, + 0x50505050U, 0xacacacacU, 0x8d8d8d8dU, 0xbfbfbfbfU, + 0x70707070U, 0x52525252U, 0x9a9a9a9aU, 0x4c4c4c4cU, + 0xeaeaeaeaU, 0xd5d5d5d5U, 0x97979797U, 0xd1d1d1d1U, + 0x33333333U, 0x51515151U, 0x5b5b5b5bU, 0xa6a6a6a6U, + 0xdedededeU, 0x48484848U, 0xa8a8a8a8U, 0x99999999U, + 0xdbdbdbdbU, 0x32323232U, 0xb7b7b7b7U, 0xfcfcfcfcU, + 0xe3e3e3e3U, 0x9e9e9e9eU, 0x91919191U, 0x9b9b9b9bU, + 0xe2e2e2e2U, 0xbbbbbbbbU, 0x41414141U, 0x6e6e6e6eU, + 0xa5a5a5a5U, 0xcbcbcbcbU, 0x6b6b6b6bU, 0x95959595U, + 0xa1a1a1a1U, 0xf3f3f3f3U, 0xb1b1b1b1U, 0x02020202U, + 0xccccccccU, 0xc4c4c4c4U, 0x1d1d1d1dU, 0x14141414U, + 0xc3c3c3c3U, 0x63636363U, 0xdadadadaU, 0x5d5d5d5dU, + 0x5f5f5f5fU, 0xdcdcdcdcU, 0x7d7d7d7dU, 0xcdcdcdcdU, + 0x7f7f7f7fU, 0x5a5a5a5aU, 0x6c6c6c6cU, 0x5c5c5c5cU, + 0xf7f7f7f7U, 0x26262626U, 0xffffffffU, 0xededededU, + 0xe8e8e8e8U, 0x9d9d9d9dU, 0x6f6f6f6fU, 0x8e8e8e8eU, + 0x19191919U, 0xa0a0a0a0U, 0xf0f0f0f0U, 0x89898989U, + 0x0f0f0f0fU, 0x07070707U, 0xafafafafU, 0xfbfbfbfbU, + 0x08080808U, 0x15151515U, 0x0d0d0d0dU, 0x04040404U, + 0x01010101U, 0x64646464U, 0xdfdfdfdfU, 0x76767676U, + 0x79797979U, 0xddddddddU, 0x3d3d3d3dU, 0x16161616U, + 0x3f3f3f3fU, 0x37373737U, 0x6d6d6d6dU, 0x38383838U, + 0xb9b9b9b9U, 0x73737373U, 0xe9e9e9e9U, 0x35353535U, + 0x55555555U, 0x71717171U, 0x7b7b7b7bU, 0x8c8c8c8cU, + 0x72727272U, 0x88888888U, 0xf6f6f6f6U, 0x2a2a2a2aU, + 0x3e3e3e3eU, 0x5e5e5e5eU, 0x27272727U, 0x46464646U, + 0x0c0c0c0cU, 0x65656565U, 0x68686868U, 0x61616161U, + 0x03030303U, 0xc1c1c1c1U, 0x57575757U, 0xd6d6d6d6U, + 0xd9d9d9d9U, 0x58585858U, 0xd8d8d8d8U, 0x66666666U, + 0xd7d7d7d7U, 0x3a3a3a3aU, 0xc8c8c8c8U, 0x3c3c3c3cU, + 0xfafafafaU, 0x96969696U, 0xa7a7a7a7U, 0x98989898U, + 0xececececU, 0xb8b8b8b8U, 0xc7c7c7c7U, 0xaeaeaeaeU, + 0x69696969U, 0x4b4b4b4bU, 0xababababU, 0xa9a9a9a9U, + 0x67676767U, 0x0a0a0a0aU, 0x47474747U, 0xf2f2f2f2U, + 0xb5b5b5b5U, 0x22222222U, 0xe5e5e5e5U, 0xeeeeeeeeU, + 0xbebebebeU, 0x2b2b2b2bU, 0x81818181U, 0x12121212U, + 0x83838383U, 0x1b1b1b1bU, 0x0e0e0e0eU, 0x23232323U, + 0xf5f5f5f5U, 0x45454545U, 0x21212121U, 0xcecececeU, + 0x49494949U, 0x2c2c2c2cU, 0xf9f9f9f9U, 0xe6e6e6e6U, + 0xb6b6b6b6U, 0x28282828U, 0x17171717U, 0x82828282U, + 0x1a1a1a1aU, 0x8b8b8b8bU, 0xfefefefeU, 0x8a8a8a8aU, + 0x09090909U, 0xc9c9c9c9U, 0x87878787U, 0x4e4e4e4eU, + 0xe1e1e1e1U, 0x2e2e2e2eU, 0xe4e4e4e4U, 0xe0e0e0e0U, + 0xebebebebU, 0x90909090U, 0xa4a4a4a4U, 0x1e1e1e1eU, + 0x85858585U, 0x60606060U, 0x00000000U, 0x25252525U, + 0xf4f4f4f4U, 0xf1f1f1f1U, 0x94949494U, 0x0b0b0b0bU, + 0xe7e7e7e7U, 0x75757575U, 0xefefefefU, 0x34343434U, + 0x31313131U, 0xd4d4d4d4U, 0xd0d0d0d0U, 0x86868686U, + 0x7e7e7e7eU, 0xadadadadU, 0xfdfdfdfdU, 0x29292929U, + 0x30303030U, 0x3b3b3b3bU, 0x9f9f9f9fU, 0xf8f8f8f8U, + 0xc6c6c6c6U, 0x13131313U, 0x06060606U, 0x05050505U, + 0xc5c5c5c5U, 0x11111111U, 0x77777777U, 0x7c7c7c7cU, + 0x7a7a7a7aU, 0x78787878U, 0x36363636U, 0x1c1c1c1cU, + 0x39393939U, 0x59595959U, 0x18181818U, 0x56565656U, + 0xb3b3b3b3U, 0xb0b0b0b0U, 0x24242424U, 0x20202020U, + 0xb2b2b2b2U, 0x92929292U, 0xa3a3a3a3U, 0xc0c0c0c0U, + 0x44444444U, 0x62626262U, 0x10101010U, 0xb4b4b4b4U, + 0x84848484U, 0x43434343U, 0x93939393U, 0xc2c2c2c2U, + 0x4a4a4a4aU, 0xbdbdbdbdU, 0x8f8f8f8fU, 0x2d2d2d2dU, + 0xbcbcbcbcU, 0x9c9c9c9cU, 0x6a6a6a6aU, 0x40404040U, + 0xcfcfcfcfU, 0xa2a2a2a2U, 0x80808080U, 0x4f4f4f4fU, + 0x1f1f1f1fU, 0xcacacacaU, 0xaaaaaaaaU, 0x42424242U, +}; + +static const ulong32 T5[256] = { + 0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U, + 0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U, + 0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U, + 0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U, + 0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U, + 0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U, + 0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U, + 0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U, + 0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U, + 0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U, + 0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U, + 0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U, + 0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U, + 0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U, + 0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U, + 0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U, + 0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U, + 0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U, + 0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U, + 0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U, + 0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U, + 0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U, + 0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U, + 0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U, + 0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU, + 0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU, + 0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU, + 0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU, + 0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU, + 0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU, + 0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU, + 0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU, + 0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU, + 0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU, + 0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU, + 0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU, + 0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU, + 0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU, + 0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU, + 0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU, + 0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U, + 0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U, + 0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U, + 0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U, + 0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U, + 0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U, + 0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U, + 0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U, + 0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U, + 0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U, + 0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U, + 0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U, + 0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U, + 0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U, + 0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U, + 0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U, + 0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU, + 0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU, + 0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU, + 0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU, + 0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU, + 0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU, + 0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU, + 0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU, +}; + +/** + * The round constants. + */ +static const ulong32 rc[] = { + 0xba542f74U, 0x53d3d24dU, 0x50ac8dbfU, 0x70529a4cU, + 0xead597d1U, 0x33515ba6U, 0xde48a899U, 0xdb32b7fcU, + 0xe39e919bU, 0xe2bb416eU, 0xa5cb6b95U, 0xa1f3b102U, + 0xccc41d14U, 0xc363da5dU, 0x5fdc7dcdU, 0x7f5a6c5cU, + 0xf726ffedU, 0xe89d6f8eU, 0x19a0f089U, +}; + + + +#else + + +static const ulong32 T0[256] = { + 0xa753a6f5U, 0xd3bb6bd0U, 0xe6d1bf6eU, 0x71e2d93bU, + 0xd0bd67daU, 0xac458acfU, 0x4d9a29b3U, 0x79f2f90bU, + 0x3a74e89cU, 0xc98f038cU, 0x913f7e41U, 0xfce5d732U, + 0x1e3c7844U, 0x478e018fU, 0x54a84de5U, 0xbd67cea9U, + 0x8c050a0fU, 0xa557aef9U, 0x7af4f501U, 0xfbebcb20U, + 0x63c69157U, 0xb86ddab7U, 0xdda753f4U, 0xd4b577c2U, + 0xe5d7b364U, 0xb37bf68dU, 0xc59733a4U, 0xbe61c2a3U, + 0xa94f9ed1U, 0x880d1a17U, 0x0c183028U, 0xa259b2ebU, + 0x3972e496U, 0xdfa35bf8U, 0x2952a4f6U, 0xdaa94fe6U, + 0x2b56acfaU, 0xa84d9ad7U, 0xcb8b0b80U, 0x4c982db5U, + 0x4b9631a7U, 0x224488ccU, 0xaa4992dbU, 0x244890d8U, + 0x4182199bU, 0x70e0dd3dU, 0xa651a2f3U, 0xf9efc32cU, + 0x5ab475c1U, 0xe2d9af76U, 0xb07dfa87U, 0x366cd8b4U, + 0x7dfae913U, 0xe4d5b762U, 0x3366ccaaU, 0xffe3db38U, + 0x60c09d5dU, 0x204080c0U, 0x08102030U, 0x8b0b161dU, + 0x5ebc65d9U, 0xab4b96ddU, 0x7ffee11fU, 0x78f0fd0dU, + 0x7cf8ed15U, 0x2c58b0e8U, 0x57ae41efU, 0xd2b96fd6U, + 0xdca557f2U, 0x6ddaa973U, 0x7efce519U, 0x0d1a342eU, + 0x53a651f7U, 0x94356a5fU, 0xc39b2bb0U, 0x2850a0f0U, + 0x274e9cd2U, 0x060c1814U, 0x5fbe61dfU, 0xad478ec9U, + 0x67ce814fU, 0x5cb86dd5U, 0x55aa49e3U, 0x48903dadU, + 0x0e1c3824U, 0x52a455f1U, 0xeac98f46U, 0x42841591U, + 0x5bb671c7U, 0x5dba69d3U, 0x3060c0a0U, 0x58b07dcdU, + 0x51a259fbU, 0x59b279cbU, 0x3c78f088U, 0x4e9c25b9U, + 0x3870e090U, 0x8a09121bU, 0x72e4d531U, 0x14285078U, + 0xe7d3bb68U, 0xc6913faeU, 0xdea15ffeU, 0x50a05dfdU, + 0x8e010203U, 0x9239724bU, 0xd1bf63dcU, 0x77eec12fU, + 0x933b764dU, 0x458a0983U, 0x9a29527bU, 0xce811f9eU, + 0x2d5ab4eeU, 0x03060c0aU, 0x62c49551U, 0xb671e293U, + 0xb96fdeb1U, 0xbf63c6a5U, 0x96316253U, 0x6bd6b167U, + 0x3f7efc82U, 0x070e1c12U, 0x1224486cU, 0xae4182c3U, + 0x40801d9dU, 0x3468d0b8U, 0x468c0589U, 0x3e7cf884U, + 0xdbab4be0U, 0xcf831b98U, 0xecc59752U, 0xcc851792U, + 0xc19f23bcU, 0xa15fbee1U, 0xc09d27baU, 0xd6b17fceU, + 0x1d3a744eU, 0xf4f5f702U, 0x61c2995bU, 0x3b76ec9aU, + 0x10204060U, 0xd8ad47eaU, 0x68d0bd6dU, 0xa05dbae7U, + 0xb17ffe81U, 0x0a14283cU, 0x69d2b96bU, 0x6cd8ad75U, + 0x499239abU, 0xfae9cf26U, 0x76ecc529U, 0xc49537a2U, + 0x9e214263U, 0x9b2b567dU, 0x6edca579U, 0x992f5e71U, + 0xc2992fb6U, 0xb773e695U, 0x982d5a77U, 0xbc65caafU, + 0x8f030605U, 0x85172e39U, 0x1f3e7c42U, 0xb475ea9fU, + 0xf8edc72aU, 0x11224466U, 0x2e5cb8e4U, 0x00000000U, + 0x254a94deU, 0x1c387048U, 0x2a54a8fcU, 0x3d7af48eU, + 0x050a141eU, 0x4f9e21bfU, 0x7bf6f107U, 0xb279f28bU, + 0x3264c8acU, 0x903d7a47U, 0xaf4386c5U, 0x19326456U, + 0xa35bb6edU, 0xf7f3fb08U, 0x73e6d137U, 0x9d274e69U, + 0x152a547eU, 0x74e8cd25U, 0xeec19f5eU, 0xca890f86U, + 0x9f234665U, 0x0f1e3c22U, 0x1b366c5aU, 0x75eac923U, + 0x86112233U, 0x84152a3fU, 0x9c254a6fU, 0x4a9435a1U, + 0x97336655U, 0x1a34685cU, 0x65ca8943U, 0xf6f1ff0eU, + 0xedc79354U, 0x09122436U, 0xbb6bd6bdU, 0x264c98d4U, + 0x831b362dU, 0xebcb8b40U, 0x6fdea17fU, 0x811f3e21U, + 0x04081018U, 0x6ad4b561U, 0x43861197U, 0x01020406U, + 0x172e5c72U, 0xe1dfa37cU, 0x87132635U, 0xf5f7f304U, + 0x8d070e09U, 0xe3dbab70U, 0x23468ccaU, 0x801d3a27U, + 0x44880d85U, 0x162c5874U, 0x66cc8549U, 0x214284c6U, + 0xfee1df3eU, 0xd5b773c4U, 0x3162c4a6U, 0xd9af43ecU, + 0x356ad4beU, 0x18306050U, 0x0204080cU, 0x64c88d45U, + 0xf2f9ef16U, 0xf1ffe31cU, 0x56ac45e9U, 0xcd871394U, + 0x8219322bU, 0xc88d078aU, 0xba69d2bbU, 0xf0fde71aU, + 0xefc39b58U, 0xe9cf834cU, 0xe8cd874aU, 0xfde7d334U, + 0x890f1e11U, 0xd7b37bc8U, 0xc7933ba8U, 0xb577ee99U, + 0xa455aaffU, 0x2f5ebce2U, 0x95376e59U, 0x13264c6aU, + 0x0b162c3aU, 0xf3fbeb10U, 0xe0dda77aU, 0x376edcb2U, +}; + +static const ulong32 T1[256] = { + 0x53a7f5a6U, 0xbbd3d06bU, 0xd1e66ebfU, 0xe2713bd9U, + 0xbdd0da67U, 0x45accf8aU, 0x9a4db329U, 0xf2790bf9U, + 0x743a9ce8U, 0x8fc98c03U, 0x3f91417eU, 0xe5fc32d7U, + 0x3c1e4478U, 0x8e478f01U, 0xa854e54dU, 0x67bda9ceU, + 0x058c0f0aU, 0x57a5f9aeU, 0xf47a01f5U, 0xebfb20cbU, + 0xc6635791U, 0x6db8b7daU, 0xa7ddf453U, 0xb5d4c277U, + 0xd7e564b3U, 0x7bb38df6U, 0x97c5a433U, 0x61bea3c2U, + 0x4fa9d19eU, 0x0d88171aU, 0x180c2830U, 0x59a2ebb2U, + 0x723996e4U, 0xa3dff85bU, 0x5229f6a4U, 0xa9dae64fU, + 0x562bfaacU, 0x4da8d79aU, 0x8bcb800bU, 0x984cb52dU, + 0x964ba731U, 0x4422cc88U, 0x49aadb92U, 0x4824d890U, + 0x82419b19U, 0xe0703dddU, 0x51a6f3a2U, 0xeff92cc3U, + 0xb45ac175U, 0xd9e276afU, 0x7db087faU, 0x6c36b4d8U, + 0xfa7d13e9U, 0xd5e462b7U, 0x6633aaccU, 0xe3ff38dbU, + 0xc0605d9dU, 0x4020c080U, 0x10083020U, 0x0b8b1d16U, + 0xbc5ed965U, 0x4babdd96U, 0xfe7f1fe1U, 0xf0780dfdU, + 0xf87c15edU, 0x582ce8b0U, 0xae57ef41U, 0xb9d2d66fU, + 0xa5dcf257U, 0xda6d73a9U, 0xfc7e19e5U, 0x1a0d2e34U, + 0xa653f751U, 0x35945f6aU, 0x9bc3b02bU, 0x5028f0a0U, + 0x4e27d29cU, 0x0c061418U, 0xbe5fdf61U, 0x47adc98eU, + 0xce674f81U, 0xb85cd56dU, 0xaa55e349U, 0x9048ad3dU, + 0x1c0e2438U, 0xa452f155U, 0xc9ea468fU, 0x84429115U, + 0xb65bc771U, 0xba5dd369U, 0x6030a0c0U, 0xb058cd7dU, + 0xa251fb59U, 0xb259cb79U, 0x783c88f0U, 0x9c4eb925U, + 0x703890e0U, 0x098a1b12U, 0xe47231d5U, 0x28147850U, + 0xd3e768bbU, 0x91c6ae3fU, 0xa1defe5fU, 0xa050fd5dU, + 0x018e0302U, 0x39924b72U, 0xbfd1dc63U, 0xee772fc1U, + 0x3b934d76U, 0x8a458309U, 0x299a7b52U, 0x81ce9e1fU, + 0x5a2deeb4U, 0x06030a0cU, 0xc4625195U, 0x71b693e2U, + 0x6fb9b1deU, 0x63bfa5c6U, 0x31965362U, 0xd66b67b1U, + 0x7e3f82fcU, 0x0e07121cU, 0x24126c48U, 0x41aec382U, + 0x80409d1dU, 0x6834b8d0U, 0x8c468905U, 0x7c3e84f8U, + 0xabdbe04bU, 0x83cf981bU, 0xc5ec5297U, 0x85cc9217U, + 0x9fc1bc23U, 0x5fa1e1beU, 0x9dc0ba27U, 0xb1d6ce7fU, + 0x3a1d4e74U, 0xf5f402f7U, 0xc2615b99U, 0x763b9aecU, + 0x20106040U, 0xadd8ea47U, 0xd0686dbdU, 0x5da0e7baU, + 0x7fb181feU, 0x140a3c28U, 0xd2696bb9U, 0xd86c75adU, + 0x9249ab39U, 0xe9fa26cfU, 0xec7629c5U, 0x95c4a237U, + 0x219e6342U, 0x2b9b7d56U, 0xdc6e79a5U, 0x2f99715eU, + 0x99c2b62fU, 0x73b795e6U, 0x2d98775aU, 0x65bcafcaU, + 0x038f0506U, 0x1785392eU, 0x3e1f427cU, 0x75b49feaU, + 0xedf82ac7U, 0x22116644U, 0x5c2ee4b8U, 0x00000000U, + 0x4a25de94U, 0x381c4870U, 0x542afca8U, 0x7a3d8ef4U, + 0x0a051e14U, 0x9e4fbf21U, 0xf67b07f1U, 0x79b28bf2U, + 0x6432acc8U, 0x3d90477aU, 0x43afc586U, 0x32195664U, + 0x5ba3edb6U, 0xf3f708fbU, 0xe67337d1U, 0x279d694eU, + 0x2a157e54U, 0xe87425cdU, 0xc1ee5e9fU, 0x89ca860fU, + 0x239f6546U, 0x1e0f223cU, 0x361b5a6cU, 0xea7523c9U, + 0x11863322U, 0x15843f2aU, 0x259c6f4aU, 0x944aa135U, + 0x33975566U, 0x341a5c68U, 0xca654389U, 0xf1f60effU, + 0xc7ed5493U, 0x12093624U, 0x6bbbbdd6U, 0x4c26d498U, + 0x1b832d36U, 0xcbeb408bU, 0xde6f7fa1U, 0x1f81213eU, + 0x08041810U, 0xd46a61b5U, 0x86439711U, 0x02010604U, + 0x2e17725cU, 0xdfe17ca3U, 0x13873526U, 0xf7f504f3U, + 0x078d090eU, 0xdbe370abU, 0x4623ca8cU, 0x1d80273aU, + 0x8844850dU, 0x2c167458U, 0xcc664985U, 0x4221c684U, + 0xe1fe3edfU, 0xb7d5c473U, 0x6231a6c4U, 0xafd9ec43U, + 0x6a35bed4U, 0x30185060U, 0x04020c08U, 0xc864458dU, + 0xf9f216efU, 0xfff11ce3U, 0xac56e945U, 0x87cd9413U, + 0x19822b32U, 0x8dc88a07U, 0x69babbd2U, 0xfdf01ae7U, + 0xc3ef589bU, 0xcfe94c83U, 0xcde84a87U, 0xe7fd34d3U, + 0x0f89111eU, 0xb3d7c87bU, 0x93c7a83bU, 0x77b599eeU, + 0x55a4ffaaU, 0x5e2fe2bcU, 0x3795596eU, 0x26136a4cU, + 0x160b3a2cU, 0xfbf310ebU, 0xdde07aa7U, 0x6e37b2dcU, +}; + +static const ulong32 T2[256] = { + 0xa6f5a753U, 0x6bd0d3bbU, 0xbf6ee6d1U, 0xd93b71e2U, + 0x67dad0bdU, 0x8acfac45U, 0x29b34d9aU, 0xf90b79f2U, + 0xe89c3a74U, 0x038cc98fU, 0x7e41913fU, 0xd732fce5U, + 0x78441e3cU, 0x018f478eU, 0x4de554a8U, 0xcea9bd67U, + 0x0a0f8c05U, 0xaef9a557U, 0xf5017af4U, 0xcb20fbebU, + 0x915763c6U, 0xdab7b86dU, 0x53f4dda7U, 0x77c2d4b5U, + 0xb364e5d7U, 0xf68db37bU, 0x33a4c597U, 0xc2a3be61U, + 0x9ed1a94fU, 0x1a17880dU, 0x30280c18U, 0xb2eba259U, + 0xe4963972U, 0x5bf8dfa3U, 0xa4f62952U, 0x4fe6daa9U, + 0xacfa2b56U, 0x9ad7a84dU, 0x0b80cb8bU, 0x2db54c98U, + 0x31a74b96U, 0x88cc2244U, 0x92dbaa49U, 0x90d82448U, + 0x199b4182U, 0xdd3d70e0U, 0xa2f3a651U, 0xc32cf9efU, + 0x75c15ab4U, 0xaf76e2d9U, 0xfa87b07dU, 0xd8b4366cU, + 0xe9137dfaU, 0xb762e4d5U, 0xccaa3366U, 0xdb38ffe3U, + 0x9d5d60c0U, 0x80c02040U, 0x20300810U, 0x161d8b0bU, + 0x65d95ebcU, 0x96ddab4bU, 0xe11f7ffeU, 0xfd0d78f0U, + 0xed157cf8U, 0xb0e82c58U, 0x41ef57aeU, 0x6fd6d2b9U, + 0x57f2dca5U, 0xa9736ddaU, 0xe5197efcU, 0x342e0d1aU, + 0x51f753a6U, 0x6a5f9435U, 0x2bb0c39bU, 0xa0f02850U, + 0x9cd2274eU, 0x1814060cU, 0x61df5fbeU, 0x8ec9ad47U, + 0x814f67ceU, 0x6dd55cb8U, 0x49e355aaU, 0x3dad4890U, + 0x38240e1cU, 0x55f152a4U, 0x8f46eac9U, 0x15914284U, + 0x71c75bb6U, 0x69d35dbaU, 0xc0a03060U, 0x7dcd58b0U, + 0x59fb51a2U, 0x79cb59b2U, 0xf0883c78U, 0x25b94e9cU, + 0xe0903870U, 0x121b8a09U, 0xd53172e4U, 0x50781428U, + 0xbb68e7d3U, 0x3faec691U, 0x5ffedea1U, 0x5dfd50a0U, + 0x02038e01U, 0x724b9239U, 0x63dcd1bfU, 0xc12f77eeU, + 0x764d933bU, 0x0983458aU, 0x527b9a29U, 0x1f9ece81U, + 0xb4ee2d5aU, 0x0c0a0306U, 0x955162c4U, 0xe293b671U, + 0xdeb1b96fU, 0xc6a5bf63U, 0x62539631U, 0xb1676bd6U, + 0xfc823f7eU, 0x1c12070eU, 0x486c1224U, 0x82c3ae41U, + 0x1d9d4080U, 0xd0b83468U, 0x0589468cU, 0xf8843e7cU, + 0x4be0dbabU, 0x1b98cf83U, 0x9752ecc5U, 0x1792cc85U, + 0x23bcc19fU, 0xbee1a15fU, 0x27bac09dU, 0x7fced6b1U, + 0x744e1d3aU, 0xf702f4f5U, 0x995b61c2U, 0xec9a3b76U, + 0x40601020U, 0x47ead8adU, 0xbd6d68d0U, 0xbae7a05dU, + 0xfe81b17fU, 0x283c0a14U, 0xb96b69d2U, 0xad756cd8U, + 0x39ab4992U, 0xcf26fae9U, 0xc52976ecU, 0x37a2c495U, + 0x42639e21U, 0x567d9b2bU, 0xa5796edcU, 0x5e71992fU, + 0x2fb6c299U, 0xe695b773U, 0x5a77982dU, 0xcaafbc65U, + 0x06058f03U, 0x2e398517U, 0x7c421f3eU, 0xea9fb475U, + 0xc72af8edU, 0x44661122U, 0xb8e42e5cU, 0x00000000U, + 0x94de254aU, 0x70481c38U, 0xa8fc2a54U, 0xf48e3d7aU, + 0x141e050aU, 0x21bf4f9eU, 0xf1077bf6U, 0xf28bb279U, + 0xc8ac3264U, 0x7a47903dU, 0x86c5af43U, 0x64561932U, + 0xb6eda35bU, 0xfb08f7f3U, 0xd13773e6U, 0x4e699d27U, + 0x547e152aU, 0xcd2574e8U, 0x9f5eeec1U, 0x0f86ca89U, + 0x46659f23U, 0x3c220f1eU, 0x6c5a1b36U, 0xc92375eaU, + 0x22338611U, 0x2a3f8415U, 0x4a6f9c25U, 0x35a14a94U, + 0x66559733U, 0x685c1a34U, 0x894365caU, 0xff0ef6f1U, + 0x9354edc7U, 0x24360912U, 0xd6bdbb6bU, 0x98d4264cU, + 0x362d831bU, 0x8b40ebcbU, 0xa17f6fdeU, 0x3e21811fU, + 0x10180408U, 0xb5616ad4U, 0x11974386U, 0x04060102U, + 0x5c72172eU, 0xa37ce1dfU, 0x26358713U, 0xf304f5f7U, + 0x0e098d07U, 0xab70e3dbU, 0x8cca2346U, 0x3a27801dU, + 0x0d854488U, 0x5874162cU, 0x854966ccU, 0x84c62142U, + 0xdf3efee1U, 0x73c4d5b7U, 0xc4a63162U, 0x43ecd9afU, + 0xd4be356aU, 0x60501830U, 0x080c0204U, 0x8d4564c8U, + 0xef16f2f9U, 0xe31cf1ffU, 0x45e956acU, 0x1394cd87U, + 0x322b8219U, 0x078ac88dU, 0xd2bbba69U, 0xe71af0fdU, + 0x9b58efc3U, 0x834ce9cfU, 0x874ae8cdU, 0xd334fde7U, + 0x1e11890fU, 0x7bc8d7b3U, 0x3ba8c793U, 0xee99b577U, + 0xaaffa455U, 0xbce22f5eU, 0x6e599537U, 0x4c6a1326U, + 0x2c3a0b16U, 0xeb10f3fbU, 0xa77ae0ddU, 0xdcb2376eU, +}; + +static const ulong32 T3[256] = { + 0xf5a653a7U, 0xd06bbbd3U, 0x6ebfd1e6U, 0x3bd9e271U, + 0xda67bdd0U, 0xcf8a45acU, 0xb3299a4dU, 0x0bf9f279U, + 0x9ce8743aU, 0x8c038fc9U, 0x417e3f91U, 0x32d7e5fcU, + 0x44783c1eU, 0x8f018e47U, 0xe54da854U, 0xa9ce67bdU, + 0x0f0a058cU, 0xf9ae57a5U, 0x01f5f47aU, 0x20cbebfbU, + 0x5791c663U, 0xb7da6db8U, 0xf453a7ddU, 0xc277b5d4U, + 0x64b3d7e5U, 0x8df67bb3U, 0xa43397c5U, 0xa3c261beU, + 0xd19e4fa9U, 0x171a0d88U, 0x2830180cU, 0xebb259a2U, + 0x96e47239U, 0xf85ba3dfU, 0xf6a45229U, 0xe64fa9daU, + 0xfaac562bU, 0xd79a4da8U, 0x800b8bcbU, 0xb52d984cU, + 0xa731964bU, 0xcc884422U, 0xdb9249aaU, 0xd8904824U, + 0x9b198241U, 0x3ddde070U, 0xf3a251a6U, 0x2cc3eff9U, + 0xc175b45aU, 0x76afd9e2U, 0x87fa7db0U, 0xb4d86c36U, + 0x13e9fa7dU, 0x62b7d5e4U, 0xaacc6633U, 0x38dbe3ffU, + 0x5d9dc060U, 0xc0804020U, 0x30201008U, 0x1d160b8bU, + 0xd965bc5eU, 0xdd964babU, 0x1fe1fe7fU, 0x0dfdf078U, + 0x15edf87cU, 0xe8b0582cU, 0xef41ae57U, 0xd66fb9d2U, + 0xf257a5dcU, 0x73a9da6dU, 0x19e5fc7eU, 0x2e341a0dU, + 0xf751a653U, 0x5f6a3594U, 0xb02b9bc3U, 0xf0a05028U, + 0xd29c4e27U, 0x14180c06U, 0xdf61be5fU, 0xc98e47adU, + 0x4f81ce67U, 0xd56db85cU, 0xe349aa55U, 0xad3d9048U, + 0x24381c0eU, 0xf155a452U, 0x468fc9eaU, 0x91158442U, + 0xc771b65bU, 0xd369ba5dU, 0xa0c06030U, 0xcd7db058U, + 0xfb59a251U, 0xcb79b259U, 0x88f0783cU, 0xb9259c4eU, + 0x90e07038U, 0x1b12098aU, 0x31d5e472U, 0x78502814U, + 0x68bbd3e7U, 0xae3f91c6U, 0xfe5fa1deU, 0xfd5da050U, + 0x0302018eU, 0x4b723992U, 0xdc63bfd1U, 0x2fc1ee77U, + 0x4d763b93U, 0x83098a45U, 0x7b52299aU, 0x9e1f81ceU, + 0xeeb45a2dU, 0x0a0c0603U, 0x5195c462U, 0x93e271b6U, + 0xb1de6fb9U, 0xa5c663bfU, 0x53623196U, 0x67b1d66bU, + 0x82fc7e3fU, 0x121c0e07U, 0x6c482412U, 0xc38241aeU, + 0x9d1d8040U, 0xb8d06834U, 0x89058c46U, 0x84f87c3eU, + 0xe04babdbU, 0x981b83cfU, 0x5297c5ecU, 0x921785ccU, + 0xbc239fc1U, 0xe1be5fa1U, 0xba279dc0U, 0xce7fb1d6U, + 0x4e743a1dU, 0x02f7f5f4U, 0x5b99c261U, 0x9aec763bU, + 0x60402010U, 0xea47add8U, 0x6dbdd068U, 0xe7ba5da0U, + 0x81fe7fb1U, 0x3c28140aU, 0x6bb9d269U, 0x75add86cU, + 0xab399249U, 0x26cfe9faU, 0x29c5ec76U, 0xa23795c4U, + 0x6342219eU, 0x7d562b9bU, 0x79a5dc6eU, 0x715e2f99U, + 0xb62f99c2U, 0x95e673b7U, 0x775a2d98U, 0xafca65bcU, + 0x0506038fU, 0x392e1785U, 0x427c3e1fU, 0x9fea75b4U, + 0x2ac7edf8U, 0x66442211U, 0xe4b85c2eU, 0x00000000U, + 0xde944a25U, 0x4870381cU, 0xfca8542aU, 0x8ef47a3dU, + 0x1e140a05U, 0xbf219e4fU, 0x07f1f67bU, 0x8bf279b2U, + 0xacc86432U, 0x477a3d90U, 0xc58643afU, 0x56643219U, + 0xedb65ba3U, 0x08fbf3f7U, 0x37d1e673U, 0x694e279dU, + 0x7e542a15U, 0x25cde874U, 0x5e9fc1eeU, 0x860f89caU, + 0x6546239fU, 0x223c1e0fU, 0x5a6c361bU, 0x23c9ea75U, + 0x33221186U, 0x3f2a1584U, 0x6f4a259cU, 0xa135944aU, + 0x55663397U, 0x5c68341aU, 0x4389ca65U, 0x0efff1f6U, + 0x5493c7edU, 0x36241209U, 0xbdd66bbbU, 0xd4984c26U, + 0x2d361b83U, 0x408bcbebU, 0x7fa1de6fU, 0x213e1f81U, + 0x18100804U, 0x61b5d46aU, 0x97118643U, 0x06040201U, + 0x725c2e17U, 0x7ca3dfe1U, 0x35261387U, 0x04f3f7f5U, + 0x090e078dU, 0x70abdbe3U, 0xca8c4623U, 0x273a1d80U, + 0x850d8844U, 0x74582c16U, 0x4985cc66U, 0xc6844221U, + 0x3edfe1feU, 0xc473b7d5U, 0xa6c46231U, 0xec43afd9U, + 0xbed46a35U, 0x50603018U, 0x0c080402U, 0x458dc864U, + 0x16eff9f2U, 0x1ce3fff1U, 0xe945ac56U, 0x941387cdU, + 0x2b321982U, 0x8a078dc8U, 0xbbd269baU, 0x1ae7fdf0U, + 0x589bc3efU, 0x4c83cfe9U, 0x4a87cde8U, 0x34d3e7fdU, + 0x111e0f89U, 0xc87bb3d7U, 0xa83b93c7U, 0x99ee77b5U, + 0xffaa55a4U, 0xe2bc5e2fU, 0x596e3795U, 0x6a4c2613U, + 0x3a2c160bU, 0x10ebfbf3U, 0x7aa7dde0U, 0xb2dc6e37U, +}; + +static const ulong32 T4[256] = { + 0xa7a7a7a7U, 0xd3d3d3d3U, 0xe6e6e6e6U, 0x71717171U, + 0xd0d0d0d0U, 0xacacacacU, 0x4d4d4d4dU, 0x79797979U, + 0x3a3a3a3aU, 0xc9c9c9c9U, 0x91919191U, 0xfcfcfcfcU, + 0x1e1e1e1eU, 0x47474747U, 0x54545454U, 0xbdbdbdbdU, + 0x8c8c8c8cU, 0xa5a5a5a5U, 0x7a7a7a7aU, 0xfbfbfbfbU, + 0x63636363U, 0xb8b8b8b8U, 0xddddddddU, 0xd4d4d4d4U, + 0xe5e5e5e5U, 0xb3b3b3b3U, 0xc5c5c5c5U, 0xbebebebeU, + 0xa9a9a9a9U, 0x88888888U, 0x0c0c0c0cU, 0xa2a2a2a2U, + 0x39393939U, 0xdfdfdfdfU, 0x29292929U, 0xdadadadaU, + 0x2b2b2b2bU, 0xa8a8a8a8U, 0xcbcbcbcbU, 0x4c4c4c4cU, + 0x4b4b4b4bU, 0x22222222U, 0xaaaaaaaaU, 0x24242424U, + 0x41414141U, 0x70707070U, 0xa6a6a6a6U, 0xf9f9f9f9U, + 0x5a5a5a5aU, 0xe2e2e2e2U, 0xb0b0b0b0U, 0x36363636U, + 0x7d7d7d7dU, 0xe4e4e4e4U, 0x33333333U, 0xffffffffU, + 0x60606060U, 0x20202020U, 0x08080808U, 0x8b8b8b8bU, + 0x5e5e5e5eU, 0xababababU, 0x7f7f7f7fU, 0x78787878U, + 0x7c7c7c7cU, 0x2c2c2c2cU, 0x57575757U, 0xd2d2d2d2U, + 0xdcdcdcdcU, 0x6d6d6d6dU, 0x7e7e7e7eU, 0x0d0d0d0dU, + 0x53535353U, 0x94949494U, 0xc3c3c3c3U, 0x28282828U, + 0x27272727U, 0x06060606U, 0x5f5f5f5fU, 0xadadadadU, + 0x67676767U, 0x5c5c5c5cU, 0x55555555U, 0x48484848U, + 0x0e0e0e0eU, 0x52525252U, 0xeaeaeaeaU, 0x42424242U, + 0x5b5b5b5bU, 0x5d5d5d5dU, 0x30303030U, 0x58585858U, + 0x51515151U, 0x59595959U, 0x3c3c3c3cU, 0x4e4e4e4eU, + 0x38383838U, 0x8a8a8a8aU, 0x72727272U, 0x14141414U, + 0xe7e7e7e7U, 0xc6c6c6c6U, 0xdedededeU, 0x50505050U, + 0x8e8e8e8eU, 0x92929292U, 0xd1d1d1d1U, 0x77777777U, + 0x93939393U, 0x45454545U, 0x9a9a9a9aU, 0xcecececeU, + 0x2d2d2d2dU, 0x03030303U, 0x62626262U, 0xb6b6b6b6U, + 0xb9b9b9b9U, 0xbfbfbfbfU, 0x96969696U, 0x6b6b6b6bU, + 0x3f3f3f3fU, 0x07070707U, 0x12121212U, 0xaeaeaeaeU, + 0x40404040U, 0x34343434U, 0x46464646U, 0x3e3e3e3eU, + 0xdbdbdbdbU, 0xcfcfcfcfU, 0xececececU, 0xccccccccU, + 0xc1c1c1c1U, 0xa1a1a1a1U, 0xc0c0c0c0U, 0xd6d6d6d6U, + 0x1d1d1d1dU, 0xf4f4f4f4U, 0x61616161U, 0x3b3b3b3bU, + 0x10101010U, 0xd8d8d8d8U, 0x68686868U, 0xa0a0a0a0U, + 0xb1b1b1b1U, 0x0a0a0a0aU, 0x69696969U, 0x6c6c6c6cU, + 0x49494949U, 0xfafafafaU, 0x76767676U, 0xc4c4c4c4U, + 0x9e9e9e9eU, 0x9b9b9b9bU, 0x6e6e6e6eU, 0x99999999U, + 0xc2c2c2c2U, 0xb7b7b7b7U, 0x98989898U, 0xbcbcbcbcU, + 0x8f8f8f8fU, 0x85858585U, 0x1f1f1f1fU, 0xb4b4b4b4U, + 0xf8f8f8f8U, 0x11111111U, 0x2e2e2e2eU, 0x00000000U, + 0x25252525U, 0x1c1c1c1cU, 0x2a2a2a2aU, 0x3d3d3d3dU, + 0x05050505U, 0x4f4f4f4fU, 0x7b7b7b7bU, 0xb2b2b2b2U, + 0x32323232U, 0x90909090U, 0xafafafafU, 0x19191919U, + 0xa3a3a3a3U, 0xf7f7f7f7U, 0x73737373U, 0x9d9d9d9dU, + 0x15151515U, 0x74747474U, 0xeeeeeeeeU, 0xcacacacaU, + 0x9f9f9f9fU, 0x0f0f0f0fU, 0x1b1b1b1bU, 0x75757575U, + 0x86868686U, 0x84848484U, 0x9c9c9c9cU, 0x4a4a4a4aU, + 0x97979797U, 0x1a1a1a1aU, 0x65656565U, 0xf6f6f6f6U, + 0xededededU, 0x09090909U, 0xbbbbbbbbU, 0x26262626U, + 0x83838383U, 0xebebebebU, 0x6f6f6f6fU, 0x81818181U, + 0x04040404U, 0x6a6a6a6aU, 0x43434343U, 0x01010101U, + 0x17171717U, 0xe1e1e1e1U, 0x87878787U, 0xf5f5f5f5U, + 0x8d8d8d8dU, 0xe3e3e3e3U, 0x23232323U, 0x80808080U, + 0x44444444U, 0x16161616U, 0x66666666U, 0x21212121U, + 0xfefefefeU, 0xd5d5d5d5U, 0x31313131U, 0xd9d9d9d9U, + 0x35353535U, 0x18181818U, 0x02020202U, 0x64646464U, + 0xf2f2f2f2U, 0xf1f1f1f1U, 0x56565656U, 0xcdcdcdcdU, + 0x82828282U, 0xc8c8c8c8U, 0xbabababaU, 0xf0f0f0f0U, + 0xefefefefU, 0xe9e9e9e9U, 0xe8e8e8e8U, 0xfdfdfdfdU, + 0x89898989U, 0xd7d7d7d7U, 0xc7c7c7c7U, 0xb5b5b5b5U, + 0xa4a4a4a4U, 0x2f2f2f2fU, 0x95959595U, 0x13131313U, + 0x0b0b0b0bU, 0xf3f3f3f3U, 0xe0e0e0e0U, 0x37373737U, +}; + +static const ulong32 T5[256] = { + 0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U, + 0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U, + 0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U, + 0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U, + 0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U, + 0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U, + 0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U, + 0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U, + 0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U, + 0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U, + 0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U, + 0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U, + 0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U, + 0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U, + 0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U, + 0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U, + 0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U, + 0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U, + 0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U, + 0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U, + 0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U, + 0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U, + 0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U, + 0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U, + 0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU, + 0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU, + 0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU, + 0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU, + 0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU, + 0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU, + 0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU, + 0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU, + 0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU, + 0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU, + 0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU, + 0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU, + 0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU, + 0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU, + 0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU, + 0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU, + 0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U, + 0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U, + 0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U, + 0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U, + 0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U, + 0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U, + 0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U, + 0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U, + 0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U, + 0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U, + 0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U, + 0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U, + 0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U, + 0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U, + 0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U, + 0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U, + 0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU, + 0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU, + 0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU, + 0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU, + 0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU, + 0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU, + 0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU, + 0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU, +}; + +/** + * The round constants. + */ +static const ulong32 rc[] = { + 0xa7d3e671U, 0xd0ac4d79U, 0x3ac991fcU, 0x1e4754bdU, + 0x8ca57afbU, 0x63b8ddd4U, 0xe5b3c5beU, 0xa9880ca2U, + 0x39df29daU, 0x2ba8cb4cU, 0x4b22aa24U, 0x4170a6f9U, + 0x5ae2b036U, 0x7de433ffU, 0x6020088bU, 0x5eab7f78U, + 0x7c2c57d2U, 0xdc6d7e0dU, 0x5394c328U, +}; + +#endif + + /** + Initialize the Anubis block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +#ifdef LTC_CLEAN_STACK +static int _anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + int N, R, i, pos, r; + ulong32 kappa[MAX_N]; + ulong32 inter[MAX_N]; + ulong32 v, K0, K1, K2, K3; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + /* Valid sizes (in bytes) are 16, 20, 24, 28, 32, 36, and 40. */ + if ((keylen & 3) || (keylen < 16) || (keylen > 40)) { + return CRYPT_INVALID_KEYSIZE; + } + skey->anubis.keyBits = keylen*8; + + /* + * determine the N length parameter: + * (N.B. it is assumed that the key length is valid!) + */ + N = skey->anubis.keyBits >> 5; + + /* + * determine number of rounds from key size: + */ + skey->anubis.R = R = 8 + N; + + if (num_rounds != 0 && num_rounds != skey->anubis.R) { + return CRYPT_INVALID_ROUNDS; + } + + /* + * map cipher key to initial key state (mu): + */ + for (i = 0, pos = 0; i < N; i++, pos += 4) { + kappa[i] = + (key[pos ] << 24) ^ + (key[pos + 1] << 16) ^ + (key[pos + 2] << 8) ^ + (key[pos + 3] ); + } + + /* + * generate R + 1 round keys: + */ + for (r = 0; r <= R; r++) { + /* + * generate r-th round key K^r: + */ + K0 = T4[(kappa[N - 1] >> 24) ]; + K1 = T4[(kappa[N - 1] >> 16) & 0xff]; + K2 = T4[(kappa[N - 1] >> 8) & 0xff]; + K3 = T4[(kappa[N - 1] ) & 0xff]; + for (i = N - 2; i >= 0; i--) { + K0 = T4[(kappa[i] >> 24) ] ^ + (T5[(K0 >> 24) ] & 0xff000000U) ^ + (T5[(K0 >> 16) & 0xff] & 0x00ff0000U) ^ + (T5[(K0 >> 8) & 0xff] & 0x0000ff00U) ^ + (T5[(K0 ) & 0xff] & 0x000000ffU); + K1 = T4[(kappa[i] >> 16) & 0xff] ^ + (T5[(K1 >> 24) ] & 0xff000000U) ^ + (T5[(K1 >> 16) & 0xff] & 0x00ff0000U) ^ + (T5[(K1 >> 8) & 0xff] & 0x0000ff00U) ^ + (T5[(K1 ) & 0xff] & 0x000000ffU); + K2 = T4[(kappa[i] >> 8) & 0xff] ^ + (T5[(K2 >> 24) ] & 0xff000000U) ^ + (T5[(K2 >> 16) & 0xff] & 0x00ff0000U) ^ + (T5[(K2 >> 8) & 0xff] & 0x0000ff00U) ^ + (T5[(K2 ) & 0xff] & 0x000000ffU); + K3 = T4[(kappa[i] ) & 0xff] ^ + (T5[(K3 >> 24) ] & 0xff000000U) ^ + (T5[(K3 >> 16) & 0xff] & 0x00ff0000U) ^ + (T5[(K3 >> 8) & 0xff] & 0x0000ff00U) ^ + (T5[(K3 ) & 0xff] & 0x000000ffU); + } + /* + -- this is the code to use with the large U tables: + K0 = K1 = K2 = K3 = 0; + for (i = 0; i < N; i++) { + K0 ^= U[i][(kappa[i] >> 24) ]; + K1 ^= U[i][(kappa[i] >> 16) & 0xff]; + K2 ^= U[i][(kappa[i] >> 8) & 0xff]; + K3 ^= U[i][(kappa[i] ) & 0xff]; + } + */ + skey->anubis.roundKeyEnc[r][0] = K0; + skey->anubis.roundKeyEnc[r][1] = K1; + skey->anubis.roundKeyEnc[r][2] = K2; + skey->anubis.roundKeyEnc[r][3] = K3; + + /* + * compute kappa^{r+1} from kappa^r: + */ + if (r == R) { + break; + } + for (i = 0; i < N; i++) { + int j = i; + inter[i] = T0[(kappa[j--] >> 24) ]; if (j < 0) j = N - 1; + inter[i] ^= T1[(kappa[j--] >> 16) & 0xff]; if (j < 0) j = N - 1; + inter[i] ^= T2[(kappa[j--] >> 8) & 0xff]; if (j < 0) j = N - 1; + inter[i] ^= T3[(kappa[j ] ) & 0xff]; + } + kappa[0] = inter[0] ^ rc[r]; + for (i = 1; i < N; i++) { + kappa[i] = inter[i]; + } + } + + /* + * generate inverse key schedule: K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r}): + */ + for (i = 0; i < 4; i++) { + skey->anubis.roundKeyDec[0][i] = skey->anubis.roundKeyEnc[R][i]; + skey->anubis.roundKeyDec[R][i] = skey->anubis.roundKeyEnc[0][i]; + } + for (r = 1; r < R; r++) { + for (i = 0; i < 4; i++) { + v = skey->anubis.roundKeyEnc[R - r][i]; + skey->anubis.roundKeyDec[r][i] = + T0[T4[(v >> 24) ] & 0xff] ^ + T1[T4[(v >> 16) & 0xff] & 0xff] ^ + T2[T4[(v >> 8) & 0xff] & 0xff] ^ + T3[T4[(v ) & 0xff] & 0xff]; + } + } + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int err; + err = _anubis_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(int) * 5 + sizeof(ulong32) * (MAX_N + MAX_N + 5)); + return err; +} +#endif + + +static void anubis_crypt(const unsigned char *plaintext, unsigned char *ciphertext, + ulong32 roundKey[18 + 1][4], int R) { + int i, pos, r; + ulong32 state[4]; + ulong32 inter[4]; + + /* + * map plaintext block to cipher state (mu) + * and add initial round key (sigma[K^0]): + */ + for (i = 0, pos = 0; i < 4; i++, pos += 4) { + state[i] = + (plaintext[pos ] << 24) ^ + (plaintext[pos + 1] << 16) ^ + (plaintext[pos + 2] << 8) ^ + (plaintext[pos + 3] ) ^ + roundKey[0][i]; + } + + /* + * R - 1 full rounds: + */ + for (r = 1; r < R; r++) { + inter[0] = + T0[(state[0] >> 24) ] ^ + T1[(state[1] >> 24) ] ^ + T2[(state[2] >> 24) ] ^ + T3[(state[3] >> 24) ] ^ + roundKey[r][0]; + inter[1] = + T0[(state[0] >> 16) & 0xff] ^ + T1[(state[1] >> 16) & 0xff] ^ + T2[(state[2] >> 16) & 0xff] ^ + T3[(state[3] >> 16) & 0xff] ^ + roundKey[r][1]; + inter[2] = + T0[(state[0] >> 8) & 0xff] ^ + T1[(state[1] >> 8) & 0xff] ^ + T2[(state[2] >> 8) & 0xff] ^ + T3[(state[3] >> 8) & 0xff] ^ + roundKey[r][2]; + inter[3] = + T0[(state[0] ) & 0xff] ^ + T1[(state[1] ) & 0xff] ^ + T2[(state[2] ) & 0xff] ^ + T3[(state[3] ) & 0xff] ^ + roundKey[r][3]; + state[0] = inter[0]; + state[1] = inter[1]; + state[2] = inter[2]; + state[3] = inter[3]; + } + + /* + * last round: + */ + inter[0] = + (T0[(state[0] >> 24) ] & 0xff000000U) ^ + (T1[(state[1] >> 24) ] & 0x00ff0000U) ^ + (T2[(state[2] >> 24) ] & 0x0000ff00U) ^ + (T3[(state[3] >> 24) ] & 0x000000ffU) ^ + roundKey[R][0]; + inter[1] = + (T0[(state[0] >> 16) & 0xff] & 0xff000000U) ^ + (T1[(state[1] >> 16) & 0xff] & 0x00ff0000U) ^ + (T2[(state[2] >> 16) & 0xff] & 0x0000ff00U) ^ + (T3[(state[3] >> 16) & 0xff] & 0x000000ffU) ^ + roundKey[R][1]; + inter[2] = + (T0[(state[0] >> 8) & 0xff] & 0xff000000U) ^ + (T1[(state[1] >> 8) & 0xff] & 0x00ff0000U) ^ + (T2[(state[2] >> 8) & 0xff] & 0x0000ff00U) ^ + (T3[(state[3] >> 8) & 0xff] & 0x000000ffU) ^ + roundKey[R][2]; + inter[3] = + (T0[(state[0] ) & 0xff] & 0xff000000U) ^ + (T1[(state[1] ) & 0xff] & 0x00ff0000U) ^ + (T2[(state[2] ) & 0xff] & 0x0000ff00U) ^ + (T3[(state[3] ) & 0xff] & 0x000000ffU) ^ + roundKey[R][3]; + + /* + * map cipher state to ciphertext block (mu^{-1}): + */ + for (i = 0, pos = 0; i < 4; i++, pos += 4) { + ulong32 w = inter[i]; + ciphertext[pos ] = (unsigned char)(w >> 24); + ciphertext[pos + 1] = (unsigned char)(w >> 16); + ciphertext[pos + 2] = (unsigned char)(w >> 8); + ciphertext[pos + 3] = (unsigned char)(w ); + } +} + +/** + Encrypts a block of text with Anubis + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + anubis_crypt(pt, ct, skey->anubis.roundKeyEnc, skey->anubis.R); + return CRYPT_OK; +} + +/** + Decrypts a block of text with Anubis + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + anubis_crypt(ct, pt, skey->anubis.roundKeyDec, skey->anubis.R); + return CRYPT_OK; +} + +/** + Performs a self-test of the Anubis block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int anubis_test(void) +{ +#if !defined(LTC_TEST) + return CRYPT_NOP; +#else + static const struct test { + int keylen; + unsigned char pt[16], ct[16], key[40]; + } tests[] = { +#ifndef ANUBIS_TWEAK + /**** ORIGINAL ANUBIS ****/ + /* 128 bit keys */ +{ + 16, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xF0, 0x68, 0x60, 0xFC, 0x67, 0x30, 0xE8, 0x18, + 0xF1, 0x32, 0xC7, 0x8A, 0xF4, 0x13, 0x2A, 0xFE }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 16, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xA8, 0x66, 0x84, 0x80, 0x07, 0x74, 0x5C, 0x89, + 0xFC, 0x5E, 0xB5, 0xBA, 0xD4, 0xFE, 0x32, 0x6D }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 160-bit keys */ +{ + 20, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xBD, 0x5E, 0x32, 0xBE, 0x51, 0x67, 0xA8, 0xE2, + 0x72, 0xD7, 0x95, 0x0F, 0x83, 0xC6, 0x8C, 0x31 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}, { + 20, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x4C, 0x1F, 0x86, 0x2E, 0x11, 0xEB, 0xCE, 0xEB, + 0xFE, 0xB9, 0x73, 0xC9, 0xDF, 0xEF, 0x7A, 0xDB }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 } +}, + + /* 192-bit keys */ +{ + 24, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x17, 0xAC, 0x57, 0x44, 0x9D, 0x59, 0x61, 0x66, + 0xD0, 0xC7, 0x9E, 0x04, 0x7C, 0xC7, 0x58, 0xF0 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 24, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x71, 0x52, 0xB4, 0xEB, 0x1D, 0xAA, 0x36, 0xFD, + 0x57, 0x14, 0x5F, 0x57, 0x04, 0x9F, 0x70, 0x74 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 224-bit keys */ +{ + 28, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xA2, 0xF0, 0xA6, 0xB9, 0x17, 0x93, 0x2A, 0x3B, + 0xEF, 0x08, 0xE8, 0x7A, 0x58, 0xD6, 0xF8, 0x53 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}, { + 28, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xF0, 0xCA, 0xFC, 0x78, 0x8B, 0x4B, 0x4E, 0x53, + 0x8B, 0xC4, 0x32, 0x6A, 0xF5, 0xB9, 0x1B, 0x5F }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 } +}, + + /* 256-bit keys */ +{ + 32, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xE0, 0x86, 0xAC, 0x45, 0x6B, 0x3C, 0xE5, 0x13, + 0xED, 0xF5, 0xDF, 0xDD, 0xD6, 0x3B, 0x71, 0x93 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 32, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x50, 0x01, 0xB9, 0xF5, 0x21, 0xC1, 0xC1, 0x29, + 0x00, 0xD5, 0xEC, 0x98, 0x2B, 0x9E, 0xE8, 0x21 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 288-bit keys */ +{ + 36, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xE8, 0xF4, 0xAF, 0x2B, 0x21, 0xA0, 0x87, 0x9B, + 0x41, 0x95, 0xB9, 0x71, 0x75, 0x79, 0x04, 0x7C }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}, { + 36, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xE6, 0xA6, 0xA5, 0xBC, 0x8B, 0x63, 0x6F, 0xE2, + 0xBD, 0xA7, 0xA7, 0x53, 0xAB, 0x40, 0x22, 0xE0 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 } +}, + + /* 320-bit keys */ +{ + 40, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x17, 0x04, 0xD7, 0x2C, 0xC6, 0x85, 0x76, 0x02, + 0x4B, 0xCC, 0x39, 0x80, 0xD8, 0x22, 0xEA, 0xA4 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 40, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x7A, 0x41, 0xE6, 0x7D, 0x4F, 0xD8, 0x64, 0xF0, + 0x44, 0xA8, 0x3C, 0x73, 0x81, 0x7E, 0x53, 0xD8 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +} +#else + /**** Tweaked ANUBIS ****/ + /* 128 bit keys */ +{ + 16, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xB8, 0x35, 0xBD, 0xC3, 0x34, 0x82, 0x9D, 0x83, + 0x71, 0xBF, 0xA3, 0x71, 0xE4, 0xB3, 0xC4, 0xFD }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 16, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xE6, 0x14, 0x1E, 0xAF, 0xEB, 0xE0, 0x59, 0x3C, + 0x48, 0xE1, 0xCD, 0xF2, 0x1B, 0xBA, 0xA1, 0x89 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 160-bit keys */ +{ + 20, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x97, 0x59, 0x79, 0x4B, 0x5C, 0xA0, 0x70, 0x73, + 0x24, 0xEF, 0xB3, 0x58, 0x67, 0xCA, 0xD4, 0xB3 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}, { + 20, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xB8, 0x0D, 0xFB, 0x9B, 0xE4, 0xA1, 0x58, 0x87, + 0xB3, 0x76, 0xD5, 0x02, 0x18, 0x95, 0xC1, 0x2E }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 } +}, + + /* 192-bit keys */ +{ + 24, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x7D, 0x62, 0x3B, 0x52, 0xC7, 0x4C, 0x64, 0xD8, + 0xEB, 0xC7, 0x2D, 0x57, 0x97, 0x85, 0x43, 0x8F }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 24, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xB1, 0x0A, 0x59, 0xDD, 0x5D, 0x5D, 0x8D, 0x67, + 0xEC, 0xEE, 0x4A, 0xC4, 0xBE, 0x4F, 0xA8, 0x4F }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 224-bit keys */ +{ + 28, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x68, 0x9E, 0x05, 0x94, 0x6A, 0x94, 0x43, 0x8F, + 0xE7, 0x8E, 0x37, 0x3D, 0x24, 0x97, 0x92, 0xF5 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}, { + 28, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xDD, 0xB7, 0xB0, 0xB4, 0xE9, 0xB4, 0x9B, 0x9C, + 0x38, 0x20, 0x25, 0x0B, 0x47, 0xC2, 0x1F, 0x89 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 } +}, + + /* 256-bit keys */ +{ + 32, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x96, 0x00, 0xF0, 0x76, 0x91, 0x69, 0x29, 0x87, + 0xF5, 0xE5, 0x97, 0xDB, 0xDB, 0xAF, 0x1B, 0x0A }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 32, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x69, 0x9C, 0xAF, 0xDD, 0x94, 0xC7, 0xBC, 0x60, + 0x44, 0xFE, 0x02, 0x05, 0x8A, 0x6E, 0xEF, 0xBD }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 288-bit keys */ +{ + 36, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x0F, 0xC7, 0xA2, 0xC0, 0x11, 0x17, 0xAC, 0x43, + 0x52, 0x5E, 0xDF, 0x6C, 0xF3, 0x96, 0x33, 0x6C }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}, { + 36, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xAD, 0x08, 0x4F, 0xED, 0x55, 0xA6, 0x94, 0x3E, + 0x7E, 0x5E, 0xED, 0x05, 0xA1, 0x9D, 0x41, 0xB4 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 } +}, + + /* 320-bit keys */ +{ + 40, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xFE, 0xE2, 0x0E, 0x2A, 0x9D, 0xC5, 0x83, 0xBA, + 0xA3, 0xA6, 0xD6, 0xA6, 0xF2, 0xE8, 0x06, 0xA5 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 40, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x86, 0x3D, 0xCC, 0x4A, 0x60, 0x34, 0x9C, 0x28, + 0xA7, 0xDA, 0xA4, 0x3B, 0x0A, 0xD7, 0xFD, 0xC7 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +} +#endif +}; + int x, y; + unsigned char buf[2][16]; + symmetric_key skey; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + anubis_setup(tests[x].key, tests[x].keylen, 0, &skey); + anubis_ecb_encrypt(tests[x].pt, buf[0], &skey); + anubis_ecb_decrypt(buf[0], buf[1], &skey); + if (memcmp(buf[0], tests[x].ct, 16) || memcmp(buf[1], tests[x].pt, 16)) { + return CRYPT_FAIL_TESTVECTOR; + } + + for (y = 0; y < 1000; y++) anubis_ecb_encrypt(buf[0], buf[0], &skey); + for (y = 0; y < 1000; y++) anubis_ecb_decrypt(buf[0], buf[0], &skey); + if (memcmp(buf[0], tests[x].ct, 16)) { + return CRYPT_FAIL_TESTVECTOR; + } + + } + return CRYPT_OK; +#endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void anubis_done(symmetric_key *skey) +{ +} + +/** + Gets suitable key size + @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. + @return CRYPT_OK if the input key size is acceptable. +*/ +int anubis_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize >= 40) { + *keysize = 40; + } else if (*keysize >= 36) { + *keysize = 36; + } else if (*keysize >= 32) { + *keysize = 32; + } else if (*keysize >= 28) { + *keysize = 28; + } else if (*keysize >= 24) { + *keysize = 24; + } else if (*keysize >= 20) { + *keysize = 20; + } else if (*keysize >= 16) { + *keysize = 16; + } else { + return CRYPT_INVALID_KEYSIZE; + } + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/helper/hash_filehandle.c b/src/hashes/helper/hash_filehandle.c index 0582449..1c9b68b 100644 --- a/src/hashes/helper/hash_filehandle.c +++ b/src/hashes/helper/hash_filehandle.c @@ -42,6 +42,7 @@ int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outle } if (*outlen < hash_descriptor[hash].hashsize) { + *outlen = hash_descriptor[hash].hashsize; return CRYPT_BUFFER_OVERFLOW; } if ((err = hash_descriptor[hash].init(&md)) != CRYPT_OK) { diff --git a/src/hashes/helper/hash_memory.c b/src/hashes/helper/hash_memory.c index 96875b1..17579d0 100644 --- a/src/hashes/helper/hash_memory.c +++ b/src/hashes/helper/hash_memory.c @@ -38,6 +38,7 @@ int hash_memory(int hash, const unsigned char *in, unsigned long inlen, unsigned } if (*outlen < hash_descriptor[hash].hashsize) { + *outlen = hash_descriptor[hash].hashsize; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/hashes/helper/hash_memory_multi.c b/src/hashes/helper/hash_memory_multi.c index 6523c7e..c1e3a8b 100644 --- a/src/hashes/helper/hash_memory_multi.c +++ b/src/hashes/helper/hash_memory_multi.c @@ -43,6 +43,7 @@ int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen, } if (*outlen < hash_descriptor[hash].hashsize) { + *outlen = hash_descriptor[hash].hashsize; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/headers/tomcrypt.h b/src/headers/tomcrypt.h index 972fe56..a732033 100644 --- a/src/headers/tomcrypt.h +++ b/src/headers/tomcrypt.h @@ -16,8 +16,8 @@ extern "C" { #endif /* version */ -#define CRYPT 0x0112 -#define SCRYPT "1.12" +#define CRYPT 0x0113 +#define SCRYPT "1.13" /* max size of either a cipher/hash block or symmetric key [largest of the two] */ #define MAXBLOCKSIZE 128 diff --git a/src/headers/tomcrypt_argchk.h b/src/headers/tomcrypt_argchk.h index a617c8f..68edb91 100644 --- a/src/headers/tomcrypt_argchk.h +++ b/src/headers/tomcrypt_argchk.h @@ -7,19 +7,28 @@ /* this is the default LibTomCrypt macro */ void crypt_argchk(char *v, char *s, int d); #define LTC_ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) #elif ARGTYPE == 1 /* fatal type of error */ #define LTC_ARGCHK(x) assert((x)) +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) #elif ARGTYPE == 2 #define LTC_ARGCHK(x) if (!(x)) { fprintf(stderr, "\nwarning: ARGCHK failed at %s:%d\n", __FILE__, __LINE__); } +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) #elif ARGTYPE == 3 #define LTC_ARGCHK(x) +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 4 + +#define LTC_ARGCHK(x) return CRYPT_INVALID_ARG; +#define LTC_ARGCHKVD(x) return; #endif diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index 8a8a588..6203308 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -274,6 +274,24 @@ typedef struct { } symmetric_LRW; #endif +#ifdef LTC_F8_MODE +/** A block cipher F8 structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE], + MIV[MAXBLOCKSIZE]; + /** Current block count */ + ulong32 blockcnt; + /** The scheduled key */ + symmetric_key key; +} symmetric_F8; +#endif /** cipher descriptor table, last entry has "name == NULL" to mark the end of table */ @@ -706,9 +724,21 @@ int lrw_test(void); /* don't call */ int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw); - - #endif + +#ifdef LTC_F8_MODE +int f8_start( int cipher, const unsigned char *IV, + const unsigned char *key, int keylen, + const unsigned char *salt_key, int skeylen, + int num_rounds, symmetric_F8 *f8); +int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8); +int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8); +int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8); +int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8); +int f8_done(symmetric_F8 *f8); +#endif + + int find_cipher(const char *name); int find_cipher_any(const char *name, int blocklen, int keylen); int find_cipher_id(unsigned char ID); diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h index 8790160..cf201eb 100644 --- a/src/headers/tomcrypt_custom.h +++ b/src/headers/tomcrypt_custom.h @@ -140,6 +140,9 @@ #define CBC #define CTR +/* F8 chaining mode */ +#define LTC_F8_MODE + /* LRW mode */ #define LRW_MODE #ifndef LTC_NO_TABLES diff --git a/src/headers/tomcrypt_math.h b/src/headers/tomcrypt_math.h index c36f67c..a3534df 100644 --- a/src/headers/tomcrypt_math.h +++ b/src/headers/tomcrypt_math.h @@ -225,7 +225,7 @@ typedef struct { @param d The remainder (can be NULL to signify don't care) @return CRYPT_OK on success */ - int (*div)(void *a, void *b, void *c, void *d); + int (*mpdiv)(void *a, void *b, void *c, void *d); /** divide by two @param a The integer to divide (shift right) @@ -267,6 +267,14 @@ typedef struct { */ int (*mulmod)(void *a, void *b, void *c, void *d); + /** Modular squaring + @param a The first source + @param b The modulus + @param c The destination (a*a mod b) + @return CRYPT_OK on success + */ + int (*sqrmod)(void *a, void *b, void *c); + /** Modular inversion @param a The value to invert @param b The modulus @@ -446,14 +454,15 @@ extern const ltc_math_descriptor gmp_desc; #define mp_mul(a, b, c) ltc_mp.mul(a, b, c) #define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c) #define mp_sqr(a, b) ltc_mp.sqr(a, b) -#define mp_div(a, b, c, d) ltc_mp.div(a, b, c, d) +#define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d) #define mp_div_2(a, b) ltc_mp.div_2(a, b) -#define mp_mod(a, b, c) ltc_mp.div(a, b, NULL, c) +#define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c) #define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c) #define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c) #define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c) #define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d) +#define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c) #define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c) #define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b) diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index ae9e4d6..9803f83 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -359,7 +359,7 @@ typedef struct ltc_asn1_list_ { int LTC_MACRO_temp = (index); \ ltc_asn1_list *LTC_MACRO_list = (list); \ LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \ - LTC_MACRO_list[LTC_MACRO_temp].data = (Data); \ + LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \ LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \ LTC_MACRO_list[LTC_MACRO_temp].used = 0; \ } while (0); diff --git a/src/math/fp/ltc_ecc_fp_mulmod.c b/src/math/fp/ltc_ecc_fp_mulmod.c index 52bc4b7..614ef20 100644 --- a/src/math/fp/ltc_ecc_fp_mulmod.c +++ b/src/math/fp/ltc_ecc_fp_mulmod.c @@ -35,11 +35,12 @@ /** Our FP cache */ static struct { ecc_point *g, /* cached COPY of base point */ - *LUT[1<x, mu, modulus, fp_cache[idx].LUT[1]->x) != CRYPT_OK) || (mp_mulmod(fp_cache[idx].g->y, mu, modulus, fp_cache[idx].LUT[1]->y) != CRYPT_OK) || - (mp_mulmod(fp_cache[idx].g->z, mu, modulus, fp_cache[idx].LUT[1]->z) != CRYPT_OK)) { goto ERR; } + (mp_mulmod(fp_cache[idx].g->z, mu, modulus, fp_cache[idx].LUT[1]->z) != CRYPT_OK)) { goto ERR; } /* make all single bit entries */ for (x = 1; x < FP_LUT; x++) { if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x, fp_cache[idx].LUT[1<x) != CRYPT_OK) || (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y, fp_cache[idx].LUT[1<y) != CRYPT_OK) || - (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z, fp_cache[idx].LUT[1<z) != CRYPT_OK)) { goto ERR; } + (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z, fp_cache[idx].LUT[1<z) != CRYPT_OK)) { goto ERR; } /* now double it bitlen/FP_LUT times */ for (y = 0; y < lut_gap; y++) { @@ -700,7 +716,7 @@ static int build_lut(int idx, void *modulus, void *mp, void *mu) /* now make all entries in increase order of hamming weight */ for (x = 2; x <= FP_LUT; x++) { - for (y = 0; y < (1<z, modulus, mp)) != CRYPT_OK) { goto ERR; } + + /* invert it */ + if ((err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus, fp_cache[idx].LUT[x]->z)) != CRYPT_OK) { goto ERR; } + + /* now square it */ + if ((err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp)) != CRYPT_OK) { goto ERR; } + + /* fix x */ + if ((err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus, fp_cache[idx].LUT[x]->x)) != CRYPT_OK) { goto ERR; } + + /* get 1/z^3 */ + if ((err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp)) != CRYPT_OK) { goto ERR; } + + /* fix y */ + if ((err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus, fp_cache[idx].LUT[x]->y)) != CRYPT_OK) { goto ERR; } + + /* free z */ + mp_clear(fp_cache[idx].LUT[x]->z); + fp_cache[idx].LUT[x]->z = NULL; + } + mp_clear(tmp); + return CRYPT_OK; ERR: err = CRYPT_MEM; DONE: - for (y = 0; y < (1<x, R->x) != CRYPT_OK) || (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != CRYPT_OK) || - (mp_copy(fp_cache[idx].LUT[z]->z, R->z) != CRYPT_OK)) { return CRYPT_MEM; } + (mp_copy(fp_cache[idx].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; } first = 0; } } @@ -846,6 +897,14 @@ static int accel_fp_mul(int idx, void *k, ecc_point *R, void *modulus, void *mp, return err; } +/** ECC Fixed Point mulmod global + @param k The multiplicand + @param G Base point to multiply + @param R [out] Destination of product + @param modulus The modulus for the curve + @param map [boolean] If non-zero maps the point back to affine co-ordinates, otherwise it's left in jacobian-montgomery form + @return CRYPT_OK if successful +*/ int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) { int idx, err; @@ -909,18 +968,23 @@ LBL_ERR: return err; } +/** Free the Fixed Point tables */ void ltc_ecc_fp_free(void) { - int x, y; + unsigned x, y; LTC_MUTEX_LOCK(<c_ecc_fp_lock); for (x = 0; x < FP_ENTRIES; x++) { if (fp_cache[x].g != NULL) { - for (y = 0; y < (1<y, &t1); if ( (fp_cmp(P->x, Q->x) == FP_EQ) && - (fp_cmp(P->z, Q->z) == FP_EQ) && + (Q->z != NULL && fp_cmp(P->z, Q->z) == FP_EQ) && (fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) { return tfm_ecc_projective_dbl_point(P, R, modulus, Mp); } @@ -546,6 +554,7 @@ static int tfm_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R fp_copy(P->z, &z); /* if Z is one then these are no-operations */ + if (Q->z != NULL) { /* T1 = Z' * Z' */ fp_sqr(Q->z, &t1); fp_montgomery_reduce(&t1, modulus, mp); @@ -558,7 +567,8 @@ static int tfm_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R /* Y = Y * T1 */ fp_mul(&t1, &y, &y); fp_montgomery_reduce(&y, modulus, mp); - + } + /* T1 = Z*Z */ fp_sqr(&z, &t1); fp_montgomery_reduce(&t1, modulus, mp); @@ -604,10 +614,12 @@ static int tfm_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R } /* if Z' != 1 */ + if (Q->z != NULL) { /* Z = Z * Z' */ fp_mul(&z, Q->z, &z); fp_montgomery_reduce(&z, modulus, mp); - + } + /* Z = Z * X */ fp_mul(&z, &x, &z); fp_montgomery_reduce(&z, modulus, mp); @@ -710,6 +722,7 @@ const ltc_math_descriptor tfm_desc = { &lcm, &mulmod, + &sqrmod, &invmod, &montgomery_setup, diff --git a/src/misc/base64/base64_encode.c b/src/misc/base64/base64_encode.c index b7c3f89..7f4b11d 100644 --- a/src/misc/base64/base64_encode.c +++ b/src/misc/base64/base64_encode.c @@ -42,6 +42,7 @@ int base64_encode(const unsigned char *in, unsigned long inlen, /* valid output size ? */ len2 = 4 * ((inlen + 2) / 3); if (*outlen < len2 + 1) { + *outlen = len2 + 1; return CRYPT_BUFFER_OVERFLOW; } p = out; diff --git a/src/misc/crypt/crypt.c b/src/misc/crypt/crypt.c index e3dd6c9..7b4e7df 100644 --- a/src/misc/crypt/crypt.c +++ b/src/misc/crypt/crypt.c @@ -175,6 +175,9 @@ const char *crypt_build_settings = #endif "\n" #endif +#if defined(LTC_F8_MODE) + " F8 MODE\n" +#endif "\nMACs:\n" #if defined(HMAC) diff --git a/src/misc/zeromem.c b/src/misc/zeromem.c index 995a498..09b7023 100644 --- a/src/misc/zeromem.c +++ b/src/misc/zeromem.c @@ -23,7 +23,7 @@ void zeromem(void *out, size_t outlen) { unsigned char *mem = out; - LTC_ARGCHK(out != NULL); + LTC_ARGCHKVD(out != NULL); while (outlen-- > 0) { *mem++ = 0; } diff --git a/src/modes/cbc/cbc_getiv.c b/src/modes/cbc/cbc_getiv.c index 9117423..055fcc5 100644 --- a/src/modes/cbc/cbc_getiv.c +++ b/src/modes/cbc/cbc_getiv.c @@ -30,6 +30,7 @@ int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc) LTC_ARGCHK(len != NULL); LTC_ARGCHK(cbc != NULL); if ((unsigned long)cbc->blocklen > *len) { + *len = cbc->blocklen; return CRYPT_BUFFER_OVERFLOW; } XMEMCPY(IV, cbc->IV, cbc->blocklen); diff --git a/src/modes/cfb/cfb_getiv.c b/src/modes/cfb/cfb_getiv.c index a27f6a6..f764970 100644 --- a/src/modes/cfb/cfb_getiv.c +++ b/src/modes/cfb/cfb_getiv.c @@ -30,6 +30,7 @@ int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb) LTC_ARGCHK(len != NULL); LTC_ARGCHK(cfb != NULL); if ((unsigned long)cfb->blocklen > *len) { + *len = cfb->blocklen; return CRYPT_BUFFER_OVERFLOW; } XMEMCPY(IV, cfb->IV, cfb->blocklen); diff --git a/src/modes/ctr/ctr_getiv.c b/src/modes/ctr/ctr_getiv.c index 8bf4ecb..ff44482 100644 --- a/src/modes/ctr/ctr_getiv.c +++ b/src/modes/ctr/ctr_getiv.c @@ -30,6 +30,7 @@ int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr) LTC_ARGCHK(len != NULL); LTC_ARGCHK(ctr != NULL); if ((unsigned long)ctr->blocklen > *len) { + *len = ctr->blocklen; return CRYPT_BUFFER_OVERFLOW; } XMEMCPY(IV, ctr->ctr, ctr->blocklen); diff --git a/src/modes/f8/f8_decrypt.c b/src/modes/f8/f8_decrypt.c new file mode 100644 index 0000000..0fbe3c0 --- /dev/null +++ b/src/modes/f8/f8_decrypt.c @@ -0,0 +1,43 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file f8_decrypt.c + F8 implementation, decrypt data, Tom St Denis +*/ + +#ifdef LTC_F8_MODE + +/** + F8 decrypt + @param ct Ciphertext + @param pt [out] Plaintext + @param len Length of ciphertext (octets) + @param f8 F8 state + @return CRYPT_OK if successful +*/ +int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(f8 != NULL); + return f8_encrypt(ct, pt, len, f8); +} + + +#endif + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/f8/f8_done.c b/src/modes/f8/f8_done.c new file mode 100644 index 0000000..14a54d0 --- /dev/null +++ b/src/modes/f8/f8_done.c @@ -0,0 +1,42 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file f8_done.c + F8 implementation, finish chain, Tom St Denis +*/ + +#ifdef LTC_F8_MODE + +/** Terminate the chain + @param f8 The F8 chain to terminate + @return CRYPT_OK on success +*/ +int f8_done(symmetric_F8 *f8) +{ + int err; + LTC_ARGCHK(f8 != NULL); + + if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[f8->cipher].done(&f8->key); + return CRYPT_OK; +} + + + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/f8/f8_encrypt.c b/src/modes/f8/f8_encrypt.c new file mode 100644 index 0000000..6fd9950 --- /dev/null +++ b/src/modes/f8/f8_encrypt.c @@ -0,0 +1,68 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file f8_encrypt.c + F8 implementation, encrypt data, Tom St Denis +*/ + +#ifdef LTC_F8_MODE + +/** + F8 encrypt + @param pt Plaintext + @param ct [out] Ciphertext + @param len Length of plaintext (octets) + @param f8 F8 state + @return CRYPT_OK if successful +*/ +int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8) +{ + int err, x; + unsigned char buf[MAXBLOCKSIZE]; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(f8 != NULL); + if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (f8->blocklen < 0 || f8->blocklen > (int)sizeof(f8->IV) || + f8->padlen < 0 || f8->padlen > (int)sizeof(f8->IV)) { + return CRYPT_INVALID_ARG; + } + + zeromem(buf, sizeof(buf)); + while (len-- > 0) { + if (f8->padlen == f8->blocklen) { + /* xor of IV, MIV and blockcnt == what goes into cipher */ + STORE32H(f8->blockcnt, (buf+(f8->blocklen-4))); + ++(f8->blockcnt); + for (x = 0; x < f8->blocklen; x++) { + f8->IV[x] ^= f8->MIV[x] ^ buf[x]; + } + if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) { + return err; + } + f8->padlen = 0; + } + *ct++ = *pt++ ^ f8->IV[f8->padlen++]; + } + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/f8/f8_getiv.c b/src/modes/f8/f8_getiv.c new file mode 100644 index 0000000..ddf9a72 --- /dev/null +++ b/src/modes/f8/f8_getiv.c @@ -0,0 +1,46 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file ofb_getiv.c + F8 implementation, get IV, Tom St Denis +*/ + +#ifdef LTC_F8_MODE + +/** + Get the current initial vector + @param IV [out] The destination of the initial vector + @param len [in/out] The max size and resulting size of the initial vector + @param f8 The F8 state + @return CRYPT_OK if successful +*/ +int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8) +{ + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(len != NULL); + LTC_ARGCHK(f8 != NULL); + if ((unsigned long)f8->blocklen > *len) { + *len = f8->blocklen; + return CRYPT_BUFFER_OVERFLOW; + } + XMEMCPY(IV, f8->IV, f8->blocklen); + *len = f8->blocklen; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/f8/f8_setiv.c b/src/modes/f8/f8_setiv.c new file mode 100644 index 0000000..f1bbe2a --- /dev/null +++ b/src/modes/f8/f8_setiv.c @@ -0,0 +1,52 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file f8_setiv.c + F8 implementation, set IV, Tom St Denis +*/ + +#ifdef LTC_F8_MODE + +/** + Set an initial vector + @param IV The initial vector + @param len The length of the vector (in octets) + @param f8 The F8 state + @return CRYPT_OK if successful +*/ +int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8) +{ + int err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(f8 != NULL); + + if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) { + return err; + } + + if (len != (unsigned long)f8->blocklen) { + return CRYPT_INVALID_ARG; + } + + /* force next block */ + f8->padlen = 0; + return cipher_descriptor[f8->cipher].ecb_encrypt(IV, f8->IV, &f8->key); +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/f8/f8_start.c b/src/modes/f8/f8_start.c new file mode 100644 index 0000000..398f395 --- /dev/null +++ b/src/modes/f8/f8_start.c @@ -0,0 +1,91 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file f8_start.c + F8 implementation, start chain, Tom St Denis +*/ + + +#ifdef LTC_F8_MODE + +/** + Initialize an F8 context + @param cipher The index of the cipher desired + @param IV The initial vector + @param key The secret key + @param keylen The length of the secret key (octets) + @param salt_key The salting key for the IV + @param skeylen The length of the salting key (octets) + @param num_rounds Number of rounds in the cipher desired (0 for default) + @param f8 The F8 state to initialize + @return CRYPT_OK if successful +*/ +int f8_start( int cipher, const unsigned char *IV, + const unsigned char *key, int keylen, + const unsigned char *salt_key, int skeylen, + int num_rounds, symmetric_F8 *f8) +{ + int x, err; + unsigned char tkey[MAXBLOCKSIZE]; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(salt_key != NULL); + LTC_ARGCHK(f8 != NULL); + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* copy details */ + f8->blockcnt = 0; + f8->cipher = cipher; + f8->blocklen = cipher_descriptor[cipher].block_length; + f8->padlen = f8->blocklen; + + /* now get key ^ salt_key [extend salt_ket with 0x55 as required to match length] */ + for (x = 0; x < keylen && x < (int)sizeof(tkey); x++) { + tkey[x] = key[x]; + } + for (x = 0; x < skeylen && x < (int)sizeof(tkey); x++) { + tkey[x] ^= salt_key[x]; + } + for (; x < keylen && x < (int)sizeof(tkey); x++) { + tkey[x] ^= 0x55; + } + + /* now encrypt with tkey[0..keylen-1] the IV and use that as the IV */ + if ((err = cipher_descriptor[cipher].setup(tkey, keylen, num_rounds, &f8->key)) != CRYPT_OK) { + return err; + } + + /* encrypt IV */ + if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(IV, f8->MIV, &f8->key)) != CRYPT_OK) { + cipher_descriptor[f8->cipher].done(&f8->key); + return err; + } + zeromem(tkey, sizeof(tkey)); + zeromem(f8->IV, sizeof(f8->IV)); + + /* terminate this cipher */ + cipher_descriptor[f8->cipher].done(&f8->key); + + /* init the cipher */ + return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &f8->key); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/f8/f8_test_mode.c b/src/modes/f8/f8_test_mode.c new file mode 100644 index 0000000..d343e5b --- /dev/null +++ b/src/modes/f8/f8_test_mode.c @@ -0,0 +1,75 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file f8_test_mode.c + F8 implementation, test, Tom St Denis +*/ + + +#ifdef LTC_F8_MODE + +int f8_test_mode(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + const unsigned char key[16] = { 0x23, 0x48, 0x29, 0x00, 0x84, 0x67, 0xbe, 0x18, + 0x6c, 0x3d, 0xe1, 0x4a, 0xae, 0x72, 0xd6, 0x2c }; + const unsigned char salt[4] = { 0x32, 0xf2, 0x87, 0x0d }; + const unsigned char IV[16] = { 0x00, 0x6e, 0x5c, 0xba, 0x50, 0x68, 0x1d, 0xe5, + 0x5c, 0x62, 0x15, 0x99, 0xd4, 0x62, 0x56, 0x4a }; + const unsigned char pt[39] = { 0x70, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x72, 0x61, + 0x6e, 0x64, 0x6f, 0x6d, 0x6e, 0x65, 0x73, 0x73, + 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x6e, 0x65, 0x78, 0x74, 0x20, 0x62, 0x65, 0x73, + 0x74, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67 }; + const unsigned char ct[39] = { 0x01, 0x9c, 0xe7, 0xa2, 0x6e, 0x78, 0x54, 0x01, + 0x4a, 0x63, 0x66, 0xaa, 0x95, 0xd4, 0xee, 0xfd, + 0x1a, 0xd4, 0x17, 0x2a, 0x14, 0xf9, 0xfa, 0xf4, + 0x55, 0xb7, 0xf1, 0xd4, 0xb6, 0x2b, 0xd0, 0x8f, + 0x56, 0x2c, 0x0e, 0xef, 0x7c, 0x48, 0x02 }; + unsigned char buf[39]; + symmetric_F8 f8; + int err, idx; + + idx = find_cipher("aes"); + if (idx == -1) { + idx = find_cipher("rijndael"); + if (idx == -1) return CRYPT_NOP; + } + + /* initialize the context */ + if ((err = f8_start(idx, IV, key, sizeof(key), salt, sizeof(salt), 0, &f8)) != CRYPT_OK) { + return err; + } + f8_done(&f8); + + /* encrypt block */ + if ((err = f8_encrypt(pt, buf, sizeof(pt), &f8)) != CRYPT_OK) { + return err; + } + + /* compare */ + if (XMEMCMP(buf, ct, sizeof(ct))) { + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; +#endif +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/lrw/lrw_getiv.c b/src/modes/lrw/lrw_getiv.c index f183169..0b8adb7 100644 --- a/src/modes/lrw/lrw_getiv.c +++ b/src/modes/lrw/lrw_getiv.c @@ -30,6 +30,7 @@ int lrw_getiv(unsigned char *IV, unsigned long *len, symmetric_LRW *lrw) LTC_ARGCHK(len != NULL); LTC_ARGCHK(lrw != NULL); if (*len < 16) { + *len = 16; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/modes/ofb/ofb_getiv.c b/src/modes/ofb/ofb_getiv.c index f32028c..99c97ac 100644 --- a/src/modes/ofb/ofb_getiv.c +++ b/src/modes/ofb/ofb_getiv.c @@ -30,6 +30,7 @@ int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb) LTC_ARGCHK(len != NULL); LTC_ARGCHK(ofb != NULL); if ((unsigned long)ofb->blocklen > *len) { + *len = ofb->blocklen; return CRYPT_BUFFER_OVERFLOW; } XMEMCPY(IV, ofb->IV, ofb->blocklen); diff --git a/src/pk/asn1/der/bit/der_decode_bit_string.c b/src/pk/asn1/der/bit/der_decode_bit_string.c index 488386c..a1c849a 100644 --- a/src/pk/asn1/der/bit/der_decode_bit_string.c +++ b/src/pk/asn1/der/bit/der_decode_bit_string.c @@ -78,6 +78,7 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen, /* too many bits? */ if (blen > *outlen) { + *outlen = blen; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/asn1/der/bit/der_encode_bit_string.c b/src/pk/asn1/der/bit/der_encode_bit_string.c index f1e3cca..62cc5a2 100644 --- a/src/pk/asn1/der/bit/der_encode_bit_string.c +++ b/src/pk/asn1/der/bit/der_encode_bit_string.c @@ -42,6 +42,7 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen, } if (len > *outlen) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/asn1/der/boolean/der_encode_boolean.c b/src/pk/asn1/der/boolean/der_encode_boolean.c index 82fb5f1..7833775 100644 --- a/src/pk/asn1/der/boolean/der_encode_boolean.c +++ b/src/pk/asn1/der/boolean/der_encode_boolean.c @@ -32,6 +32,7 @@ int der_encode_boolean(int in, LTC_ARGCHK(out != NULL); if (*outlen < 3) { + *outlen = 3; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/asn1/der/ia5/der_decode_ia5_string.c b/src/pk/asn1/der/ia5/der_decode_ia5_string.c index 7d3bf94..98404f8 100644 --- a/src/pk/asn1/der/ia5/der_decode_ia5_string.c +++ b/src/pk/asn1/der/ia5/der_decode_ia5_string.c @@ -67,6 +67,7 @@ int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, /* is it too long? */ if (len > *outlen) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/asn1/der/ia5/der_encode_ia5_string.c b/src/pk/asn1/der/ia5/der_encode_ia5_string.c index 385b4d6..f19756d 100644 --- a/src/pk/asn1/der/ia5/der_encode_ia5_string.c +++ b/src/pk/asn1/der/ia5/der_encode_ia5_string.c @@ -42,6 +42,7 @@ int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, /* too big? */ if (len > *outlen) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/asn1/der/integer/der_encode_integer.c b/src/pk/asn1/der/integer/der_encode_integer.c index 74750bf..10985f9 100644 --- a/src/pk/asn1/der/integer/der_encode_integer.c +++ b/src/pk/asn1/der/integer/der_encode_integer.c @@ -41,6 +41,7 @@ int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen) } if (*outlen < tmplen) { + *outlen = tmplen; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c b/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c index a7e689e..9f1fe3b 100644 --- a/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c +++ b/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c @@ -39,6 +39,7 @@ int der_encode_object_identifier(unsigned long *words, unsigned long nwords, return err; } if (x > *outlen) { + *outlen = x; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/asn1/der/octet/der_decode_octet_string.c b/src/pk/asn1/der/octet/der_decode_octet_string.c index b0577da..2b7401b 100644 --- a/src/pk/asn1/der/octet/der_decode_octet_string.c +++ b/src/pk/asn1/der/octet/der_decode_octet_string.c @@ -66,6 +66,7 @@ int der_decode_octet_string(const unsigned char *in, unsigned long inlen, /* is it too long? */ if (len > *outlen) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/asn1/der/octet/der_encode_octet_string.c b/src/pk/asn1/der/octet/der_encode_octet_string.c index 4cd1eb2..54bd38b 100644 --- a/src/pk/asn1/der/octet/der_encode_octet_string.c +++ b/src/pk/asn1/der/octet/der_encode_octet_string.c @@ -43,6 +43,7 @@ int der_encode_octet_string(const unsigned char *in, unsigned long inlen, /* too big? */ if (len > *outlen) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/asn1/der/printable_string/der_decode_printable_string.c b/src/pk/asn1/der/printable_string/der_decode_printable_string.c index aa13cdb..932b5ab 100644 --- a/src/pk/asn1/der/printable_string/der_decode_printable_string.c +++ b/src/pk/asn1/der/printable_string/der_decode_printable_string.c @@ -67,6 +67,7 @@ int der_decode_printable_string(const unsigned char *in, unsigned long inlen, /* is it too long? */ if (len > *outlen) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/asn1/der/printable_string/der_encode_printable_string.c b/src/pk/asn1/der/printable_string/der_encode_printable_string.c index ce9ce94..ae81ced 100644 --- a/src/pk/asn1/der/printable_string/der_encode_printable_string.c +++ b/src/pk/asn1/der/printable_string/der_encode_printable_string.c @@ -42,6 +42,7 @@ int der_encode_printable_string(const unsigned char *in, unsigned long inlen, /* too big? */ if (len > *outlen) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/asn1/der/sequence/der_encode_sequence_ex.c b/src/pk/asn1/der/sequence/der_encode_sequence_ex.c index aa6e6de..fc2eba1 100644 --- a/src/pk/asn1/der/sequence/der_encode_sequence_ex.c +++ b/src/pk/asn1/der/sequence/der_encode_sequence_ex.c @@ -153,6 +153,7 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, /* too big ? */ if (*outlen < y) { + *outlen = y; err = CRYPT_BUFFER_OVERFLOW; goto LBL_ERR; } diff --git a/src/pk/asn1/der/short_integer/der_encode_short_integer.c b/src/pk/asn1/der/short_integer/der_encode_short_integer.c index 5f3e06f..d9aebba 100644 --- a/src/pk/asn1/der/short_integer/der_encode_short_integer.c +++ b/src/pk/asn1/der/short_integer/der_encode_short_integer.c @@ -42,6 +42,7 @@ int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned lon } if (*outlen < len) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/asn1/der/utctime/der_encode_utctime.c b/src/pk/asn1/der/utctime/der_encode_utctime.c index 021a38a..510f09f 100644 --- a/src/pk/asn1/der/utctime/der_encode_utctime.c +++ b/src/pk/asn1/der/utctime/der_encode_utctime.c @@ -44,6 +44,7 @@ int der_encode_utctime(ltc_utctime *utctime, return err; } if (tmplen > *outlen) { + *outlen = tmplen; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/dsa/dsa_decrypt_key.c b/src/pk/dsa/dsa_decrypt_key.c index ab4b3e4..d574759 100644 --- a/src/pk/dsa/dsa_decrypt_key.c +++ b/src/pk/dsa/dsa_decrypt_key.c @@ -105,6 +105,7 @@ int dsa_decrypt_key(const unsigned char *in, unsigned long inlen, /* avoid buffer overflow */ if (*outlen < decode[2].size) { + *outlen = decode[2].size; err = CRYPT_BUFFER_OVERFLOW; goto LBL_ERR; } diff --git a/src/pk/dsa/dsa_free.c b/src/pk/dsa/dsa_free.c index 102230f..9a6d4f9 100644 --- a/src/pk/dsa/dsa_free.c +++ b/src/pk/dsa/dsa_free.c @@ -23,7 +23,7 @@ */ void dsa_free(dsa_key *key) { - LTC_ARGCHK(key != NULL); + LTC_ARGCHKVD(key != NULL); mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL); } diff --git a/src/pk/dsa/dsa_shared_secret.c b/src/pk/dsa/dsa_shared_secret.c index 564fe8e..ed7c4fb 100644 --- a/src/pk/dsa/dsa_shared_secret.c +++ b/src/pk/dsa/dsa_shared_secret.c @@ -51,6 +51,7 @@ int dsa_shared_secret(void *private_key, void *base, x = (unsigned long)mp_unsigned_bin_size(res); if (*outlen < x) { + *outlen = x; err = CRYPT_BUFFER_OVERFLOW; goto done; } diff --git a/src/pk/ecc/ecc_decrypt_key.c b/src/pk/ecc/ecc_decrypt_key.c index 6d2aea9..6f5dccd 100644 --- a/src/pk/ecc/ecc_decrypt_key.c +++ b/src/pk/ecc/ecc_decrypt_key.c @@ -116,6 +116,7 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, /* avoid buffer overflow */ if (*outlen < decode[2].size) { + *outlen = decode[2].size; err = CRYPT_BUFFER_OVERFLOW; goto LBL_ERR; } diff --git a/src/pk/ecc/ecc_free.c b/src/pk/ecc/ecc_free.c index f5f92f3..5d8b7c2 100644 --- a/src/pk/ecc/ecc_free.c +++ b/src/pk/ecc/ecc_free.c @@ -29,7 +29,7 @@ */ void ecc_free(ecc_key *key) { - LTC_ARGCHK(key != NULL); + LTC_ARGCHKVD(key != NULL); mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); } diff --git a/src/pk/ecc/ecc_shared_secret.c b/src/pk/ecc/ecc_shared_secret.c index 4f135a4..c1f8a7d 100644 --- a/src/pk/ecc/ecc_shared_secret.c +++ b/src/pk/ecc/ecc_shared_secret.c @@ -73,6 +73,7 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, x = (unsigned long)mp_unsigned_bin_size(prime); if (*outlen < x) { + *outlen = x; err = CRYPT_BUFFER_OVERFLOW; goto done; } diff --git a/src/pk/ecc/ecc_sizes.c b/src/pk/ecc/ecc_sizes.c index 41da86f..c673bfc 100644 --- a/src/pk/ecc/ecc_sizes.c +++ b/src/pk/ecc/ecc_sizes.c @@ -26,8 +26,8 @@ void ecc_sizes(int *low, int *high) { int i; - LTC_ARGCHK(low != NULL); - LTC_ARGCHK(high != NULL); + LTC_ARGCHKVD(low != NULL); + LTC_ARGCHKVD(high != NULL); *low = INT_MAX; *high = 0; diff --git a/src/pk/ecc/ltc_ecc_points.c b/src/pk/ecc/ltc_ecc_points.c index 6b10d11..07d003b 100644 --- a/src/pk/ecc/ltc_ecc_points.c +++ b/src/pk/ecc/ltc_ecc_points.c @@ -48,7 +48,7 @@ void ltc_ecc_del_point(ecc_point *p) { /* prevents free'ing null arguments */ if (p != NULL) { - mp_clear_multi(p->x, p->y, p->z, NULL); + mp_clear_multi(p->x, p->y, p->z, NULL); /* note: p->z may be NULL but that's ok with this function anyways */ XFREE(p); } } diff --git a/src/pk/ecc/ltc_ecc_projective_add_point.c b/src/pk/ecc/ltc_ecc_projective_add_point.c index 7be6704..1cf4880 100644 --- a/src/pk/ecc/ltc_ecc_projective_add_point.c +++ b/src/pk/ecc/ltc_ecc_projective_add_point.c @@ -51,7 +51,7 @@ int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void if ((err = mp_sub(modulus, Q->y, t1)) != CRYPT_OK) { goto done; } if ( (mp_cmp(P->x, Q->x) == LTC_MP_EQ) && - (mp_cmp(P->z, Q->z) == LTC_MP_EQ) && + (Q->z != NULL && mp_cmp(P->z, Q->z) == LTC_MP_EQ) && (mp_cmp(P->y, Q->y) == LTC_MP_EQ || mp_cmp(P->y, t1) == LTC_MP_EQ)) { mp_clear_multi(t1, t2, x, y, z, NULL); return ltc_ecc_projective_dbl_point(P, R, modulus, mp); @@ -62,6 +62,7 @@ int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void if ((err = mp_copy(P->z, z)) != CRYPT_OK) { goto done; } /* if Z is one then these are no-operations */ + if (Q->z != NULL) { /* T1 = Z' * Z' */ if ((err = mp_sqr(Q->z, t1)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } @@ -74,7 +75,8 @@ int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void /* Y = Y * T1 */ if ((err = mp_mul(t1, y, y)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(y, modulus, mp)) != CRYPT_OK) { goto done; } - + } + /* T1 = Z*Z */ if ((err = mp_sqr(z, t1)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } @@ -120,10 +122,12 @@ int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void } /* if Z' != 1 */ + if (Q->z != NULL) { /* Z = Z * Z' */ if ((err = mp_mul(z, Q->z, z)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; } - + } + /* Z = Z * X */ if ((err = mp_mul(z, x, z)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; } diff --git a/src/pk/katja/katja_encrypt_key.c b/src/pk/katja/katja_encrypt_key.c index e4f6f54..fada966 100644 --- a/src/pk/katja/katja_encrypt_key.c +++ b/src/pk/katja/katja_encrypt_key.c @@ -64,6 +64,7 @@ int katja_encrypt_key(const unsigned char *in, unsigned long inlen, /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size((key->N)); if (modulus_bytelen > *outlen) { + *outlen = modulus_bytelen; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/katja/katja_exptmod.c b/src/pk/katja/katja_exptmod.c index 7e8d1ee..4f4bf4c 100644 --- a/src/pk/katja/katja_exptmod.c +++ b/src/pk/katja/katja_exptmod.c @@ -83,6 +83,7 @@ int katja_exptmod(const unsigned char *in, unsigned long inlen, /* read it back */ x = (unsigned long)mp_unsigned_bin_size(key->N); if (x > *outlen) { + *outlen = x; err = CRYPT_BUFFER_OVERFLOW; goto done; } diff --git a/src/pk/pkcs1/pkcs_1_oaep_decode.c b/src/pk/pkcs1/pkcs_1_oaep_decode.c index 3b7c2dd..81bff41 100644 --- a/src/pk/pkcs1/pkcs_1_oaep_decode.c +++ b/src/pk/pkcs1/pkcs_1_oaep_decode.c @@ -154,6 +154,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, /* rest is the message (and skip 0x01) */ if ((modulus_len - hLen - 1 - ++x) > *outlen) { + *outlen = modulus_len - hLen - 1 - x; err = CRYPT_BUFFER_OVERFLOW; goto LBL_ERR; } diff --git a/src/pk/pkcs1/pkcs_1_oaep_encode.c b/src/pk/pkcs1/pkcs_1_oaep_encode.c index bb34bd7..842f0b9 100644 --- a/src/pk/pkcs1/pkcs_1_oaep_encode.c +++ b/src/pk/pkcs1/pkcs_1_oaep_encode.c @@ -135,6 +135,7 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, /* create string of length modulus_len */ if (*outlen < modulus_len) { + *outlen = modulus_len; err = CRYPT_BUFFER_OVERFLOW; goto LBL_ERR; } diff --git a/src/pk/pkcs1/pkcs_1_pss_encode.c b/src/pk/pkcs1/pkcs_1_pss_encode.c index 8087c69..e435d3d 100644 --- a/src/pk/pkcs1/pkcs_1_pss_encode.c +++ b/src/pk/pkcs1/pkcs_1_pss_encode.c @@ -129,6 +129,7 @@ int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, /* output is DB || hash || 0xBC */ if (*outlen < modulus_len) { + *outlen = modulus_len; err = CRYPT_BUFFER_OVERFLOW; goto LBL_ERR; } diff --git a/src/pk/rsa/rsa_encrypt_key.c b/src/pk/rsa/rsa_encrypt_key.c index c8c2686..91bac09 100644 --- a/src/pk/rsa/rsa_encrypt_key.c +++ b/src/pk/rsa/rsa_encrypt_key.c @@ -58,6 +58,7 @@ int rsa_encrypt_key(const unsigned char *in, unsigned long inlen, /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size( (key->N)); if (modulus_bytelen > *outlen) { + *outlen = modulus_bytelen; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/pk/rsa/rsa_exptmod.c b/src/pk/rsa/rsa_exptmod.c index ce70835..e751365 100644 --- a/src/pk/rsa/rsa_exptmod.c +++ b/src/pk/rsa/rsa_exptmod.c @@ -83,6 +83,7 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, /* read it back */ x = (unsigned long)mp_unsigned_bin_size(key->N); if (x > *outlen) { + *outlen = x; err = CRYPT_BUFFER_OVERFLOW; goto done; } diff --git a/src/pk/rsa/rsa_free.c b/src/pk/rsa/rsa_free.c index 972a8ea..b477fb9 100644 --- a/src/pk/rsa/rsa_free.c +++ b/src/pk/rsa/rsa_free.c @@ -23,7 +23,7 @@ */ void rsa_free(rsa_key *key) { - LTC_ARGCHK(key != NULL); + LTC_ARGCHKVD(key != NULL); mp_clear_multi( key->e, key->d, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); } diff --git a/src/pk/rsa/rsa_sign_hash.c b/src/pk/rsa/rsa_sign_hash.c index bae8aa9..dcaf4ed 100644 --- a/src/pk/rsa/rsa_sign_hash.c +++ b/src/pk/rsa/rsa_sign_hash.c @@ -58,6 +58,7 @@ int rsa_sign_hash(const unsigned char *in, unsigned long inlen, /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size( (key->N)); if (modulus_bytelen > *outlen) { + *outlen = modulus_bytelen; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/prngs/fortuna.c b/src/prngs/fortuna.c index 1724ffc..72055c9 100644 --- a/src/prngs/fortuna.c +++ b/src/prngs/fortuna.c @@ -74,6 +74,7 @@ static int fortuna_reseed(prng_state *prng) /* new K == SHA256(K || s) where s == SHA256(P0) || SHA256(P1) ... */ sha256_init(&md); if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) { + sha256_done(&md, tmp); return err; } @@ -81,14 +82,19 @@ static int fortuna_reseed(prng_state *prng) if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) { /* terminate this hash */ if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) { + sha256_done(&md, tmp); return err; } /* add it to the string */ if ((err = sha256_process(&md, tmp, 32)) != CRYPT_OK) { + sha256_done(&md, tmp); return err; } /* reset this pool */ - sha256_init(&prng->fortuna.pool[x]); + if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) { + sha256_done(&md, tmp); + return err; + } } else { break; } @@ -123,13 +129,19 @@ static int fortuna_reseed(prng_state *prng) */ int fortuna_start(prng_state *prng) { - int err, x; + int err, x, y; + unsigned char tmp[MAXBLOCKSIZE]; LTC_ARGCHK(prng != NULL); /* initialize the pools */ for (x = 0; x < FORTUNA_POOLS; x++) { - sha256_init(&prng->fortuna.pool[x]); + if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) { + for (y = 0; y < x; y++) { + sha256_done(&prng->fortuna.pool[x], tmp); + } + return err; + } } prng->fortuna.pool_idx = prng->fortuna.pool0_len = prng->fortuna.reset_cnt = prng->fortuna.wd = 0; @@ -137,6 +149,9 @@ int fortuna_start(prng_state *prng) /* reset bufs */ zeromem(prng->fortuna.K, 32); if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { + for (x = 0; x < FORTUNA_POOLS; x++) { + sha256_done(&prng->fortuna.pool[x], tmp); + } return err; } zeromem(prng->fortuna.IV, 16); @@ -312,6 +327,7 @@ int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng) /* we'll write bytes for s&g's */ if (*outlen < 32*FORTUNA_POOLS) { LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); + *outlen = 32*FORTUNA_POOLS; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/prngs/rc4.c b/src/prngs/rc4.c index 5c78006..da52cb6 100644 --- a/src/prngs/rc4.c +++ b/src/prngs/rc4.c @@ -171,6 +171,7 @@ int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng) LTC_ARGCHK(prng != NULL); if (*outlen < 32) { + *outlen = 32; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/prngs/sober128.c b/src/prngs/sober128.c index 191a4d3..34c0b51 100644 --- a/src/prngs/sober128.c +++ b/src/prngs/sober128.c @@ -381,6 +381,7 @@ int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng) LTC_ARGCHK(prng != NULL); if (*outlen < 64) { + *outlen = 64; return CRYPT_BUFFER_OVERFLOW; } diff --git a/src/prngs/yarrow.c b/src/prngs/yarrow.c index dc7aec0..298ec5e 100644 --- a/src/prngs/yarrow.c +++ b/src/prngs/yarrow.c @@ -273,6 +273,7 @@ int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng) /* we'll write 64 bytes for s&g's */ if (*outlen < 64) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); + *outlen = 64; return CRYPT_BUFFER_OVERFLOW; } diff --git a/testprof/der_tests.c b/testprof/der_tests.c index e3ad1ed..315ba98 100644 --- a/testprof/der_tests.c +++ b/testprof/der_tests.c @@ -63,19 +63,19 @@ static void der_set_test(void) exit(EXIT_FAILURE); } - strcpy(strs[0], "one"); - strcpy(strs[1], "one2"); - strcpy(strs[2], "two"); - strcpy(strs[3], "aaa"); - strcpy(strs[4], "aaaa"); - strcpy(strs[5], "aab"); - strcpy(strs[6], "aaab"); - strcpy(strs[7], "bbb"); - strcpy(strs[8], "bbba"); - strcpy(strs[9], "bbbb"); + strcpy((char*)strs[0], "one"); + strcpy((char*)strs[1], "one2"); + strcpy((char*)strs[2], "two"); + strcpy((char*)strs[3], "aaa"); + strcpy((char*)strs[4], "aaaa"); + strcpy((char*)strs[5], "aab"); + strcpy((char*)strs[6], "aaab"); + strcpy((char*)strs[7], "bbb"); + strcpy((char*)strs[8], "bbba"); + strcpy((char*)strs[9], "bbbb"); for (x = 0; x < 10; x++) { - LTC_SET_ASN1(list, x, LTC_ASN1_PRINTABLE_STRING, strs[x], strlen(strs[x])); + LTC_SET_ASN1(list, x, LTC_ASN1_PRINTABLE_STRING, strs[x], strlen((char*)strs[x])); } outlen = sizeof(outbuf); @@ -96,8 +96,8 @@ static void der_set_test(void) /* now compare */ for (x = 1; x < 10; x++) { - if (!(strlen(strs[x-1]) <= strlen(strs[x])) && strcmp(strs[x-1], strs[x]) >= 0) { - fprintf(stderr, "error SET OF order at %d is wrong\n", x); + if (!(strlen((char*)strs[x-1]) <= strlen((char*)strs[x])) && strcmp((char*)strs[x-1], (char*)strs[x]) >= 0) { + fprintf(stderr, "error SET OF order at %lu is wrong\n", x); exit(EXIT_FAILURE); } } @@ -638,7 +638,7 @@ int der_tests(void) /* test OID */ x = sizeof(buf[0]); - DO(der_encode_object_identifier(rsa_oid, sizeof(rsa_oid)/sizeof(rsa_oid[0]), buf[0], &x)); + DO(der_encode_object_identifier((unsigned long*)rsa_oid, sizeof(rsa_oid)/sizeof(rsa_oid[0]), buf[0], &x)); if (x != sizeof(rsa_oid_der) || memcmp(rsa_oid_der, buf[0], x)) { fprintf(stderr, "rsa_oid_der encode failed to match, %lu, ", x); for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]); @@ -698,45 +698,45 @@ int der_tests(void) /* IA5 string */ x = sizeof(buf[0]); - DO(der_encode_ia5_string(rsa_ia5, strlen(rsa_ia5), buf[0], &x)); + DO(der_encode_ia5_string(rsa_ia5, strlen((char*)rsa_ia5), buf[0], &x)); if (x != sizeof(rsa_ia5_der) || memcmp(buf[0], rsa_ia5_der, x)) { fprintf(stderr, "IA5 encode failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_ia5_der)); return 1; } - DO(der_length_ia5_string(rsa_ia5, strlen(rsa_ia5), &y)); + DO(der_length_ia5_string(rsa_ia5, strlen((char*)rsa_ia5), &y)); if (y != x) { fprintf(stderr, "IA5 length failed to match: %lu, %lu\n", x, y); return 1; } y = sizeof(buf[1]); DO(der_decode_ia5_string(buf[0], x, buf[1], &y)); - if (y != strlen(rsa_ia5) || memcmp(buf[1], rsa_ia5, strlen(rsa_ia5))) { + if (y != strlen((char*)rsa_ia5) || memcmp(buf[1], rsa_ia5, strlen((char*)rsa_ia5))) { fprintf(stderr, "DER IA5 failed test vector\n"); return 1; } /* Printable string */ x = sizeof(buf[0]); - DO(der_encode_printable_string(rsa_printable, strlen(rsa_printable), buf[0], &x)); + DO(der_encode_printable_string(rsa_printable, strlen((char*)rsa_printable), buf[0], &x)); if (x != sizeof(rsa_printable_der) || memcmp(buf[0], rsa_printable_der, x)) { fprintf(stderr, "PRINTABLE encode failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_printable_der)); return 1; } - DO(der_length_printable_string(rsa_printable, strlen(rsa_printable), &y)); + DO(der_length_printable_string(rsa_printable, strlen((char*)rsa_printable), &y)); if (y != x) { fprintf(stderr, "printable length failed to match: %lu, %lu\n", x, y); return 1; } y = sizeof(buf[1]); DO(der_decode_printable_string(buf[0], x, buf[1], &y)); - if (y != strlen(rsa_printable) || memcmp(buf[1], rsa_printable, strlen(rsa_printable))) { + if (y != strlen((char*)rsa_printable) || memcmp(buf[1], rsa_printable, strlen((char*)rsa_printable))) { fprintf(stderr, "DER printable failed test vector\n"); return 1; } /* Test UTC time */ x = sizeof(buf[0]); - DO(der_encode_utctime(&rsa_time1, buf[0], &x)); + DO(der_encode_utctime((ltc_utctime*)&rsa_time1, buf[0], &x)); if (x != sizeof(rsa_time1_der) || memcmp(buf[0], rsa_time1_der, x)) { fprintf(stderr, "UTCTIME encode of rsa_time1 failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_time1_der)); fprintf(stderr, "\n\n"); @@ -744,7 +744,7 @@ for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]); printf("\n"); return 1; } - DO(der_length_utctime(&rsa_time1, &y)); + DO(der_length_utctime((ltc_utctime*)&rsa_time1, &y)); if (y != x) { fprintf(stderr, "UTCTIME length failed to match for rsa_time1: %lu, %lu\n", x, y); return 1; @@ -766,7 +766,7 @@ tmp_time.off_hh); } x = sizeof(buf[0]); - DO(der_encode_utctime(&rsa_time2, buf[0], &x)); + DO(der_encode_utctime((ltc_utctime*)&rsa_time2, buf[0], &x)); if (x != sizeof(rsa_time2_der) || memcmp(buf[0], rsa_time2_der, x)) { fprintf(stderr, "UTCTIME encode of rsa_time2 failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_time1_der)); fprintf(stderr, "\n\n"); @@ -774,7 +774,7 @@ for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]); printf("\n"); return 1; } - DO(der_length_utctime(&rsa_time2, &y)); + DO(der_length_utctime((ltc_utctime*)&rsa_time2, &y)); if (y != x) { fprintf(stderr, "UTCTIME length failed to match for rsa_time2: %lu, %lu\n", x, y); return 1; diff --git a/testprof/makefile b/testprof/makefile index 05ff9b4..4cc70ff 100644 --- a/testprof/makefile +++ b/testprof/makefile @@ -7,7 +7,7 @@ endif OBJECTS = base64_test.o cipher_hash_test.o der_tests.o \ dsa_test.o ecc_test.o mac_test.o modes_test.o pkcs_1_test.o rsa_test.o \ -store_test.o test.o x86_prof.o katja_test.o +store_test.o test_driver.o x86_prof.o katja_test.o ifndef LIBTEST_S LIBTEST_S=libtomcrypt_prof.a diff --git a/testprof/makefile.icc b/testprof/makefile.icc index e021d77..60628ce 100644 --- a/testprof/makefile.icc +++ b/testprof/makefile.icc @@ -3,7 +3,7 @@ CC=icc OBJECTS = base64_test.o cipher_hash_test.o der_tests.o \ dsa_test.o ecc_test.o mac_test.o modes_test.o pkcs_1_test.o rsa_test.o \ -store_test.o test.o x86_prof.o katja_test.o +store_test.o test_driver.o x86_prof.o katja_test.o ifndef LIBTEST_S LIBTEST_S = libtomcrypt_prof.a diff --git a/testprof/makefile.msvc b/testprof/makefile.msvc index e05e9e6..d330f93 100644 --- a/testprof/makefile.msvc +++ b/testprof/makefile.msvc @@ -2,7 +2,7 @@ CFLAGS = /I../src/headers/ /I./ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@ OBJECTS=base64_test.obj cipher_hash_test.obj der_tests.obj \ dsa_test.obj ecc_test.obj mac_test.obj modes_test.obj pkcs_1_test.obj \ -rsa_test.obj store_test.obj test.obj x86_prof.obj katja_test.obj +rsa_test.obj store_test.obj test_driver.obj x86_prof.obj katja_test.obj tomcrypt_prof.lib: $(OBJECTS) lib /out:tomcrypt_prof.lib $(OBJECTS) diff --git a/testprof/makefile.shared b/testprof/makefile.shared index f57968b..b3abba5 100644 --- a/testprof/makefile.shared +++ b/testprof/makefile.shared @@ -9,7 +9,7 @@ endif OBJECTS = base64_test.o cipher_hash_test.o der_tests.o \ dsa_test.o ecc_test.o mac_test.o modes_test.o pkcs_1_test.o rsa_test.o \ -store_test.o test.o x86_prof.o katja_test.o +store_test.o test_driver.o x86_prof.o katja_test.o ifndef LIBTEST LIBTEST=libtomcrypt_prof.la diff --git a/testprof/modes_test.c b/testprof/modes_test.c index e6d49f8..0e7c672 100644 --- a/testprof/modes_test.c +++ b/testprof/modes_test.c @@ -31,6 +31,10 @@ int modes_test(void) return 1; } +#ifdef LTC_F8_MODE + DO(f8_test_mode()); +#endif + #ifdef LRW_MODE DO(lrw_test()); #endif diff --git a/testprof/test.c b/testprof/test_driver.c similarity index 100% rename from testprof/test.c rename to testprof/test_driver.c diff --git a/testprof/tomcrypt_test.h b/testprof/tomcrypt_test.h index 559d6cf..ebcacbb 100644 --- a/testprof/tomcrypt_test.h +++ b/testprof/tomcrypt_test.h @@ -5,7 +5,7 @@ #include /* enable stack testing */ -// #define STACK_TEST +/* #define STACK_TEST */ /* stack testing, define this if stack usage goes downwards [e.g. x86] */ #define STACK_DOWN diff --git a/testprof/x86_prof.c b/testprof/x86_prof.c index 0fbc7ad..03c58d6 100644 --- a/testprof/x86_prof.c +++ b/testprof/x86_prof.c @@ -18,7 +18,7 @@ void tally_results(int type) { int x; - // qsort the results + /* qsort the results */ qsort(results, no_results, sizeof(struct list), &sorter); fprintf(stderr, "\n"); @@ -75,7 +75,7 @@ ulong64 rdtsc (void) return XCLOCK(); #endif - // Microsoft and Intel Windows compilers + /* Microsoft and Intel Windows compilers */ #elif defined _M_IX86 && !defined(LTC_NO_ASM) __asm rdtsc #elif defined _M_AMD64 && !defined(LTC_NO_ASM) @@ -627,7 +627,7 @@ int time_hash(void) } #undef MPI -//#warning you need an mp_rand!!! +/*#warning you need an mp_rand!!!*/ #ifdef MPI void time_mult(void) @@ -781,7 +781,7 @@ void time_rsa(void) t_start(); t1 = t_read(); z = sizeof(buf[1]); - if ((err = rsa_encrypt_key(buf[0], 32, buf[1], &z, "testprog", 8, &yarrow_prng, + if ((err = rsa_encrypt_key(buf[0], 32, buf[1], &z, (const unsigned char *)"testprog", 8, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), &key)) != CRYPT_OK) { fprintf(stderr, "\n\nrsa_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); @@ -798,7 +798,7 @@ void time_rsa(void) t_start(); t1 = t_read(); zzz = sizeof(buf[0]); - if ((err = rsa_decrypt_key(buf[1], z, buf[0], &zzz, "testprog", 8, find_hash("sha1"), + if ((err = rsa_decrypt_key(buf[1], z, buf[0], &zzz, (const unsigned char *)"testprog", 8, find_hash("sha1"), &zz, &key)) != CRYPT_OK) { fprintf(stderr, "\n\nrsa_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); @@ -916,7 +916,7 @@ void time_ecc(void) for (x = sizes[i=0]; x < 100000; x = sizes[++i]) { t2 = 0; - for (y = 0; y < 64; y++) { + for (y = 0; y < 256; y++) { t_start(); t1 = t_read(); if ((err = ecc_make_key(&yarrow_prng, find_prng("yarrow"), x, &key)) != CRYPT_OK) { @@ -926,15 +926,15 @@ void time_ecc(void) t1 = t_read() - t1; t2 += t1; - if (y < 63) { + if (y < 255) { ecc_free(&key); } } - t2 >>= 6; + t2 >>= 8; fprintf(stderr, "ECC-%lu make_key took %15llu cycles\n", x*8, t2); t2 = 0; - for (y = 0; y < 16; y++) { + for (y = 0; y < 256; y++) { t_start(); t1 = t_read(); z = sizeof(buf[1]); @@ -946,7 +946,7 @@ void time_ecc(void) t1 = t_read() - t1; t2 += t1; } - t2 >>= 4; + t2 >>= 8; fprintf(stderr, "ECC-%lu encrypt_key took %15llu cycles\n", x*8, t2); ecc_free(&key); }