00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "sha1.hpp"
00029
00030 #include <iomanip>
00031 #include <sstream>
00032
00033 #define sha_rotl(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
00034 #define sha_ch(x,y,z) ( ((x) & (y)) | ((!(x)) & (z)) )
00035 #define sha_parity(x,y,z) ( (x) ^ (y) ^ (z) )
00036 #define sha_maj(x,y,z) ( ((x) & (y)) | ((x) & (z)) | ((y) & (z)) )
00037
00038
00039 std::string sha1_hash::display() {
00040 std::stringstream s;
00041 s << std::hex << std::setfill('0') << std::setw(8) << H0;
00042 s << std::hex << std::setfill('0') << std::setw(8) << H1;
00043 s << std::hex << std::setfill('0') << std::setw(8) << H2;
00044 s << std::hex << std::setfill('0') << std::setw(8) << H3;
00045 s << std::hex << std::setfill('0') << std::setw(8) << H4;
00046 return s.str();
00047 }
00048
00049
00050 sha1_hash::sha1_hash(const std::string& str)
00051 : H0(0x67452301), H1(0xefcdab89), H2(0x98badcfe), H3(0x10325476), H4(0xc3d2e1f0)
00052 {
00053 Uint8 block[64];
00054
00055 int bytes_left = str.size();
00056 Uint32 ssz = bytes_left * 8;
00057
00058 std::stringstream iss (str, std::stringstream::in);
00059
00060 while (bytes_left > 0) {
00061 iss.read(reinterpret_cast<char*>(block), 64);
00062 if (bytes_left <= 64) {
00063 if (bytes_left < 64) {
00064 block[bytes_left]= 0x80;
00065 }
00066 int i;
00067 for (i = 63; i > bytes_left; i--) {
00068 block[i]=0;
00069 }
00070 if (bytes_left < 60) {
00071
00072 block[60] = ssz >> 24;
00073 block[61] = ssz >> 16;
00074 block[62] = ssz >> 8;
00075 block[63] = ssz;
00076 } else {
00077 next(block);
00078
00079 for (i = 0; i < 60 ; i++) {
00080 block[i]=0;
00081 }
00082 if (bytes_left == 64) {
00083 block[0]= 0x80;
00084 }
00085
00086 block[60] = ssz >> 24;
00087 block[61] = ssz >> 16;
00088 block[62] = ssz >> 8;
00089 block[63] = ssz;
00090 }
00091 }
00092 next(block);
00093 bytes_left -= 64;
00094 }
00095 }
00096
00097
00098 void sha1_hash::next(Uint8 block[64]) {
00099 Uint32 W[80];
00100 Uint32 A, B, C, D, E, T;
00101 int i;
00102
00103 A = H0;
00104 B = H1;
00105 C = H2;
00106 D = H3;
00107 E = H4;
00108 for (i = 0; i < 16; i++) {
00109 W[i]= (block[4 * i] << 24) | (block[4 * i + 1] << 16) | (block[4 * i + 2] << 8) | block[4 * i + 3];
00110 }
00111 for (; i < 80; i++) {
00112 W[i]=sha_rotl(1, W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]);
00113 }
00114 for (i = 0; i < 20; i++) {
00115 T = sha_rotl(5,A) + sha_ch(B,C,D) + E + W[i] + 0x5a827999;
00116 E = D;
00117 D = C;
00118 C = sha_rotl(30,B);
00119 B = A;
00120 A = T;
00121 }
00122 for (; i < 40; i++) {
00123 T = sha_rotl(5,A) + sha_parity(B,C,D) + E + W[i] + 0x6ed9eba1;
00124 E = D;
00125 D = C;
00126 C = sha_rotl(30,B);
00127 B = A;
00128 A = T;
00129 }
00130 for (; i < 60; i++) {
00131 T = sha_rotl(5,A) + sha_maj(B,C,D) + E + W[i] + 0x8f1bbcdc;
00132 E = D;
00133 D = C;
00134 C = sha_rotl(30,B);
00135 B = A;
00136 A = T;
00137 }
00138 for (; i < 80; i++) {
00139 T = sha_rotl(5,A) + sha_parity(B,C,D) + E + W[i] + 0xca62c1d6;
00140 E = D;
00141 D = C;
00142 C = sha_rotl(30,B);
00143 B = A;
00144 A = T;
00145 }
00146 H0 += A;
00147 H1 += B;
00148 H2 += C;
00149 H3 += D;
00150 H4 += E;
00151 }