line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
/* edonr.c - an implementation of EDON-R 256/224/384/512 hash functions |
2
|
|
|
|
|
|
|
* |
3
|
|
|
|
|
|
|
* Copyright (c) 2011, Aleksey Kravchenko |
4
|
|
|
|
|
|
|
* |
5
|
|
|
|
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any |
6
|
|
|
|
|
|
|
* purpose with or without fee is hereby granted. |
7
|
|
|
|
|
|
|
* |
8
|
|
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH |
9
|
|
|
|
|
|
|
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
10
|
|
|
|
|
|
|
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, |
11
|
|
|
|
|
|
|
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
12
|
|
|
|
|
|
|
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
13
|
|
|
|
|
|
|
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
14
|
|
|
|
|
|
|
* PERFORMANCE OF THIS SOFTWARE. |
15
|
|
|
|
|
|
|
* |
16
|
|
|
|
|
|
|
* This implementation is based on the article: |
17
|
|
|
|
|
|
|
* D. Gligoroski, R. S. Odegard, M. Mihova, S. J. Knapskog, ..., |
18
|
|
|
|
|
|
|
* Cryptographic Hash Function EDON-R - Submission to NIST, 2008 |
19
|
|
|
|
|
|
|
* |
20
|
|
|
|
|
|
|
* EDON-R has been designed to be much more efficient than SHA-2 |
21
|
|
|
|
|
|
|
* cryptographic hash functions, offering the same or better security. |
22
|
|
|
|
|
|
|
*/ |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
#include |
25
|
|
|
|
|
|
|
#include "byte_order.h" |
26
|
|
|
|
|
|
|
#include "edonr.h" |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
/** |
29
|
|
|
|
|
|
|
* Initialize context before calculaing hash. |
30
|
|
|
|
|
|
|
* |
31
|
|
|
|
|
|
|
* @param ctx context to initialize |
32
|
|
|
|
|
|
|
*/ |
33
|
2
|
|
|
|
|
|
void rhash_edonr256_init(edonr_ctx* ctx) |
34
|
|
|
|
|
|
|
{ |
35
|
|
|
|
|
|
|
static const unsigned EDONR256_H0[16] = { |
36
|
|
|
|
|
|
|
0x40414243, 0x44454647, 0x48494a4b, 0x4c4d4e4f, 0x50515253, 0x54555657, |
37
|
|
|
|
|
|
|
0x58595a5b, 0x5c5d5e5f, 0x60616263, 0x64656667, 0x68696a6b, 0x6c6d6e6f, |
38
|
|
|
|
|
|
|
0x70717273, 0x74757677, 0x78797a7b, 0x7c7d7e7f |
39
|
|
|
|
|
|
|
}; |
40
|
2
|
|
|
|
|
|
memcpy(ctx->u.data256.hash, EDONR256_H0, sizeof(EDONR256_H0)); |
41
|
|
|
|
|
|
|
|
42
|
2
|
|
|
|
|
|
ctx->length = 0; |
43
|
2
|
|
|
|
|
|
ctx->digest_length = edonr256_hash_size; |
44
|
2
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
/** |
47
|
|
|
|
|
|
|
* Initialize context before calculaing hash. |
48
|
|
|
|
|
|
|
* |
49
|
|
|
|
|
|
|
* @param ctx context to initialize |
50
|
|
|
|
|
|
|
*/ |
51
|
0
|
|
|
|
|
|
void rhash_edonr224_init(struct edonr_ctx* ctx) |
52
|
|
|
|
|
|
|
{ |
53
|
|
|
|
|
|
|
static const unsigned EDONR224_H0[16] = { |
54
|
|
|
|
|
|
|
0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, 0x10111213, 0x14151617, |
55
|
|
|
|
|
|
|
0x18191a1b, 0x1c1d1e1f, 0x20212223, 0x24252627, 0x28292a2b, 0x2c2d2e2f, |
56
|
|
|
|
|
|
|
0x30313233, 0x24353637, 0x38393a3b, 0x3c3d3e3f |
57
|
|
|
|
|
|
|
}; |
58
|
|
|
|
|
|
|
|
59
|
0
|
|
|
|
|
|
ctx->length = 0; |
60
|
0
|
|
|
|
|
|
ctx->digest_length = edonr224_hash_size; |
61
|
0
|
|
|
|
|
|
memcpy(ctx->u.data256.hash, EDONR224_H0, sizeof(EDONR224_H0)); |
62
|
0
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
/** |
65
|
|
|
|
|
|
|
* Initialize context before calculaing hash. |
66
|
|
|
|
|
|
|
* |
67
|
|
|
|
|
|
|
* @param ctx context to initialize |
68
|
|
|
|
|
|
|
*/ |
69
|
2
|
|
|
|
|
|
void rhash_edonr512_init(edonr_ctx* ctx) |
70
|
|
|
|
|
|
|
{ |
71
|
|
|
|
|
|
|
static const uint64_t EDONR512_H0[16] = { |
72
|
|
|
|
|
|
|
I64(0x8081828384858687), I64(0x88898a8b8c8d8e8f), I64(0x9091929394959697), |
73
|
|
|
|
|
|
|
I64(0x98999a9b9c9d9e9f), I64(0xa0a1a2a3a4a5a6a7), I64(0xa8a9aaabacadaeaf), |
74
|
|
|
|
|
|
|
I64(0xb0b1b2b3b4b5b6b7), I64(0xb8b9babbbcbdbebf), I64(0xc0c1c2c3c4c5c6c7), |
75
|
|
|
|
|
|
|
I64(0xc8c9cacbcccdcecf), I64(0xd0d1d2d3d4d5d6d7), I64(0xd8d9dadbdcdddedf), |
76
|
|
|
|
|
|
|
I64(0xe0e1e2e3e4e5e6e7), I64(0xe8e9eaebecedeeef), I64(0xf0f1f2f3f4f5f6f7), |
77
|
|
|
|
|
|
|
I64(0xf8f9fafbfcfdfeff) |
78
|
|
|
|
|
|
|
}; |
79
|
|
|
|
|
|
|
|
80
|
2
|
|
|
|
|
|
ctx->length = 0; |
81
|
2
|
|
|
|
|
|
ctx->digest_length = edonr512_hash_size; |
82
|
2
|
|
|
|
|
|
memcpy(ctx->u.data512.hash, EDONR512_H0, sizeof(EDONR512_H0)); |
83
|
2
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
/** |
86
|
|
|
|
|
|
|
* Initialize context before calculaing hash. |
87
|
|
|
|
|
|
|
* |
88
|
|
|
|
|
|
|
* @param ctx context to initialize |
89
|
|
|
|
|
|
|
*/ |
90
|
0
|
|
|
|
|
|
void rhash_edonr384_init(struct edonr_ctx* ctx) |
91
|
|
|
|
|
|
|
{ |
92
|
|
|
|
|
|
|
static const uint64_t EDONR384_H0[16] = { |
93
|
|
|
|
|
|
|
I64(0x0001020304050607), I64(0x08090a0b0c0d0e0f), I64(0x1011121314151617), |
94
|
|
|
|
|
|
|
I64(0x18191a1b1c1d1e1f), I64(0x2021222324252627), I64(0x28292a2b2c2d2e2f), |
95
|
|
|
|
|
|
|
I64(0x3031323324353637), I64(0x38393a3b3c3d3e3f), I64(0x4041424344454647), |
96
|
|
|
|
|
|
|
I64(0x48494a4b4c4d4e4f), I64(0x5051525354555657), I64(0x58595a5b5c5d5e5f), |
97
|
|
|
|
|
|
|
I64(0x6061626364656667), I64(0x68696a6b6c6d6e6f), I64(0x7071727374757677), |
98
|
|
|
|
|
|
|
I64(0x78797a7b7c7d7e7f) |
99
|
|
|
|
|
|
|
}; |
100
|
|
|
|
|
|
|
|
101
|
0
|
|
|
|
|
|
ctx->length = 0; |
102
|
0
|
|
|
|
|
|
ctx->digest_length = edonr224_hash_size; |
103
|
0
|
|
|
|
|
|
memcpy(ctx->u.data512.hash, EDONR384_H0, sizeof(EDONR384_H0)); |
104
|
0
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
/* Q256 macro, taken from eBASH submission */ |
107
|
|
|
|
|
|
|
#define Q256(x0,x1,x2,x3,x4,x5,x6,x7,y0,y1,y2,y3,y4,y5,y6,y7,z0,z1,z2,z3,z4,z5,z6,z7) \ |
108
|
|
|
|
|
|
|
{\ |
109
|
|
|
|
|
|
|
/* The First Latin Square\ |
110
|
|
|
|
|
|
|
0 7 1 3 2 4 6 5\ |
111
|
|
|
|
|
|
|
4 1 7 6 3 0 5 2\ |
112
|
|
|
|
|
|
|
7 0 4 2 5 3 1 6\ |
113
|
|
|
|
|
|
|
1 4 0 5 6 2 7 3\ |
114
|
|
|
|
|
|
|
2 3 6 7 1 5 0 4\ |
115
|
|
|
|
|
|
|
5 2 3 1 7 6 4 0\ |
116
|
|
|
|
|
|
|
3 6 5 0 4 7 2 1\ |
117
|
|
|
|
|
|
|
6 5 2 4 0 1 3 7\ |
118
|
|
|
|
|
|
|
*/\ |
119
|
|
|
|
|
|
|
t8 = x0 + x4; \ |
120
|
|
|
|
|
|
|
t9 = x1 + x7; \ |
121
|
|
|
|
|
|
|
t12 = t8 + t9; \ |
122
|
|
|
|
|
|
|
t10 = x2 + x3; \ |
123
|
|
|
|
|
|
|
t11 = x5 + x6; \ |
124
|
|
|
|
|
|
|
t13 = t10 + t11; \ |
125
|
|
|
|
|
|
|
t0 = 0xaaaaaaaa + t12 + x2; \ |
126
|
|
|
|
|
|
|
t1 = t12 + x3; \ |
127
|
|
|
|
|
|
|
t1 = ROTL32((t1), 5); \ |
128
|
|
|
|
|
|
|
t2 = t12 + x6; \ |
129
|
|
|
|
|
|
|
t2 = ROTL32((t2), 11); \ |
130
|
|
|
|
|
|
|
t3 = t13 + x7; \ |
131
|
|
|
|
|
|
|
t3 = ROTL32((t3), 13); \ |
132
|
|
|
|
|
|
|
t4 = x1 + t13; \ |
133
|
|
|
|
|
|
|
t4 = ROTL32((t4), 17); \ |
134
|
|
|
|
|
|
|
t5 = t8 + t10 + x5; \ |
135
|
|
|
|
|
|
|
t5 = ROTL32((t5), 19); \ |
136
|
|
|
|
|
|
|
t6 = x0 + t9 + t11; \ |
137
|
|
|
|
|
|
|
t6 = ROTL32((t6), 29); \ |
138
|
|
|
|
|
|
|
t7 = t13 + x4; \ |
139
|
|
|
|
|
|
|
t7 = ROTL32((t7), 31); \ |
140
|
|
|
|
|
|
|
\ |
141
|
|
|
|
|
|
|
t16 = t0 ^ t4; \ |
142
|
|
|
|
|
|
|
t17 = t1 ^ t7; \ |
143
|
|
|
|
|
|
|
t18 = t2 ^ t3; \ |
144
|
|
|
|
|
|
|
t19 = t5 ^ t6; \ |
145
|
|
|
|
|
|
|
t8 = t3 ^ t19; \ |
146
|
|
|
|
|
|
|
t9 = t2 ^ t19; \ |
147
|
|
|
|
|
|
|
t10 = t18 ^ t5; \ |
148
|
|
|
|
|
|
|
t11 = t16 ^ t1; \ |
149
|
|
|
|
|
|
|
t12 = t16 ^ t7; \ |
150
|
|
|
|
|
|
|
t13 = t17 ^ t6; \ |
151
|
|
|
|
|
|
|
t14 = t18 ^ t4; \ |
152
|
|
|
|
|
|
|
t15 = t0 ^ t17; \ |
153
|
|
|
|
|
|
|
\ |
154
|
|
|
|
|
|
|
/* The Second Orthogonal Latin Square\ |
155
|
|
|
|
|
|
|
0 4 2 3 1 6 5 7\ |
156
|
|
|
|
|
|
|
7 6 3 2 5 4 1 0\ |
157
|
|
|
|
|
|
|
5 3 1 6 0 2 7 4\ |
158
|
|
|
|
|
|
|
1 0 5 4 3 7 2 6\ |
159
|
|
|
|
|
|
|
2 1 0 7 4 5 6 3\ |
160
|
|
|
|
|
|
|
3 5 7 0 6 1 4 2\ |
161
|
|
|
|
|
|
|
4 7 6 1 2 0 3 5\ |
162
|
|
|
|
|
|
|
6 2 4 5 7 3 0 1\ |
163
|
|
|
|
|
|
|
*/\ |
164
|
|
|
|
|
|
|
t16 = y0 + y1; \ |
165
|
|
|
|
|
|
|
t17 = y2 + y5; \ |
166
|
|
|
|
|
|
|
t20 = t16 + t17; \ |
167
|
|
|
|
|
|
|
t18 = y3 + y4; \ |
168
|
|
|
|
|
|
|
t22 = t16 + t18; \ |
169
|
|
|
|
|
|
|
t19 = y6 + y7; \ |
170
|
|
|
|
|
|
|
t21 = t18 + t19; \ |
171
|
|
|
|
|
|
|
t23 = t17 + t19; \ |
172
|
|
|
|
|
|
|
t0 = 0x55555555 + t20 + y7; \ |
173
|
|
|
|
|
|
|
t1 = t22 + y6; \ |
174
|
|
|
|
|
|
|
t1 = ROTL32((t1), 3); \ |
175
|
|
|
|
|
|
|
t2 = t20 + y3; \ |
176
|
|
|
|
|
|
|
t2 = ROTL32((t2), 7); \ |
177
|
|
|
|
|
|
|
t3 = y2 + t21; \ |
178
|
|
|
|
|
|
|
t3 = ROTL32((t3), 11); \ |
179
|
|
|
|
|
|
|
t4 = t22 + y5; \ |
180
|
|
|
|
|
|
|
t4 = ROTL32((t4), 17); \ |
181
|
|
|
|
|
|
|
t5 = t23 + y4; \ |
182
|
|
|
|
|
|
|
t5 = ROTL32((t5), 19); \ |
183
|
|
|
|
|
|
|
t6 = y1 + t23; \ |
184
|
|
|
|
|
|
|
t6 = ROTL32((t6), 23); \ |
185
|
|
|
|
|
|
|
t7 = y0 + t21; \ |
186
|
|
|
|
|
|
|
t7 = ROTL32((t7), 29); \ |
187
|
|
|
|
|
|
|
\ |
188
|
|
|
|
|
|
|
t16 = t0 ^ t1; \ |
189
|
|
|
|
|
|
|
t17 = t2 ^ t5; \ |
190
|
|
|
|
|
|
|
t18 = t3 ^ t4; \ |
191
|
|
|
|
|
|
|
t19 = t6 ^ t7; \ |
192
|
|
|
|
|
|
|
z5 = t8 + (t18 ^ t6); \ |
193
|
|
|
|
|
|
|
z6 = t9 + (t17 ^ t7); \ |
194
|
|
|
|
|
|
|
z7 = t10 + (t4 ^ t19); \ |
195
|
|
|
|
|
|
|
z0 = t11 + (t16 ^ t5); \ |
196
|
|
|
|
|
|
|
z1 = t12 + (t2 ^ t19); \ |
197
|
|
|
|
|
|
|
z2 = t13 + (t16 ^ t3); \ |
198
|
|
|
|
|
|
|
z3 = t14 + (t0 ^ t18); \ |
199
|
|
|
|
|
|
|
z4 = t15 + (t1 ^ t17); \ |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
/* Q512 macro, taken from eBASH submission */ |
203
|
|
|
|
|
|
|
#define Q512(x0,x1,x2,x3,x4,x5,x6,x7,y0,y1,y2,y3,y4,y5,y6,y7,z0,z1,z2,z3,z4,z5,z6,z7) \ |
204
|
|
|
|
|
|
|
{\ |
205
|
|
|
|
|
|
|
/* First Latin Square\ |
206
|
|
|
|
|
|
|
0 7 1 3 2 4 6 5\ |
207
|
|
|
|
|
|
|
4 1 7 6 3 0 5 2\ |
208
|
|
|
|
|
|
|
7 0 4 2 5 3 1 6\ |
209
|
|
|
|
|
|
|
1 4 0 5 6 2 7 3\ |
210
|
|
|
|
|
|
|
2 3 6 7 1 5 0 4\ |
211
|
|
|
|
|
|
|
5 2 3 1 7 6 4 0\ |
212
|
|
|
|
|
|
|
3 6 5 0 4 7 2 1\ |
213
|
|
|
|
|
|
|
6 5 2 4 0 1 3 7\ |
214
|
|
|
|
|
|
|
*/\ |
215
|
|
|
|
|
|
|
t8 = x0 + x4; \ |
216
|
|
|
|
|
|
|
t9 = x1 + x7; \ |
217
|
|
|
|
|
|
|
t12 = t8 + t9; \ |
218
|
|
|
|
|
|
|
t10 = x2 + x3; \ |
219
|
|
|
|
|
|
|
t11 = x5 + x6; \ |
220
|
|
|
|
|
|
|
t13 = t10 + t11; \ |
221
|
|
|
|
|
|
|
t0 = I64(0xaaaaaaaaaaaaaaaa) + t12 + x2; \ |
222
|
|
|
|
|
|
|
t1 = t12 + x3; \ |
223
|
|
|
|
|
|
|
t1 = ROTL64((t1), 5); \ |
224
|
|
|
|
|
|
|
t2 = t12 + x6; \ |
225
|
|
|
|
|
|
|
t2 = ROTL64((t2),19); \ |
226
|
|
|
|
|
|
|
t3 = t13 + x7; \ |
227
|
|
|
|
|
|
|
t3 = ROTL64((t3),29); \ |
228
|
|
|
|
|
|
|
t4 = x1 + t13; \ |
229
|
|
|
|
|
|
|
t4 = ROTL64((t4),31); \ |
230
|
|
|
|
|
|
|
t5 = t8 + t10 + x5; \ |
231
|
|
|
|
|
|
|
t5 = ROTL64((t5),41); \ |
232
|
|
|
|
|
|
|
t6 = x0 + t9 + t11; \ |
233
|
|
|
|
|
|
|
t6 = ROTL64((t6),57); \ |
234
|
|
|
|
|
|
|
t7 = t13 + x4; \ |
235
|
|
|
|
|
|
|
t7 = ROTL64((t7),61); \ |
236
|
|
|
|
|
|
|
\ |
237
|
|
|
|
|
|
|
t16 = t0 ^ t4; \ |
238
|
|
|
|
|
|
|
t17 = t1 ^ t7; \ |
239
|
|
|
|
|
|
|
t18 = t2 ^ t3; \ |
240
|
|
|
|
|
|
|
t19 = t5 ^ t6; \ |
241
|
|
|
|
|
|
|
t8 = t3 ^ t19; \ |
242
|
|
|
|
|
|
|
t9 = t2 ^ t19; \ |
243
|
|
|
|
|
|
|
t10 = t18 ^ t5; \ |
244
|
|
|
|
|
|
|
t11 = t16 ^ t1; \ |
245
|
|
|
|
|
|
|
t12 = t16 ^ t7; \ |
246
|
|
|
|
|
|
|
t13 = t17 ^ t6; \ |
247
|
|
|
|
|
|
|
t14 = t18 ^ t4; \ |
248
|
|
|
|
|
|
|
t15 = t0 ^ t17; \ |
249
|
|
|
|
|
|
|
\ |
250
|
|
|
|
|
|
|
/* Second Orthogonal Latin Square\ |
251
|
|
|
|
|
|
|
0 4 2 3 1 6 5 7\ |
252
|
|
|
|
|
|
|
7 6 3 2 5 4 1 0\ |
253
|
|
|
|
|
|
|
5 3 1 6 0 2 7 4\ |
254
|
|
|
|
|
|
|
1 0 5 4 3 7 2 6\ |
255
|
|
|
|
|
|
|
2 1 0 7 4 5 6 3\ |
256
|
|
|
|
|
|
|
3 5 7 0 6 1 4 2\ |
257
|
|
|
|
|
|
|
4 7 6 1 2 0 3 5\ |
258
|
|
|
|
|
|
|
6 2 4 5 7 3 0 1\ |
259
|
|
|
|
|
|
|
*/\ |
260
|
|
|
|
|
|
|
t16 = y0 + y1; \ |
261
|
|
|
|
|
|
|
t17 = y2 + y5; \ |
262
|
|
|
|
|
|
|
t20 = t16 + t17; \ |
263
|
|
|
|
|
|
|
t18 = y3 + y4; \ |
264
|
|
|
|
|
|
|
t22 = t16 + t18; \ |
265
|
|
|
|
|
|
|
t19 = y6 + y7; \ |
266
|
|
|
|
|
|
|
t21 = t18 + t19; \ |
267
|
|
|
|
|
|
|
t23 = t17 + t19; \ |
268
|
|
|
|
|
|
|
t0 = I64(0x5555555555555555) + t20 + y7; \ |
269
|
|
|
|
|
|
|
t1 = t22 + y6; \ |
270
|
|
|
|
|
|
|
t1 = ROTL64((t1), 3); \ |
271
|
|
|
|
|
|
|
t2 = t20 + y3; \ |
272
|
|
|
|
|
|
|
t2 = ROTL64((t2), 17); \ |
273
|
|
|
|
|
|
|
t3 = y2 + t21; \ |
274
|
|
|
|
|
|
|
t3 = ROTL64((t3), 23); \ |
275
|
|
|
|
|
|
|
t4 = t22 + y5; \ |
276
|
|
|
|
|
|
|
t4 = ROTL64((t4), 31); \ |
277
|
|
|
|
|
|
|
t5 = t23 + y4; \ |
278
|
|
|
|
|
|
|
t5 = ROTL64((t5), 37); \ |
279
|
|
|
|
|
|
|
t6 = y1 + t23; \ |
280
|
|
|
|
|
|
|
t6 = ROTL64((t6), 45); \ |
281
|
|
|
|
|
|
|
t7 = y0 + t21; \ |
282
|
|
|
|
|
|
|
t7 = ROTL64((t7), 59); \ |
283
|
|
|
|
|
|
|
\ |
284
|
|
|
|
|
|
|
t16 = t0 ^ t1; \ |
285
|
|
|
|
|
|
|
t17 = t2 ^ t5; \ |
286
|
|
|
|
|
|
|
t18 = t3 ^ t4; \ |
287
|
|
|
|
|
|
|
t19 = t6 ^ t7; \ |
288
|
|
|
|
|
|
|
z5 = t8 + (t18 ^ t6); \ |
289
|
|
|
|
|
|
|
z6 = t9 + (t17 ^ t7); \ |
290
|
|
|
|
|
|
|
z7 = t10 + (t4 ^ t19); \ |
291
|
|
|
|
|
|
|
z0 = t11 + (t16 ^ t5); \ |
292
|
|
|
|
|
|
|
z1 = t12 + (t2 ^ t19); \ |
293
|
|
|
|
|
|
|
z2 = t13 + (t16 ^ t3); \ |
294
|
|
|
|
|
|
|
z3 = t14 + (t0 ^ t18); \ |
295
|
|
|
|
|
|
|
z4 = t15 + (t1 ^ t17); \ |
296
|
|
|
|
|
|
|
} |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
/** |
299
|
|
|
|
|
|
|
* The core transformation. Process a 512-bit block. |
300
|
|
|
|
|
|
|
* |
301
|
|
|
|
|
|
|
* @param hash algorithm state |
302
|
|
|
|
|
|
|
* @param block the message block to process |
303
|
|
|
|
|
|
|
*/ |
304
|
2
|
|
|
|
|
|
static void rhash_edonr256_process_block(unsigned hash[16], const unsigned* block, size_t count) |
305
|
|
|
|
|
|
|
{ |
306
|
|
|
|
|
|
|
while (1) { |
307
|
|
|
|
|
|
|
uint32_t t0, t1, t2, t3, t4, t5, t6, t7; |
308
|
|
|
|
|
|
|
uint32_t t8, t9, t10, t11, t12, t13, t14, t15; |
309
|
|
|
|
|
|
|
uint32_t t16, t17,t18, t19, t20, t21, t22, t23; |
310
|
|
|
|
|
|
|
uint32_t p16, p17, p18, p19, p20, p21, p22, p23; |
311
|
|
|
|
|
|
|
uint32_t p24, p25, p26, p27, p28, p29, p30, p31; |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
/* First row of quasigroup e-transformations */ |
314
|
2
|
|
|
|
|
|
Q256(block[15], block[14], block[13], block[12], block[11], block[10], block[ 9], block[ 8], |
315
|
|
|
|
|
|
|
block[ 0], block[ 1], block[ 2], block[ 3], block[ 4], block[ 5], block[ 6], block[ 7], |
316
|
|
|
|
|
|
|
p16, p17, p18, p19, p20, p21, p22, p23); |
317
|
2
|
|
|
|
|
|
Q256(p16, p17, p18, p19, p20, p21, p22, p23, |
318
|
|
|
|
|
|
|
block[ 8], block[ 9], block[10], block[11], block[12], block[13], block[14], block[15], |
319
|
|
|
|
|
|
|
p24, p25, p26, p27, p28, p29, p30, p31); |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
/* Second row of quasigroup e-transformations */ |
322
|
2
|
|
|
|
|
|
Q256(hash[ 8], hash[ 9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15], |
323
|
|
|
|
|
|
|
p16, p17, p18, p19, p20, p21, p22, p23, |
324
|
|
|
|
|
|
|
p16, p17, p18, p19, p20, p21, p22, p23); |
325
|
2
|
|
|
|
|
|
Q256(p16, p17, p18, p19, p20, p21, p22, p23, |
326
|
|
|
|
|
|
|
p24, p25, p26, p27, p28, p29, p30, p31, |
327
|
|
|
|
|
|
|
p24, p25, p26, p27, p28, p29, p30, p31); |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
/* Third row of quasigroup e-transformations */ |
330
|
2
|
|
|
|
|
|
Q256(p16, p17, p18, p19, p20, p21, p22, p23, |
331
|
|
|
|
|
|
|
hash[ 0], hash[ 1], hash[ 2], hash[ 3], hash[ 4], hash[ 5], hash[ 6], hash[ 7], |
332
|
|
|
|
|
|
|
p16, p17, p18, p19, p20, p21, p22, p23); |
333
|
2
|
|
|
|
|
|
Q256(p24, p25, p26, p27, p28, p29, p30, p31, |
334
|
|
|
|
|
|
|
p16, p17, p18, p19, p20, p21, p22, p23, |
335
|
|
|
|
|
|
|
p24, p25, p26, p27, p28, p29, p30, p31); |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
/* Fourth row of quasigroup e-transformations */ |
338
|
2
|
|
|
|
|
|
Q256(block[ 7], block[ 6], block[ 5], block[ 4], block[ 3], block[ 2], block[ 1], block[ 0], |
339
|
|
|
|
|
|
|
p16, p17, p18, p19, p20, p21, p22, p23, |
340
|
|
|
|
|
|
|
hash[ 0], hash[ 1], hash[ 2], hash[ 3], hash[ 4], hash[ 5], hash[ 6], hash[ 7]); |
341
|
2
|
|
|
|
|
|
Q256(hash[ 0], hash[ 1], hash[ 2], hash[ 3], hash[ 4], hash[ 5], hash[ 6], hash[ 7], |
342
|
|
|
|
|
|
|
p24, p25, p26, p27, p28, p29, p30, p31, |
343
|
|
|
|
|
|
|
hash[ 8], hash[ 9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15]); |
344
|
|
|
|
|
|
|
|
345
|
2
|
50
|
|
|
|
|
if (!--count) return; |
346
|
0
|
|
|
|
|
|
block += edonr256_block_size / sizeof(unsigned); |
347
|
0
|
|
|
|
|
|
}; |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
/** |
351
|
|
|
|
|
|
|
* The core transformation. Process a 1024-bit block. |
352
|
|
|
|
|
|
|
* |
353
|
|
|
|
|
|
|
* @param hash algorithm state |
354
|
|
|
|
|
|
|
* @param block the message block to process |
355
|
|
|
|
|
|
|
*/ |
356
|
2
|
|
|
|
|
|
static void rhash_edonr512_process_block(uint64_t hash[16], const uint64_t* block, size_t count) |
357
|
|
|
|
|
|
|
{ |
358
|
|
|
|
|
|
|
while (1) { |
359
|
|
|
|
|
|
|
uint64_t t0, t1, t2, t3, t4, t5, t6, t7; |
360
|
|
|
|
|
|
|
uint64_t t8, t9, t10, t11, t12, t13, t14, t15; |
361
|
|
|
|
|
|
|
uint64_t t16, t17,t18, t19, t20, t21, t22, t23; |
362
|
|
|
|
|
|
|
uint64_t p16, p17, p18, p19, p20, p21, p22, p23; |
363
|
|
|
|
|
|
|
uint64_t p24, p25, p26, p27, p28, p29, p30, p31; |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
/* First row of quasigroup e-transformations */ |
366
|
2
|
|
|
|
|
|
Q512(block[15], block[14], block[13], block[12], block[11], block[10], block[ 9], block[ 8], |
367
|
|
|
|
|
|
|
block[ 0], block[ 1], block[ 2], block[ 3], block[ 4], block[ 5], block[ 6], block[ 7], |
368
|
|
|
|
|
|
|
p16, p17, p18, p19, p20, p21, p22, p23); |
369
|
2
|
|
|
|
|
|
Q512(p16, p17, p18, p19, p20, p21, p22, p23, |
370
|
|
|
|
|
|
|
block[ 8], block[ 9], block[10], block[11], block[12], block[13], block[14], block[15], |
371
|
|
|
|
|
|
|
p24, p25, p26, p27, p28, p29, p30, p31); |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
/* Second row of quasigroup e-transformations */ |
374
|
2
|
|
|
|
|
|
Q512(hash[ 8], hash[ 9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15], |
375
|
|
|
|
|
|
|
p16, p17, p18, p19, p20, p21, p22, p23, |
376
|
|
|
|
|
|
|
p16, p17, p18, p19, p20, p21, p22, p23); |
377
|
2
|
|
|
|
|
|
Q512(p16, p17, p18, p19, p20, p21, p22, p23, |
378
|
|
|
|
|
|
|
p24, p25, p26, p27, p28, p29, p30, p31, |
379
|
|
|
|
|
|
|
p24, p25, p26, p27, p28, p29, p30, p31); |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
/* Third row of quasigroup e-transformations */ |
382
|
2
|
|
|
|
|
|
Q512(p16, p17, p18, p19, p20, p21, p22, p23, |
383
|
|
|
|
|
|
|
hash[ 0], hash[ 1], hash[ 2], hash[ 3], hash[ 4], hash[ 5], hash[ 6], hash[ 7], |
384
|
|
|
|
|
|
|
p16, p17, p18, p19, p20, p21, p22, p23); |
385
|
2
|
|
|
|
|
|
Q512(p24, p25, p26, p27, p28, p29, p30, p31, |
386
|
|
|
|
|
|
|
p16, p17, p18, p19, p20, p21, p22, p23, |
387
|
|
|
|
|
|
|
p24, p25, p26, p27, p28, p29, p30, p31); |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
/* Fourth row of quasigroup e-transformations */ |
390
|
2
|
|
|
|
|
|
Q512(block[ 7], block[ 6], block[ 5], block[ 4], block[ 3], block[ 2], block[ 1], block[ 0], |
391
|
|
|
|
|
|
|
p16, p17, p18, p19, p20, p21, p22, p23, |
392
|
|
|
|
|
|
|
hash[ 0], hash[ 1], hash[ 2], hash[ 3], hash[ 4], hash[ 5], hash[ 6], hash[ 7]); |
393
|
2
|
|
|
|
|
|
Q512(hash[ 0], hash[ 1], hash[ 2], hash[ 3], hash[ 4], hash[ 5], hash[ 6], hash[ 7], |
394
|
|
|
|
|
|
|
p24, p25, p26, p27, p28, p29, p30, p31, |
395
|
|
|
|
|
|
|
hash[ 8], hash[ 9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15]); |
396
|
|
|
|
|
|
|
|
397
|
2
|
50
|
|
|
|
|
if (!--count) return; |
398
|
0
|
|
|
|
|
|
block += edonr512_block_size / sizeof(uint64_t); |
399
|
0
|
|
|
|
|
|
}; |
400
|
|
|
|
|
|
|
} |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
/** |
403
|
|
|
|
|
|
|
* Calculate message hash. |
404
|
|
|
|
|
|
|
* Can be called repeatedly with chunks of the message to be hashed. |
405
|
|
|
|
|
|
|
* |
406
|
|
|
|
|
|
|
* @param ctx the algorithm context containing current hashing state |
407
|
|
|
|
|
|
|
* @param msg message chunk |
408
|
|
|
|
|
|
|
* @param size length of the message chunk |
409
|
|
|
|
|
|
|
*/ |
410
|
2
|
|
|
|
|
|
void rhash_edonr256_update(edonr_ctx* ctx, const unsigned char* msg, size_t size) |
411
|
|
|
|
|
|
|
{ |
412
|
2
|
|
|
|
|
|
size_t index = (size_t)ctx->length & 63; |
413
|
2
|
|
|
|
|
|
ctx->length += size; |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
/* fill partial block */ |
416
|
2
|
50
|
|
|
|
|
if (index) { |
417
|
0
|
|
|
|
|
|
size_t left = edonr256_block_size - index; |
418
|
0
|
|
|
|
|
|
le32_copy(ctx->u.data256.message, index, msg, (size < left ? size : left)); |
419
|
0
|
0
|
|
|
|
|
if (size < left) return; |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
/* process partial block */ |
422
|
0
|
|
|
|
|
|
rhash_edonr256_process_block(ctx->u.data256.hash, ctx->u.data256.message, 1); |
423
|
0
|
|
|
|
|
|
msg += left; |
424
|
0
|
|
|
|
|
|
size -= left; |
425
|
|
|
|
|
|
|
} |
426
|
|
|
|
|
|
|
|
427
|
2
|
50
|
|
|
|
|
if (size >= edonr256_block_size) { |
428
|
|
|
|
|
|
|
#if defined(CPU_IA32) || defined(CPU_X64) |
429
|
|
|
|
|
|
|
if (1) |
430
|
|
|
|
|
|
|
#else |
431
|
|
|
|
|
|
|
if (IS_LITTLE_ENDIAN && IS_ALIGNED_32(msg)) |
432
|
|
|
|
|
|
|
#endif |
433
|
|
|
|
|
|
|
{ |
434
|
|
|
|
|
|
|
/* the most common case is processing a 32-bit aligned message |
435
|
|
|
|
|
|
|
on a little-endian CPU without copying it */ |
436
|
0
|
|
|
|
|
|
size_t count = size / edonr256_block_size; |
437
|
0
|
|
|
|
|
|
rhash_edonr256_process_block(ctx->u.data256.hash, (unsigned*)msg, count); |
438
|
0
|
|
|
|
|
|
msg += edonr256_block_size * count; |
439
|
0
|
|
|
|
|
|
size -= edonr256_block_size * count; |
440
|
|
|
|
|
|
|
} else { |
441
|
|
|
|
|
|
|
do { |
442
|
|
|
|
|
|
|
le32_copy(ctx->u.data256.message, 0, msg, edonr256_block_size); |
443
|
|
|
|
|
|
|
rhash_edonr256_process_block(ctx->u.data256.hash, ctx->u.data256.message, 1); |
444
|
|
|
|
|
|
|
msg += edonr256_block_size; |
445
|
|
|
|
|
|
|
size -= edonr256_block_size; |
446
|
|
|
|
|
|
|
} while (size >= edonr256_block_size); |
447
|
|
|
|
|
|
|
} |
448
|
|
|
|
|
|
|
} |
449
|
|
|
|
|
|
|
|
450
|
2
|
50
|
|
|
|
|
if (size) { |
451
|
2
|
|
|
|
|
|
le32_copy(ctx->u.data256.message, 0, msg, size); /* save leftovers */ |
452
|
|
|
|
|
|
|
} |
453
|
|
|
|
|
|
|
} |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
/** |
456
|
|
|
|
|
|
|
* Store calculated hash into the given array. |
457
|
|
|
|
|
|
|
* |
458
|
|
|
|
|
|
|
* @param ctx the algorithm context containing current hashing state |
459
|
|
|
|
|
|
|
* @param result calculated hash in binary form |
460
|
|
|
|
|
|
|
*/ |
461
|
2
|
|
|
|
|
|
void rhash_edonr256_final(edonr_ctx* ctx, unsigned char* result) |
462
|
|
|
|
|
|
|
{ |
463
|
2
|
|
|
|
|
|
size_t index = ((unsigned)ctx->length & 63) >> 2; |
464
|
2
|
|
|
|
|
|
unsigned shift = ((unsigned)ctx->length & 3) * 8; |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
/* pad message and run for the last block */ |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
/* append the byte 0x80 to the message */ |
469
|
2
|
|
|
|
|
|
ctx->u.data256.message[index] &= ~(0xFFFFFFFFu << shift); |
470
|
2
|
|
|
|
|
|
ctx->u.data256.message[index++] ^= 0x80u << shift; |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
/* if no room left in the message to store 64-bit message length */ |
473
|
2
|
50
|
|
|
|
|
if (index > 14) { |
474
|
|
|
|
|
|
|
/* then fill the rest with zeros and process it */ |
475
|
0
|
0
|
|
|
|
|
while (index < 16) { |
476
|
0
|
|
|
|
|
|
ctx->u.data256.message[index++] = 0; |
477
|
|
|
|
|
|
|
} |
478
|
0
|
|
|
|
|
|
rhash_edonr256_process_block(ctx->u.data256.hash, ctx->u.data256.message, 1); |
479
|
0
|
|
|
|
|
|
index = 0; |
480
|
|
|
|
|
|
|
} |
481
|
28
|
100
|
|
|
|
|
while (index < 14) { |
482
|
26
|
|
|
|
|
|
ctx->u.data256.message[index++] = 0; |
483
|
|
|
|
|
|
|
} |
484
|
|
|
|
|
|
|
/* store message length in bits */ |
485
|
2
|
|
|
|
|
|
ctx->u.data256.message[14] = (unsigned)(ctx->length << 3); |
486
|
2
|
|
|
|
|
|
ctx->u.data256.message[15] = (unsigned)(ctx->length >> 29); |
487
|
2
|
|
|
|
|
|
rhash_edonr256_process_block(ctx->u.data256.hash, ctx->u.data256.message, 1); |
488
|
|
|
|
|
|
|
|
489
|
2
|
50
|
|
|
|
|
if (result) { |
490
|
|
|
|
|
|
|
/* copy last bytes of intermidiate hash */ |
491
|
2
|
50
|
|
|
|
|
int off = (ctx->digest_length <= 256 ? 64 : 128) - ctx->digest_length; |
492
|
2
|
|
|
|
|
|
le32_copy(result, 0, ((char*)ctx->u.data256.hash) + off, ctx->digest_length); |
493
|
|
|
|
|
|
|
} |
494
|
2
|
|
|
|
|
|
} |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
/** |
497
|
|
|
|
|
|
|
* Calculate message hash. |
498
|
|
|
|
|
|
|
* Can be called repeatedly with chunks of the message to be hashed. |
499
|
|
|
|
|
|
|
* |
500
|
|
|
|
|
|
|
* @param ctx the algorithm context containing current hashing state |
501
|
|
|
|
|
|
|
* @param msg message chunk |
502
|
|
|
|
|
|
|
* @param size length of the message chunk |
503
|
|
|
|
|
|
|
*/ |
504
|
2
|
|
|
|
|
|
void rhash_edonr512_update(edonr_ctx* ctx, const unsigned char* msg, size_t size) |
505
|
|
|
|
|
|
|
{ |
506
|
2
|
|
|
|
|
|
size_t index = (size_t)ctx->length & 127; |
507
|
2
|
|
|
|
|
|
ctx->length += size; |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
/* fill partial block */ |
510
|
2
|
50
|
|
|
|
|
if (index) { |
511
|
0
|
|
|
|
|
|
size_t left = edonr512_block_size - index; |
512
|
0
|
|
|
|
|
|
le64_copy(ctx->u.data512.message, index, msg, (size < left ? size : left)); |
513
|
0
|
0
|
|
|
|
|
if (size < left) return; |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
/* process partial block */ |
516
|
0
|
|
|
|
|
|
rhash_edonr512_process_block(ctx->u.data512.hash, ctx->u.data512.message, 1); |
517
|
0
|
|
|
|
|
|
msg += left; |
518
|
0
|
|
|
|
|
|
size -= left; |
519
|
|
|
|
|
|
|
} |
520
|
2
|
50
|
|
|
|
|
if (size >= edonr512_block_size) { |
521
|
|
|
|
|
|
|
#if defined(CPU_IA32) || defined(CPU_X64) |
522
|
|
|
|
|
|
|
if (1) |
523
|
|
|
|
|
|
|
#else |
524
|
|
|
|
|
|
|
if (IS_LITTLE_ENDIAN && IS_ALIGNED_64(msg)) |
525
|
|
|
|
|
|
|
#endif |
526
|
|
|
|
|
|
|
{ |
527
|
|
|
|
|
|
|
/* the most common case is processing a 64-bit aligned message |
528
|
|
|
|
|
|
|
on a little-endian CPU without copying it */ |
529
|
0
|
|
|
|
|
|
size_t count = size / edonr512_block_size; |
530
|
0
|
|
|
|
|
|
rhash_edonr512_process_block(ctx->u.data512.hash, (uint64_t*)msg, count); |
531
|
0
|
|
|
|
|
|
msg += edonr512_block_size * count; |
532
|
0
|
|
|
|
|
|
size -= edonr512_block_size * count; |
533
|
|
|
|
|
|
|
} else { |
534
|
|
|
|
|
|
|
do { |
535
|
|
|
|
|
|
|
le64_copy(ctx->u.data512.message, 0, msg, edonr512_block_size); |
536
|
|
|
|
|
|
|
rhash_edonr512_process_block(ctx->u.data512.hash, ctx->u.data512.message, 1); |
537
|
|
|
|
|
|
|
msg += edonr512_block_size; |
538
|
|
|
|
|
|
|
size -= edonr512_block_size; |
539
|
|
|
|
|
|
|
} while (size >= edonr512_block_size); |
540
|
|
|
|
|
|
|
} |
541
|
|
|
|
|
|
|
} |
542
|
|
|
|
|
|
|
|
543
|
2
|
50
|
|
|
|
|
if (size) { |
544
|
2
|
|
|
|
|
|
le64_copy(ctx->u.data512.message, 0, msg, size); /* save leftovers */ |
545
|
|
|
|
|
|
|
} |
546
|
|
|
|
|
|
|
} |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
/** |
549
|
|
|
|
|
|
|
* Store calculated hash into the given array. |
550
|
|
|
|
|
|
|
* |
551
|
|
|
|
|
|
|
* @param ctx the algorithm context containing current hashing state |
552
|
|
|
|
|
|
|
* @param result calculated hash in binary form |
553
|
|
|
|
|
|
|
*/ |
554
|
2
|
|
|
|
|
|
void rhash_edonr512_final(edonr_ctx* ctx, unsigned char* result) |
555
|
|
|
|
|
|
|
{ |
556
|
2
|
|
|
|
|
|
size_t index = ((unsigned)ctx->length & 127) >> 3; |
557
|
2
|
|
|
|
|
|
unsigned shift = ((unsigned)ctx->length & 7) * 8; |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
/* pad message and run for the last block */ |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
/* append the byte 0x80 to the message */ |
562
|
2
|
|
|
|
|
|
ctx->u.data512.message[index] &= ~(I64(0xFFFFFFFFFFFFFFFF) << shift); |
563
|
2
|
|
|
|
|
|
ctx->u.data512.message[index++] ^= I64(0x80) << shift; |
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
/* if no room left in the message to store 64-bit message length */ |
566
|
2
|
50
|
|
|
|
|
if (index == 16) { |
567
|
0
|
|
|
|
|
|
rhash_edonr512_process_block(ctx->u.data512.hash, ctx->u.data512.message, 1); |
568
|
0
|
|
|
|
|
|
index = 0; |
569
|
|
|
|
|
|
|
} |
570
|
30
|
100
|
|
|
|
|
while (index < 15) { |
571
|
28
|
|
|
|
|
|
ctx->u.data512.message[index++] = 0; |
572
|
|
|
|
|
|
|
} |
573
|
|
|
|
|
|
|
/* store message length in bits */ |
574
|
2
|
|
|
|
|
|
ctx->u.data512.message[15] = ctx->length << 3; |
575
|
2
|
|
|
|
|
|
rhash_edonr512_process_block(ctx->u.data512.hash, ctx->u.data512.message, 1); |
576
|
|
|
|
|
|
|
|
577
|
2
|
50
|
|
|
|
|
if (result) { |
578
|
|
|
|
|
|
|
/* copy last bytes of intermidiate hash */ |
579
|
2
|
|
|
|
|
|
int off = edonr512_block_size - ctx->digest_length; |
580
|
2
|
|
|
|
|
|
le64_copy(result, 0, ((char*)ctx->u.data512.hash) + off, ctx->digest_length); |
581
|
|
|
|
|
|
|
} |
582
|
2
|
|
|
|
|
|
} |