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