| 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 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 += edonr256_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((char*)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((char*)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
|
|
|
|
|
|
} |