home *** CD-ROM | disk | FTP | other *** search
/ ftp.rarlab.com / 2014.05.ftp.rarlab.com.tar / ftp.rarlab.com / rar / unrar_vms_alpha-3.6.5.zip / sha1.cxx < prev    next >
C/C++ Source or Header  |  2006-06-27  |  8KB  |  232 lines

  1. #include "rar.hpp"
  2.  
  3. /*
  4. SHA-1 in C
  5. By Steve Reid <steve@edmweb.com>
  6. 100% Public Domain
  7.  
  8. Test Vectors (from FIPS PUB 180-1)
  9. "abc"
  10.   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
  11. "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
  12.   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
  13. A million repetitions of "a"
  14.   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
  15. */
  16.  
  17. #if !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
  18.   #if defined(_M_IX86) || defined(_M_I86) || defined(__alpha)
  19.     #define LITTLE_ENDIAN
  20.   #else
  21.     #error "LITTLE_ENDIAN or BIG_ENDIAN must be defined"
  22.     #endif
  23. #endif
  24.  
  25. /* #define SHA1HANDSOFF * Copies data before messing with it. */
  26.  
  27. #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
  28.  
  29. /* blk0() and blk() perform the initial expand. */
  30. /* I got the idea of expanding during the round function from SSLeay */
  31. #ifdef LITTLE_ENDIAN
  32. #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
  33.     |(rol(block->l[i],8)&0x00FF00FF))
  34. #else
  35. #define blk0(i) block->l[i]
  36. #endif
  37. #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
  38.     ^block->l[(i+2)&15]^block->l[i&15],1))
  39.  
  40. /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
  41. #define R0(v,w,x,y,z,i) {z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);}
  42. #define R1(v,w,x,y,z,i) {z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);}
  43. #define R2(v,w,x,y,z,i) {z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);}
  44. #define R3(v,w,x,y,z,i) {z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);}
  45. #define R4(v,w,x,y,z,i) {z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);}
  46.  
  47.  
  48. /* Hash a single 512-bit block. This is the core of the algorithm. */
  49.  
  50. void SHA1Transform(uint32 state[5], unsigned char buffer[64], bool handsoff)
  51. {
  52.   uint32 a, b, c, d, e;
  53.   typedef union {
  54.     unsigned char c[64];
  55.     uint32 l[16];
  56. } CHAR64LONG16;
  57. CHAR64LONG16* block;
  58. static unsigned char workspace[64];
  59.     if (handsoff)
  60.     {
  61.       block = (CHAR64LONG16*)workspace;
  62.       memcpy(block, buffer, 64);
  63.     }
  64.     else
  65.       block = (CHAR64LONG16*)buffer;
  66. #ifdef SFX_MODULE
  67.     static int pos[80][5];
  68.     static bool pinit=false;
  69.     if (!pinit)
  70.     {
  71.       for (int I=0,P=0;I<80;I++,P=(P ? P-1:4))
  72.       {
  73.         pos[I][0]=P;
  74.         pos[I][1]=(P+1)%5;
  75.         pos[I][2]=(P+2)%5;
  76.         pos[I][3]=(P+3)%5;
  77.         pos[I][4]=(P+4)%5;
  78.       }
  79.       pinit=true;
  80.     }
  81.     uint32 s[5];
  82.     for (int I=0;I<sizeof(s)/sizeof(s[0]);I++)
  83.       s[I]=state[I];
  84.  
  85.     for (int I=0;I<16;I++)
  86.       R0(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
  87.     for (int I=16;I<20;I++)
  88.       R1(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
  89.     for (int I=20;I<40;I++)
  90.       R2(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
  91.     for (int I=40;I<60;I++)
  92.       R3(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
  93.     for (int I=60;I<80;I++)
  94.       R4(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
  95.  
  96.     for (int I=0;I<sizeof(s)/sizeof(s[0]);I++)
  97.       state[I]+=s[I];
  98. #else
  99.     /* Copy context->state[] to working vars */
  100.     a = state[0];
  101.     b = state[1];
  102.     c = state[2];
  103.     d = state[3];
  104.     e = state[4];
  105.     /* 4 rounds of 20 operations each. Loop unrolled. */
  106.     R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
  107.     R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
  108.     R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
  109.     R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
  110.     R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
  111.     R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
  112.     R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
  113.     R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
  114.     R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
  115.     R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
  116.     R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
  117.     R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
  118.     R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
  119.     R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
  120.     R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
  121.     R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
  122.     R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
  123.     R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
  124.     R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
  125.     R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
  126.     /* Add the working vars back into context.state[] */
  127.     state[0] += a;
  128.     state[1] += b;
  129.     state[2] += c;
  130.     state[3] += d;
  131.     state[4] += e;
  132.  
  133.     /* Wipe variables */
  134.     a = b = c = d = e = 0;
  135.     memset(&a,0,sizeof(a));
  136. #endif
  137. }
  138.  
  139.  
  140. /* Initialize new context */
  141.  
  142. void hash_initial(hash_context* context)
  143. {
  144.     /* SHA1 initialization constants */
  145.     context->state[0] = 0x67452301;
  146.     context->state[1] = 0xEFCDAB89;
  147.     context->state[2] = 0x98BADCFE;
  148.     context->state[3] = 0x10325476;
  149.     context->state[4] = 0xC3D2E1F0;
  150.     context->count[0] = context->count[1] = 0;
  151. }
  152.  
  153.  
  154. /* Run your data through this. */
  155. void hash_process( hash_context * context, unsigned char * data, unsigned len,
  156.                    bool handsoff )
  157. {
  158. unsigned int i, j;
  159. uint blen = ((uint)len)<<3;
  160.  
  161.     j = (context->count[0] >> 3) & 63;
  162.     if ((context->count[0] += blen) < blen ) context->count[1]++;
  163.     context->count[1] += (len >> 29);
  164.     if ((j + len) > 63) {
  165.         memcpy(&context->buffer[j], data, (i = 64-j));
  166.         SHA1Transform(context->state, context->buffer, handsoff);
  167.         for ( ; i + 63 < len; i += 64) {
  168. #ifdef ALLOW_NOT_ALIGNED_INT
  169.             SHA1Transform(context->state, &data[i], handsoff);
  170. #else
  171.             unsigned char buffer[64];
  172.             memcpy(buffer,data+i,sizeof(buffer));
  173.             SHA1Transform(context->state, buffer, handsoff);
  174.             memcpy(data+i,buffer,sizeof(buffer));
  175. #endif
  176. #ifdef BIG_ENDIAN
  177.             if (!handsoff)
  178.             {
  179.               unsigned char *d=data+i;
  180.               for (int k=0;k<64;k+=4)
  181.               {
  182.                 byte b0=d[k],b1=d[k+1];
  183.                 d[k]=d[k+3];
  184.                 d[k+1]=d[k+2];
  185.                 d[k+2]=b1;
  186.                 d[k+3]=b0;
  187.               }
  188.             }
  189. #endif
  190.         }
  191.         j = 0;
  192.     }
  193.     else i = 0;
  194.     if (len > i)
  195.       memcpy(&context->buffer[j], &data[i], len - i);
  196. }
  197.  
  198.  
  199. /* Add padding and return the message digest. */
  200.  
  201. void hash_final( hash_context* context, uint32 digest[5], bool handsoff)
  202. {
  203. uint i, j;
  204. unsigned char finalcount[8];
  205.  
  206.     for (i = 0; i < 8; i++) {
  207.         finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
  208.          >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
  209.     }
  210.     unsigned char ch= (unsigned char)'\200';
  211.     hash_process(context, &ch, 1, handsoff);
  212.     while ((context->count[0] & 504) != 448) {
  213.         ch=0;
  214.         hash_process(context, &ch, 1, handsoff);
  215.     }
  216.     hash_process(context, finalcount, 8, handsoff);  /* Should cause a SHA1Transform() */
  217.     for (i = 0; i < 5; i++) {
  218.         digest[i] = context->state[i] & 0xffffffff;
  219.     }
  220.     /* Wipe variables */
  221.     memset(&i,0,sizeof(i));
  222.     memset(&j,0,sizeof(j));
  223.     memset(context->buffer, 0, 64);
  224.     memset(context->state, 0, 20);
  225.     memset(context->count, 0, 8);
  226.     memset(&finalcount, 0, 8);
  227.     if (handsoff)
  228.       SHA1Transform(context->state, context->buffer, true);
  229. }
  230.  
  231.  
  232.