Line data Source code
1 : /* This is a modified copy of the teeny sha1 library, see NOTICES for 2 : license information. */ 3 : 4 : #include "fd_sha1.h" 5 : 6 : uchar * 7 : fd_sha1_hash( uchar const * data, 8 : ulong data_len, 9 15 : uchar * hash ) { 10 15 : uint W[ 80 ]; 11 15 : uint H[] = { 0x67452301, 12 15 : 0xEFCDAB89, 13 15 : 0x98BADCFE, 14 15 : 0x10325476, 15 15 : 0xC3D2E1F0 }; 16 : 17 15 : ulong data_bits = data_len*8UL; 18 15 : ulong loop_cnt = (data_len+8UL)/64UL + 1; 19 15 : ulong tailbytes = 64UL*loop_cnt-data_len; 20 15 : uchar datatail[ 128 ] = {0}; 21 : 22 : /* Pre-processing of data tail (includes padding to fill out 512-bit 23 : chunk): 24 : Add bit '1' to end of message (big-endian) 25 : Add 64-bit message length in bits at very end (big-endian) */ 26 : 27 15 : datatail[ 0 ] = 0x80; 28 15 : datatail[ tailbytes-8UL ] = (uchar)( data_bits>>56 & 0xFF); 29 15 : datatail[ tailbytes-7UL ] = (uchar)( data_bits>>48 & 0xFF); 30 15 : datatail[ tailbytes-6UL ] = (uchar)( data_bits>>40 & 0xFF); 31 15 : datatail[ tailbytes-5UL ] = (uchar)( data_bits>>32 & 0xFF); 32 15 : datatail[ tailbytes-4UL ] = (uchar)( data_bits>>24 & 0xFF); 33 15 : datatail[ tailbytes-3UL ] = (uchar)( data_bits>>16 & 0xFF); 34 15 : datatail[ tailbytes-2UL ] = (uchar)( data_bits>>8 & 0xFF); 35 15 : datatail[ tailbytes-1UL ] = (uchar)( data_bits>>0 & 0xFF); 36 : 37 15 : uint didx = 0; 38 36 : for( ulong lidx=0UL; lidx<loop_cnt; lidx++ ) { 39 : /* Compute all elements in W */ 40 21 : fd_memset( W, 0U, sizeof(W) ); 41 : 42 : /* Break 512-bit chunk into sixteen 32-bit, big endian words */ 43 357 : for( ulong widx=0UL; widx<=15UL; widx++ ) { 44 336 : int wcount = 24; 45 : 46 : /* Copy byte-per byte from specified buffer */ 47 978 : while( didx<data_len && wcount>=0 ) { 48 642 : W[ widx ] += (((uint)data[ didx ]) << wcount); 49 642 : didx++; 50 642 : wcount -= 8; 51 642 : } 52 : 53 : /* Fill out W with padding as needed */ 54 1038 : while( wcount>=0 ) { 55 702 : W[ widx ] += (((uint)datatail[ didx-data_len ]) << wcount); 56 702 : didx++; 57 702 : wcount -= 8; 58 702 : } 59 336 : } 60 : 61 : /* Extend the sixteen 32-bit words into eighty 32-bit words, with potential optimization from: 62 : "Improving the Performance of the Secure Hash Algorithm (SHA-1)" by Max Locktyukhin */ 63 4704 : #define SHA1ROTATELEFT(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 64 357 : for( ulong widx=16UL; widx<=31UL; widx++) W[ widx ] = SHA1ROTATELEFT( W[ widx-3UL ] ^ W[ widx-8UL ] ^ W[ widx-14UL ] ^ W[ widx-16UL ], 1 ); 65 1029 : for( ulong widx=32UL; widx<=79UL; widx++ ) W[ widx ] = SHA1ROTATELEFT( W[ widx-6UL ] ^ W[ widx-16UL ] ^ W[ widx-28UL ] ^ W[ widx-32UL ], 2 ); 66 : 67 : /* Main loop */ 68 21 : uint a = H[ 0 ]; 69 21 : uint b = H[ 1 ]; 70 21 : uint c = H[ 2 ]; 71 21 : uint d = H[ 3 ]; 72 21 : uint e = H[ 4 ]; 73 : 74 21 : uint f = 0, k = 0; 75 1701 : for( ulong idx=0UL; idx<=79UL; idx++ ) { 76 1680 : if( idx<=19UL ) { 77 420 : f = (b & c) | ((~b) & d); 78 420 : k = 0x5A827999; 79 1260 : } else if( idx>=20UL && idx<=39UL ) { 80 420 : f = b ^ c ^ d; 81 420 : k = 0x6ED9EBA1; 82 840 : } else if( idx>=40UL && idx<=59UL ) { 83 420 : f = (b & c) | (b & d) | (c & d); 84 420 : k = 0x8F1BBCDC; 85 420 : } else if( idx>=60UL && idx<=79UL ) { 86 420 : f = b ^ c ^ d; 87 420 : k = 0xCA62C1D6; 88 420 : } 89 : 90 1680 : uint temp = SHA1ROTATELEFT( a, 5 )+f+e+k+W[ idx ]; 91 1680 : e = d; 92 1680 : d = c; 93 1680 : c = SHA1ROTATELEFT( b, 30 ); 94 1680 : b = a; 95 1680 : a = temp; 96 1680 : } 97 21 : #undef SHA1ROTATELEFT 98 : 99 21 : H[ 0 ] += a; 100 21 : H[ 1 ] += b; 101 21 : H[ 2 ] += c; 102 21 : H[ 3 ] += d; 103 21 : H[ 4 ] += e; 104 : 105 126 : for( ulong idx=0UL; idx<5UL; idx++ ) { 106 105 : hash[ idx*4UL+0UL ] = (uchar)( H[ idx ] >> 24 ); 107 105 : hash[ idx*4UL+1UL ] = (uchar)( H[ idx ] >> 16 ); 108 105 : hash[ idx*4UL+2UL ] = (uchar)( H[ idx ] >> 8 ); 109 105 : hash[ idx*4UL+3UL ] = (uchar)( H[ idx ] ); 110 105 : } 111 21 : } 112 : 113 15 : return hash; 114 15 : }