sha1.C

Go to the documentation of this file.
00001 /*!@file Util/sha1.C general sha1 (160-bit) message-digest implementation */
00002 
00003 // This code is from http://www.cr0.net:8040/code/crypto/sha1/, also
00004 // under the GPL (see original copyright notice below).
00005 
00006 /*
00007  *  FIPS-180-1 compliant SHA-1 implementation
00008  *
00009  *  Copyright (C) 2001-2003  Christophe Devine
00010  *
00011  *  This program is free software; you can redistribute it and/or
00012  *  modify it under the terms of the GNU General Public License as
00013  *  published by the Free Software Foundation; either version 2 of the
00014  *  License, or (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  *  General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License
00022  *  along with this program; if not, write to the Free Software
00023  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00024  *  02111-1307 USA
00025  */
00026 
00027 //
00028 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu>
00029 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Util/sha1.C $
00030 // $Id: sha1.C 5367 2005-08-22 21:45:50Z rjpeters $
00031 //
00032 
00033 #ifndef UTIL_SHA1_C_DEFINED
00034 #define UTIL_SHA1_C_DEFINED
00035 
00036 #include "Util/sha1.H"
00037 
00038 #include <string.h>
00039 
00040 typedef byte uint8;
00041 
00042 #define GET_UINT32(n,b,i)                       \
00043 {                                               \
00044     (n) = ( (uint32) (b)[(i)    ] << 24 )       \
00045         | ( (uint32) (b)[(i) + 1] << 16 )       \
00046         | ( (uint32) (b)[(i) + 2] <<  8 )       \
00047         | ( (uint32) (b)[(i) + 3]       );      \
00048 }
00049 
00050 #define PUT_UINT32(n,b,i)                       \
00051 {                                               \
00052     (b)[(i)    ] = (uint8) ( (n) >> 24 );       \
00053     (b)[(i) + 1] = (uint8) ( (n) >> 16 );       \
00054     (b)[(i) + 2] = (uint8) ( (n) >>  8 );       \
00055     (b)[(i) + 3] = (uint8) ( (n)       );       \
00056 }
00057 
00058 void sha1_starts( sha1_context *ctx )
00059 {
00060     ctx->total[0] = 0;
00061     ctx->total[1] = 0;
00062 
00063     ctx->state[0] = 0x67452301;
00064     ctx->state[1] = 0xEFCDAB89;
00065     ctx->state[2] = 0x98BADCFE;
00066     ctx->state[3] = 0x10325476;
00067     ctx->state[4] = 0xC3D2E1F0;
00068 }
00069 
00070 void sha1_process( sha1_context *ctx, const uint8 data[64] )
00071 {
00072     uint32 temp, W[16], A, B, C, D, E;
00073 
00074     GET_UINT32( W[0],  data,  0 );
00075     GET_UINT32( W[1],  data,  4 );
00076     GET_UINT32( W[2],  data,  8 );
00077     GET_UINT32( W[3],  data, 12 );
00078     GET_UINT32( W[4],  data, 16 );
00079     GET_UINT32( W[5],  data, 20 );
00080     GET_UINT32( W[6],  data, 24 );
00081     GET_UINT32( W[7],  data, 28 );
00082     GET_UINT32( W[8],  data, 32 );
00083     GET_UINT32( W[9],  data, 36 );
00084     GET_UINT32( W[10], data, 40 );
00085     GET_UINT32( W[11], data, 44 );
00086     GET_UINT32( W[12], data, 48 );
00087     GET_UINT32( W[13], data, 52 );
00088     GET_UINT32( W[14], data, 56 );
00089     GET_UINT32( W[15], data, 60 );
00090 
00091 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
00092 
00093 #define R(t)                                            \
00094 (                                                       \
00095     temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^     \
00096            W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],      \
00097     ( W[t & 0x0F] = S(temp,1) )                         \
00098 )
00099 
00100 #define P(a,b,c,d,e,x)                                  \
00101 {                                                       \
00102     e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \
00103 }
00104 
00105     A = ctx->state[0];
00106     B = ctx->state[1];
00107     C = ctx->state[2];
00108     D = ctx->state[3];
00109     E = ctx->state[4];
00110 
00111 #define F(x,y,z) (z ^ (x & (y ^ z)))
00112 #define K 0x5A827999
00113 
00114     P( A, B, C, D, E, W[0]  );
00115     P( E, A, B, C, D, W[1]  );
00116     P( D, E, A, B, C, W[2]  );
00117     P( C, D, E, A, B, W[3]  );
00118     P( B, C, D, E, A, W[4]  );
00119     P( A, B, C, D, E, W[5]  );
00120     P( E, A, B, C, D, W[6]  );
00121     P( D, E, A, B, C, W[7]  );
00122     P( C, D, E, A, B, W[8]  );
00123     P( B, C, D, E, A, W[9]  );
00124     P( A, B, C, D, E, W[10] );
00125     P( E, A, B, C, D, W[11] );
00126     P( D, E, A, B, C, W[12] );
00127     P( C, D, E, A, B, W[13] );
00128     P( B, C, D, E, A, W[14] );
00129     P( A, B, C, D, E, W[15] );
00130     P( E, A, B, C, D, R(16) );
00131     P( D, E, A, B, C, R(17) );
00132     P( C, D, E, A, B, R(18) );
00133     P( B, C, D, E, A, R(19) );
00134 
00135 #undef K
00136 #undef F
00137 
00138 #define F(x,y,z) (x ^ y ^ z)
00139 #define K 0x6ED9EBA1
00140 
00141     P( A, B, C, D, E, R(20) );
00142     P( E, A, B, C, D, R(21) );
00143     P( D, E, A, B, C, R(22) );
00144     P( C, D, E, A, B, R(23) );
00145     P( B, C, D, E, A, R(24) );
00146     P( A, B, C, D, E, R(25) );
00147     P( E, A, B, C, D, R(26) );
00148     P( D, E, A, B, C, R(27) );
00149     P( C, D, E, A, B, R(28) );
00150     P( B, C, D, E, A, R(29) );
00151     P( A, B, C, D, E, R(30) );
00152     P( E, A, B, C, D, R(31) );
00153     P( D, E, A, B, C, R(32) );
00154     P( C, D, E, A, B, R(33) );
00155     P( B, C, D, E, A, R(34) );
00156     P( A, B, C, D, E, R(35) );
00157     P( E, A, B, C, D, R(36) );
00158     P( D, E, A, B, C, R(37) );
00159     P( C, D, E, A, B, R(38) );
00160     P( B, C, D, E, A, R(39) );
00161 
00162 #undef K
00163 #undef F
00164 
00165 #define F(x,y,z) ((x & y) | (z & (x | y)))
00166 #define K 0x8F1BBCDC
00167 
00168     P( A, B, C, D, E, R(40) );
00169     P( E, A, B, C, D, R(41) );
00170     P( D, E, A, B, C, R(42) );
00171     P( C, D, E, A, B, R(43) );
00172     P( B, C, D, E, A, R(44) );
00173     P( A, B, C, D, E, R(45) );
00174     P( E, A, B, C, D, R(46) );
00175     P( D, E, A, B, C, R(47) );
00176     P( C, D, E, A, B, R(48) );
00177     P( B, C, D, E, A, R(49) );
00178     P( A, B, C, D, E, R(50) );
00179     P( E, A, B, C, D, R(51) );
00180     P( D, E, A, B, C, R(52) );
00181     P( C, D, E, A, B, R(53) );
00182     P( B, C, D, E, A, R(54) );
00183     P( A, B, C, D, E, R(55) );
00184     P( E, A, B, C, D, R(56) );
00185     P( D, E, A, B, C, R(57) );
00186     P( C, D, E, A, B, R(58) );
00187     P( B, C, D, E, A, R(59) );
00188 
00189 #undef K
00190 #undef F
00191 
00192 #define F(x,y,z) (x ^ y ^ z)
00193 #define K 0xCA62C1D6
00194 
00195     P( A, B, C, D, E, R(60) );
00196     P( E, A, B, C, D, R(61) );
00197     P( D, E, A, B, C, R(62) );
00198     P( C, D, E, A, B, R(63) );
00199     P( B, C, D, E, A, R(64) );
00200     P( A, B, C, D, E, R(65) );
00201     P( E, A, B, C, D, R(66) );
00202     P( D, E, A, B, C, R(67) );
00203     P( C, D, E, A, B, R(68) );
00204     P( B, C, D, E, A, R(69) );
00205     P( A, B, C, D, E, R(70) );
00206     P( E, A, B, C, D, R(71) );
00207     P( D, E, A, B, C, R(72) );
00208     P( C, D, E, A, B, R(73) );
00209     P( B, C, D, E, A, R(74) );
00210     P( A, B, C, D, E, R(75) );
00211     P( E, A, B, C, D, R(76) );
00212     P( D, E, A, B, C, R(77) );
00213     P( C, D, E, A, B, R(78) );
00214     P( B, C, D, E, A, R(79) );
00215 
00216 #undef K
00217 #undef F
00218 
00219     ctx->state[0] += A;
00220     ctx->state[1] += B;
00221     ctx->state[2] += C;
00222     ctx->state[3] += D;
00223     ctx->state[4] += E;
00224 }
00225 
00226 void sha1_update( sha1_context *ctx, const uint8 *input, uint32 length )
00227 {
00228     uint32 left, fill;
00229 
00230     if( ! length ) return;
00231 
00232     left = ctx->total[0] & 0x3F;
00233     fill = 64 - left;
00234 
00235     ctx->total[0] += length;
00236     ctx->total[0] &= 0xFFFFFFFF;
00237 
00238     if( ctx->total[0] < length )
00239         ctx->total[1]++;
00240 
00241     if( left && length >= fill )
00242     {
00243         memcpy( (void *) (ctx->buffer + left),
00244                 (void *) input, fill );
00245         sha1_process( ctx, ctx->buffer );
00246         length -= fill;
00247         input  += fill;
00248         left = 0;
00249     }
00250 
00251     while( length >= 64 )
00252     {
00253         sha1_process( ctx, input );
00254         length -= 64;
00255         input  += 64;
00256     }
00257 
00258     if( length )
00259     {
00260         memcpy( (void *) (ctx->buffer + left),
00261                 (void *) input, length );
00262     }
00263 }
00264 
00265 static uint8 sha1_padding[64] =
00266 {
00267  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00268     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00269     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00270     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00271 };
00272 
00273 void sha1_finish( sha1_context *ctx, uint8 digest[20] )
00274 {
00275     uint32 last, padn;
00276     uint32 high, low;
00277     uint8 msglen[8];
00278 
00279     high = ( ctx->total[0] >> 29 )
00280          | ( ctx->total[1] <<  3 );
00281     low  = ( ctx->total[0] <<  3 );
00282 
00283     PUT_UINT32( high, msglen, 0 );
00284     PUT_UINT32( low,  msglen, 4 );
00285 
00286     last = ctx->total[0] & 0x3F;
00287     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
00288 
00289     sha1_update( ctx, sha1_padding, padn );
00290     sha1_update( ctx, msglen, 8 );
00291 
00292     PUT_UINT32( ctx->state[0], digest,  0 );
00293     PUT_UINT32( ctx->state[1], digest,  4 );
00294     PUT_UINT32( ctx->state[2], digest,  8 );
00295     PUT_UINT32( ctx->state[3], digest, 12 );
00296     PUT_UINT32( ctx->state[4], digest, 16 );
00297 }
00298 
00299 // ######################################################################
00300 /* So things look consistent in everyone's emacs... */
00301 /* Local Variables: */
00302 /* indent-tabs-mode: nil */
00303 /* End: */
00304 
00305 #endif // UTIL_SHA1_C_DEFINED
Generated on Sun May 8 08:06:59 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3