49 #define F(X,Y,Z) (((X)&(Y)) | ((~(X))&(Z)))
50 #define G(X,Y,Z) (((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z)))
51 #define H(X,Y,Z) ((X)^(Y)^(Z))
52 #define lshift(x,s) (((x)<<(s)) | ((x)>>(32-(s))))
54 #define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
55 #define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + 0x5A827999,s)
56 #define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + 0x6ED9EBA1,s)
60 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
65 static void rs_mdfour_block(
rs_mdfour_t *md,
void const *p);
81 uint32_t AA, BB, CC, DD;
83 const uint32_t *X = (
const uint32_t *)p;
94 ROUND1(A, B, C, D, 0, 3);
95 ROUND1(D, A, B, C, 1, 7);
96 ROUND1(C, D, A, B, 2, 11);
97 ROUND1(B, C, D, A, 3, 19);
98 ROUND1(A, B, C, D, 4, 3);
99 ROUND1(D, A, B, C, 5, 7);
100 ROUND1(C, D, A, B, 6, 11);
101 ROUND1(B, C, D, A, 7, 19);
102 ROUND1(A, B, C, D, 8, 3);
103 ROUND1(D, A, B, C, 9, 7);
104 ROUND1(C, D, A, B, 10, 11);
105 ROUND1(B, C, D, A, 11, 19);
106 ROUND1(A, B, C, D, 12, 3);
107 ROUND1(D, A, B, C, 13, 7);
108 ROUND1(C, D, A, B, 14, 11);
109 ROUND1(B, C, D, A, 15, 19);
111 ROUND2(A, B, C, D, 0, 3);
112 ROUND2(D, A, B, C, 4, 5);
113 ROUND2(C, D, A, B, 8, 9);
114 ROUND2(B, C, D, A, 12, 13);
115 ROUND2(A, B, C, D, 1, 3);
116 ROUND2(D, A, B, C, 5, 5);
117 ROUND2(C, D, A, B, 9, 9);
118 ROUND2(B, C, D, A, 13, 13);
119 ROUND2(A, B, C, D, 2, 3);
120 ROUND2(D, A, B, C, 6, 5);
121 ROUND2(C, D, A, B, 10, 9);
122 ROUND2(B, C, D, A, 14, 13);
123 ROUND2(A, B, C, D, 3, 3);
124 ROUND2(D, A, B, C, 7, 5);
125 ROUND2(C, D, A, B, 11, 9);
126 ROUND2(B, C, D, A, 15, 13);
128 ROUND3(A, B, C, D, 0, 3);
129 ROUND3(D, A, B, C, 8, 9);
130 ROUND3(C, D, A, B, 4, 11);
131 ROUND3(B, C, D, A, 12, 15);
132 ROUND3(A, B, C, D, 2, 3);
133 ROUND3(D, A, B, C, 10, 9);
134 ROUND3(C, D, A, B, 6, 11);
135 ROUND3(B, C, D, A, 14, 15);
136 ROUND3(A, B, C, D, 1, 3);
137 ROUND3(D, A, B, C, 9, 9);
138 ROUND3(C, D, A, B, 5, 11);
139 ROUND3(B, C, D, A, 13, 15);
140 ROUND3(A, B, C, D, 3, 3);
141 ROUND3(D, A, B, C, 11, 9);
142 ROUND3(C, D, A, B, 7, 11);
143 ROUND3(B, C, D, A, 15, 15);
163 inline static void copy4(
unsigned char *out, uint32_t
const x)
174 inline static void copy8(
unsigned char *out, uint64_t
const x)
188 #ifdef WORDS_BIGENDIAN
189 inline static void copy64( uint32_t *M,
unsigned char const *in)
194 *M++ = (in[3] << 24) | (in[2] << 16) | (in[1] << 8) | in[0];
201 inline static void rs_mdfour_block(
rs_mdfour_t *md,
void const *p)
214 inline static void rs_mdfour_block(
rs_mdfour_t *md,
void const *p)
226 inline static void rs_mdfour_block(
rs_mdfour_t *md,
void const *p)
228 if ((uintptr_t)p & 3) {
231 memcpy(M, p, 16 *
sizeof(uint32_t));
243 memset(md, 0,
sizeof(*md));
251 md->totalN_hi = md->totalN_lo = 0;
269 unsigned char buf[8];
277 b[0] = m->totalN_lo << 3;
278 b[1] = ((m->totalN_hi << 3) | (m->totalN_lo >> 29));
280 copy4(buf + 4, b[1]);
284 pad_len = (m->tail_len < 56) ? (56 - m->tail_len) : (120 - m->tail_len);
292 unsigned char const *in = (
unsigned char const *)in_void;
298 if ((md->totalN_lo += n) < n)
305 size_t tail_gap = 64 - md->tail_len;
307 memcpy(&md->tail[md->tail_len], in, tail_gap);
308 rs_mdfour_block(md, md->tail);
316 rs_mdfour_block(md, in);
322 memcpy(&md->tail[md->tail_len], in, n);
327 void rs_mdfour_result(
rs_mdfour_t *md,
unsigned char *out)
332 copy4(out + 4, md->B);
333 copy4(out + 8, md->C);
334 copy4(out + 12, md->D);
337 void rs_mdfour(
unsigned char *out,
void const *in,
size_t n)
341 rs_mdfour_begin(&md);
343 rs_mdfour_result(&md, out);
Public header for librsync.
struct rs_mdfour rs_mdfour_t
MD4 message-digest accumulator.
static void copy4(unsigned char *out, uint32_t const x)
These next routines are necessary because MD4 is specified in terms of little-endian int32s,...
static void rs_mdfour64(rs_mdfour_t *m, const void *p)
Update an MD4 accumulator from a 64-byte chunk.
static void rs_mdfour_tail(rs_mdfour_t *m)
Handle special behaviour for processing the last block of a file when calculating its MD4 checksum.
static unsigned char PADDING[64]
padding data used for finalising
void rs_mdfour_update(rs_mdfour_t *md, void const *in_void, size_t n)
Feed some data into the MD4 accumulator.