25 #include "utility/EndianUtil.h"
26 #include "utility/RotateUtil.h"
27 #include "utility/ProgMemUtil.h"
72 #define BLAKE2s_IV0 0x6A09E667
73 #define BLAKE2s_IV1 0xBB67AE85
74 #define BLAKE2s_IV2 0x3C6EF372
75 #define BLAKE2s_IV3 0xA54FF53A
76 #define BLAKE2s_IV4 0x510E527F
77 #define BLAKE2s_IV5 0x9B05688C
78 #define BLAKE2s_IV6 0x1F83D9AB
79 #define BLAKE2s_IV7 0x5BE0CD19
83 state.h[0] = BLAKE2s_IV0 ^ 0x01010020;
84 state.h[1] = BLAKE2s_IV1;
85 state.h[2] = BLAKE2s_IV2;
86 state.h[3] = BLAKE2s_IV3;
87 state.h[4] = BLAKE2s_IV4;
88 state.h[5] = BLAKE2s_IV5;
89 state.h[6] = BLAKE2s_IV6;
90 state.h[7] = BLAKE2s_IV7;
92 state.finalized =
false;
105 state.h[0] = BLAKE2s_IV0 ^ 0x01010000 ^ outputLength;
106 state.h[1] = BLAKE2s_IV1;
107 state.h[2] = BLAKE2s_IV2;
108 state.h[3] = BLAKE2s_IV3;
109 state.h[4] = BLAKE2s_IV4;
110 state.h[5] = BLAKE2s_IV5;
111 state.h[6] = BLAKE2s_IV6;
112 state.h[7] = BLAKE2s_IV7;
114 state.finalized =
false;
125 const uint8_t *d = (
const uint8_t *)data;
127 if (state.chunkSize == 64) {
133 uint8_t size = 64 - state.chunkSize;
136 memcpy(((uint8_t *)state.m) + state.chunkSize, d, size);
137 state.chunkSize += size;
138 state.length += size;
147 if (!state.finalized) {
149 memset(((uint8_t *)state.m) + state.chunkSize, 0, 64 - state.chunkSize);
150 processChunk(0xFFFFFFFF);
153 for (uint8_t posn = 0; posn < 8; ++posn)
154 state.m[posn] = htole32(state.h[posn]);
155 state.finalized =
true;
161 memcpy(hash, state.m, len);
171 static const uint8_t sigma[10][16] PROGMEM = {
172 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
173 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
174 {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
175 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
176 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
177 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
178 {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
179 {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
180 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
181 {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0}
185 #define quarterRound(a, b, c, d, i) \
188 uint32_t _a = (a) + _b + state.m[pgm_read_byte(&(sigma[index][2 * (i)]))]; \
189 uint32_t _d = rightRotate16((d) ^ _a); \
190 uint32_t _c = (c) + _d; \
191 _b = rightRotate12(_b ^ _c); \
192 _a += _b + state.m[pgm_read_byte(&(sigma[index][2 * (i) + 1]))]; \
193 (d) = _d = rightRotate8(_d ^ _a); \
196 (b) = rightRotate7(_b ^ _c); \
200 void BLAKE2s::processChunk(uint32_t f0)
205 #if !defined(CRYPTO_LITTLE_ENDIAN)
206 for (index = 0; index < 16; ++index)
207 state.m[index] = le32toh(state.m[index]);
211 memcpy(state.v, state.h,
sizeof(state.h));
212 state.v[8] = BLAKE2s_IV0;
213 state.v[9] = BLAKE2s_IV1;
214 state.v[10] = BLAKE2s_IV2;
215 state.v[11] = BLAKE2s_IV3;
216 state.v[12] = BLAKE2s_IV4 ^ (uint32_t)(state.length);
217 state.v[13] = BLAKE2s_IV5 ^ (uint32_t)(state.length >> 32);
218 state.v[14] = BLAKE2s_IV6 ^ f0;
219 state.v[15] = BLAKE2s_IV7;
222 for (index = 0; index < 10; ++index) {
224 quarterRound(state.v[0], state.v[4], state.v[8], state.v[12], 0);
225 quarterRound(state.v[1], state.v[5], state.v[9], state.v[13], 1);
226 quarterRound(state.v[2], state.v[6], state.v[10], state.v[14], 2);
227 quarterRound(state.v[3], state.v[7], state.v[11], state.v[15], 3);
230 quarterRound(state.v[0], state.v[5], state.v[10], state.v[15], 4);
231 quarterRound(state.v[1], state.v[6], state.v[11], state.v[12], 5);
232 quarterRound(state.v[2], state.v[7], state.v[8], state.v[13], 6);
233 quarterRound(state.v[3], state.v[4], state.v[9], state.v[14], 7);
237 for (index = 0; index < 8; ++index)
238 state.h[index] ^= (state.v[index] ^ state.v[index + 8]);
virtual ~BLAKE2s()
Destroys this BLAKE2s hash object after clearing sensitive information.
size_t hashSize() const
Size of the hash result from finalize().
void clear()
Clears the hash state, removing all sensitive data, and then resets the hash ready for a new hashing ...
void reset()
Resets the hash ready for a new hashing process.
size_t blockSize() const
Size of the internal block used by the hash algorithm.
void update(const void *data, size_t len)
Updates the hash with more data.
void finalize(void *hash, size_t len)
Finalizes the hashing process and returns the hash.
uint8_t * data()
Returns a pointer to the start of the bitmap's data buffer.
BLAKE2s()
Constructs a BLAKE2s hash object.