File Coverage

_ripemd-160.c
Criterion Covered Total %
statement 199 216 92.1
branch 6 16 37.5
condition n/a
subroutine n/a
pod n/a
total 205 232 88.3


line stmt bran cond sub pod time code
1             /* ripemd-160.c - an implementation of RIPEMD-160 Hash function
2             * based on the original aritcle:
3             * H. Dobbertin, A. Bosselaers, B. Preneel, RIPEMD-160: A strengthened version
4             * of RIPEMD, Lecture Notes in Computer, 1996, V.1039, pp.71-82
5             *
6             * Copyright (c) 2009, Aleksey Kravchenko
7             *
8             * Permission to use, copy, modify, and/or distribute this software for any
9             * purpose with or without fee is hereby granted.
10             *
11             * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12             * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13             * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14             * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15             * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16             * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17             * PERFORMANCE OF THIS SOFTWARE.
18             */
19              
20             #include
21             #include "byte_order.h"
22             #include "ripemd-160.h"
23              
24             /**
25             * Initialize algorithm context before calculating hash.
26             *
27             * @param ctx context to initialize
28             */
29 2           void rhash_ripemd160_init(ripemd160_ctx* ctx)
30             {
31 2           memset(ctx->message, 0, sizeof(ctx->message));
32 2           ctx->length = 0;
33              
34             /* initialize state */
35 2           ctx->hash[0] = 0x67452301;
36 2           ctx->hash[1] = 0xefcdab89;
37 2           ctx->hash[2] = 0x98badcfe;
38 2           ctx->hash[3] = 0x10325476;
39 2           ctx->hash[4] = 0xc3d2e1f0;
40 2           }
41              
42             /* five boolean functions */
43             #define F1(x, y, z) ((x) ^ (y) ^ (z))
44             #define F2(x, y, z) ((((y) ^ (z)) & (x)) ^ (z))
45             #define F3(x, y, z) (((x) | ~(y)) ^ (z))
46             #define F4(x, y, z) ((((x) ^ (y)) & (z)) ^ (y))
47             #define F5(x, y, z) ((x) ^ ((y) | ~(z)))
48              
49             #define RMD_FUNC(FUNC, A, B, C, D, E, X, S, K) \
50             (A) += FUNC((B), (C), (D)) + (X) + K; \
51             (A) = ROTL32((A), (S)) + (E); \
52             (C) = ROTL32((C), 10);
53              
54             /* steps for the left and right half of algorithm */
55             #define L1(A, B, C, D, E, X, S) RMD_FUNC(F1, A, B, C, D, E, X, S, 0)
56             #define L2(A, B, C, D, E, X, S) RMD_FUNC(F2, A, B, C, D, E, X, S, 0x5a827999UL)
57             #define L3(A, B, C, D, E, X, S) RMD_FUNC(F3, A, B, C, D, E, X, S, 0x6ed9eba1UL)
58             #define L4(A, B, C, D, E, X, S) RMD_FUNC(F4, A, B, C, D, E, X, S, 0x8f1bbcdcUL)
59             #define L5(A, B, C, D, E, X, S) RMD_FUNC(F5, A, B, C, D, E, X, S, 0xa953fd4eUL)
60             #define R1(A, B, C, D, E, X, S) RMD_FUNC(F5, A, B, C, D, E, X, S, 0x50a28be6UL)
61             #define R2(A, B, C, D, E, X, S) RMD_FUNC(F4, A, B, C, D, E, X, S, 0x5c4dd124UL)
62             #define R3(A, B, C, D, E, X, S) RMD_FUNC(F3, A, B, C, D, E, X, S, 0x6d703ef3UL)
63             #define R4(A, B, C, D, E, X, S) RMD_FUNC(F2, A, B, C, D, E, X, S, 0x7a6d76e9UL)
64             #define R5(A, B, C, D, E, X, S) RMD_FUNC(F1, A, B, C, D, E, X, S, 0)
65              
66             /**
67             * The core transformation. Process a 512-bit block.
68             *
69             * @param hash algorithm intermediate hash
70             * @param X the message block to process
71             */
72 2           static void rhash_ripemd160_process_block(unsigned* hash, const unsigned* X)
73             {
74 2           register unsigned A = hash[0], B = hash[1], C = hash[2], D = hash[3], E = hash[4];
75 2           register unsigned a1 = hash[0], b1 = hash[1], c1 = hash[2], d1 = hash[3], e1 = hash[4];
76              
77             /* rounds of the left and right half interleaved */
78 2           L1(a1, b1, c1, d1, e1, X[ 0], 11);
79 2           R1(A, B, C, D, E, X[ 5], 8);
80 2           L1(e1, a1, b1, c1, d1, X[ 1], 14);
81 2           R1(E, A, B, C, D, X[14], 9);
82 2           L1(d1, e1, a1, b1, c1, X[ 2], 15);
83 2           R1(D, E, A, B, C, X[ 7], 9);
84 2           L1(c1, d1, e1, a1, b1, X[ 3], 12);
85 2           R1(C, D, E, A, B, X[ 0], 11);
86 2           L1(b1, c1, d1, e1, a1, X[ 4], 5);
87 2           R1(B, C, D, E, A, X[ 9], 13);
88 2           L1(a1, b1, c1, d1, e1, X[ 5], 8);
89 2           R1(A, B, C, D, E, X[ 2], 15);
90 2           L1(e1, a1, b1, c1, d1, X[ 6], 7);
91 2           R1(E, A, B, C, D, X[11], 15);
92 2           L1(d1, e1, a1, b1, c1, X[ 7], 9);
93 2           R1(D, E, A, B, C, X[ 4], 5);
94 2           L1(c1, d1, e1, a1, b1, X[ 8], 11);
95 2           R1(C, D, E, A, B, X[13], 7);
96 2           L1(b1, c1, d1, e1, a1, X[ 9], 13);
97 2           R1(B, C, D, E, A, X[ 6], 7);
98 2           L1(a1, b1, c1, d1, e1, X[10], 14);
99 2           R1(A, B, C, D, E, X[15], 8);
100 2           L1(e1, a1, b1, c1, d1, X[11], 15);
101 2           R1(E, A, B, C, D, X[ 8], 11);
102 2           L1(d1, e1, a1, b1, c1, X[12], 6);
103 2           R1(D, E, A, B, C, X[ 1], 14);
104 2           L1(c1, d1, e1, a1, b1, X[13], 7);
105 2           R1(C, D, E, A, B, X[10], 14);
106 2           L1(b1, c1, d1, e1, a1, X[14], 9);
107 2           R1(B, C, D, E, A, X[ 3], 12);
108 2           L1(a1, b1, c1, d1, e1, X[15], 8);
109 2           R1(A, B, C, D, E, X[12], 6);
110              
111 2           L2(e1, a1, b1, c1, d1, X[ 7], 7);
112 2           R2(E, A, B, C, D, X[ 6], 9);
113 2           L2(d1, e1, a1, b1, c1, X[ 4], 6);
114 2           R2(D, E, A, B, C, X[11], 13);
115 2           L2(c1, d1, e1, a1, b1, X[13], 8);
116 2           R2(C, D, E, A, B, X[ 3], 15);
117 2           L2(b1, c1, d1, e1, a1, X[ 1], 13);
118 2           R2(B, C, D, E, A, X[ 7], 7);
119 2           L2(a1, b1, c1, d1, e1, X[10], 11);
120 2           R2(A, B, C, D, E, X[ 0], 12);
121 2           L2(e1, a1, b1, c1, d1, X[ 6], 9);
122 2           R2(E, A, B, C, D, X[13], 8);
123 2           L2(d1, e1, a1, b1, c1, X[15], 7);
124 2           R2(D, E, A, B, C, X[ 5], 9);
125 2           L2(c1, d1, e1, a1, b1, X[ 3], 15);
126 2           R2(C, D, E, A, B, X[10], 11);
127 2           L2(b1, c1, d1, e1, a1, X[12], 7);
128 2           R2(B, C, D, E, A, X[14], 7);
129 2           L2(a1, b1, c1, d1, e1, X[ 0], 12);
130 2           R2(A, B, C, D, E, X[15], 7);
131 2           L2(e1, a1, b1, c1, d1, X[ 9], 15);
132 2           R2(E, A, B, C, D, X[ 8], 12);
133 2           L2(d1, e1, a1, b1, c1, X[ 5], 9);
134 2           R2(D, E, A, B, C, X[12], 7);
135 2           L2(c1, d1, e1, a1, b1, X[ 2], 11);
136 2           R2(C, D, E, A, B, X[ 4], 6);
137 2           L2(b1, c1, d1, e1, a1, X[14], 7);
138 2           R2(B, C, D, E, A, X[ 9], 15);
139 2           L2(a1, b1, c1, d1, e1, X[11], 13);
140 2           R2(A, B, C, D, E, X[ 1], 13);
141 2           L2(e1, a1, b1, c1, d1, X[ 8], 12);
142 2           R2(E, A, B, C, D, X[ 2], 11);
143              
144 2           L3(d1, e1, a1, b1, c1, X[ 3], 11);
145 2           R3(D, E, A, B, C, X[15], 9);
146 2           L3(c1, d1, e1, a1, b1, X[10], 13);
147 2           R3(C, D, E, A, B, X[ 5], 7);
148 2           L3(b1, c1, d1, e1, a1, X[14], 6);
149 2           R3(B, C, D, E, A, X[ 1], 15);
150 2           L3(a1, b1, c1, d1, e1, X[ 4], 7);
151 2           R3(A, B, C, D, E, X[ 3], 11);
152 2           L3(e1, a1, b1, c1, d1, X[ 9], 14);
153 2           R3(E, A, B, C, D, X[ 7], 8);
154 2           L3(d1, e1, a1, b1, c1, X[15], 9);
155 2           R3(D, E, A, B, C, X[14], 6);
156 2           L3(c1, d1, e1, a1, b1, X[ 8], 13);
157 2           R3(C, D, E, A, B, X[ 6], 6);
158 2           L3(b1, c1, d1, e1, a1, X[ 1], 15);
159 2           R3(B, C, D, E, A, X[ 9], 14);
160 2           L3(a1, b1, c1, d1, e1, X[ 2], 14);
161 2           R3(A, B, C, D, E, X[11], 12);
162 2           L3(e1, a1, b1, c1, d1, X[ 7], 8);
163 2           R3(E, A, B, C, D, X[ 8], 13);
164 2           L3(d1, e1, a1, b1, c1, X[ 0], 13);
165 2           R3(D, E, A, B, C, X[12], 5);
166 2           L3(c1, d1, e1, a1, b1, X[ 6], 6);
167 2           R3(C, D, E, A, B, X[ 2], 14);
168 2           L3(b1, c1, d1, e1, a1, X[13], 5);
169 2           R3(B, C, D, E, A, X[10], 13);
170 2           L3(a1, b1, c1, d1, e1, X[11], 12);
171 2           R3(A, B, C, D, E, X[ 0], 13);
172 2           L3(e1, a1, b1, c1, d1, X[ 5], 7);
173 2           R3(E, A, B, C, D, X[ 4], 7);
174 2           L3(d1, e1, a1, b1, c1, X[12], 5);
175 2           R3(D, E, A, B, C, X[13], 5);
176              
177 2           L4(c1, d1, e1, a1, b1, X[ 1], 11);
178 2           R4(C, D, E, A, B, X[ 8], 15);
179 2           L4(b1, c1, d1, e1, a1, X[ 9], 12);
180 2           R4(B, C, D, E, A, X[ 6], 5);
181 2           L4(a1, b1, c1, d1, e1, X[11], 14);
182 2           R4(A, B, C, D, E, X[ 4], 8);
183 2           L4(e1, a1, b1, c1, d1, X[10], 15);
184 2           R4(E, A, B, C, D, X[ 1], 11);
185 2           L4(d1, e1, a1, b1, c1, X[ 0], 14);
186 2           R4(D, E, A, B, C, X[ 3], 14);
187 2           L4(c1, d1, e1, a1, b1, X[ 8], 15);
188 2           R4(C, D, E, A, B, X[11], 14);
189 2           L4(b1, c1, d1, e1, a1, X[12], 9);
190 2           R4(B, C, D, E, A, X[15], 6);
191 2           L4(a1, b1, c1, d1, e1, X[ 4], 8);
192 2           R4(A, B, C, D, E, X[ 0], 14);
193 2           L4(e1, a1, b1, c1, d1, X[13], 9);
194 2           R4(E, A, B, C, D, X[ 5], 6);
195 2           L4(d1, e1, a1, b1, c1, X[ 3], 14);
196 2           R4(D, E, A, B, C, X[12], 9);
197 2           L4(c1, d1, e1, a1, b1, X[ 7], 5);
198 2           R4(C, D, E, A, B, X[ 2], 12);
199 2           L4(b1, c1, d1, e1, a1, X[15], 6);
200 2           R4(B, C, D, E, A, X[13], 9);
201 2           L4(a1, b1, c1, d1, e1, X[14], 8);
202 2           R4(A, B, C, D, E, X[ 9], 12);
203 2           L4(e1, a1, b1, c1, d1, X[ 5], 6);
204 2           R4(E, A, B, C, D, X[ 7], 5);
205 2           L4(d1, e1, a1, b1, c1, X[ 6], 5);
206 2           R4(D, E, A, B, C, X[10], 15);
207 2           L4(c1, d1, e1, a1, b1, X[ 2], 12);
208 2           R4(C, D, E, A, B, X[14], 8);
209              
210 2           L5(b1, c1, d1, e1, a1, X[ 4], 9);
211 2           R5(B, C, D, E, A, X[12] , 8);
212 2           L5(a1, b1, c1, d1, e1, X[ 0], 15);
213 2           R5(A, B, C, D, E, X[15] , 5);
214 2           L5(e1, a1, b1, c1, d1, X[ 5], 5);
215 2           R5(E, A, B, C, D, X[10] , 12);
216 2           L5(d1, e1, a1, b1, c1, X[ 9], 11);
217 2           R5(D, E, A, B, C, X[ 4] , 9);
218 2           L5(c1, d1, e1, a1, b1, X[ 7], 6);
219 2           R5(C, D, E, A, B, X[ 1] , 12);
220 2           L5(b1, c1, d1, e1, a1, X[12], 8);
221 2           R5(B, C, D, E, A, X[ 5] , 5);
222 2           L5(a1, b1, c1, d1, e1, X[ 2], 13);
223 2           R5(A, B, C, D, E, X[ 8] , 14);
224 2           L5(e1, a1, b1, c1, d1, X[10], 12);
225 2           R5(E, A, B, C, D, X[ 7] , 6);
226 2           L5(d1, e1, a1, b1, c1, X[14], 5);
227 2           R5(D, E, A, B, C, X[ 6] , 8);
228 2           L5(c1, d1, e1, a1, b1, X[ 1], 12);
229 2           R5(C, D, E, A, B, X[ 2] , 13);
230 2           L5(b1, c1, d1, e1, a1, X[ 3], 13);
231 2           R5(B, C, D, E, A, X[13] , 6);
232 2           L5(a1, b1, c1, d1, e1, X[ 8], 14);
233 2           R5(A, B, C, D, E, X[14] , 5);
234 2           L5(e1, a1, b1, c1, d1, X[11], 11);
235 2           R5(E, A, B, C, D, X[ 0] , 15);
236 2           L5(d1, e1, a1, b1, c1, X[ 6], 8);
237 2           R5(D, E, A, B, C, X[ 3] , 13);
238 2           L5(c1, d1, e1, a1, b1, X[15], 5);
239 2           R5(C, D, E, A, B, X[ 9] , 11);
240 2           L5(b1, c1, d1, e1, a1, X[13], 6);
241 2           R5(B, C, D, E, A, X[11] , 11);
242              
243             /* update intermediate hash */
244 2           D += c1 + hash[1];
245 2           hash[1] = hash[2] + d1 + E;
246 2           hash[2] = hash[3] + e1 + A;
247 2           hash[3] = hash[4] + a1 + B;
248 2           hash[4] = hash[0] + b1 + C;
249 2           hash[0] = D;
250 2           }
251              
252             /**
253             * Calculate message hash.
254             * Can be called repeatedly with chunks of the message to be hashed.
255             *
256             * @param ctx the algorithm context containing current hashing state
257             * @param msg message chunk
258             * @param size length of the message chunk
259             */
260 2           void rhash_ripemd160_update(ripemd160_ctx* ctx, const unsigned char* msg, size_t size)
261             {
262 2           unsigned index = (unsigned)ctx->length & 63;
263 2           ctx->length += size;
264              
265             /* fill partial block */
266 2 50         if (index) {
267 0           unsigned left = ripemd160_block_size - index;
268 0           le32_copy(ctx->message, index, msg, (size < left ? size : left));
269 0 0         if (size < left) return;
270              
271             /* process partial block */
272 0           rhash_ripemd160_process_block(ctx->hash, (unsigned*)ctx->message);
273 0           msg += left;
274 0           size -= left;
275             }
276 2 50         while (size >= ripemd160_block_size) {
277             unsigned* aligned_message_block;
278 0 0         if (IS_LITTLE_ENDIAN && IS_ALIGNED_32(msg)) {
279             /* the most common case is processing of an already aligned message
280             on little-endian CPU without copying it */
281 0           aligned_message_block = (unsigned*)msg;
282             } else {
283 0           le32_copy(ctx->message, 0, msg, ripemd160_block_size);
284 0           aligned_message_block = ctx->message;
285             }
286              
287 0           rhash_ripemd160_process_block(ctx->hash, aligned_message_block);
288 0           msg += ripemd160_block_size;
289 0           size -= ripemd160_block_size;
290             }
291 2 50         if (size) {
292             /* save leftovers */
293 2           le32_copy(ctx->message, 0, msg, size);
294             }
295             }
296              
297             /**
298             * Store calculated hash into the given array.
299             *
300             * @param ctx the algorithm context containing current hashing state
301             * @param result calculated hash in binary form
302             */
303 2           void rhash_ripemd160_final(ripemd160_ctx* ctx, unsigned char result[20])
304             {
305 2           unsigned index = ((unsigned)ctx->length & 63) >> 2;
306 2           unsigned shift = ((unsigned)ctx->length & 3) * 8;
307              
308             /* pad message and run for last block */
309              
310             /* append the byte 0x80 to the message */
311 2           ctx->message[index] &= ~(0xFFFFFFFFu << shift);
312 2           ctx->message[index++] ^= 0x80u << shift;
313              
314             /* if no room left in the message to store 64-bit message length */
315 2 50         if (index > 14) {
316             /* then fill the rest with zeros and process it */
317 0 0         while (index < 16) {
318 0           ctx->message[index++] = 0;
319             }
320 0           rhash_ripemd160_process_block(ctx->hash, ctx->message);
321 0           index = 0;
322             }
323 28 100         while (index < 14) {
324 26           ctx->message[index++] = 0;
325             }
326 2           ctx->message[14] = (unsigned)(ctx->length << 3);
327 2           ctx->message[15] = (unsigned)(ctx->length >> 29);
328 2           rhash_ripemd160_process_block(ctx->hash, ctx->message);
329              
330 2           le32_copy(result, 0, &ctx->hash, 20);
331 2           }