diff --git a/changes b/changes index b97b9fb..93ea898 100644 --- a/changes +++ b/changes @@ -1,3 +1,31 @@ +Sept 7th, 2003 +v0.90 -- new ROL/ROR for x86 GCC + -- Jochen Katz submitted a patch to the makefile to prevent "make" from making the .a library + when not required. + == By default the KR code is not enabled [it's only a demo anyways!] + -- changed the "buf" in ecc_make_key from 4KB to 128 bytes [since the largest key is 65 bytes] + -- hmac_done() now requires you pass it the size of the destination buffer to prevent + buffer overflows. (API CHANGE) + -- hmac/hash filebased routines now return CRYPT_NOP if NO_FILE is defined. + -- I've removed the primes from dh.c and replaced them with DR safe primes suitable for the default + configuration of LibTomMath. Check out these comparisons on a 1.3Ghz Athlon XP, optimized for size, + +768-bit, 4 vs. 10 +1024-bit, 8 vs. 18 +1280-bit, 12 vs. 34 +1536-bit, 20 vs. 56 +1792-bit 28 vs. 88 +2048-bit, 40 vs. 124 +2560-bit, 71 vs. 234 +3072-bit, 113 vs. 386 +4096-bit, 283 vs. 916 + + Times are all in milliseconds for key generation. New primes times on the left. This makes the code binary + incompatible with previous releases. However, this addition is long overdue as LibTomMath has supported DR + reductions for quite some time. + -- Added RIPE-MD 128 and 160 to the list of supported hashes [10 in total]. + -- The project has been released as public domain. TDCAL no longer applies. + July 15th, 2003 v0.89 -- Fix a bug in bits.c which would prevent it from building with msvc -- Merged in LibTomMath v0.24 [and I used the alloc/free macros this time!] diff --git a/config.pl b/config.pl index 92392eb..4aa8695 100644 --- a/config.pl +++ b/config.pl @@ -21,7 +21,7 @@ ); @opts = ( - "SMALL_CODE,Use small code where possible (slower code),n", + "SMALL_CODE,Use small code where possible (slower code),y", "NO_FILE,Avoid file I/O calls,n", "CLEAN_STACK,Clean the stack within functions,n", "LTC_TEST,Include Test Vector Routines,y", @@ -55,6 +55,8 @@ "MD5,Include MD5 one-way hash,y", "MD4,Include MD4 one-way hash,y", "MD2,Include MD2 one-way hash,y", + "RIPEMD128,Include RIPEMD-128 one-way hash,y", + "RIPEMD160,Include RIPEMD-160 one-way hash,y", "HMAC,Include Hash based Message Authentication Support,y", "BASE64,Include Base64 encoding support,y", @@ -68,7 +70,7 @@ "MRSA,Include RSA public key support,y", "MDH,Include Diffie-Hellman (over Z/pZ) public key support,y", "MECC,Include Eliptic Curve public key crypto support,y", - "KR,Include Keyring support (groups all three PK systems),y", + "KR,Include Keyring support (groups all three PK systems),n", "DH768,768-bit DH key support,y", "DH1024,1024-bit DH key support,y", diff --git a/crypt.c b/crypt.c index 1cefc89..4c4a07f 100644 --- a/crypt.c +++ b/crypt.c @@ -443,6 +443,9 @@ const char *crypt_build_settings = #if defined(MD2) " MD2\n" #endif +#if defined(RIPEMD128) + " RIPEMD128\n" +#endif "\nBlock Chaining Modes:\n" #if defined(CFB) diff --git a/crypt.pdf b/crypt.pdf index 97b8666..bd4e895 100644 Binary files a/crypt.pdf and b/crypt.pdf differ diff --git a/crypt.tex b/crypt.tex index a01cea6..748e811 100644 --- a/crypt.tex +++ b/crypt.tex @@ -47,7 +47,7 @@ \def\gap{\vspace{0.5ex}} \makeindex \begin{document} -\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.89} +\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.90} \author{Tom St Denis \\ Algonquin College \\ \\ @@ -158,25 +158,20 @@ can make use of the cipher right away. \section{License} All of the source code except for the following files have been written by the author or donated to the project -under the TDCAL license: +under a public domain license: \begin{enumerate} \item rc2.c \item safer.c \end{enumerate} -`mpi.c'' was originally written -by Michael Fromberger (sting@linguist.dartmouth.edu) but has since been replaced with my LibTomMath library. -``rc2.c'' is based on publicly available code that is not attributed to a person from the given source. ``safer.c'' +`mpi.c'' was originally written by Michael Fromberger (sting@linguist.dartmouth.edu) but has since been replaced with my LibTomMath +library. + +``rc2.c'' is based on publicly available code that is not attributed to a person from the given source. ``safer.c'' was written by Richard De Moliner (demoliner@isi.ee.ethz.ch) and is public domain. -The rest of the code was written either by Tom St Denis or contributed to the project under the ``Tom Doesn't Care -About Licenses'' (TDCAL) license. Essentially this license grants the user unlimited distribution and usage (including -commercial usage). This means that you can use the package, you can re-distribute the package and even branch it. I -still retain ownership over the name of the package. If you want to branch the project you can use the code as a base -but you must change the name. The package is also royalty free which means you can use it in commercial products -without compensation towards the author. I assume no risk from usage of the code nor do I guarantee it works as -desired or stated. +The project is hereby released as public domain. \section{Patent Disclosure} @@ -364,7 +359,7 @@ have the same prototype and store their keys as naturally as possible. All cip are (given that XXX is the name of the cipher): \index{Cipher Setup} \begin{verbatim} -int XXX_setup(const unsigned char *key, int keylen, int rounds, +int XXX_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey); \end{verbatim} @@ -973,6 +968,8 @@ The following hashes are provided as of this release: \hline SHA-256 & sha256\_desc & 32 \\ \hline TIGER-192 & tiger\_desc & 24 \\ \hline SHA-1 & sha1\_desc & 20 \\ + \hline RIPEMD-160 & rmd160\_desc & 20 \\ + \hline RIPEMD-128 & rmd128\_desc & 16 \\ \hline MD5 & md5\_desc & 16 \\ \hline MD4 & md4\_desc & 16 \\ \hline MD2 & md2\_desc & 16 \\ @@ -1019,10 +1016,12 @@ int hmac_process(hmac_state *hmac, const unsigned char *buf, number of octets to process. Like the hash process routines you can send the data in arbitrarly sized chunks. When you are finished with the HMAC process you must call the following function to get the HMAC code: \begin{verbatim} -int hmac_done(hmac_state *hmac, unsigned char *hash); +int hmac_done(hmac_state *hmac, unsigned char *hashOut, + unsigned long *outlen); \end{verbatim} -``hmac'' is the HMAC state you are working with. ``hash'' is the array of octets where the HMAC code should be stored. You -must ensure that your destination array is the right size (or just make it of size MAXBLOCKSIZE to be sure). +``hmac'' is the HMAC state you are working with. ``hashOut'' is the array of octets where the HMAC code should be stored. You must +set ``outlen'' to the size of the destination buffer before calling this function. It is updated with the length of the HMAC code +produced (depending on which hash was picked) There are two utility functions provided to make using HMACs easier todo. They accept the key and information about the message (file pointer, address in memory) and produce the HMAC result in one shot. These are useful if you want to avoid @@ -1061,6 +1060,7 @@ int main(void) int idx, errno; hmac_state hmac; unsigned char key[16], dst[MAXBLOCKSIZE]; + unsigned long dstlen; /* register SHA-1 */ if (register_hash(&sha1_desc) == -1) { @@ -1086,10 +1086,12 @@ int main(void) } /* get result (presumably to use it somehow...) */ - if ((errno = hmac_done(&hmac, dst)) != CRYPT_OK) { + dstlen = sizeof(dst); + if ((errno = hmac_done(&hmac, dst, &dstlen)) != CRYPT_OK) { printf("Error finishing hmac: %s\n", error_to_string(errno)); return -1; } + printf("The hmac is %lu bytes long\n", dstlen); /* return */ return 0; diff --git a/demos/test.c b/demos/test.c index cc6ff98..81d3472 100644 --- a/demos/test.c +++ b/demos/test.c @@ -89,7 +89,7 @@ store_tests (void) L = 0; LOAD32H (L, &buf[0]); if (L != 0x12345678UL) { - printf ("LOAD/STORE32 High don't work\n"); + printf ("LOAD/STORE32 High don't work, %08lx\n", L); exit (-1); } LL = CONST64 (0x01020304050607); @@ -839,7 +839,12 @@ dh_tests (void) dh_key usera, userb; clock_t t1; -/* if ((errnum = dh_test()) != CRYPT_OK) printf("DH Error: %s\n", error_to_string(errnum)); */ + printf("Testing builting DH parameters...."); fflush(stdout); + if ((errnum = dh_test()) != CRYPT_OK) { + printf("DH Error: %s\n", error_to_string(errnum)); + exit(-1); + } + printf("Passed.\n"); dh_sizes (&low, &high); printf ("DH Keys from %d to %d supported.\n", low * 8, high * 8); @@ -916,13 +921,13 @@ dh_tests (void) for (ii = 0; ii < (int) (sizeof (sizes) / sizeof (sizes[0])); ii++) { t1 = XCLOCK (); - for (tt = 0; tt < 5; tt++) { + for (tt = 0; tt < 25; tt++) { dh_make_key (&prng, find_prng ("yarrow"), sizes[ii], &usera); dh_free (&usera); } t1 = XCLOCK () - t1; printf ("Make dh-%d key took %f msec\n", sizes[ii] * 8, - 1000.0 * (((double) t1 / 5.0) / (double) XCLOCKS_PER_SEC)); + 1000.0 * (((double) t1 / 25.0) / (double) XCLOCKS_PER_SEC)); } } @@ -1359,6 +1364,12 @@ register_all_algs (void) #ifdef SHA512 register_hash (&sha512_desc); #endif +#ifdef RIPEMD128 + register_hash (&rmd128_desc); +#endif +#ifdef RIPEMD160 + register_hash (&rmd160_desc); +#endif #ifdef YARROW register_prng (&yarrow_desc); @@ -1713,7 +1724,7 @@ main (void) if ((errnum = yarrow_start (&prng)) != CRYPT_OK) { printf ("yarrow_start: %s\n", error_to_string (errnum)); } - if ((errnum = yarrow_add_entropy ("hello", 5, &prng)) != CRYPT_OK) { + if ((errnum = yarrow_add_entropy ((unsigned char *)"hello", 5, &prng)) != CRYPT_OK) { printf ("yarrow_add_entropy: %s\n", error_to_string (errnum)); } if ((errnum = yarrow_ready (&prng)) != CRYPT_OK) { @@ -1742,7 +1753,7 @@ main (void) #ifdef KR kr_test (); -#endif +#endif rsa_test (); pad_test (); ecc_tests (); diff --git a/demos/x86_prof.c b/demos/x86_prof.c index 72a2eb6..df2e007 100644 --- a/demos/x86_prof.c +++ b/demos/x86_prof.c @@ -132,6 +132,9 @@ void reg_algs(void) #ifdef SHA512 register_hash (&sha512_desc); #endif +#ifdef RIPEMD128 + register_hash (&rmd128_desc); +#endif } diff --git a/dh.c b/dh.c index 1745ef4..0d12de5 100644 --- a/dh.c +++ b/dh.c @@ -11,118 +11,118 @@ static const struct { { 96, "DH-768", - "2", - "1tH+dRFGpEYyVLe4ydZcYyGDpeAxnChz0yk+pNCtkEXwUsOORyguBtx8spUD" - "FAjEDS8PutUBTEu2q4USqu19dUbCLj9D2jY7y3871RnSccurMBsMm35ILcyQ" - "rpN0MQKc/" + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "//////m3wvV" }, #endif #ifdef DH1024 { 128, "DH-1024", - "2", - "Uypu+t9nfUnCj7xD+xokM+Cd6mASW4ofg1jpC2BpQasC5edtA1dJC+RjbOBZ" - "z+5mvq5VYT8Wfjmlpjm9tQxHOYB0+3Myl7gbCQ5SRljWT2oBLukLNvgFjiU4" - "wiWkmu41Ern/j6uxwKb740C+VIgDAdeUY4fA5hyfr3/+DWYb14/" + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////m3C47" }, #endif #ifdef DH1280 { 160, "DH-1280", - "2", - "520QV4Tsq4NwK9Mt5CGR9xk4slvaikgi/ax3OPky5GERKTsoqEXOlFyMzURP" - "P8jYzCVz1izKd2zTDxbFfLxrJry0ceaQ5YZa5N4teByCPVlQh4v6iQl+944+" - "/NDlKzvWpx7HG7k8cGKhva7aFF8bP/CvLpaQhrfXlOX+X9pcmML9QH63tUjq" - "B80l8Yx9KN0dC3iNnsTV3DnqnEvFQkoqql" + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "//////////////////////////////m4kSN" }, #endif #ifdef DH1536 { 192, "DH-1536", - "3", - "1FTWXrPcY1w74oZ0ouIzSN8uZcRiOf6U11fx0ka6+7fqIAezPhd3Ab43QnDf" - "KFg+or/fFRGEWAxF8WIE2jx8iTOu010yNEQyH14CK0RAyy2zY4gRs2MpnU5r" - "/feWf60OkLtnPzN34+Xnlg5xf7Jl00wkHRCeJG17L3SklOidAPxWnE+Wm4BS" - "SOzdQBgiZOjlhrYS1+TIU3NP5H7BrtKFcf+ZwBULibf29L7LkDOgQbie1+43" - "lU+8SHAyBwAeGYMfZ" + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////m5uqd" }, #endif #ifdef DH1792 { 224, "DH-1792", - "2", - "IPo3wjvfS7vBYnFHwJHmesA51od9fnR8Aenezif4qLE2HX+YCv1tpvHA8yLH" - "yYbKe9QfSHHtOgVjK8AYEyPirpXxlmdykGuj+dX7EiWMRGYc+v1kKkqmCn0o" - "5tU416O/1HXTpQ2Hps0buchUD+HlCMrSgnIqRxK6Fjr0ZfiCS4XgAD6sLgi0" - "BxKFMxDsVzpGMNwF5Lj2R/cJiTi0cNDDY3gn4lK/PRUsJtRKU+9sxy0q5Yof" - "aG5VO8VcHkZJVwUKhDFHkZYWMHV808TGHXM2RQ9kRa2QvS2mXxMrDSCloQ/" + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////mT/sd" }, #endif #ifdef DH2048 { 256, "DH-2048", - "2", - "5sR1VmdsQQzzjN0iridVVyveug6sAC3+/jTIHSgEoimPOREXQ05r2WJZJAF2" - "CRu8kuusiPw2ivRli+fdLr63v1uZG5nQa28uLwNxZEsu4gu6TrGjepXeXm4Z" - "CVOC1HMmi660fLZ2ruHLa4v2NWex2Zx91/y4ygPlZM+K//iy+Gft9Ma9Ayn0" - "eYwofZeUL9vJSfutPVp2ZrIEUQDBKMvMm0SRSLiUjDtzXqrH+b/wuwIFG1K4" - "var3ucsT45mDzD9qb3tBdksSPZbr6yrELV8h+qmjiBr15oHKEglS0XwSvCap" - "abUn5XPPVoaKv13+tOnG9mGgzQ8JeClVXN63Q+GGEF" + "4", + "3///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////////////////////////////////////////m8MPh" }, #endif #ifdef DH2560 { 320, "DH-2560", - "3", - "G7UVKk+N6LfpGkdBP6XLB4QJ3wzee5YH/3o6tBDMwr4FS8YjCmeP6l4gu0hX" - "dzY2Rive4TYOu4Akm4naZuv32d71/2lQeNcO23BNYOEPxtn9BU8uYfaHP9Mo" - "M+m76oUCiI5uqpag5RH3BO34FyE4BiKkzjEXq9xxc8ERacG8Mo8DNiXu79p9" - "Q/0wsRz+W/lIN4gYw3w4iLMooAGnDrhcj5cZb0HysHWYfqmFo+jTBP6Egi0g" - "cmVO2qWQh2cZIQMfppaf1Ffq0XGIJpgDFyOHPl3NVxDabVK1tkVct+hathxJ" - "UTdqZmR2VFwMASXjfgj4VFdvFCUxV8Xr8JcwXkwlMjOJbAl0LoCa4M7hpYvz" - "G/0XviGCpv7qQaONKtsiQ6mHhMcyo9hBCRZXtNPkfPMZkPeV05akvaDs6Ek7" - "DZ62oKR" + "4", + "3///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////mKFpF" }, #endif #ifdef DH3072 { 384, "DH-3072", - "2", - "1zsV6XgY57R/hu2RR4H/BjwRqmQL9h+Dc5rgoWOcqiTS8qpVTWafi1KFV77V" - "rUcjcer1EDgCV0tpzlemtyrC2pHpw7hr3EEl2evfWOvg05FRI6mKc2UPNv2c" - "2Bjww4LD/tdsLleX7AHHXCXFSSyd6C3qWq7BqABZriSpQeaEtXbWfeC6ytFe" - "2i3VeQsLa40XQ21UxwhPAjamjSOfYzkW7xi0fwI1e+4OQiFcWOfOuvswoaEf" - "MIICyAmVp67vjGo66dk81dMemyplipgXAWPdl7ppnDd6cEjyN4N90D7kQiNg" - "lVmJlKLecldOUtdIqMnbJCbiN/t/3/AEFaokGO9om5ckc6M9gG5PG0T7Oh1N" - "dSx/PstGdxwvs9DOwjyo5wl5C9QSLtUYJl2+GZYMj6WfsgCrb6jjRJJJQe2C" - "y7wUcBILbRsP3lYT8s14zm4xFBrfMUoLN287j3wQ1TNUXjYSCi4ZLKT1XDai" - "93345OiutLOqGGikFg6ypnymJK3yeHuul" + "4", + "3///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////////////////////////////m32nN" }, #endif #ifdef DH4096 { 512, "DH-4096", - "3", - "Id8ukxZdao3hS0NGTKAXdt3c8PpiyigIyBY8lwOHjM2cqkaZgwvr1pA6OowS" - "32kJkeOqKB8gNTZZZVqOFkPXgvC4WveUgA5a7rhTj28pDidNROmMO70CCcSw" - "aHI3GLFuEMz3JJyvQKGaGwpV3C9gS70dFWTxEfNRzdYEdvIic8/SXI79VgNP" - "LGR68nzd4qxCgaLpVBnWsanRp7mfEj52S/7Kxjs14lrbAOMjCuHgN4F6THWh" - "PNhG0VXfFFIwAMW2unrfpdo+gQHNclqCf2N1FALpABzvUesgs3wIP+QTMqms" - "os/AkuulG7MusbeFl3SoCtaoW12CF038ZbqW+e+DKI1zObhtsLanvaiZm/N4" - "BsJirW7avcWNQYm1oYjZ2bR/jYqfoJ0CLXLO/vqHb8J9a5VE9nz7cqMD3/MH" - "k/g7BapsOtKuol6ipbUvxQPtf4KCwqQQ40JeqgS6amivI/aLu05S7bAxKOwE" - "Yu8YxjN6lXm3co5Wy+BmNSuRlzKhxICyHEqMfKwUtm48XHzHuPaGQzHgkn6H" - "3A+FQjQGLHewADYlbfdTF3sHYyc5k9h/9cYVkbmv7bQze53CJGr3T1hZYbN6" - "+fuz0SPnfjiKu+bWD+8RYtZpLs2+f32huMz3OqoryGfULxC2aEjL2rdBn+ZR" - "PT0+ZAUyLSAVHbsul++cawh" + "4", + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////////////////////m8pOF" }, #endif { diff --git a/ecc.c b/ecc.c index 5bc6398..036f7cb 100644 --- a/ecc.c +++ b/ecc.c @@ -590,7 +590,7 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) int x, res, err; ecc_point *base; mp_int prime; - unsigned char buf[4096]; + unsigned char buf[128]; _ARGCHK(key != NULL); diff --git a/hash.c b/hash.c index 1d3eb57..0665ac9 100644 --- a/hash.c +++ b/hash.c @@ -27,7 +27,7 @@ int hash_memory(int hash, const unsigned char *data, unsigned long len, unsigned int hash_filehandle(int hash, FILE *in, unsigned char *dst, unsigned long *outlen) { #ifdef NO_FILE - return CRYPT_ERROR; + return CRYPT_NOP; #else hash_state md; unsigned char buf[512]; @@ -64,7 +64,7 @@ int hash_filehandle(int hash, FILE *in, unsigned char *dst, unsigned long *outle int hash_file(int hash, const char *fname, unsigned char *dst, unsigned long *outlen) { #ifdef NO_FILE - return CRYPT_ERROR; + return CRYPT_NOP; #else FILE *in; int err; diff --git a/hmac.c b/hmac.c index 833f749..4edbf8f 100644 --- a/hmac.c +++ b/hmac.c @@ -37,7 +37,8 @@ int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned lon return err; } - if (keylen == 0) { + /* valid key length? */ + if (keylen == 0 || keylen > MAXBLOCKSIZE) { return CRYPT_INVALID_KEYSIZE; } @@ -88,7 +89,7 @@ int hmac_process(hmac_state *hmac, const unsigned char *buf, unsigned long len) return CRYPT_OK; } -int hmac_done(hmac_state *hmac, unsigned char *hashOut) +int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen) { unsigned char buf[MAXBLOCKSIZE]; unsigned char isha[MAXBLOCKSIZE]; @@ -103,11 +104,17 @@ int hmac_done(hmac_state *hmac, unsigned char *hashOut) return err; } + /* ensure the output size is valid */ + hashsize = hash_descriptor[hash].hashsize; + if (*outlen < hashsize) { + return CRYPT_BUFFER_OVERFLOW; + } + *outlen = hashsize; + // Get the hash of the first HMAC vector plus the data hash_descriptor[hash].done(&hmac->md, isha); // Create the second HMAC vector vector for step (3) - hashsize = hash_descriptor[hash].hashsize; for(i=0; i < HMAC_BLOCKSIZE; i++) { buf[i] = hmac->key[i] ^ 0x5C; } @@ -138,20 +145,16 @@ int hmac_memory(int hash, const unsigned char *key, unsigned long keylen, if((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } - if (hash_descriptor[hash].hashsize > *dstlen) { - return CRYPT_BUFFER_OVERFLOW; - } - *dstlen = hash_descriptor[hash].hashsize; if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) { return err; } - + if ((err = hmac_process(&hmac, data, len)) != CRYPT_OK) { return err; } - if ((err = hmac_done(&hmac, dst)) != CRYPT_OK) { + if ((err = hmac_done(&hmac, dst, dstlen)) != CRYPT_OK) { return err; } return CRYPT_OK; @@ -163,7 +166,7 @@ int hmac_file(int hash, const char *fname, const unsigned char *key, unsigned char *dst, unsigned long *dstlen) { #ifdef NO_FILE - return CRYPT_ERROR; + return CRYPT_NOP; #else hmac_state hmac; FILE *in; @@ -178,10 +181,6 @@ int hmac_file(int hash, const char *fname, const unsigned char *key, if((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } - if (hash_descriptor[hash].hashsize > *dstlen) { - return CRYPT_BUFFER_OVERFLOW; - } - *dstlen = hash_descriptor[hash].hashsize; if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) { return err; @@ -203,7 +202,7 @@ int hmac_file(int hash, const char *fname, const unsigned char *key, (void)fclose(in); /* get final hmac */ - if ((err = hmac_done(&hmac, dst)) != CRYPT_OK) { + if ((err = hmac_done(&hmac, dst, dstlen)) != CRYPT_OK) { return err; } diff --git a/legal.txt b/legal.txt deleted file mode 100644 index 6ef478e..0000000 --- a/legal.txt +++ /dev/null @@ -1,53 +0,0 @@ -Legal Issues Regarding LibTomCrypt -Tom St Denis - -The bulk of the code was written or donated under the TDCAL "Tom Doesn't Care About License" license. It entitles the developer to free-reign on -the use and distribution of derived works, commercial or otherwise. Certain files are taken from public domain packages. - -DES.C ------ -Author: Unknown, Submitted by Dobes Vandermeer -Email : dobes@smartt.com -Disclaimer: None -Status: TDCAL submission by Dobes, modified [not original] - -MD4.C ------ -Author: Dobes Vandermeer -Email : dobes@smartt.com -Disclaimer: None -Status: TDCAL submission by Dobes, modified [not original] - -HMAC.C ------- -Author: Dobes Vandermeer -Email: dobes@smartt.com -Disclaimer: None -Status: TDCAL submission by Dobes, modified [not original] - -MPI.C ------ -Author: Original [v0.80 and prior] Michael Fromberger, Current [v0.81 and later] Tom St Denis -Email: tomstdenis@iahu.ca -Disclaimer: None -Status: TDCAL submission by Tom - -RC2.C ------ -Author: Unknown, found on public domain archive [www.wiretapped.net] -Email: none -Disclaimer: Possible legal issues [should remove RC2/RC5/RC6 to simplify legal issues] -Status: Public Domain, questionable legal status, modified [not original] - -SAFER.C -------- -Author: [copied verbatim] ----- -* AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch) -* Signal and Information Processing Laboratory -* Swiss Federal Institute of Technology -* CH-8092 Zuerich, Switzerland ----- -Email: demoliner@isi.ee.ethz.ch -Disclaimer: Appears to be Public Domain [not quite sure] -Status: Public Domain, modified [not original] \ No newline at end of file diff --git a/makefile b/makefile index 7eb0a78..dde9b93 100644 --- a/makefile +++ b/makefile @@ -9,7 +9,7 @@ # a build. This is easy to remedy though, for those that have problems. # The version -VERSION=0.89 +VERSION=0.90 #ch1-01-1 # Compiler and Linker Names @@ -49,7 +49,6 @@ SMALL=small PROF=x86_prof TV=tv_gen - #LIBPATH-The directory for libtomcrypt to be installed to. #INCPATH-The directory to install the header files for libtomcrypt. #DATAPATH-The directory to install the pdf docs. @@ -67,7 +66,7 @@ OBJECTS=keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o \ bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o \ md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o \ safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o \ -prime.o twofish.o packet.o hmac.o strings.o $(MPIOBJECT) +prime.o twofish.o packet.o hmac.o strings.o rmd128.o rmd160.o $(MPIOBJECT) TESTOBJECTS=demos/test.o HASHOBJECTS=demos/hashsum.o @@ -98,9 +97,10 @@ aes.o: aes.c aes_tab.c sha512.o: sha512.c sha384.c #This rule makes the libtomcrypt library. -library: $(OBJECTS) - $(AR) $(ARFLAGS) $(LIBNAME) $(OBJECTS) - ranlib $(LIBNAME) +library: $(LIBNAME) + +$(LIBNAME): $(OBJECTS) + $(AR) $(ARFLAGS) $@ $(OBJECTS) #This rule makes the test program included with libtomcrypt test: library $(TESTOBJECTS) diff --git a/makefile.msvc b/makefile.msvc index dde8628..3310ee7 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -10,7 +10,7 @@ OBJECTS=keyring.obj gf.obj mem.obj sprng.obj ecc.obj base64.obj dh.obj rsa.obj \ bits.obj yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj sha1.obj \ md5.obj md4.obj md2.obj sha256.obj sha512.obj xtea.obj aes.obj des.obj \ safer_tab.obj safer.obj safer+.obj rc4.obj rc2.obj rc6.obj rc5.obj cast5.obj noekeon.obj \ -blowfish.obj crypt.obj mpi.obj prime.obj twofish.obj packet.obj hmac.obj strings.obj +blowfish.obj crypt.obj mpi.obj prime.obj twofish.obj packet.obj hmac.obj strings.obj rmd128.obj rmd160.obj library: $(OBJECTS) lib /out:tomcrypt.lib $(OBJECTS) diff --git a/mpi.c b/mpi.c index 4737ce7..3c139c9 100644 --- a/mpi.c +++ b/mpi.c @@ -1,10 +1,10 @@ -/* Start: bn_fast_mp_invmod.c */ +/* Start: bn_error.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -16,6 +16,51 @@ #include "mycrypt.h" #include +static const struct { + int code; + char *msg; +} msgs[] = { + { MP_OKAY, "Successful" }, + { MP_MEM, "Out of heap" }, + { MP_VAL, "Value out of range" } +}; + +/* return a char * string for a given code */ +char *mp_error_to_string(int code) +{ + int x; + + /* scan the lookup table for the given message */ + for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) { + if (msgs[x].code == code) { + return msgs[x].msg; + } + } + + /* generic reply for invalid code */ + return "Invalid error code"; +} + + +/* End: bn_error.c */ + +/* Start: bn_fast_mp_invmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + /* computes the modular inverse via binary extended euclidean algorithm, * that is c = 1/a mod b * @@ -28,6 +73,14 @@ fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) mp_int x, y, u, v, B, D; int res, neg; + /* 2. [modified] if a,b are both even then return an error! + * + * That is if gcd(a,b) = 2**k * q then obviously there is no inverse. + */ + if (mp_iseven (a) == 1 && mp_iseven (b) == 1) { + return MP_VAL; + } + /* init all our temps */ if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { return res; @@ -43,15 +96,6 @@ fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) goto __ERR; } - /* 2. [modified] if x,y are both even then return an error! - * - * That is if gcd(x,y) = 2 * k then obviously there is no inverse. - */ - if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { - res = MP_VAL; - goto __ERR; - } - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ if ((res = mp_copy (&x, &u)) != MP_OKAY) { goto __ERR; @@ -153,10 +197,10 @@ __ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); /* Start: bn_fast_mp_montgomery_reduce.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -191,11 +235,17 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) } } + /* first we have to get the digits of the input into + * an array of double precision words W[...] + */ { register mp_word *_W; register mp_digit *tmpx; - _W = W; + /* alias for the W[] array */ + _W = W; + + /* alias for the digits of x*/ tmpx = x->dp; /* copy the digits of a into W[0..a->used-1] */ @@ -209,6 +259,9 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) } } + /* now we proceed to zero successive digits + * from the least significant upwards + */ for (ix = 0; ix < n->used; ix++) { /* mu = ai * m' mod b * @@ -254,12 +307,20 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); } + /* now we have to propagate the carries and + * shift the words downward [all those least + * significant digits we zeroed]. + */ { register mp_digit *tmpx; register mp_word *_W, *_W1; /* nox fix rest of carries */ + + /* alias for current word */ _W1 = W + ix; + + /* alias for next word, where the carry goes */ _W = W + ++ix; for (; ix <= n->used * 2 + 1; ix++) { @@ -272,7 +333,11 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) * array of mp_word to mp_digit than calling mp_rshd * we just copy them in the right order */ + + /* alias for destination word */ tmpx = x->dp; + + /* alias for shifted double precision result */ _W = W + n->used; for (ix = 0; ix < n->used + 1; ix++) { @@ -280,7 +345,8 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) } /* zero oldused digits, if the input a was larger than - * m->used+1 we'll have to clear the digits */ + * m->used+1 we'll have to clear the digits + */ for (; ix < olduse; ix++) { *tmpx++ = 0; } @@ -302,10 +368,10 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) /* Start: bn_fast_s_mp_mul_digs.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -436,10 +502,10 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) /* Start: bn_fast_s_mp_mul_high_digs.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -448,7 +514,7 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include + #include /* this is a modified version of fast_s_mp_mul_digs that only produces * output digits *above* digs. See the comments for fast_s_mp_mul_digs @@ -538,10 +604,10 @@ fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) /* Start: bn_fast_s_mp_sqr.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -586,14 +652,14 @@ fast_s_mp_sqr (mp_int * a, mp_int * b) /* zero temp buffer (columns) * Note that there are two buffers. Since squaring requires - * a outter and inner product and the inner product requires + * a outer and inner product and the inner product requires * computing a product and doubling it (a relatively expensive * op to perform n**2 times if you don't have to) the inner and * outer products are computed in different buffers. This way * the inner product can be doubled using n doublings instead of * n**2 */ - memset (W, 0, newused * sizeof (mp_word)); + memset (W, 0, newused * sizeof (mp_word)); memset (W2, 0, newused * sizeof (mp_word)); /* This computes the inner product. To simplify the inner N**2 loop @@ -605,6 +671,7 @@ fast_s_mp_sqr (mp_int * a, mp_int * b) * Note that every outer product is computed * for a particular column only once which means that * there is no need todo a double precision addition + * into the W2[] array. */ W2[ix + ix] = ((mp_word)a->dp[ix]) * ((mp_word)a->dp[ix]); @@ -633,7 +700,12 @@ fast_s_mp_sqr (mp_int * a, mp_int * b) olduse = b->used; b->used = newused; - /* now compute digits */ + /* now compute digits + * + * We have to double the inner product sums, add in the + * outer product sums, propagate carries and convert + * to single precision. + */ { register mp_digit *tmpb; @@ -647,16 +719,21 @@ fast_s_mp_sqr (mp_int * a, mp_int * b) /* double/add next digit */ W[ix] += W[ix] + W2[ix]; + /* propagate carry forwards [from the previous digit] */ W[ix] = W[ix] + (W[ix - 1] >> ((mp_word) DIGIT_BIT)); + + /* store the current digit now that the carry isn't + * needed + */ *tmpb++ = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK)); } - /* set the last value. Note even if the carry is zero - * this is required since the next step will not zero + /* set the last value. Note even if the carry is zero + * this is required since the next step will not zero * it if b originally had a value at b->dp[2*a.used] */ *tmpb++ = (mp_digit) (W[(newused) - 1] & ((mp_word) MP_MASK)); - /* clear high digits */ + /* clear high digits of b if there were any originally */ for (; ix < olduse; ix++) { *tmpb++ = 0; } @@ -671,10 +748,10 @@ fast_s_mp_sqr (mp_int * a, mp_int * b) /* Start: bn_mp_2expt.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -695,11 +772,18 @@ mp_2expt (mp_int * a, int b) { int res; + /* zero a as per default */ mp_zero (a); + + /* grow a to accomodate the single bit */ if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { return res; } + + /* set the used count of where the bit will go */ a->used = b / DIGIT_BIT + 1; + + /* put the single bit in its place */ a->dp[b / DIGIT_BIT] = 1 << (b % DIGIT_BIT); return MP_OKAY; @@ -710,10 +794,10 @@ mp_2expt (mp_int * a, int b) /* Start: bn_mp_abs.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -732,10 +816,17 @@ int mp_abs (mp_int * a, mp_int * b) { int res; - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; + + /* copy a to b */ + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } } + + /* force the sign of b to positive */ b->sign = MP_ZPOS; + return MP_OKAY; } @@ -744,10 +835,10 @@ mp_abs (mp_int * a, mp_int * b) /* Start: bn_mp_add.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -796,10 +887,10 @@ mp_add (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_add_d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -838,7 +929,6 @@ mp_add_d (mp_int * a, mp_digit b, mp_int * c) return res; } - /* old number of used digits in c */ oldused = c->used; @@ -872,13 +962,16 @@ mp_add_d (mp_int * a, mp_digit b, mp_int * c) /* set final carry */ ix++; *tmpc++ = mu; - } else { /* a was negative and |a| < b */ c->used = 1; /* the result is a single digit */ - *tmpc++ = b - a->dp[0]; + if (a->used == 1) { + *tmpc++ = b - a->dp[0]; + } else { + *tmpc++ = b; + } /* setup count so the clearing of oldused * can fall through correctly @@ -901,10 +994,10 @@ mp_add_d (mp_int * a, mp_digit b, mp_int * c) /* Start: bn_mp_addmod.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -940,10 +1033,10 @@ mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) /* Start: bn_mp_and.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -995,10 +1088,10 @@ mp_and (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_clamp.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1019,9 +1112,14 @@ mp_and (mp_int * a, mp_int * b, mp_int * c) void mp_clamp (mp_int * a) { + /* decrease used while the most significant digit is + * zero. + */ while (a->used > 0 && a->dp[a->used - 1] == 0) { --(a->used); } + + /* reset the sign flag if used == 0 */ if (a->used == 0) { a->sign = MP_ZPOS; } @@ -1032,10 +1130,10 @@ mp_clamp (mp_int * a) /* Start: bn_mp_clear.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1050,6 +1148,7 @@ mp_clamp (mp_int * a) void mp_clear (mp_int * a) { + /* only do anything if a hasn't been freed previously */ if (a->dp != NULL) { /* first zero the digits */ memset (a->dp, 0, sizeof (mp_digit) * a->used); @@ -1060,18 +1159,51 @@ mp_clear (mp_int * a) /* reset members to make debugging easier */ a->dp = NULL; a->alloc = a->used = 0; + a->sign = MP_ZPOS; } } /* End: bn_mp_clear.c */ +/* Start: bn_mp_clear_multi.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include +#include + +void mp_clear_multi(mp_int *mp, ...) +{ + mp_int* next_mp = mp; + va_list args; + va_start(args, mp); + while (next_mp != NULL) { + mp_clear(next_mp); + next_mp = va_arg(args, mp_int*); + } + va_end(args); +} + +/* End: bn_mp_clear_multi.c */ + /* Start: bn_mp_cmp.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1087,12 +1219,12 @@ int mp_cmp (mp_int * a, mp_int * b) { /* compare based on sign */ - if (a->sign == MP_NEG && b->sign == MP_ZPOS) { - return MP_LT; - } - - if (a->sign == MP_ZPOS && b->sign == MP_NEG) { - return MP_GT; + if (a->sign != b->sign) { + if (a->sign == MP_NEG) { + return MP_LT; + } else { + return MP_GT; + } } /* compare digits */ @@ -1109,10 +1241,10 @@ mp_cmp (mp_int * a, mp_int * b) /* Start: bn_mp_cmp_d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1127,15 +1259,17 @@ mp_cmp (mp_int * a, mp_int * b) int mp_cmp_d (mp_int * a, mp_digit b) { - + /* compare based on sign */ if (a->sign == MP_NEG) { return MP_LT; } + /* compare based on magnitude */ if (a->used > 1) { return MP_GT; } + /* compare the only digit of a to b */ if (a->dp[0] > b) { return MP_GT; } else if (a->dp[0] < b) { @@ -1150,10 +1284,10 @@ mp_cmp_d (mp_int * a, mp_digit b) /* Start: bn_mp_cmp_mag.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1169,23 +1303,30 @@ int mp_cmp_mag (mp_int * a, mp_int * b) { int n; + mp_digit *tmpa, *tmpb; /* compare based on # of non-zero digits */ if (a->used > b->used) { return MP_GT; - } + } if (a->used < b->used) { return MP_LT; } + /* alias for a */ + tmpa = a->dp + (a->used - 1); + + /* alias for b */ + tmpb = b->dp + (a->used - 1); + /* compare based on digits */ - for (n = a->used - 1; n >= 0; n--) { - if (a->dp[n] > b->dp[n]) { + for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { + if (*tmpa > *tmpb) { return MP_GT; - } - - if (a->dp[n] < b->dp[n]) { + } + + if (*tmpa < *tmpb) { return MP_LT; } } @@ -1197,10 +1338,10 @@ mp_cmp_mag (mp_int * a, mp_int * b) /* Start: bn_mp_cnt_lsb.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1217,6 +1358,7 @@ int mp_cnt_lsb(mp_int *a) int x; mp_digit q; + /* easy out */ if (mp_iszero(a) == 1) { return 0; } @@ -1241,10 +1383,10 @@ int mp_cnt_lsb(mp_int *a) /* Start: bn_mp_copy.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1267,8 +1409,10 @@ mp_copy (mp_int * a, mp_int * b) } /* grow dest */ - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } } /* zero b and copy the parameters over */ @@ -1276,7 +1420,11 @@ mp_copy (mp_int * a, mp_int * b) register mp_digit *tmpa, *tmpb; /* pointer aliases */ + + /* source */ tmpa = a->dp; + + /* destination */ tmpb = b->dp; /* copy all the digits */ @@ -1289,6 +1437,8 @@ mp_copy (mp_int * a, mp_int * b) *tmpb++ = 0; } } + + /* copy used count and sign */ b->used = a->used; b->sign = a->sign; return MP_OKAY; @@ -1299,10 +1449,10 @@ mp_copy (mp_int * a, mp_int * b) /* Start: bn_mp_count_bits.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1342,10 +1492,10 @@ mp_count_bits (mp_int * a) /* Start: bn_mp_div.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1453,8 +1603,9 @@ mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) /* step 3. for i from n down to (t + 1) */ for (i = n; i >= (t + 1); i--) { - if (i > x.used) + if (i > x.used) { continue; + } /* step 3.1 if xi == yt then set q{i-t-1} to b-1, * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ @@ -1557,10 +1708,10 @@ __Q:mp_clear (&q); /* Start: bn_mp_div_2.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1624,10 +1775,10 @@ mp_div_2 (mp_int * a, mp_int * b) /* Start: bn_mp_div_2d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1720,10 +1871,10 @@ mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) /* Start: bn_mp_div_3.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1755,10 +1906,17 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) w = 0; for (ix = a->used - 1; ix >= 0; ix--) { w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - + if (w >= 3) { + /* multiply w by [1/3] */ t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); + + /* now subtract 3 * [w/3] from w, to get the remainder */ w -= (t << ((mp_word)1)) + t; + + /* fixup the remainder as required since + * the optimization is not exact. + */ while (w >= 3) { t += 1; w -= 3; @@ -1768,11 +1926,13 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) } q.dp[ix] = (mp_digit)t; } - + + /* [optional] store the remainder */ if (d != NULL) { *d = (mp_digit)w; } - + + /* [optional] store the quotient */ if (c != NULL) { mp_clamp(&q); mp_exch(&q, c); @@ -1788,10 +1948,10 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) /* Start: bn_mp_div_d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1895,10 +2055,10 @@ mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) /* Start: bn_mp_dr_is_modulus.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1919,6 +2079,9 @@ int mp_dr_is_modulus(mp_int *a) return 0; } + /* must be of the form b**k - a [a <= b] so all + * but the first digit must be equal to -1 (mod b). + */ for (ix = 1; ix < a->used; ix++) { if (a->dp[ix] != MP_MASK) { return 0; @@ -1933,10 +2096,10 @@ int mp_dr_is_modulus(mp_int *a) /* Start: bn_mp_dr_reduce.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1958,6 +2121,8 @@ int mp_dr_is_modulus(mp_int *a) * The modulus must be of a special format [see manual] * * Has been modified to use algorithm 7.10 from the LTM book instead + * + * Input x must be in the range 0 <= x <= (n-1)^2 */ int mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) @@ -1990,16 +2155,16 @@ top: /* set carry to zero */ mu = 0; - /* compute (x mod B**m) + mp * [x/B**m] inline and inplace */ + /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ for (i = 0; i < m; i++) { r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu; *tmpx1++ = (mp_digit)(r & MP_MASK); mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); } - + /* set final carry */ *tmpx1++ = mu; - + /* zero words above m */ for (i = m + 1; i < x->used; i++) { *tmpx1++ = 0; @@ -2023,10 +2188,10 @@ top: /* Start: bn_mp_dr_setup.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2053,10 +2218,10 @@ void mp_dr_setup(mp_int *a, mp_digit *d) /* Start: bn_mp_exch.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2075,7 +2240,7 @@ mp_exch (mp_int * a, mp_int * b) { mp_int t; - t = *a; + t = *a; *a = *b; *b = t; } @@ -2085,10 +2250,10 @@ mp_exch (mp_int * a, mp_int * b) /* Start: bn_mp_expt_d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2141,10 +2306,10 @@ mp_expt_d (mp_int * a, mp_digit b, mp_int * c) /* Start: bn_mp_exptmod.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2201,7 +2366,10 @@ mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) return err; } + /* is it a DR modulus? */ dr = mp_dr_is_modulus(P); + + /* if not, is it a uDR modulus? */ if (dr == 0) { dr = mp_reduce_is_2k(P) << 1; } @@ -2210,6 +2378,7 @@ mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) if (mp_isodd (P) == 1 || dr != 0) { return mp_exptmod_fast (G, X, P, Y, dr); } else { + /* otherwise use the generic Barrett reduction technique */ return s_mp_exptmod (G, X, P, Y); } } @@ -2220,10 +2389,10 @@ mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) /* Start: bn_mp_exptmod_fast.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2314,15 +2483,15 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { redux = fast_mp_montgomery_reduce; } else { - /* use slower baselien method */ + /* use slower baseline Montgomery method */ redux = mp_montgomery_reduce; } } else if (redmode == 1) { - /* setup DR reduction */ + /* setup DR reduction for moduli of the form B**k - b */ mp_dr_setup(P, &mp); redux = mp_dr_reduce; } else { - /* setup 2k reduction */ + /* setup DR reduction for moduli of the form 2**k - b */ if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { goto __M; } @@ -2331,7 +2500,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) /* setup result */ if ((err = mp_init (&res)) != MP_OKAY) { - goto __RES; + goto __M; } /* create M table @@ -2393,15 +2562,17 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) for (;;) { /* grab next digit as required */ if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits so break */ if (digidx == -1) { break; } - buf = X->dp[digidx--]; - bitcnt = (int) DIGIT_BIT; + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)DIGIT_BIT; } /* grab the next msb from the exponent */ - y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; + y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; buf <<= (mp_digit)1; /* if the bit is zero and mode == 0 then we ignore it @@ -2426,7 +2597,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) /* else we add it to the window */ bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; + mode = 2; if (bitcpy == winsize) { /* ok window is filled so square as required and multiply */ @@ -2451,7 +2622,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) /* empty window and reset */ bitcpy = 0; bitbuf = 0; - mode = 1; + mode = 1; } } @@ -2466,6 +2637,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) goto __RES; } + /* get next bit of the window */ bitbuf <<= 1; if ((bitbuf & (1 << winsize)) != 0) { /* then multiply */ @@ -2480,12 +2652,18 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) } if (redmode == 0) { - /* fixup result if Montgomery reduction is used */ + /* fixup result if Montgomery reduction is used + * recall that any value in a Montgomery system is + * actually multiplied by R mod n. So we have + * to reduce one more time to cancel out the factor + * of R. + */ if ((err = mp_montgomery_reduce (&res, P, mp)) != MP_OKAY) { goto __RES; } } + /* swap res with Y */ mp_exch (&res, Y); err = MP_OKAY; __RES:mp_clear (&res); @@ -2502,10 +2680,10 @@ __M: /* Start: bn_mp_fread.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2567,10 +2745,10 @@ int mp_fread(mp_int *a, int radix, FILE *stream) /* Start: bn_mp_fwrite.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2590,25 +2768,25 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream) if (len == 0) { return MP_VAL; } - + buf = XMALLOC(len); if (buf == NULL) { return MP_MEM; } if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) { - XFREE(buf); + free(buf); return err; } for (x = 0; x < len; x++) { if (fputc(buf[x], stream) == EOF) { - XFREE(buf); + free(buf); return MP_VAL; } } - XFREE(buf); + free(buf); return MP_OKAY; } @@ -2618,10 +2796,10 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream) /* Start: bn_mp_gcd.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2641,16 +2819,21 @@ mp_gcd (mp_int * a, mp_int * b, mp_int * c) /* either zero than gcd is the largest */ if (mp_iszero (a) == 1 && mp_iszero (b) == 0) { - return mp_copy (b, c); + return mp_abs (b, c); } if (mp_iszero (a) == 0 && mp_iszero (b) == 1) { - return mp_copy (a, c); + return mp_abs (a, c); } - if (mp_iszero (a) == 1 && mp_iszero (b) == 1) { + + /* optimized. At this point if a == 0 then + * b must equal zero too + */ + if (mp_iszero (a) == 1) { mp_zero(c); return MP_OKAY; } + /* get copies of a and b we can modify */ if ((res = mp_init_copy (&u, a)) != MP_OKAY) { return res; } @@ -2667,12 +2850,15 @@ mp_gcd (mp_int * a, mp_int * b, mp_int * c) v_lsb = mp_cnt_lsb(&v); k = MIN(u_lsb, v_lsb); - if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { - goto __V; - } + if (k > 0) { + /* divide the power of two out */ + if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { + goto __V; + } - if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { - goto __V; + if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { + goto __V; + } } /* divide any remaining factors of two out */ @@ -2687,10 +2873,11 @@ mp_gcd (mp_int * a, mp_int * b, mp_int * c) goto __V; } } - + while (mp_iszero(&v) == 0) { /* make sure v is the largest */ if (mp_cmp_mag(&u, &v) == MP_GT) { + /* swap u and v to make sure v is >= u */ mp_exch(&u, &v); } @@ -2704,10 +2891,10 @@ mp_gcd (mp_int * a, mp_int * b, mp_int * c) goto __V; } } - - /* multiply by 2**k which we divided out at the beginning */ + + /* multiply by 2**k which we divided out at the beginning */ if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { - goto __V; + goto __V; } c->sign = MP_ZPOS; res = MP_OKAY; @@ -2721,10 +2908,10 @@ __U:mp_clear (&v); /* Start: bn_mp_grow.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2744,7 +2931,7 @@ mp_grow (mp_int * a, int size) /* if the alloc size is smaller alloc more ram */ if (a->alloc < size) { /* ensure there are always at least MP_PREC digits extra on top */ - size += (MP_PREC * 2) - (size & (MP_PREC - 1)); + size += (MP_PREC * 2) - (size % MP_PREC); a->dp = OPT_CAST XREALLOC (a->dp, sizeof (mp_digit) * size); if (a->dp == NULL) { @@ -2766,11 +2953,11 @@ mp_grow (mp_int * a, int size) /* Start: bn_mp_init.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with * additional optimizations in place. * * The library is free for all purposes without any express @@ -2784,7 +2971,7 @@ mp_grow (mp_int * a, int size) int mp_init (mp_int * a) { - /* allocate ram required and clear it */ + /* allocate memory required and clear it */ a->dp = OPT_CAST calloc (sizeof (mp_digit), MP_PREC); if (a->dp == NULL) { return MP_MEM; @@ -2804,10 +2991,10 @@ mp_init (mp_int * a) /* Start: bn_mp_init_copy.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2832,13 +3019,70 @@ mp_init_copy (mp_int * a, mp_int * b) /* End: bn_mp_init_copy.c */ +/* Start: bn_mp_init_multi.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include +#include + +int mp_init_multi(mp_int *mp, ...) +{ + mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ + int n = 0; /* Number of ok inits */ + mp_int* cur_arg = mp; + va_list args; + + va_start(args, mp); /* init args to next argument from caller */ + while (cur_arg != NULL) { + if (mp_init(cur_arg) != MP_OKAY) { + /* Oops - error! Back-track and mp_clear what we already + succeeded in init-ing, then return error. + */ + va_list clean_args; + + /* end the current list */ + va_end(args); + + /* now start cleaning up */ + cur_arg = mp; + va_start(clean_args, mp); + while (n--) { + mp_clear(cur_arg); + cur_arg = va_arg(clean_args, mp_int*); + } + va_end(clean_args); + res = MP_MEM; + break; + } + n++; + cur_arg = va_arg(args, mp_int*); + } + va_end(args); + return res; /* Assumed ok, if error flagged above. */ +} + + +/* End: bn_mp_init_multi.c */ + /* Start: bn_mp_init_size.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2849,22 +3093,21 @@ mp_init_copy (mp_int * a, mp_int * b) */ #include -/* init a mp_init and grow it to a given size */ +/* init an mp_init for a given size */ int mp_init_size (mp_int * a, int size) { - /* pad size so there are always extra digits */ - size += (MP_PREC * 2) - (size & (MP_PREC - 1)); + size += (MP_PREC * 2) - (size % MP_PREC); /* alloc mem */ a->dp = OPT_CAST calloc (sizeof (mp_digit), size); if (a->dp == NULL) { return MP_MEM; } - a->used = 0; + a->used = 0; a->alloc = size; - a->sign = MP_ZPOS; + a->sign = MP_ZPOS; return MP_OKAY; } @@ -2874,10 +3117,10 @@ mp_init_size (mp_int * a, int size) /* Start: bn_mp_invmod.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3053,10 +3296,10 @@ __ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); /* Start: bn_mp_jacobi.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3077,6 +3320,11 @@ mp_jacobi (mp_int * a, mp_int * p, int *c) int k, s, r, res; mp_digit residue; + /* if p <= 0 return MP_VAL */ + if (mp_cmp_d(p, 0) != MP_GT) { + return MP_VAL; + } + /* step 1. if a == 0, return 0 */ if (mp_iszero (a) == 1) { *c = 0; @@ -3090,7 +3338,7 @@ mp_jacobi (mp_int * a, mp_int * p, int *c) } /* default */ - k = s = 0; + s = 0; /* step 3. write a = a1 * 2**k */ if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { @@ -3101,11 +3349,10 @@ mp_jacobi (mp_int * a, mp_int * p, int *c) goto __A1; } - while (mp_iseven (&a1) == 1) { - k = k + 1; - if ((res = mp_div_2 (&a1, &a1)) != MP_OKAY) { - goto __P1; - } + /* divide out larger power of two */ + k = mp_cnt_lsb(&a1); + if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { + goto __P1; } /* step 4. if e is even set s=1 */ @@ -3153,10 +3400,10 @@ __A1:mp_clear (&a1); /* Start: bn_mp_karatsuba_mul.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3322,10 +3569,10 @@ ERR: /* Start: bn_mp_karatsuba_sqr.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3442,10 +3689,10 @@ ERR: /* Start: bn_mp_lcm.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3456,30 +3703,43 @@ ERR: */ #include -/* computes least common multiple as a*b/(a, b) */ +/* computes least common multiple as |a*b|/(a, b) */ int mp_lcm (mp_int * a, mp_int * b, mp_int * c) { int res; - mp_int t; + mp_int t1, t2; - if ((res = mp_init (&t)) != MP_OKAY) { + if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) { return res; } - if ((res = mp_mul (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; + /* t1 = get the GCD of the two inputs */ + if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) { + goto __T; } - if ((res = mp_gcd (a, b, c)) != MP_OKAY) { - mp_clear (&t); - return res; + /* divide the smallest by the GCD */ + if (mp_cmp_mag(a, b) == MP_LT) { + /* store quotient in t2 such that t2 * b is the LCM */ + if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { + goto __T; + } + res = mp_mul(b, &t2, c); + } else { + /* store quotient in t2 such that t2 * a is the LCM */ + if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { + goto __T; + } + res = mp_mul(a, &t2, c); } - res = mp_div (&t, c, c, NULL); - mp_clear (&t); + /* fix the sign to positive */ + c->sign = MP_ZPOS; + +__T: + mp_clear_multi (&t1, &t2, NULL); return res; } @@ -3488,10 +3748,10 @@ mp_lcm (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_lshd.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3554,10 +3814,10 @@ mp_lshd (mp_int * a, int b) /* Start: bn_mp_mod.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3601,10 +3861,10 @@ mp_mod (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_mod_2d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3621,7 +3881,6 @@ mp_mod_2d (mp_int * a, int b, mp_int * c) { int x, res; - /* if b is <= 0 then zero the int */ if (b <= 0) { mp_zero (c); @@ -3655,10 +3914,10 @@ mp_mod_2d (mp_int * a, int b, mp_int * c) /* Start: bn_mp_mod_d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3680,10 +3939,10 @@ mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) /* Start: bn_mp_montgomery_calc_normalization.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3737,10 +3996,10 @@ mp_montgomery_calc_normalization (mp_int * a, mp_int * b) /* Start: bn_mp_montgomery_reduce.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3780,7 +4039,14 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) x->used = digs; for (ix = 0; ix < n->used; ix++) { - /* mu = ai * m' mod b */ + /* mu = ai * rho mod b + * + * The value of rho must be precalculated via + * bn_mp_montgomery_setup() such that + * it equals -1/n0 mod b this allows the + * following inner loop to reduce the + * input one digit at a time + */ mu = ((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK; /* a = a + mu * m * b**i */ @@ -3789,8 +4055,10 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) register mp_digit *tmpn, *tmpx, u; register mp_word r; - /* aliases */ + /* alias for digits of the modulus */ tmpn = n->dp; + + /* alias for the digits of x [the input] */ tmpx = x->dp + ix; /* set the carry to zero */ @@ -3798,12 +4066,20 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) /* Multiply and add in place */ for (iy = 0; iy < n->used; iy++) { + /* compute product and sum */ r = ((mp_word)mu) * ((mp_word)*tmpn++) + ((mp_word) u) + ((mp_word) * tmpx); + + /* get carry */ u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* fix digit */ *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); } - /* propagate carries */ + /* At this point the ix'th digit of x should be zero */ + + + /* propagate carries upwards as required*/ while (u) { *tmpx += u; u = *tmpx >> DIGIT_BIT; @@ -3812,11 +4088,18 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) } } + /* at this point the n.used'th least + * significant digits of x are all zero + * which means we can shift x to the + * right by n.used digits and the + * residue is unchanged. + */ + /* x = x/b**n.used */ mp_clamp(x); mp_rshd (x, n->used); - /* if A >= m then A = A - m */ + /* if x >= n then x = x - n */ if (mp_cmp_mag (x, n) != MP_LT) { return s_mp_sub (x, n, x); } @@ -3829,10 +4112,10 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) /* Start: bn_mp_montgomery_setup.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3886,10 +4169,10 @@ mp_montgomery_setup (mp_int * n, mp_digit * rho) /* Start: bn_mp_mul.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3906,13 +4189,14 @@ mp_mul (mp_int * a, mp_int * b, mp_int * c) { int res, neg; neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - + + /* use Toom-Cook? */ if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { res = mp_toom_mul(a, b, c); + /* use Karatsuba? */ } else if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { res = mp_karatsuba_mul (a, b, c); } else { - /* can we use the fast multiplier? * * The fast multiplier can be used if the output will @@ -3939,10 +4223,10 @@ mp_mul (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_mul_2.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4000,7 +4284,7 @@ mp_mul_2 (mp_int * a, mp_int * b) if (r != 0) { /* add a MSB which is always 1 at this point */ *tmpb = 1; - ++b->used; + ++(b->used); } /* now zero any excess digits on the destination @@ -4020,10 +4304,10 @@ mp_mul_2 (mp_int * a, mp_int * b) /* Start: bn_mp_mul_2d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4092,7 +4376,7 @@ mp_mul_2d (mp_int * a, int b, mp_int * c) /* set final carry */ if (r != 0) { - c->dp[c->used++] = r; + c->dp[(c->used)++] = r; } } mp_clamp (c); @@ -4104,10 +4388,10 @@ mp_mul_2d (mp_int * a, int b, mp_int * c) /* Start: bn_mp_mul_d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4180,10 +4464,10 @@ mp_mul_d (mp_int * a, mp_digit b, mp_int * c) /* Start: bn_mp_mulmod.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4217,81 +4501,13 @@ mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) /* End: bn_mp_mulmod.c */ -/* Start: bn_mp_multi.c */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org - */ -#include -#include - -int mp_init_multi(mp_int *mp, ...) -{ - mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ - int n = 0; /* Number of ok inits */ - mp_int* cur_arg = mp; - va_list args; - - va_start(args, mp); /* init args to next argument from caller */ - while (cur_arg != NULL) { - if (mp_init(cur_arg) != MP_OKAY) { - /* Oops - error! Back-track and mp_clear what we already - succeeded in init-ing, then return error. - */ - va_list clean_args; - - /* end the current list */ - va_end(args); - - /* now start cleaning up */ - cur_arg = mp; - va_start(clean_args, mp); - while (n--) { - mp_clear(cur_arg); - cur_arg = va_arg(clean_args, mp_int*); - } - va_end(clean_args); - res = MP_MEM; - break; - } - n++; - cur_arg = va_arg(args, mp_int*); - } - va_end(args); - return res; /* Assumed ok, if error flagged above. */ -} - -void mp_clear_multi(mp_int *mp, ...) -{ - mp_int* next_mp = mp; - va_list args; - va_start(args, mp); - while (next_mp != NULL) { - mp_clear(next_mp); - next_mp = va_arg(args, mp_int*); - } - va_end(args); -} - -/* End: bn_mp_multi.c */ - /* Start: bn_mp_n_root.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4336,7 +4552,7 @@ mp_n_root (mp_int * a, mp_digit b, mp_int * c) } /* if a is negative fudge the sign but keep track */ - neg = a->sign; + neg = a->sign; a->sign = MP_ZPOS; /* t2 = 2 */ @@ -4419,10 +4635,10 @@ __T1:mp_clear (&t1); /* Start: bn_mp_neg.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4441,7 +4657,9 @@ mp_neg (mp_int * a, mp_int * b) if ((res = mp_copy (a, b)) != MP_OKAY) { return res; } - b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; + if (mp_iszero(b) != 1) { + b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; + } return MP_OKAY; } @@ -4450,10 +4668,10 @@ mp_neg (mp_int * a, mp_int * b) /* Start: bn_mp_or.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4499,10 +4717,10 @@ mp_or (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_prime_fermat.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4527,7 +4745,7 @@ mp_prime_fermat (mp_int * a, mp_int * b, int *result) mp_int t; int err; - /* default to fail */ + /* default to composite */ *result = 0; /* ensure b > 1 */ @@ -4560,10 +4778,10 @@ __T:mp_clear (&t); /* Start: bn_mp_prime_is_divisible.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4609,10 +4827,10 @@ mp_prime_is_divisible (mp_int * a, int *result) /* Start: bn_mp_prime_is_prime.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4691,10 +4909,10 @@ __B:mp_clear (&b); /* Start: bn_mp_prime_miller_rabin.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4793,10 +5011,10 @@ __N1:mp_clear (&n1); /* Start: bn_mp_prime_next_prime.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4824,9 +5042,7 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) } /* force positive */ - if (a->sign == MP_NEG) { - a->sign = MP_ZPOS; - } + a->sign = MP_ZPOS; /* simple algo if a is less than the largest prime in the table */ if (mp_cmp_d(a, __prime_tab[PRIME_SIZE-1]) == MP_LT) { @@ -4930,8 +5146,8 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) goto __ERR; } - /* if step == MAX then skip test */ - if (step >= ((((mp_digit)1)<= ((((mp_digit)1)<rmd128.buf + (4 * i)); + } + + /* load state */ + aa = aaa = md->rmd128.state[0]; + bb = bbb = md->rmd128.state[1]; + cc = ccc = md->rmd128.state[2]; + dd = ddd = md->rmd128.state[3]; + + /* round 1 */ + FF(aa, bb, cc, dd, X[ 0], 11); + FF(dd, aa, bb, cc, X[ 1], 14); + FF(cc, dd, aa, bb, X[ 2], 15); + FF(bb, cc, dd, aa, X[ 3], 12); + FF(aa, bb, cc, dd, X[ 4], 5); + FF(dd, aa, bb, cc, X[ 5], 8); + FF(cc, dd, aa, bb, X[ 6], 7); + FF(bb, cc, dd, aa, X[ 7], 9); + FF(aa, bb, cc, dd, X[ 8], 11); + FF(dd, aa, bb, cc, X[ 9], 13); + FF(cc, dd, aa, bb, X[10], 14); + FF(bb, cc, dd, aa, X[11], 15); + FF(aa, bb, cc, dd, X[12], 6); + FF(dd, aa, bb, cc, X[13], 7); + FF(cc, dd, aa, bb, X[14], 9); + FF(bb, cc, dd, aa, X[15], 8); + + /* round 2 */ + GG(aa, bb, cc, dd, X[ 7], 7); + GG(dd, aa, bb, cc, X[ 4], 6); + GG(cc, dd, aa, bb, X[13], 8); + GG(bb, cc, dd, aa, X[ 1], 13); + GG(aa, bb, cc, dd, X[10], 11); + GG(dd, aa, bb, cc, X[ 6], 9); + GG(cc, dd, aa, bb, X[15], 7); + GG(bb, cc, dd, aa, X[ 3], 15); + GG(aa, bb, cc, dd, X[12], 7); + GG(dd, aa, bb, cc, X[ 0], 12); + GG(cc, dd, aa, bb, X[ 9], 15); + GG(bb, cc, dd, aa, X[ 5], 9); + GG(aa, bb, cc, dd, X[ 2], 11); + GG(dd, aa, bb, cc, X[14], 7); + GG(cc, dd, aa, bb, X[11], 13); + GG(bb, cc, dd, aa, X[ 8], 12); + + /* round 3 */ + HH(aa, bb, cc, dd, X[ 3], 11); + HH(dd, aa, bb, cc, X[10], 13); + HH(cc, dd, aa, bb, X[14], 6); + HH(bb, cc, dd, aa, X[ 4], 7); + HH(aa, bb, cc, dd, X[ 9], 14); + HH(dd, aa, bb, cc, X[15], 9); + HH(cc, dd, aa, bb, X[ 8], 13); + HH(bb, cc, dd, aa, X[ 1], 15); + HH(aa, bb, cc, dd, X[ 2], 14); + HH(dd, aa, bb, cc, X[ 7], 8); + HH(cc, dd, aa, bb, X[ 0], 13); + HH(bb, cc, dd, aa, X[ 6], 6); + HH(aa, bb, cc, dd, X[13], 5); + HH(dd, aa, bb, cc, X[11], 12); + HH(cc, dd, aa, bb, X[ 5], 7); + HH(bb, cc, dd, aa, X[12], 5); + + /* round 4 */ + II(aa, bb, cc, dd, X[ 1], 11); + II(dd, aa, bb, cc, X[ 9], 12); + II(cc, dd, aa, bb, X[11], 14); + II(bb, cc, dd, aa, X[10], 15); + II(aa, bb, cc, dd, X[ 0], 14); + II(dd, aa, bb, cc, X[ 8], 15); + II(cc, dd, aa, bb, X[12], 9); + II(bb, cc, dd, aa, X[ 4], 8); + II(aa, bb, cc, dd, X[13], 9); + II(dd, aa, bb, cc, X[ 3], 14); + II(cc, dd, aa, bb, X[ 7], 5); + II(bb, cc, dd, aa, X[15], 6); + II(aa, bb, cc, dd, X[14], 8); + II(dd, aa, bb, cc, X[ 5], 6); + II(cc, dd, aa, bb, X[ 6], 5); + II(bb, cc, dd, aa, X[ 2], 12); + + /* parallel round 1 */ + III(aaa, bbb, ccc, ddd, X[ 5], 8); + III(ddd, aaa, bbb, ccc, X[14], 9); + III(ccc, ddd, aaa, bbb, X[ 7], 9); + III(bbb, ccc, ddd, aaa, X[ 0], 11); + III(aaa, bbb, ccc, ddd, X[ 9], 13); + III(ddd, aaa, bbb, ccc, X[ 2], 15); + III(ccc, ddd, aaa, bbb, X[11], 15); + III(bbb, ccc, ddd, aaa, X[ 4], 5); + III(aaa, bbb, ccc, ddd, X[13], 7); + III(ddd, aaa, bbb, ccc, X[ 6], 7); + III(ccc, ddd, aaa, bbb, X[15], 8); + III(bbb, ccc, ddd, aaa, X[ 8], 11); + III(aaa, bbb, ccc, ddd, X[ 1], 14); + III(ddd, aaa, bbb, ccc, X[10], 14); + III(ccc, ddd, aaa, bbb, X[ 3], 12); + III(bbb, ccc, ddd, aaa, X[12], 6); + + /* parallel round 2 */ + HHH(aaa, bbb, ccc, ddd, X[ 6], 9); + HHH(ddd, aaa, bbb, ccc, X[11], 13); + HHH(ccc, ddd, aaa, bbb, X[ 3], 15); + HHH(bbb, ccc, ddd, aaa, X[ 7], 7); + HHH(aaa, bbb, ccc, ddd, X[ 0], 12); + HHH(ddd, aaa, bbb, ccc, X[13], 8); + HHH(ccc, ddd, aaa, bbb, X[ 5], 9); + HHH(bbb, ccc, ddd, aaa, X[10], 11); + HHH(aaa, bbb, ccc, ddd, X[14], 7); + HHH(ddd, aaa, bbb, ccc, X[15], 7); + HHH(ccc, ddd, aaa, bbb, X[ 8], 12); + HHH(bbb, ccc, ddd, aaa, X[12], 7); + HHH(aaa, bbb, ccc, ddd, X[ 4], 6); + HHH(ddd, aaa, bbb, ccc, X[ 9], 15); + HHH(ccc, ddd, aaa, bbb, X[ 1], 13); + HHH(bbb, ccc, ddd, aaa, X[ 2], 11); + + /* parallel round 3 */ + GGG(aaa, bbb, ccc, ddd, X[15], 9); + GGG(ddd, aaa, bbb, ccc, X[ 5], 7); + GGG(ccc, ddd, aaa, bbb, X[ 1], 15); + GGG(bbb, ccc, ddd, aaa, X[ 3], 11); + GGG(aaa, bbb, ccc, ddd, X[ 7], 8); + GGG(ddd, aaa, bbb, ccc, X[14], 6); + GGG(ccc, ddd, aaa, bbb, X[ 6], 6); + GGG(bbb, ccc, ddd, aaa, X[ 9], 14); + GGG(aaa, bbb, ccc, ddd, X[11], 12); + GGG(ddd, aaa, bbb, ccc, X[ 8], 13); + GGG(ccc, ddd, aaa, bbb, X[12], 5); + GGG(bbb, ccc, ddd, aaa, X[ 2], 14); + GGG(aaa, bbb, ccc, ddd, X[10], 13); + GGG(ddd, aaa, bbb, ccc, X[ 0], 13); + GGG(ccc, ddd, aaa, bbb, X[ 4], 7); + GGG(bbb, ccc, ddd, aaa, X[13], 5); + + /* parallel round 4 */ + FFF(aaa, bbb, ccc, ddd, X[ 8], 15); + FFF(ddd, aaa, bbb, ccc, X[ 6], 5); + FFF(ccc, ddd, aaa, bbb, X[ 4], 8); + FFF(bbb, ccc, ddd, aaa, X[ 1], 11); + FFF(aaa, bbb, ccc, ddd, X[ 3], 14); + FFF(ddd, aaa, bbb, ccc, X[11], 14); + FFF(ccc, ddd, aaa, bbb, X[15], 6); + FFF(bbb, ccc, ddd, aaa, X[ 0], 14); + FFF(aaa, bbb, ccc, ddd, X[ 5], 6); + FFF(ddd, aaa, bbb, ccc, X[12], 9); + FFF(ccc, ddd, aaa, bbb, X[ 2], 12); + FFF(bbb, ccc, ddd, aaa, X[13], 9); + FFF(aaa, bbb, ccc, ddd, X[ 9], 12); + FFF(ddd, aaa, bbb, ccc, X[ 7], 5); + FFF(ccc, ddd, aaa, bbb, X[10], 15); + FFF(bbb, ccc, ddd, aaa, X[14], 8); + + /* combine results */ + ddd += cc + md->rmd128.state[1]; /* final result for MDbuf[0] */ + md->rmd128.state[1] = md->rmd128.state[2] + dd + aaa; + md->rmd128.state[2] = md->rmd128.state[3] + aa + bbb; + md->rmd128.state[3] = md->rmd128.state[0] + bb + ccc; + md->rmd128.state[0] = ddd; +} + +#ifdef CLEAN_STACK +static void rmd128_compress(hash_state *md) +{ + _rmd128_compress(md); + burn_stack(sizeof(unsigned long) * 24 + sizeof(int)); +} +#endif + +void rmd128_init(hash_state * md) +{ + _ARGCHK(md != NULL); + md->rmd128.state[0] = 0x67452301UL; + md->rmd128.state[1] = 0xefcdab89UL; + md->rmd128.state[2] = 0x98badcfeUL; + md->rmd128.state[3] = 0x10325476UL; + md->rmd128.curlen = 0; + md->rmd128.length = 0; +} + +void rmd128_process(hash_state * md, const unsigned char *buf, unsigned long len) +{ + unsigned long n; + _ARGCHK(md != NULL); + _ARGCHK(buf != NULL); + while (len > 0) { + n = MIN(len, (64 - md->rmd128.curlen)); + memcpy(md->rmd128.buf + md->rmd128.curlen, buf, (size_t)n); + md->rmd128.curlen += n; + buf += n; + len -= n; + + /* is 64 bytes full? */ + if (md->rmd128.curlen == 64) { + rmd128_compress(md); + md->rmd128.length += 512; + md->rmd128.curlen = 0; + } + } +} + +void rmd128_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + /* increase the length of the message */ + md->rmd128.length += md->rmd128.curlen * 8; + + /* append the '1' bit */ + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->rmd128.curlen > 56) { + while (md->rmd128.curlen < 64) { + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; + } + rmd128_compress(md); + md->rmd128.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->rmd128.curlen < 56) { + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->rmd128.length, md->rmd128.buf+56); + rmd128_compress(md); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md->rmd128.state[i], hash+(4*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif +} + +int rmd128_test(void) +{ + static const struct { + char *msg; + unsigned char md[16]; + } tests[] = { + { "", + { 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e, + 0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 } + }, + { "a", + { 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7, + 0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 } + }, + { "abc", + { 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba, + 0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 } + }, + { "message digest", + { 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62, + 0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 } + }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5, + 0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f, + 0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 } + } + }; + int x; + unsigned char buf[16]; + hash_state md; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + rmd128_init(&md); + rmd128_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); + rmd128_done(&md, buf); + if (memcmp(buf, tests[x].md, 16) != 0) { + #if 0 + printf("Failed test %d\n", x); + #endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +} + +#endif + diff --git a/rmd160.c b/rmd160.c new file mode 100644 index 0000000..934a239 --- /dev/null +++ b/rmd160.c @@ -0,0 +1,425 @@ +/* Implementation of RIPEMD-160 based on the source by Antoon Bosselaers, ESAT-COSIC + * + * This source has been radically overhauled to be portable and work within + * the LibTomCrypt API by Tom St Denis + */ +#include "mycrypt.h" + +#ifdef RIPEMD160 + +const struct _hash_descriptor rmd160_desc = +{ + "rmd160", + 9, + 20, + 64, + &rmd160_init, + &rmd160_process, + &rmd160_done, + &rmd160_test +}; + +/* the five basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define J(x, y, z) ((x) ^ ((y) | ~(z))) + +/* the ten basic operations FF() through III() */ +#define FF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define GG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define HH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define II(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define JJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define FFF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define GGG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define HHH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define III(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define JJJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + + +#ifdef CLEAN_STACK +static void _rmd160_compress(hash_state *md) +#else +static void rmd160_compress(hash_state *md) +#endif +{ + unsigned long aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16]; + int i; + + /* load words X */ + for (i = 0; i < 16; i++){ + LOAD32L(X[i], md->rmd160.buf + (4 * i)); + } + + /* load state */ + aa = aaa = md->rmd160.state[0]; + bb = bbb = md->rmd160.state[1]; + cc = ccc = md->rmd160.state[2]; + dd = ddd = md->rmd160.state[3]; + ee = eee = md->rmd160.state[4]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, X[ 0], 11); + FF(ee, aa, bb, cc, dd, X[ 1], 14); + FF(dd, ee, aa, bb, cc, X[ 2], 15); + FF(cc, dd, ee, aa, bb, X[ 3], 12); + FF(bb, cc, dd, ee, aa, X[ 4], 5); + FF(aa, bb, cc, dd, ee, X[ 5], 8); + FF(ee, aa, bb, cc, dd, X[ 6], 7); + FF(dd, ee, aa, bb, cc, X[ 7], 9); + FF(cc, dd, ee, aa, bb, X[ 8], 11); + FF(bb, cc, dd, ee, aa, X[ 9], 13); + FF(aa, bb, cc, dd, ee, X[10], 14); + FF(ee, aa, bb, cc, dd, X[11], 15); + FF(dd, ee, aa, bb, cc, X[12], 6); + FF(cc, dd, ee, aa, bb, X[13], 7); + FF(bb, cc, dd, ee, aa, X[14], 9); + FF(aa, bb, cc, dd, ee, X[15], 8); + + /* round 2 */ + GG(ee, aa, bb, cc, dd, X[ 7], 7); + GG(dd, ee, aa, bb, cc, X[ 4], 6); + GG(cc, dd, ee, aa, bb, X[13], 8); + GG(bb, cc, dd, ee, aa, X[ 1], 13); + GG(aa, bb, cc, dd, ee, X[10], 11); + GG(ee, aa, bb, cc, dd, X[ 6], 9); + GG(dd, ee, aa, bb, cc, X[15], 7); + GG(cc, dd, ee, aa, bb, X[ 3], 15); + GG(bb, cc, dd, ee, aa, X[12], 7); + GG(aa, bb, cc, dd, ee, X[ 0], 12); + GG(ee, aa, bb, cc, dd, X[ 9], 15); + GG(dd, ee, aa, bb, cc, X[ 5], 9); + GG(cc, dd, ee, aa, bb, X[ 2], 11); + GG(bb, cc, dd, ee, aa, X[14], 7); + GG(aa, bb, cc, dd, ee, X[11], 13); + GG(ee, aa, bb, cc, dd, X[ 8], 12); + + /* round 3 */ + HH(dd, ee, aa, bb, cc, X[ 3], 11); + HH(cc, dd, ee, aa, bb, X[10], 13); + HH(bb, cc, dd, ee, aa, X[14], 6); + HH(aa, bb, cc, dd, ee, X[ 4], 7); + HH(ee, aa, bb, cc, dd, X[ 9], 14); + HH(dd, ee, aa, bb, cc, X[15], 9); + HH(cc, dd, ee, aa, bb, X[ 8], 13); + HH(bb, cc, dd, ee, aa, X[ 1], 15); + HH(aa, bb, cc, dd, ee, X[ 2], 14); + HH(ee, aa, bb, cc, dd, X[ 7], 8); + HH(dd, ee, aa, bb, cc, X[ 0], 13); + HH(cc, dd, ee, aa, bb, X[ 6], 6); + HH(bb, cc, dd, ee, aa, X[13], 5); + HH(aa, bb, cc, dd, ee, X[11], 12); + HH(ee, aa, bb, cc, dd, X[ 5], 7); + HH(dd, ee, aa, bb, cc, X[12], 5); + + /* round 4 */ + II(cc, dd, ee, aa, bb, X[ 1], 11); + II(bb, cc, dd, ee, aa, X[ 9], 12); + II(aa, bb, cc, dd, ee, X[11], 14); + II(ee, aa, bb, cc, dd, X[10], 15); + II(dd, ee, aa, bb, cc, X[ 0], 14); + II(cc, dd, ee, aa, bb, X[ 8], 15); + II(bb, cc, dd, ee, aa, X[12], 9); + II(aa, bb, cc, dd, ee, X[ 4], 8); + II(ee, aa, bb, cc, dd, X[13], 9); + II(dd, ee, aa, bb, cc, X[ 3], 14); + II(cc, dd, ee, aa, bb, X[ 7], 5); + II(bb, cc, dd, ee, aa, X[15], 6); + II(aa, bb, cc, dd, ee, X[14], 8); + II(ee, aa, bb, cc, dd, X[ 5], 6); + II(dd, ee, aa, bb, cc, X[ 6], 5); + II(cc, dd, ee, aa, bb, X[ 2], 12); + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, X[ 4], 9); + JJ(aa, bb, cc, dd, ee, X[ 0], 15); + JJ(ee, aa, bb, cc, dd, X[ 5], 5); + JJ(dd, ee, aa, bb, cc, X[ 9], 11); + JJ(cc, dd, ee, aa, bb, X[ 7], 6); + JJ(bb, cc, dd, ee, aa, X[12], 8); + JJ(aa, bb, cc, dd, ee, X[ 2], 13); + JJ(ee, aa, bb, cc, dd, X[10], 12); + JJ(dd, ee, aa, bb, cc, X[14], 5); + JJ(cc, dd, ee, aa, bb, X[ 1], 12); + JJ(bb, cc, dd, ee, aa, X[ 3], 13); + JJ(aa, bb, cc, dd, ee, X[ 8], 14); + JJ(ee, aa, bb, cc, dd, X[11], 11); + JJ(dd, ee, aa, bb, cc, X[ 6], 8); + JJ(cc, dd, ee, aa, bb, X[15], 5); + JJ(bb, cc, dd, ee, aa, X[13], 6); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, X[11], 13); + III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, X[13], 8); + III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, X[10], 11); + III(bbb, ccc, ddd, eee, aaa, X[14], 7); + III(aaa, bbb, ccc, ddd, eee, X[15], 7); + III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, X[12], 7); + III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); + + /* combine results */ + ddd += cc + md->rmd160.state[1]; /* final result for md->rmd160.state[0] */ + md->rmd160.state[1] = md->rmd160.state[2] + dd + eee; + md->rmd160.state[2] = md->rmd160.state[3] + ee + aaa; + md->rmd160.state[3] = md->rmd160.state[4] + aa + bbb; + md->rmd160.state[4] = md->rmd160.state[0] + bb + ccc; + md->rmd160.state[0] = ddd; +} + +#ifdef CLEAN_STACK +static void rmd160_compress(hash_state *md) +{ + _rmd160_compress(md); + burn_stack(sizeof(unsigned long) * 26 + sizeof(int)); +} +#endif + +void rmd160_init(hash_state * md) +{ + _ARGCHK(md != NULL); + md->rmd160.state[0] = 0x67452301UL; + md->rmd160.state[1] = 0xefcdab89UL; + md->rmd160.state[2] = 0x98badcfeUL; + md->rmd160.state[3] = 0x10325476UL; + md->rmd160.state[4] = 0xc3d2e1f0UL; + md->rmd160.curlen = 0; + md->rmd160.length = 0; +} + +void rmd160_process(hash_state * md, const unsigned char *buf, unsigned long len) +{ + unsigned long n; + _ARGCHK(md != NULL); + _ARGCHK(buf != NULL); + while (len > 0) { + n = MIN(len, (64 - md->rmd160.curlen)); + memcpy(md->rmd160.buf + md->rmd160.curlen, buf, (size_t)n); + md->rmd160.curlen += n; + buf += n; + len -= n; + + /* is 64 bytes full? */ + if (md->rmd160.curlen == 64) { + rmd160_compress(md); + md->rmd160.length += 512; + md->rmd160.curlen = 0; + } + } +} + +void rmd160_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + /* increase the length of the message */ + md->rmd160.length += md->rmd160.curlen * 8; + + /* append the '1' bit */ + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->rmd160.curlen > 56) { + while (md->rmd160.curlen < 64) { + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0; + } + rmd160_compress(md); + md->rmd160.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->rmd160.curlen < 56) { + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->rmd160.length, md->rmd160.buf+56); + rmd160_compress(md); + + /* copy output */ + for (i = 0; i < 5; i++) { + STORE32L(md->rmd160.state[i], hash+(4*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif +} + +int rmd160_test(void) +{ + static const struct { + char *msg; + unsigned char md[20]; + } tests[] = { + { "", + { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, + 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 } + }, + { "a", + { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, + 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe } + }, + { "abc", + { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, + 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc } + }, + { "message digest", + { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, + 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 } + }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, + 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, + 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b } + } + }; + int x; + unsigned char buf[20]; + hash_state md; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + rmd160_init(&md); + rmd160_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); + rmd160_done(&md, buf); + if (memcmp(buf, tests[x].md, 20) != 0) { +#if 0 + printf("Failed test %d\n", x); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +} + +#endif + diff --git a/tdcal.pdf b/tdcal.pdf deleted file mode 100644 index e4f4b35..0000000 Binary files a/tdcal.pdf and /dev/null differ diff --git a/tommath.h b/tommath.h index e5e166b..069e51c 100644 --- a/tommath.h +++ b/tommath.h @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -82,8 +82,10 @@ extern "C" { typedef ulong64 mp_word; #ifdef MP_31BIT + /* this is an extension that uses 31-bit digits */ #define DIGIT_BIT 31 #else + /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ #define DIGIT_BIT 28 #define MP_28BIT #endif @@ -94,7 +96,6 @@ extern "C" { #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */ #endif - #define MP_DIGIT_BIT DIGIT_BIT #define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) #define MP_DIGIT_MAX MP_MASK @@ -121,7 +122,7 @@ extern int KARATSUBA_MUL_CUTOFF, TOOM_SQR_CUTOFF; /* various build options */ -#define MP_PREC 64 /* default digits of precision (must be power of two) */ +#define MP_PREC 64 /* default digits of precision */ /* define this to use lower memory usage routines (exptmods mostly) */ /* #define MP_LOW_MEM */ @@ -135,11 +136,13 @@ typedef struct { } mp_int; #define USED(m) ((m)->used) -#define DIGIT(m,k) ((m)->dp[k]) +#define DIGIT(m,k) ((m)->dp[(k)]) #define SIGN(m) ((m)->sign) -/* ---> init and deinit bignum functions <--- */ +/* error code to char* string */ +char *mp_error_to_string(int code); +/* ---> init and deinit bignum functions <--- */ /* init a bignum */ int mp_init(mp_int *a); @@ -165,7 +168,6 @@ int mp_grow(mp_int *a, int size); int mp_init_size(mp_int *a, int size); /* ---> Basic Manipulations <--- */ - #define mp_iszero(a) (((a)->used == 0) ? 1 : 0) #define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? 1 : 0) #define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? 1 : 0) @@ -462,5 +464,5 @@ extern const char *mp_s_rmap; } #endif -#endif +#endif /* ?BN_H_ */ diff --git a/yarrow.c b/yarrow.c index ee53a5c..be638f6 100644 --- a/yarrow.c +++ b/yarrow.c @@ -123,7 +123,11 @@ int yarrow_ready(prng_state *prng) return err; } - if ((err = ctr_start(prng->yarrow.cipher, prng->yarrow.pool, prng->yarrow.pool, ks, 0, &prng->yarrow.ctr)) != CRYPT_OK) { + if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */ + prng->yarrow.pool, /* IV */ + prng->yarrow.pool, ks, /* KEY and key size */ + 0, /* number of rounds */ + &prng->yarrow.ctr)) != CRYPT_OK) { return err; } return CRYPT_OK;