31 return ((x << n) | (x >> (32 - n)));
34 static inline uint32_t
F(uint32_t
x, uint32_t
y, uint32_t z)
36 return ((x & y) | ((~x) & z));
39 static inline uint32_t
G(uint32_t
x, uint32_t
y, uint32_t z)
41 return ((x & z) | (y & (~z)));
44 static inline uint32_t
H(uint32_t
x, uint32_t
y, uint32_t z)
49 static inline uint32_t
I(uint32_t
x, uint32_t
y, uint32_t z)
51 return (y ^ (x | (~z)));
68 LOG(
"md5::process_chunk (A,B,C,D) = (" << AA <<
"," << BB <<
"," << CC <<
"," << DD <<
")");
71 register uint32_t A=AA;
72 register uint32_t B=BB;
73 register uint32_t C=CC;
74 register uint32_t D=
DD;
77 unsigned char* buf =
reinterpret_cast<unsigned char*
>(_buf);
79 #if ARCH_LITTLE_ENDIAN
83 uint32_t* wbuf =
reinterpret_cast<uint32_t*
>(buf);
88 for (
unsigned int i=0, j=0; i <
block_size; i += 4, ++j) {
90 wbuf[j] = buf[i] + (buf[i+1] << 8) + (buf[i+2] << 16) + (buf[i+3] << 24);
98 #define BRA(q,w,e,r,k,s,Ti) \
99 q = w + ( rotate_left( q + FUN(w,e,r) + wbuf[k] + Ti, s) );
103 BRA(A, B, C, D, 0, 7,
T1);
104 BRA(D, A, B, C, 1, 12,
T2);
105 BRA(C, D, A, B, 2, 17,
T3);
106 BRA(B, C, D, A, 3, 22,
T4);
107 BRA(A, B, C, D, 4, 7,
T5);
108 BRA(D, A, B, C, 5, 12,
T6);
109 BRA(C, D, A, B, 6, 17,
T7);
110 BRA(B, C, D, A, 7, 22,
T8);
111 BRA(A, B, C, D, 8, 7,
T9);
112 BRA(D, A, B, C, 9, 12,
T10);
113 BRA(C, D, A, B, 10, 17,
T11);
114 BRA(B, C, D, A, 11, 22,
T12);
115 BRA(A, B, C, D, 12, 7,
T13);
116 BRA(D, A, B, C, 13, 12,
T14);
117 BRA(C, D, A, B, 14, 17,
T15);
118 BRA(B, C, D, A, 15, 22,
T16);
123 BRA(A, B, C, D, 1, 5,
T17);
124 BRA(D, A, B, C, 6, 9,
T18);
125 BRA(C, D, A, B, 11, 14,
T19);
126 BRA(B, C, D, A, 0, 20,
T20);
127 BRA(A, B, C, D, 5, 5,
T21);
128 BRA(D, A, B, C, 10, 9,
T22);
129 BRA(C, D, A, B, 15, 14,
T23);
130 BRA(B, C, D, A, 4, 20,
T24);
131 BRA(A, B, C, D, 9, 5,
T25);
132 BRA(D, A, B, C, 14, 9,
T26);
133 BRA(C, D, A, B, 3, 14,
T27);
134 BRA(B, C, D, A, 8, 20,
T28);
135 BRA(A, B, C, D, 13, 5,
T29);
136 BRA(D, A, B, C, 2, 9,
T30);
137 BRA(C, D, A, B, 7, 14,
T31);
138 BRA(B, C, D, A, 12, 20,
T32);
143 BRA(A, B, C, D, 5, 4,
T33);
144 BRA(D, A, B, C, 8, 11,
T34);
145 BRA(C, D, A, B, 11, 16,
T35);
146 BRA(B, C, D, A, 14, 23,
T36);
147 BRA(A, B, C, D, 1, 4,
T37);
148 BRA(D, A, B, C, 4, 11,
T38);
149 BRA(C, D, A, B, 7, 16,
T39);
150 BRA(B, C, D, A, 10, 23,
T40);
151 BRA(A, B, C, D, 13, 4,
T41);
152 BRA(D, A, B, C, 0, 11,
T42);
153 BRA(C, D, A, B, 3, 16,
T43);
154 BRA(B, C, D, A, 6, 23,
T44);
155 BRA(A, B, C, D, 9, 4,
T45);
156 BRA(D, A, B, C, 12, 11,
T46);
157 BRA(C, D, A, B, 15, 16,
T47);
158 BRA(B, C, D, A, 2, 23,
T48);
163 BRA(A, B, C, D, 0, 6,
T49);
164 BRA(D, A, B, C, 7, 10,
T50);
165 BRA(C, D, A, B, 14, 15,
T51);
166 BRA(B, C, D, A, 5, 21,
T52);
167 BRA(A, B, C, D, 12, 6,
T53);
168 BRA(D, A, B, C, 3, 10,
T54);
169 BRA(C, D, A, B, 10, 15,
T55);
170 BRA(B, C, D, A, 1, 21,
T56);
171 BRA(A, B, C, D, 8, 6,
T57);
172 BRA(D, A, B, C, 15, 10,
T58);
173 BRA(C, D, A, B, 6, 15,
T59);
174 BRA(B, C, D, A, 13, 21,
T60);
175 BRA(A, B, C, D, 4, 6,
T61);
176 BRA(D, A, B, C, 11, 10,
T62);
177 BRA(C, D, A, B, 2, 15,
T63);
178 BRA(B, C, D, A, 9, 21,
T64);
182 LOG(
"\tchunk values (A,B,C,D) = (" << A <<
"," << B <<
"," << C <<
"," << D <<
")");
197 void md5::reset_digest()
199 LOG(
"digest::md5::reset_digest");
200 result.a = 0x67452301;
201 result.b = 0xefcdab89;
202 result.c = 0x98badcfe;
203 result.d = 0x10325476;
206 void md5::calculate_digest()
208 LOG(
"digest::md5::calculate_digest");
218 struct md5::result md5::digest()
220 LOG(
"digest::md5::digest");
225 struct result d = result;
227 const unsigned long int t = taken();
228 const unsigned long int l = length + t;
229 const char* orig = pbase();
234 std::copy(orig, orig + t, b);
240 LOG(
"\ttaken = " << t <<
"\tlen=" << l);
243 unsigned long int ll = l * 8;
245 LOG(
"\tend-b = " << (end - b));
247 for (
int i=0; i < 8; ++i){
248 end[i] = ll & ((1 << 8) - 1);
252 LOG(
"\tprocessing chunks");
253 for(
char* ptr=b; ptr < end; ptr +=
block_size) {
254 LOG(
"\tend-ptr = " << (end - ptr));
260 struct md5::result md5::reset()
262 LOG(
"digest::md5::reset");
263 struct result r = digest();
270 for (
int i=0; i < 4; ++i) {
273 o << (n & ((1 << 8) - 1));
278 std::ostream&
operator<<(std::ostream& o,
const struct md5::result& r)
280 std::ios::fmtflags orig = o.flags();
281 o.setf(std::ios::hex, std::ios::basefield);
debugging/logging support
static uint32_t I(uint32_t x, uint32_t y, uint32_t z)
C++ objects to calculate digests of data.
static void process_chunk(uint32_t &AA, uint32_t &BB, uint32_t &CC, uint32_t &DD, char *_buf)
static void print_hex(std::ostream &o, uint32_t n)
#define BRA(q, w, e, r, k, s, Ti)
static uint32_t G(uint32_t x, uint32_t y, uint32_t z)
static uint32_t F(uint32_t x, uint32_t y, uint32_t z)
static uint32_t rotate_left(uint32_t x, unsigned int n)
std::ostream & operator<<(std::ostream &o, const struct md5::result &m)
static const size_t block_size
static uint32_t H(uint32_t x, uint32_t y, uint32_t z)