-
Notifications
You must be signed in to change notification settings - Fork 0
/
SHA3.h
205 lines (167 loc) · 7.76 KB
/
SHA3.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
///////////////////////////////////////////////////////////////////////////////////////////////
//
// SWIFFTX ANSI C OPTIMIZED 64BIT IMPLEMENTATION FOR NIST SHA-3 COMPETITION
//
// SHA3.h
//
// October 2008
//
// This file is the exact copy from the reference implementation.
//
///////////////////////////////////////////////////////////////////////////////////////////////
#ifndef __SHA_3__
#define __SHA_3__
// Remove these while using gcc:
#include "stdbool.h"
#include "stdint.h"
///////////////////////////////////////////////////////////////////////////////////////////////
// SWIFFTX-related constants portion
///////////////////////////////////////////////////////////////////////////////////////////////
// The size of SWIFFTX input in bytes.
#define SWIFFTX_INPUT_BLOCK_SIZE 256
// The size of output block in bytes. The compression function of SWIFFT outputs a block of
// this size (i.e., this is the size of the resulting hash value).
#define SWIFFTX_OUTPUT_BLOCK_SIZE 65
///////////////////////////////////////////////////////////////////////////////////////////////
// HAIFA-related constants portion 1
///////////////////////////////////////////////////////////////////////////////////////////////
// The size in bytes of "salt" field.
#define HAIFA_SALT_SIZE 8
// The size in bytes of "#bits" field, as it is called in HAIFA paper.
#define HAIFA_NUM_OF_BITS_SIZE 8
// The size of the input block in bytes that we use in HAIFA (|M_i| in HAIFA paper).
#define HAIFA_INPUT_BLOCK_SIZE (SWIFFTX_INPUT_BLOCK_SIZE - SWIFFTX_OUTPUT_BLOCK_SIZE \
- HAIFA_NUM_OF_BITS_SIZE - HAIFA_SALT_SIZE)
///////////////////////////////////////////////////////////////////////////////////////////////
// NIST API definitions
///////////////////////////////////////////////////////////////////////////////////////////////
// The type of the input data as specified by NIST.
typedef unsigned char BitSequence;
// The data length type. Here we assume a typical modern machine with 64bit architecture.
typedef uint64_t DataLength;
// The success code values.
typedef enum
{
// Successfully computed the hash value.
SUCCESS = 0,
// Failed to compute the hash value.
FAIL = 1,
// Unsupported hash bit length.
BAD_HASHBITLEN = 2,
// The given salt is not of proper size.
// The size shall be 'HAIFA_SALT_SIZE'.
BAD_SALT_SIZE = 3,
// Cannot change a salt value in the middle of a computation.
SET_SALT_VALUE_FAILED = 4,
// Will happen if 'Update()' is called after another 'Update()' with #bits not 0 mod 8.
INPUT_DATA_NOT_ALIGNED = 5
} HashReturn;
// Here we specify the tables needed for SWIFFTX along with the intermediate values.
typedef struct hashState
{
// An integer value that indicates the length of the hash output in bits.
// The supported values are:
// - 224
// - 256
// - 384
// - 512
unsigned short hashbitlen;
// The data remained after the recent call to 'Update()'.
BitSequence remaining[HAIFA_INPUT_BLOCK_SIZE + 1];
// The size of the remaining data in bits.
// Is 0 in case there is no remaning data at all.
unsigned int remainingSize;
// The current output of the compression function. At the end will contain the final digest
// (which may be needed to be truncated, depending on hashbitlen).
BitSequence currOutputBlock[SWIFFTX_OUTPUT_BLOCK_SIZE];
// The value of '#bits hashed so far' field in HAIFA, in base 256.
BitSequence numOfBitsChar[HAIFA_NUM_OF_BITS_SIZE];
// The salt value currently in use:
BitSequence salt[HAIFA_SALT_SIZE];
// Indicates whether a single 'Update()' occured.
// Ater a call to 'Update()' the key and the salt values cannot be changed.
bool wasUpdated;
} hashState;
// Initializes a hashState with the intended hash length of this particular instantiation.
// Additionally, any data independent setup is performed.
//
// Parameters:
// - state: a structure that holds the hashState information
// - hashbitlen: an integer value that indicates the length of the hash output in bits.
//
// Returns:
// - Success value.
HashReturn Init(hashState *state, int hashbitlen);
// Update() processes data using the algorithm�s compression function.
// Whatever integral amount of data the Update() routine can process through the compression
// function is handled. Any remaining data must be stored for future processing.
//
// Parameters:
// - state: a structure that holds the hashState information
// - data: the input data to be hashed
// - databitlen: the length, in bits, of the input data to be hashed
//
// Returns:
// - Success value.
HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen);
// Final() processes any remaining partial block of the input data and performs any output
// filtering that may be needed to produce the final hash value.
// This function is called with pointers to the appropriate hashState structure and the storage
// for the final hash value to be returned (hashval). It performs any post processing that is
// necessary, including the handling of any partial blocks, and places the final hash value in
// hashval. Lastly, an appropriate status value is returned.
//
// Parameters:
// - state: a structure that holds the hashState information
// - hashval: the storage for the final (output) hash value to be returned
//
// Returns:
// - Success value.
HashReturn Final(hashState *state, BitSequence *hashval);
// Hash() provides a method to perform all-at-once processing of the input data using SWIFFTX
// and returns the resulting hash value. The Hash() function is called with a pointer to the
// data to be processed, the length of the data to be processed (databitlen), a pointer to the
// storage for the resulting hash value (hashval), and a length of the desired hash value
// (hashbitlen). This function utilizes the previous three function calls, namely Init(),
// Update(), and Final().
//
// Parameters:
// - hashbitlen: the length in bits of the desired hash value
// - data: the input data to be hashed
// - databitlen: the length, in bits, of the data to be hashed
// - hashval: the resulting hash value of the provided data
//
// Returns:
// - Success value.
HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen,
BitSequence *hashval);
///////////////////////////////////////////////////////////////////////////////////////////////
// Additional API definition for salt that currently is not part of NIST's API.
///////////////////////////////////////////////////////////////////////////////////////////////
// Sets the salt.
//
// Parameters:
// - state: a structure that holds the hashState information.
// - salt: the salt to set.
// - saltLength: the length of the salt to set, in bytes.
//
// Returns:
// - Success value.
HashReturn SetSalt(hashState *state, BitSequence *salt, unsigned short saltLength);
///////////////////////////////////////////////////////////////////////////////////////////////
// HAIFA-related constants portion 2
///////////////////////////////////////////////////////////////////////////////////////////////
// The default salt value.
const DataLength SALT_VALUE;
// This is the initial value we choose. For each digest size m, IV_m is derived from this IV
// through SWIFFTX compression function, as specified in HAIFA paper.
#define HAIFA_IV 0
// The initial value for 224 digest size.
const BitSequence HAIFA_IV_224[SWIFFTX_OUTPUT_BLOCK_SIZE];
// The initial value for 256 digest size.
const BitSequence HAIFA_IV_256[SWIFFTX_OUTPUT_BLOCK_SIZE];
// The initial value for 384 digest size.
const BitSequence HAIFA_IV_384[SWIFFTX_OUTPUT_BLOCK_SIZE];
// The initial value for 512 digest size.
const BitSequence HAIFA_IV_512[SWIFFTX_OUTPUT_BLOCK_SIZE];
#endif // __SHA_3__