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 0 : uchar * hash ) { 10 0 : uint W[ 80 ]; 11 0 : uint H[] = { 0x67452301, 12 0 : 0xEFCDAB89, 13 0 : 0x98BADCFE, 14 0 : 0x10325476, 15 0 : 0xC3D2E1F0 }; 16 : 17 0 : ulong data_bits = data_len*8UL; 18 0 : ulong loop_cnt = (data_len+8UL)/64UL + 1; 19 0 : ulong tailbytes = 64UL*loop_cnt-data_len; 20 0 : 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 0 : datatail[ 0 ] = 0x80; 28 0 : datatail[ tailbytes-8UL ] = (uchar)( data_bits>>56 & 0xFF); 29 0 : datatail[ tailbytes-7UL ] = (uchar)( data_bits>>48 & 0xFF); 30 0 : datatail[ tailbytes-6UL ] = (uchar)( data_bits>>40 & 0xFF); 31 0 : datatail[ tailbytes-5UL ] = (uchar)( data_bits>>32 & 0xFF); 32 0 : datatail[ tailbytes-4UL ] = (uchar)( data_bits>>24 & 0xFF); 33 0 : datatail[ tailbytes-3UL ] = (uchar)( data_bits>>16 & 0xFF); 34 0 : datatail[ tailbytes-2UL ] = (uchar)( data_bits>>8 & 0xFF); 35 0 : datatail[ tailbytes-1UL ] = (uchar)( data_bits>>0 & 0xFF); 36 : 37 0 : uint didx = 0; 38 0 : for( ulong lidx=0UL; lidx<loop_cnt; lidx++ ) { 39 : /* Compute all elements in W */ 40 0 : fd_memset( W, 0U, sizeof(W) ); 41 : 42 : /* Break 512-bit chunk into sixteen 32-bit, big endian words */ 43 0 : for( ulong widx=0UL; widx<=15UL; widx++ ) { 44 0 : int wcount = 24; 45 : 46 : /* Copy byte-per byte from specified buffer */ 47 0 : while( didx<data_len && wcount>=0 ) { 48 0 : W[ widx ] += (((uint)data[ didx ]) << wcount); 49 0 : didx++; 50 0 : wcount -= 8; 51 0 : } 52 : 53 : /* Fill out W with padding as needed */ 54 0 : while( wcount>=0 ) { 55 0 : W[ widx ] += (((uint)datatail[ didx-data_len ]) << wcount); 56 0 : didx++; 57 0 : wcount -= 8; 58 0 : } 59 0 : } 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 0 : #define SHA1ROTATELEFT(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 64 0 : for( ulong widx=16UL; widx<=31UL; widx++) W[ widx ] = SHA1ROTATELEFT( W[ widx-3UL ] ^ W[ widx-8UL ] ^ W[ widx-14UL ] ^ W[ widx-16UL ], 1 ); 65 0 : 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 0 : uint a = H[ 0 ]; 69 0 : uint b = H[ 1 ]; 70 0 : uint c = H[ 2 ]; 71 0 : uint d = H[ 3 ]; 72 0 : uint e = H[ 4 ]; 73 : 74 0 : uint f = 0, k = 0; 75 0 : for( ulong idx=0UL; idx<=79UL; idx++ ) { 76 0 : if( idx<=19UL ) { 77 0 : f = (b & c) | ((~b) & d); 78 0 : k = 0x5A827999; 79 0 : } else if( idx>=20UL && idx<=39UL ) { 80 0 : f = b ^ c ^ d; 81 0 : k = 0x6ED9EBA1; 82 0 : } else if( idx>=40UL && idx<=59UL ) { 83 0 : f = (b & c) | (b & d) | (c & d); 84 0 : k = 0x8F1BBCDC; 85 0 : } else if( idx>=60UL && idx<=79UL ) { 86 0 : f = b ^ c ^ d; 87 0 : k = 0xCA62C1D6; 88 0 : } 89 : 90 0 : uint temp = SHA1ROTATELEFT( a, 5 )+f+e+k+W[ idx ]; 91 0 : e = d; 92 0 : d = c; 93 0 : c = SHA1ROTATELEFT( b, 30 ); 94 0 : b = a; 95 0 : a = temp; 96 0 : } 97 0 : #undef SHA1ROTATELEFT 98 : 99 0 : H[ 0 ] += a; 100 0 : H[ 1 ] += b; 101 0 : H[ 2 ] += c; 102 0 : H[ 3 ] += d; 103 0 : H[ 4 ] += e; 104 : 105 0 : for( ulong idx=0UL; idx<5UL; idx++ ) { 106 0 : hash[ idx*4UL+0UL ] = (uchar)( H[ idx ] >> 24 ); 107 0 : hash[ idx*4UL+1UL ] = (uchar)( H[ idx ] >> 16 ); 108 0 : hash[ idx*4UL+2UL ] = (uchar)( H[ idx ] >> 8 ); 109 0 : hash[ idx*4UL+3UL ] = (uchar)( H[ idx ] ); 110 0 : } 111 0 : } 112 : 113 0 : return hash; 114 0 : }