Browse Source

added libtomcrypt-0.90

Tom St Denis 22 years ago
parent
commit
16100c38eb
24 changed files with 1314 additions and 295 deletions
  1. 28 0
      changes
  2. 4 2
      config.pl
  3. 3 0
      crypt.c
  4. BIN
      crypt.pdf
  5. 19 17
      crypt.tex
  6. 17 6
      demos/test.c
  7. 3 0
      demos/x86_prof.c
  8. 64 64
      dh.c
  9. 1 1
      ecc.c
  10. 2 2
      hash.c
  11. 14 15
      hmac.c
  12. 0 53
      legal.txt
  13. 6 6
      makefile
  14. 1 1
      makefile.msvc
  15. 281 112
      mpi.c
  16. 2 2
      mycrypt.h
  17. 5 4
      mycrypt_custom.h
  18. 40 1
      mycrypt_hash.h
  19. 18 0
      mycrypt_macros.h
  20. 366 0
      rmd128.c
  21. 425 0
      rmd160.c
  22. BIN
      tdcal.pdf
  23. 10 8
      tommath.h
  24. 5 1
      yarrow.c

+ 28 - 0
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!]

+ 4 - 2
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",

+ 3 - 0
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)

BIN
crypt.pdf


+ 19 - 17
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 ([email protected]) 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 ([email protected]) 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 ([email protected]) 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;

+ 17 - 6
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 ();

+ 3 - 0
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
 
 }
 

+ 64 - 64
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
 {

+ 1 - 1
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);
 

+ 2 - 2
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;

+ 14 - 15
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;
    }
 

+ 0 - 53
legal.txt

@@ -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 :  [email protected]
-Disclaimer:  None
-Status:  TDCAL submission by Dobes, modified [not original]
-
-MD4.C
------
-Author:  Dobes Vandermeer
-Email : [email protected]
-Disclaimer:  None
-Status:  TDCAL submission by Dobes, modified [not original]
-
-HMAC.C
-------
-Author:  Dobes Vandermeer
-Email: [email protected]
-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:  [email protected]
-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 ([email protected])
-*                 Signal and Information Processing Laboratory
-*                 Swiss Federal Institute of Technology
-*                 CH-8092 Zuerich, Switzerland
-----
-Email: [email protected]
-Disclaimer:  Appears to be Public Domain [not quite sure]
-Status: Public Domain, modified [not original]

+ 6 - 6
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)

+ 1 - 1
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)

File diff suppressed because it is too large
+ 281 - 112
mpi.c


+ 2 - 2
mycrypt.h

@@ -16,8 +16,8 @@ extern "C" {
 #endif
 
 /* version */
-#define CRYPT   0x0089
-#define SCRYPT  "0.89"
+#define CRYPT   0x0090
+#define SCRYPT  "0.90"
 
 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
 #define MAXBLOCKSIZE           128

+ 5 - 4
mycrypt_custom.h

@@ -6,7 +6,7 @@
 #define MYCRYPT_CUSTOM_H_
 
 #ifdef CRYPT
-    #error mycrypt_custom.h should be included before mycrypt.h
+	#error mycrypt_custom.h should be included before mycrypt.h
 #endif
 
 #define XMALLOC malloc
@@ -15,8 +15,8 @@
 #define XFREE free
 #define XCLOCK clock
 #define XCLOCKS_PER_SEC CLOCKS_PER_SEC
-#define LTC_TEST
 #define SMALL_CODE
+#define LTC_TEST
 #define BLOWFISH
 #define RC2
 #define RC5
@@ -24,9 +24,9 @@
 #define SAFERP
 #define SAFER
 #define RIJNDAEL
-#define SERPENT
 #define XTEA
 #define TWOFISH
+#define TWOFISH_TABLES
 #define DES
 #define CAST5
 #define NOEKEON
@@ -43,6 +43,8 @@
 #define MD5
 #define MD4
 #define MD2
+#define RIPEMD128
+#define RIPEMD160
 #define HMAC
 #define BASE64
 #define YARROW
@@ -52,7 +54,6 @@
 #define MRSA
 #define MDH
 #define MECC
-#define KR
 #define DH768
 #define DH1024
 #define DH1280

+ 40 - 1
mycrypt_hash.h

@@ -54,6 +54,22 @@ struct md2_state {
 };
 #endif
 
+#ifdef RIPEMD128
+struct rmd128_state {
+    ulong64 length;
+    unsigned char buf[64];
+    unsigned long curlen, state[4];
+};
+#endif
+
+#ifdef RIPEMD160
+struct rmd160_state {
+    ulong64 length;
+    unsigned char buf[64];
+    unsigned long curlen, state[5];
+};
+#endif
+
 typedef union Hash_state {
 #ifdef SHA512
     struct sha512_state sha512;
@@ -76,6 +92,12 @@ typedef union Hash_state {
 #ifdef TIGER
     struct tiger_state  tiger;
 #endif
+#ifdef RIPEMD128
+    struct rmd128_state rmd128;
+#endif
+#ifdef RIPEMD160
+    struct rmd160_state rmd160;
+#endif
 } hash_state;
 
 extern struct _hash_descriptor {
@@ -153,6 +175,23 @@ extern int  tiger_test(void);
 extern const struct _hash_descriptor tiger_desc;
 #endif
 
+#ifdef RIPEMD128
+extern void rmd128_init(hash_state * md);
+extern void rmd128_process(hash_state * md, const unsigned char *buf, unsigned long len);
+extern void rmd128_done(hash_state * md, unsigned char *hash);
+extern int  rmd128_test(void);
+extern const struct _hash_descriptor rmd128_desc;
+#endif
+
+#ifdef RIPEMD160
+extern void rmd160_init(hash_state * md);
+extern void rmd160_process(hash_state * md, const unsigned char *buf, unsigned long len);
+extern void rmd160_done(hash_state * md, unsigned char *hash);
+extern int  rmd160_test(void);
+extern const struct _hash_descriptor rmd160_desc;
+#endif
+
+
 extern int find_hash(const char *name);
 extern int find_hash_id(unsigned char ID);
 extern int register_hash(const struct _hash_descriptor *hash);
@@ -174,7 +213,7 @@ typedef struct Hmac_state {
 
 extern int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen);
 extern int hmac_process(hmac_state *hmac, const unsigned char *buf, unsigned long len);
-extern int hmac_done(hmac_state *hmac, unsigned char *hash);
+extern int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen);
 extern int hmac_test(void);
 extern int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
                        const unsigned char *data, unsigned long len, 

+ 18 - 0
mycrypt_macros.h

@@ -194,6 +194,24 @@ typedef unsigned long ulong32;
 #define ROR(x,n) _lrotr(x,n)
 #define ROL(x,n) _lrotl(x,n)
 
+#elif defined(__GNUC__) && defined(__i386__)
+
+static inline unsigned long ROL(unsigned long word, int i)
+{
+	__asm__("roll %%cl,%0"
+		:"=r" (word)
+		:"0" (word),"c" (i));
+	return word;
+}
+
+static inline unsigned long ROR(unsigned long word, int i)
+{
+	__asm__("rorl %%cl,%0"
+		:"=r" (word)
+		:"0" (word),"c" (i));
+	return word;
+}
+
 #else
 
 /* rotates the hard way */

+ 366 - 0
rmd128.c

@@ -0,0 +1,366 @@
+/* Implementation of RIPEMD-128 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 RIPEMD128
+
+const struct _hash_descriptor rmd128_desc =
+{
+    "rmd128",
+    8,
+    16,
+    64,
+    &rmd128_init,
+    &rmd128_process,
+    &rmd128_done,
+    &rmd128_test
+};
+
+/* the four 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))) 
+  
+/* the eight basic operations FF() through III() */
+#define FF(a, b, c, d, x, s)        \
+      (a) += F((b), (c), (d)) + (x);\
+      (a) = ROL((a), (s));
+
+#define GG(a, b, c, d, x, s)        \
+      (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
+      (a) = ROL((a), (s));
+
+#define HH(a, b, c, d, x, s)        \
+      (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
+      (a) = ROL((a), (s));
+
+#define II(a, b, c, d, x, s)        \
+      (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
+      (a) = ROL((a), (s));
+
+#define FFF(a, b, c, d, x, s)        \
+      (a) += F((b), (c), (d)) + (x);\
+      (a) = ROL((a), (s));
+
+#define GGG(a, b, c, d, x, s)        \
+      (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\
+      (a) = ROL((a), (s));
+
+#define HHH(a, b, c, d, x, s)        \
+      (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\
+      (a) = ROL((a), (s));
+
+#define III(a, b, c, d, x, s)        \
+      (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\
+      (a) = ROL((a), (s));
+
+#ifdef CLEAN_STACK
+static void _rmd128_compress(hash_state *md)
+#else
+static void rmd128_compress(hash_state *md)
+#endif
+{
+   unsigned long aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16];
+   int i;
+
+   /* load words X */
+   for (i = 0; i < 16; i++){
+      LOAD32L(X[i], md->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
+

+ 425 - 0
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
+

BIN
tdcal.pdf


+ 10 - 8
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_ */
 

+ 5 - 1
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;

Some files were not shown because too many files changed in this diff