home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / crypl200.zip / HASH / RIPEMD.C < prev    next >
Text File  |  1996-09-29  |  19KB  |  418 lines

  1. /****************************************************************************
  2. *                                                                            *
  3. *                       RIPEMD-160 Message Digest Algorithm                     *
  4. *                        Copyright Peter Gutmann 1992-1996                    *
  5. *                                                                            *
  6. ****************************************************************************/
  7.  
  8. #include <string.h>
  9. #if defined( INC_ALL )
  10.   #include "crypt.h"
  11.   #include "ripemd.h"
  12. #elif defined( INC_CHILD )
  13.   #include "../crypt.h"
  14.   #include "ripemd.h"
  15. #else
  16.   #include "crypt.h"
  17.   #include "hash/ripemd.h"
  18. #endif /* Compiler-specific includes */
  19.  
  20. /* The RIPEMD-160 f()-functions.  The f1 function can be optimized to save
  21.    one boolean operation each - thanks to Rich Schroeppel
  22.    <rcs@cs.arizona.edu> for discovering this.  The f2 function can be
  23.    optimized to eliminate one boolean operation - thanks for Wei Dai for
  24.    discovering this */
  25.  
  26. #define f1(x,y,z)    ( x ^ y ^ z )                        /* Rounds  0-15 */
  27. /*#define f2(x,y,z)    ( ( x & y ) | ( ~x & z ) )            // Rounds 16-31 */
  28. #define f2(x,y,z)    ( z ^ ( x & ( y ^ z ) ) )            /* Rounds 16-31 */
  29. #define f3(x,y,z)    ( ( x | ~y ) ^ z )                    /* Rounds 32-47 */
  30. /*#define f4(x,y,z)    ( ( x & z ) | ( y & ~z ) )            /* Rounds 48-63 */
  31. #define    f4(x,y,z)    ( y ^ ( z & ( x ^ y ) ) )            /* Rounds 48-63 */
  32. #define f5(x,y,z)    ( x ^ ( y | ~z ) )                    /* Rounds 64-79 */
  33.  
  34. /* The RIPEMD-160 Mysterious Constants */
  35.  
  36. #define K1A        0x00000000UL
  37. #define K1B        0x50A28BE6UL                            /* Rounds  0-15 */
  38. #define K2A        0x5A827999UL
  39. #define K2B     0x5C4DD124UL                            /* Rounds 16-31 */
  40. #define K3A        0x6ED9EBA1UL
  41. #define K3B        0x6D703EF3UL                            /* Rounds 32-47 */
  42. #define K4A        0x8F1BBCDCUL
  43. #define K4B        0x7A6D76E9UL                            /* Rounds 48-63 */
  44. #define K5A        0xA953FD4EUL
  45. #define K5B        0x00000000UL                            /* Rounds 64-79 */
  46.  
  47. /* RIPEMD-160 initial values */
  48.  
  49. #define h0init    0x67452301UL
  50. #define h1init    0xEFCDAB89UL
  51. #define h2init    0x98BADCFEUL
  52. #define h3init    0x10325476UL
  53. #define h4init    0xC3D2E1F0UL
  54.  
  55. /* Note that it may be necessary to add parentheses to these macros if they
  56.    are to be called with expressions as arguments */
  57.  
  58. /* 32-bit rotate left - kludged with shifts */
  59.  
  60. #define ROTL(n,X)  ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
  61.  
  62. /* The prototype RIPE-MD160 sub-round.  The fundamental sub-round is:
  63.  
  64.         a' = ROTL( a + f( b, c, d ) + data + k, s ) + e;
  65.         b' = a;
  66.         c' = ROTL( 10, c );
  67.         d' = c;
  68.         e' = d;
  69.  
  70.    but this is implemented by unrolling the loop 5 times and renaming the
  71.    variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
  72.    This code is then replicated 16 times for each of the 5 functions */
  73.  
  74. #define subRound( a, b, c, d, e, f, s, k, data ) \
  75.     a += f( b, c, d ) + data + k; \
  76.     a = MASK32( ROTL( s, MASK32( a ) ) + e ); \
  77.     c = MASK32( ROTL( 10, c ) )
  78.  
  79. /* Perform the RIPEMD-160 transformation.  This performs a parellel
  80.    transformation of the hX values (hXl and hXr) and then combines the
  81.    results back into hX at the end */
  82.  
  83. void RIPEMD160Transform( LONG *digest, LONG *data )
  84.     {
  85.     LONG h1l, h2l, h3l, h4l, h5l, h1r, h2r, h3r, h4r, h5r;
  86.  
  87.     h1l = h1r = digest[ 0 ];
  88.     h2l = h2r = digest[ 1 ];
  89.     h3l = h3r = digest[ 2 ];
  90.     h4l = h4r = digest[ 3 ];
  91.     h5l = h5r = digest[ 4 ];
  92.  
  93.     subRound( h1l, h2l, h3l, h4l, h5l, f1, 11, K1A, data[  0 ] );
  94.     subRound( h5l, h1l, h2l, h3l, h4l, f1, 14, K1A, data[  1 ] );
  95.     subRound( h4l, h5l, h1l, h2l, h3l, f1, 15, K1A, data[  2 ] );
  96.     subRound( h3l, h4l, h5l, h1l, h2l, f1, 12, K1A, data[  3 ] );
  97.     subRound( h2l, h3l, h4l, h5l, h1l, f1,  5, K1A, data[  4 ] );
  98.     subRound( h1l, h2l, h3l, h4l, h5l, f1,  8, K1A, data[  5 ] );
  99.     subRound( h5l, h1l, h2l, h3l, h4l, f1,  7, K1A, data[  6 ] );
  100.     subRound( h4l, h5l, h1l, h2l, h3l, f1,  9, K1A, data[  7 ] );
  101.     subRound( h3l, h4l, h5l, h1l, h2l, f1, 11, K1A, data[  8 ] );
  102.     subRound( h2l, h3l, h4l, h5l, h1l, f1, 13, K1A, data[  9 ] );
  103.     subRound( h1l, h2l, h3l, h4l, h5l, f1, 14, K1A, data[ 10 ] );
  104.     subRound( h5l, h1l, h2l, h3l, h4l, f1, 15, K1A, data[ 11 ] );
  105.     subRound( h4l, h5l, h1l, h2l, h3l, f1,  6, K1A, data[ 12 ] );
  106.     subRound( h3l, h4l, h5l, h1l, h2l, f1,  7, K1A, data[ 13 ] );
  107.     subRound( h2l, h3l, h4l, h5l, h1l, f1,  9, K1A, data[ 14 ] );
  108.     subRound( h1l, h2l, h3l, h4l, h5l, f1,  8, K1A, data[ 15 ] );
  109.  
  110.     subRound( h5l, h1l, h2l, h3l, h4l, f2,  7, K2A, data[  7 ] );
  111.     subRound( h4l, h5l, h1l, h2l, h3l, f2,  6, K2A, data[  4 ] );
  112.     subRound( h3l, h4l, h5l, h1l, h2l, f2,  8, K2A, data[ 13 ] );
  113.     subRound( h2l, h3l, h4l, h5l, h1l, f2, 13, K2A, data[  1 ] );
  114.     subRound( h1l, h2l, h3l, h4l, h5l, f2, 11, K2A, data[ 10 ] );
  115.     subRound( h5l, h1l, h2l, h3l, h4l, f2,  9, K2A, data[  6 ] );
  116.     subRound( h4l, h5l, h1l, h2l, h3l, f2,  7, K2A, data[ 15 ] );
  117.     subRound( h3l, h4l, h5l, h1l, h2l, f2, 15, K2A, data[  3 ] );
  118.     subRound( h2l, h3l, h4l, h5l, h1l, f2,  7, K2A, data[ 12 ] );
  119.     subRound( h1l, h2l, h3l, h4l, h5l, f2, 12, K2A, data[  0 ] );
  120.     subRound( h5l, h1l, h2l, h3l, h4l, f2, 15, K2A, data[  9 ] );
  121.     subRound( h4l, h5l, h1l, h2l, h3l, f2,  9, K2A, data[  5 ] );
  122.     subRound( h3l, h4l, h5l, h1l, h2l, f2, 11, K2A, data[  2 ] );
  123.     subRound( h2l, h3l, h4l, h5l, h1l, f2,  7, K2A, data[ 14 ] );
  124.     subRound( h1l, h2l, h3l, h4l, h5l, f2, 13, K2A, data[ 11 ] );
  125.     subRound( h5l, h1l, h2l, h3l, h4l, f2, 12, K2A, data[  8 ] );
  126.                                                        
  127.     subRound( h4l, h5l, h1l, h2l, h3l, f3, 11, K3A, data[  3 ] );
  128.     subRound( h3l, h4l, h5l, h1l, h2l, f3, 13, K3A, data[ 10 ] );
  129.     subRound( h2l, h3l, h4l, h5l, h1l, f3,  6, K3A, data[ 14 ] );
  130.     subRound( h1l, h2l, h3l, h4l, h5l, f3,  7, K3A, data[  4 ] );
  131.     subRound( h5l, h1l, h2l, h3l, h4l, f3, 14, K3A, data[  9 ] );
  132.     subRound( h4l, h5l, h1l, h2l, h3l, f3,  9, K3A, data[ 15 ] );
  133.     subRound( h3l, h4l, h5l, h1l, h2l, f3, 13, K3A, data[  8 ] );
  134.     subRound( h2l, h3l, h4l, h5l, h1l, f3, 15, K3A, data[  1 ] );
  135.     subRound( h1l, h2l, h3l, h4l, h5l, f3, 14, K3A, data[  2 ] );
  136.     subRound( h5l, h1l, h2l, h3l, h4l, f3,  8, K3A, data[  7 ] );
  137.     subRound( h4l, h5l, h1l, h2l, h3l, f3, 13, K3A, data[  0 ] );
  138.     subRound( h3l, h4l, h5l, h1l, h2l, f3,  6, K3A, data[  6 ] );
  139.     subRound( h2l, h3l, h4l, h5l, h1l, f3,  5, K3A, data[ 13 ] );
  140.     subRound( h1l, h2l, h3l, h4l, h5l, f3, 12, K3A, data[ 11 ] );
  141.     subRound( h5l, h1l, h2l, h3l, h4l, f3,  7, K3A, data[  5 ] );
  142.     subRound( h4l, h5l, h1l, h2l, h3l, f3,  5, K3A, data[ 12 ] );
  143.  
  144.     subRound( h3l, h4l, h5l, h1l, h2l, f4, 11, K4A, data[  1 ] );
  145.     subRound( h2l, h3l, h4l, h5l, h1l, f4, 12, K4A, data[  9 ] );
  146.     subRound( h1l, h2l, h3l, h4l, h5l, f4, 14, K4A, data[ 11 ] );
  147.     subRound( h5l, h1l, h2l, h3l, h4l, f4, 15, K4A, data[ 10 ] );
  148.     subRound( h4l, h5l, h1l, h2l, h3l, f4, 14, K4A, data[  0 ] );
  149.     subRound( h3l, h4l, h5l, h1l, h2l, f4, 15, K4A, data[  8 ] );
  150.     subRound( h2l, h3l, h4l, h5l, h1l, f4,  9, K4A, data[ 12 ] );
  151.     subRound( h1l, h2l, h3l, h4l, h5l, f4,  8, K4A, data[  4 ] );
  152.     subRound( h5l, h1l, h2l, h3l, h4l, f4,  9, K4A, data[ 13 ] );
  153.     subRound( h4l, h5l, h1l, h2l, h3l, f4, 14, K4A, data[  3 ] );
  154.     subRound( h3l, h4l, h5l, h1l, h2l, f4,  5, K4A, data[  7 ] );
  155.     subRound( h2l, h3l, h4l, h5l, h1l, f4,  6, K4A, data[ 15 ] );
  156.     subRound( h1l, h2l, h3l, h4l, h5l, f4,  8, K4A, data[ 14 ] );
  157.     subRound( h5l, h1l, h2l, h3l, h4l, f4,  6, K4A, data[  5 ] );
  158.     subRound( h4l, h5l, h1l, h2l, h3l, f4,  5, K4A, data[  6 ] );
  159.     subRound( h3l, h4l, h5l, h1l, h2l, f4, 12, K4A, data[  2 ] );
  160.                                                        
  161.     subRound( h2l, h3l, h4l, h5l, h1l, f5,  9, K5A, data[  4 ] );
  162.     subRound( h1l, h2l, h3l, h4l, h5l, f5, 15, K5A, data[  0 ] );
  163.     subRound( h5l, h1l, h2l, h3l, h4l, f5,  5, K5A, data[  5 ] );
  164.     subRound( h4l, h5l, h1l, h2l, h3l, f5, 11, K5A, data[  9 ] );
  165.     subRound( h3l, h4l, h5l, h1l, h2l, f5,  6, K5A, data[  7 ] );
  166.     subRound( h2l, h3l, h4l, h5l, h1l, f5,  8, K5A, data[ 12 ] );
  167.     subRound( h1l, h2l, h3l, h4l, h5l, f5, 13, K5A, data[  2 ] );
  168.     subRound( h5l, h1l, h2l, h3l, h4l, f5, 12, K5A, data[ 10 ] );
  169.     subRound( h4l, h5l, h1l, h2l, h3l, f5,  5, K5A, data[ 14 ] );
  170.     subRound( h3l, h4l, h5l, h1l, h2l, f5, 12, K5A, data[  1 ] );
  171.     subRound( h2l, h3l, h4l, h5l, h1l, f5, 13, K5A, data[  3 ] );
  172.     subRound( h1l, h2l, h3l, h4l, h5l, f5, 14, K5A, data[  8 ] );
  173.     subRound( h5l, h1l, h2l, h3l, h4l, f5, 11, K5A, data[ 11 ] );
  174.     subRound( h4l, h5l, h1l, h2l, h3l, f5,  8, K5A, data[  6 ] );
  175.     subRound( h3l, h4l, h5l, h1l, h2l, f5,  5, K5A, data[ 15 ] );
  176.     subRound( h2l, h3l, h4l, h5l, h1l, f5,  6, K5A, data[ 13 ] );
  177.  
  178.     subRound( h1r, h2r, h3r, h4r, h5r, f5,  8, K1B, data[  5 ] );
  179.     subRound( h5r, h1r, h2r, h3r, h4r, f5,  9, K1B, data[ 14 ] );
  180.     subRound( h4r, h5r, h1r, h2r, h3r, f5,  9, K1B, data[  7 ] );
  181.     subRound( h3r, h4r, h5r, h1r, h2r, f5, 11, K1B, data[  0 ] );
  182.     subRound( h2r, h3r, h4r, h5r, h1r, f5, 13, K1B, data[  9 ] );
  183.     subRound( h1r, h2r, h3r, h4r, h5r, f5, 15, K1B, data[  2 ] );
  184.     subRound( h5r, h1r, h2r, h3r, h4r, f5, 15, K1B, data[ 11 ] );
  185.     subRound( h4r, h5r, h1r, h2r, h3r, f5,  5, K1B, data[  4 ] );
  186.     subRound( h3r, h4r, h5r, h1r, h2r, f5,  7, K1B, data[ 13 ] );
  187.     subRound( h2r, h3r, h4r, h5r, h1r, f5,  7, K1B, data[  6 ] );
  188.     subRound( h1r, h2r, h3r, h4r, h5r, f5,  8, K1B, data[ 15 ] );
  189.     subRound( h5r, h1r, h2r, h3r, h4r, f5, 11, K1B, data[  8 ] );
  190.     subRound( h4r, h5r, h1r, h2r, h3r, f5, 14, K1B, data[  1 ] );
  191.     subRound( h3r, h4r, h5r, h1r, h2r, f5, 14, K1B, data[ 10 ] );
  192.     subRound( h2r, h3r, h4r, h5r, h1r, f5, 12, K1B, data[  3 ] );
  193.     subRound( h1r, h2r, h3r, h4r, h5r, f5,  6, K1B, data[ 12 ] );
  194.  
  195.     subRound( h5r, h1r, h2r, h3r, h4r, f4,  9, K2B, data[  6 ] );
  196.     subRound( h4r, h5r, h1r, h2r, h3r, f4, 13, K2B, data[ 11 ] );
  197.     subRound( h3r, h4r, h5r, h1r, h2r, f4, 15, K2B, data[  3 ] );
  198.     subRound( h2r, h3r, h4r, h5r, h1r, f4,  7, K2B, data[  7 ] );
  199.     subRound( h1r, h2r, h3r, h4r, h5r, f4, 12, K2B, data[  0 ] );
  200.     subRound( h5r, h1r, h2r, h3r, h4r, f4,  8, K2B, data[ 13 ] );
  201.     subRound( h4r, h5r, h1r, h2r, h3r, f4,  9, K2B, data[  5 ] );
  202.     subRound( h3r, h4r, h5r, h1r, h2r, f4, 11, K2B, data[ 10 ] );
  203.     subRound( h2r, h3r, h4r, h5r, h1r, f4,  7, K2B, data[ 14 ] );
  204.     subRound( h1r, h2r, h3r, h4r, h5r, f4,  7, K2B, data[ 15 ] );
  205.     subRound( h5r, h1r, h2r, h3r, h4r, f4, 12, K2B, data[  8 ] );
  206.     subRound( h4r, h5r, h1r, h2r, h3r, f4,  7, K2B, data[ 12 ] );
  207.     subRound( h3r, h4r, h5r, h1r, h2r, f4,  6, K2B, data[  4 ] );
  208.     subRound( h2r, h3r, h4r, h5r, h1r, f4, 15, K2B, data[  9 ] );
  209.     subRound( h1r, h2r, h3r, h4r, h5r, f4, 13, K2B, data[  1 ] );
  210.     subRound( h5r, h1r, h2r, h3r, h4r, f4, 11, K2B, data[  2 ] );
  211.                                                        
  212.     subRound( h4r, h5r, h1r, h2r, h3r, f3,  9, K3B, data[ 15 ] );
  213.     subRound( h3r, h4r, h5r, h1r, h2r, f3,  7, K3B, data[  5 ] );
  214.     subRound( h2r, h3r, h4r, h5r, h1r, f3, 15, K3B, data[  1 ] );
  215.     subRound( h1r, h2r, h3r, h4r, h5r, f3, 11, K3B, data[  3 ] );
  216.     subRound( h5r, h1r, h2r, h3r, h4r, f3,  8, K3B, data[  7 ] );
  217.     subRound( h4r, h5r, h1r, h2r, h3r, f3,  6, K3B, data[ 14 ] );
  218.     subRound( h3r, h4r, h5r, h1r, h2r, f3,  6, K3B, data[  6 ] );
  219.     subRound( h2r, h3r, h4r, h5r, h1r, f3, 14, K3B, data[  9 ] );
  220.     subRound( h1r, h2r, h3r, h4r, h5r, f3, 12, K3B, data[ 11 ] );
  221.     subRound( h5r, h1r, h2r, h3r, h4r, f3, 13, K3B, data[  8 ] );
  222.     subRound( h4r, h5r, h1r, h2r, h3r, f3,  5, K3B, data[ 12 ] );
  223.     subRound( h3r, h4r, h5r, h1r, h2r, f3, 14, K3B, data[  2 ] );
  224.     subRound( h2r, h3r, h4r, h5r, h1r, f3, 13, K3B, data[ 10 ] );
  225.     subRound( h1r, h2r, h3r, h4r, h5r, f3, 13, K3B, data[  0 ] );
  226.     subRound( h5r, h1r, h2r, h3r, h4r, f3,  7, K3B, data[  4 ] );
  227.     subRound( h4r, h5r, h1r, h2r, h3r, f3,  5, K3B, data[ 13 ] );
  228.                                                        
  229.     subRound( h3r, h4r, h5r, h1r, h2r, f2, 15, K4B, data[  8 ] );
  230.     subRound( h2r, h3r, h4r, h5r, h1r, f2,  5, K4B, data[  6 ] );
  231.     subRound( h1r, h2r, h3r, h4r, h5r, f2,  8, K4B, data[  4 ] );
  232.     subRound( h5r, h1r, h2r, h3r, h4r, f2, 11, K4B, data[  1 ] );
  233.     subRound( h4r, h5r, h1r, h2r, h3r, f2, 14, K4B, data[  3 ] );
  234.     subRound( h3r, h4r, h5r, h1r, h2r, f2, 14, K4B, data[ 11 ] );
  235.     subRound( h2r, h3r, h4r, h5r, h1r, f2,  6, K4B, data[ 15 ] );
  236.     subRound( h1r, h2r, h3r, h4r, h5r, f2, 14, K4B, data[  0 ] );
  237.     subRound( h5r, h1r, h2r, h3r, h4r, f2,  6, K4B, data[  5 ] );
  238.     subRound( h4r, h5r, h1r, h2r, h3r, f2,  9, K4B, data[ 12 ] );
  239.     subRound( h3r, h4r, h5r, h1r, h2r, f2, 12, K4B, data[  2 ] );
  240.     subRound( h2r, h3r, h4r, h5r, h1r, f2,  9, K4B, data[ 13 ] );
  241.     subRound( h1r, h2r, h3r, h4r, h5r, f2, 12, K4B, data[  9 ] );
  242.     subRound( h5r, h1r, h2r, h3r, h4r, f2,  5, K4B, data[  7 ] );
  243.     subRound( h4r, h5r, h1r, h2r, h3r, f2, 15, K4B, data[ 10 ] );
  244.     subRound( h3r, h4r, h5r, h1r, h2r, f2,  8, K4B, data[ 14 ] );
  245.                                                        
  246.     subRound( h2r, h3r, h4r, h5r, h1r, f1,  8, K5B, data[ 12 ] );
  247.     subRound( h1r, h2r, h3r, h4r, h5r, f1,  5, K5B, data[ 15 ] );
  248.     subRound( h5r, h1r, h2r, h3r, h4r, f1, 12, K5B, data[ 10 ] );
  249.     subRound( h4r, h5r, h1r, h2r, h3r, f1,  9, K5B, data[  4 ] );
  250.     subRound( h3r, h4r, h5r, h1r, h2r, f1, 12, K5B, data[  1 ] );
  251.     subRound( h2r, h3r, h4r, h5r, h1r, f1,  5, K5B, data[  5 ] );
  252.     subRound( h1r, h2r, h3r, h4r, h5r, f1, 14, K5B, data[  8 ] );
  253.     subRound( h5r, h1r, h2r, h3r, h4r, f1,  6, K5B, data[  7 ] );
  254.     subRound( h4r, h5r, h1r, h2r, h3r, f1,  8, K5B, data[  6 ] );
  255.     subRound( h3r, h4r, h5r, h1r, h2r, f1, 13, K5B, data[  2 ] );
  256.     subRound( h2r, h3r, h4r, h5r, h1r, f1,  6, K5B, data[ 13 ] );
  257.     subRound( h1r, h2r, h3r, h4r, h5r, f1,  5, K5B, data[ 14 ] );
  258.     subRound( h5r, h1r, h2r, h3r, h4r, f1, 15, K5B, data[  0 ] );
  259.     subRound( h4r, h5r, h1r, h2r, h3r, f1, 13, K5B, data[  3 ] );
  260.     subRound( h3r, h4r, h5r, h1r, h2r, f1, 11, K5B, data[  9 ] );
  261.     subRound( h2r, h3r, h4r, h5r, h1r, f1, 11, K5B, data[ 11 ] );
  262.  
  263.     h3l = digest[ 1 ] + h3l + h4r;
  264.     digest[ 1 ] = MASK32( digest[ 2 ] + h4l + h5r );
  265.     digest[ 2 ] = MASK32( digest[ 3 ] + h5l + h1r );
  266.     digest[ 3 ] = MASK32( digest[ 4 ] + h1l + h2r );
  267.     digest[ 4 ] = MASK32( digest[ 0 ] + h2l + h3r );
  268.     digest[ 0 ] = MASK32( h3l );
  269.     }
  270.  
  271. /****************************************************************************
  272. *                                                                            *
  273. *                        RIPEMD-160 Support Routines                            *
  274. *                                                                            *
  275. ****************************************************************************/
  276.  
  277. /* Initialize the RIPEMD160 values */
  278.  
  279. void ripemd160Initial( RIPEMD160_INFO *ripemd160Info )
  280.     {
  281.     /* Clear all fields */
  282.     memset( ripemd160Info, 0, sizeof( RIPEMD160_INFO ) );
  283.  
  284.     /* Set the h-vars to their initial values */
  285.     ripemd160Info->digest[ 0 ] = h0init;
  286.     ripemd160Info->digest[ 1 ] = h1init;
  287.     ripemd160Info->digest[ 2 ] = h2init;
  288.     ripemd160Info->digest[ 3 ] = h3init;
  289.     ripemd160Info->digest[ 4 ] = h4init;
  290.     }
  291.  
  292. /* Update RIPEMD160 for a block of data */
  293.  
  294. void ripemd160Update( RIPEMD160_INFO *ripemd160Info, BYTE *buffer, int count )
  295.     {
  296.     LONG tmp;
  297.     int dataCount;
  298.  
  299.     /* Update bitcount */
  300.     tmp = ripemd160Info->countLo;
  301.     if ( ( ripemd160Info->countLo = tmp + ( ( LONG ) count << 3 ) ) < tmp )
  302.         ripemd160Info->countHi++;                /* Carry from low to high */
  303.     ripemd160Info->countHi += count >> 29;
  304.  
  305.     /* Get count of bytes already in data */
  306.     dataCount = ( int ) ( tmp >> 3 ) & 0x3F;
  307.  
  308.     /* Handle any leading odd-sized chunks */
  309.     if( dataCount )
  310.         {
  311. #ifdef _BIG_WORDS
  312.         BYTE *p = ripemd160Info->dataBuffer + dataCount;
  313. #else
  314.         BYTE *p = ( BYTE * ) ripemd160Info->data + dataCount;
  315. #endif /* _BIG_WORDS */
  316.  
  317.         dataCount = RIPEMD160_DATASIZE - dataCount;
  318.         if( count < dataCount )
  319.             {
  320.             memcpy( p, buffer, count );
  321.             return;
  322.             }
  323.         memcpy( p, buffer, dataCount );
  324. #ifdef _BIG_WORDS
  325.         copyToLLong( ripemd160Info->data, ripemd160Info->dataBuffer, RIPEMD160_DATASIZE );
  326. #else
  327.         littleToBigLong( ripemd160Info->data, RIPEMD160_DATASIZE );
  328. #endif /* _BIG_WORDS */
  329.         RIPEMD160Transform( ripemd160Info->digest, ripemd160Info->data );
  330.         buffer += dataCount;
  331.         count -= dataCount;
  332.         }
  333.  
  334.     /* Process data in RIPEMD160_DATASIZE chunks */
  335.     while( count >= RIPEMD160_DATASIZE )
  336.         {
  337. #ifdef _BIG_WORDS
  338.         memcpy( ripemd160Info->dataBuffer, buffer, RIPEMD160_DATASIZE );
  339.         copyToLLong( ripemd160Info->data, ripemd160Info->dataBuffer, RIPEMD160_DATASIZE );
  340. #else
  341.         memcpy( ripemd160Info->data, buffer, RIPEMD160_DATASIZE );
  342.         littleToBigLong( ripemd160Info->data, RIPEMD160_DATASIZE );
  343. #endif /* _BIG_WORDS */
  344.         RIPEMD160Transform( ripemd160Info->digest, ripemd160Info->data );
  345.         buffer += RIPEMD160_DATASIZE;
  346.         count -= RIPEMD160_DATASIZE;
  347.         }
  348.  
  349.     /* Handle any remaining bytes of data. */
  350. #ifdef _BIG_WORDS
  351.     memcpy( ripemd160Info->dataBuffer, buffer, count );
  352. #else
  353.     memcpy( ripemd160Info->data, buffer, count );
  354. #endif /* _BIG_WORDS */
  355.     }
  356.  
  357. /* Final wrapup - pad to RIPEMD160_DATASIZE-byte boundary with the bit
  358.    pattern 1 0* (64-bit count of bits processed, MSB-first) */
  359.  
  360. void ripemd160Final( RIPEMD160_INFO *ripemd160Info )
  361.     {
  362.     int count;
  363.     BYTE *dataPtr;
  364.  
  365.     /* Compute number of bytes mod 64 */
  366.     count = ( int ) ripemd160Info->countLo;
  367.     count = ( count >> 3 ) & 0x3F;
  368.  
  369.     /* Set the first char of padding to 0x80.  This is safe since there is
  370.        always at least one byte free */
  371. #ifdef _BIG_WORDS
  372.     dataPtr = ripemd160Info->dataBuffer + count;
  373. #else
  374.     dataPtr = ( BYTE * ) ripemd160Info->data + count;
  375. #endif /* _BIG_WORDS */
  376.     *dataPtr++ = 0x80;
  377.  
  378.     /* Bytes of padding needed to make 64 bytes */
  379.     count = RIPEMD160_DATASIZE - 1 - count;
  380.  
  381.     /* Pad out to 56 mod 64 */
  382.     if( count < 8 )
  383.         {
  384.         /* Two lots of padding:  Pad the first block to 64 bytes */
  385.         memset( dataPtr, 0, count );
  386. #ifdef _BIG_WORDS
  387.         copyToLLong( ripemd160Info->data, ripemd160Info->dataBuffer, RIPEMD160_DATASIZE );
  388. #else
  389.         littleToBigLong( ripemd160Info->data, RIPEMD160_DATASIZE );
  390. #endif /* _BIG_WORDS */
  391.         RIPEMD160Transform( ripemd160Info->digest, ripemd160Info->data );
  392.  
  393.         /* Now fill the next block with 56 bytes */
  394. #ifdef _BIG_WORDS
  395.         memset( ripemd160Info->dataBuffer, 0, RIPEMD160_DATASIZE - 8 );
  396. #else
  397.         memset( ripemd160Info->data, 0, RIPEMD160_DATASIZE - 8 );
  398. #endif /* _BIG_WORDS */
  399.         }
  400.     else
  401.         /* Pad block to 56 bytes */
  402.         memset( dataPtr, 0, count - 8 );
  403. #ifdef _BIG_WORDS
  404.     copyToLLong( ripemd160Info->data, ripemd160Info->dataBuffer, RIPEMD160_DATASIZE );
  405. #endif /* _BIG_WORDS */
  406.  
  407.     /* Append length in bits and transform */
  408.     ripemd160Info->data[ 14 ] = ripemd160Info->countLo;
  409.     ripemd160Info->data[ 15 ] = ripemd160Info->countHi;
  410.  
  411. #ifndef _BIG_WORDS
  412.     littleToBigLong( ripemd160Info->data, RIPEMD160_DATASIZE - 8 );
  413. #endif /* _BIG_WORDS */
  414.     RIPEMD160Transform( ripemd160Info->digest, ripemd160Info->data );
  415.  
  416.     ripemd160Info->done = TRUE;
  417.     }
  418.