-
Notifications
You must be signed in to change notification settings - Fork 0
/
hash.h
142 lines (121 loc) · 3.55 KB
/
hash.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#ifndef HASH_H
#define HASH_H
#include <inttypes.h>
#include <stddef.h>
#include "config.h"
#include "block.h"
#include "KeccakHash.h"
#include "KeccakHashtimes4.h"
// TODO: Is the error checking really needed?
// Either add it to hash_state_x4, or remove it from hash_state.
typedef Keccak_HashInstance hash_state;
inline int hash_init(hash_state* ctx)
{
#if SECURITY_PARAM <= 128
return Keccak_HashInitialize_SHAKE128(ctx);
#else
return Keccak_HashInitialize_SHAKE256(ctx);
#endif
}
inline int hash_update(hash_state* ctx, const void* input, size_t bytes)
{
return Keccak_HashUpdate(ctx, (const uint8_t*) input, bytes * 8);
}
inline int hash_update_byte(hash_state* ctx, uint8_t b)
{
return hash_update(ctx, &b, 1);
}
inline int hash_final(hash_state* ctx, void* digest, size_t bytes)
{
int ret = Keccak_HashFinal(ctx, NULL);
if (ret != KECCAK_SUCCESS)
return ret;
return Keccak_HashSqueeze(ctx, (uint8_t*) digest, bytes * 8);
}
// Mostly copied from Picnic: Instances that work with 4 states in parallel.
typedef Keccak_HashInstancetimes4 hash_state_x4;
inline void hash_init_x4(hash_state_x4* ctx)
{
#if SECURITY_PARAM <= 128
Keccak_HashInitializetimes4_SHAKE128(ctx);
#else
Keccak_HashInitializetimes4_SHAKE256(ctx);
#endif
}
inline void hash_update_x4(hash_state_x4* ctx, const void** data, size_t size)
{
const uint8_t* data_casted[4] = {
(const uint8_t*) data[0], (const uint8_t*) data[1],
(const uint8_t*) data[2], (const uint8_t*) data[3]
};
Keccak_HashUpdatetimes4(ctx, data_casted, size << 3);
}
inline void hash_update_x4_4(
hash_state_x4* ctx,
const void* data0, const void* data1, const void* data2, const void* data3, size_t size)
{
const void* data[4] = {data0, data1, data2, data3};
hash_update_x4(ctx, data, size);
}
inline void hash_update_x4_1(hash_state_x4* ctx, const void* data, size_t size)
{
hash_update_x4_4(ctx, data, data, data, data, size);
}
inline void hash_update_x4_1_byte(hash_state_x4* ctx, uint8_t b)
{
hash_update_x4_1(ctx, &b, 1);
}
inline void hash_init_prefix_x4(hash_state_x4* ctx, const uint8_t prefix)
{
hash_init_x4(ctx);
hash_update_x4_1(ctx, &prefix, sizeof(prefix));
}
inline void hash_final_x4(hash_state_x4* ctx, void** buffer, size_t buflen)
{
uint8_t* buffer_casted[4] = {
(uint8_t*) buffer[0], (uint8_t*) buffer[1],
(uint8_t*) buffer[2], (uint8_t*) buffer[3]
};
Keccak_HashFinaltimes4(ctx, NULL);
Keccak_HashSqueezetimes4(ctx, buffer_casted, buflen << 3);
}
inline void hash_final_x4_4(
hash_state_x4* ctx, void* buffer0, void* buffer1, void* buffer2, void* buffer3, size_t buflen)
{
void* buffer[4] = {buffer0, buffer1, buffer2, buffer3};
hash_final_x4(ctx, buffer, buflen);
}
inline void shake_prg(
const block_secpar* restrict keys, const block128* restrict ivs,
size_t num_keys, size_t num_bytes, uint8_t* restrict output)
{
size_t i;
for (i = 0; i + 4 <= num_keys; i += 4)
{
const void* key_arr[4];
const void* iv_arr[4];
void* output_arr[4];
for (size_t j = 0; j < 4; ++j)
{
key_arr[j] = &keys[i + j];
iv_arr[j] = &ivs[i + j];
output_arr[j] = output + (i + j) * num_bytes;
}
hash_state_x4 hasher;
hash_init_x4(&hasher);
hash_update_x4(&hasher, key_arr, sizeof(keys[i]));
hash_update_x4(&hasher, iv_arr, sizeof(ivs[i]));
hash_update_x4_1_byte(&hasher, 0);
hash_final_x4(&hasher, output_arr, num_bytes);
}
for (; i < num_keys; ++i)
{
hash_state hasher;
hash_init(&hasher);
hash_update(&hasher, &keys[i], sizeof(keys[i]));
hash_update(&hasher, &ivs[i], sizeof(ivs[i]));
hash_update_byte(&hasher, 0);
hash_final(&hasher, output + i * num_bytes, num_bytes);
}
}
#endif