25 #include "exceptions.h"
30 #define RIPEMD_BLOCK_SIZE 64
32 const cx_hash_info_t cx_ripemd160_info
36 sizeof(cx_ripemd160_t),
37 (cx_err_t(*)(cx_hash_t * ctx)) cx_ripemd160_init_no_throw,
38 (cx_err_t(*)(cx_hash_t * ctx,
const uint8_t *data,
size_t len)) cx_ripemd160_update,
39 (cx_err_t(*)(cx_hash_t * ctx,
uint8_t *digest)) cx_ripemd160_final,
48 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
49 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
50 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
51 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
52 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13,
56 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
57 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
58 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
59 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
60 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11,
65 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
66 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
67 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
68 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
69 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6,
73 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
74 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
75 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
76 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
77 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11,
80 static const uint32_t hzero[]
81 = {0x67452301UL, 0xEFCDAB89UL, 0x98BADCFEUL, 0x10325476UL, 0xC3D2E1F0UL};
84 #define kL_0_15 0x00000000UL
85 #define kL_16_31 0x5A827999UL
86 #define kL_32_47 0x6ED9EBA1UL
87 #define kL_48_63 0x8F1BBCDCUL
88 #define kL_64_78 0xA953FD4EUL
90 #define kR_0_15 0x50A28BE6UL
91 #define kR_16_31 0x5C4DD124UL
92 #define kR_32_47 0x6D703EF3UL
93 #define kR_48_63 0x7A6D76E9UL
94 #define kR_64_78 0x00000000UL
99 static unsigned long int f1(uint32_t *BCD)
101 return ((x) ^ (y) ^ (z));
103 static unsigned long int f2(uint32_t *BCD)
105 return (((x) & (y)) | ((~x) & (z)));
107 static unsigned long int f3(uint32_t *BCD)
109 return (((x) | (~(y))) ^ (z));
111 static unsigned long int f4(uint32_t *BCD)
113 return (((x) & (z)) | ((y) & (~(z))));
115 static unsigned long int f5(uint32_t *BCD)
117 return ((x) ^ ((y) | (~(z))));
123 #define rotL(x, n) cx_rotl(x, n)
125 cx_err_t cx_ripemd160_init_no_throw(cx_ripemd160_t *hash)
127 memset(hash, 0,
sizeof(cx_ripemd160_t));
128 hash->header.info = &cx_ripemd160_info;
129 memmove(hash->acc, hzero,
sizeof(hzero));
133 static void cx_ripemd160_block(cx_ripemd160_t *hash)
141 uint32_t *accumulator;
157 X = (uint32_t *) &hash->block[0];
158 accumulator = (uint32_t *) &hash->acc[0];
159 memmove(ACCl, accumulator,
sizeof(ACCl));
160 memmove(ACCr, accumulator,
sizeof(ACCr));
162 #ifdef ARCH_BIG_ENDIAN
166 for (j = 0; j < 80; j++) {
171 Tl += f1(&Bl) + kL_0_15;
172 Tr += f5(&Br) + kR_0_15;
175 Tl += f2(&Bl) + kL_16_31;
176 Tr += f4(&Br) + kR_16_31;
179 Tl += f3(&Bl) + kL_32_47;
180 Tr += f3(&Br) + kR_32_47;
183 Tl += f4(&Bl) + kL_48_63;
184 Tr += f2(&Br) + kR_48_63;
187 Tl += f5(&Bl) + kL_64_78;
188 Tr += f1(&Br) + kR_64_78;
194 Tl = rotL(Tl, sL[j]);
202 Tr = rotL(Tr, sR[j]);
212 Tl = accumulator[1] + Cl + Dr;
213 accumulator[1] = accumulator[2] + Dl + Er;
214 accumulator[2] = accumulator[3] + El + Ar;
215 accumulator[3] = accumulator[4] + Al + Br;
216 accumulator[4] = accumulator[0] + Bl + Cr;
220 cx_err_t cx_ripemd160_update(cx_ripemd160_t *ctx,
const uint8_t *data,
size_t len)
223 return CX_INVALID_PARAMETER;
225 if (data == NULL && len != 0) {
226 return CX_INVALID_PARAMETER;
239 if (blen >= block_size) {
240 return CX_INVALID_PARAMETER;
244 if ((blen + len) >= block_size) {
245 r = block_size - blen;
247 if (ctx->header.counter == CX_HASH_MAX_BLOCK_COUNT) {
248 return CX_INVALID_PARAMETER;
250 memcpy(block + blen, data, r);
251 cx_ripemd160_block(ctx);
253 ctx->header.counter++;
257 }
while (len >= block_size);
261 memcpy(block + blen, data, len);
267 cx_err_t cx_ripemd160_final(cx_ripemd160_t *ctx,
uint8_t *digest)
271 unsigned long int bitlen;
280 = (((
unsigned long int) ctx->header.counter) * 64UL + (
unsigned long int) blen - 1UL) * 8UL;
284 memset(block + blen, 0, (64 - blen));
285 cx_ripemd160_block(ctx);
289 memset(block + blen, 0, (64 - blen));
290 #ifdef ARCH_BIG_ENDIAN
291 (*(
unsigned long int *) (&block[64 - 8])) =
cx_swap_uint32(bitlen);
293 (*(uint64_t *) (&block[64 - 8])) = bitlen;
295 cx_ripemd160_block(ctx);
297 #ifdef ARCH_BIG_ENDIAN
300 memcpy(digest, ctx->acc, CX_RIPEMD160_SIZE);
304 size_t cx_hash_ripemd160(
const uint8_t *in,
size_t in_len,
uint8_t *out,
size_t out_len)
306 if (out_len < CX_RIPEMD160_SIZE) {
309 if (cx_ripemd160_init_no_throw(&
G_cx.ripemd160) != CX_OK
310 || cx_ripemd160_update(&
G_cx.ripemd160, in, in_len) != CX_OK
311 || cx_ripemd160_final(&
G_cx.ripemd160, out) != CX_OK) {
312 explicit_bzero(&
G_cx.ripemd160,
sizeof(cx_ripemd160_t));
315 explicit_bzero(&
G_cx.ripemd160,
sizeof(cx_ripemd160_t));
316 return CX_RIPEMD160_SIZE;
uint32_t cx_swap_uint32(uint32_t v)
void cx_swap_buffer32(uint32_t *v, size_t len)