25 #include "utility/RotateUtil.h"
26 #include "utility/EndianUtil.h"
27 #include "utility/ProgMemUtil.h"
68 static uint64_t
const hashStart[8] PROGMEM = {
69 0x6A09E667F3BCC908ULL, 0xBB67AE8584CAA73BULL, 0x3C6EF372FE94F82BULL,
70 0xA54FF53A5F1D36F1ULL, 0x510E527FADE682D1ULL, 0x9B05688C2B3E6C1FULL,
71 0x1F83D9ABFB41BD6BULL, 0x5BE0CD19137E2179ULL
73 memcpy_P(state.h, hashStart,
sizeof(hashStart));
75 state.finalized =
false;
87 uint64_t temp = state.lengthLow;
88 state.lengthLow += (((uint64_t)len) << 3);
89 state.lengthHigh += (((uint64_t)len) >> 61);
90 if (state.lengthLow < temp)
94 const uint8_t *d = (
const uint8_t *)data;
96 uint8_t size = 128 - state.chunkSize;
99 memcpy(((uint8_t *)state.w) + state.chunkSize, d, size);
100 state.chunkSize += size;
103 if (state.chunkSize == 128) {
113 if (!state.finalized) {
116 uint8_t *wbytes = (uint8_t *)state.w;
117 if (state.chunkSize <= (128 - 17)) {
118 wbytes[state.chunkSize] = 0x80;
119 memset(wbytes + state.chunkSize + 1, 0x00, 128 - 16 - (state.chunkSize + 1));
120 state.w[14] = htobe64(state.lengthHigh);
121 state.w[15] = htobe64(state.lengthLow);
124 wbytes[state.chunkSize] = 0x80;
125 memset(wbytes + state.chunkSize + 1, 0x00, 128 - (state.chunkSize + 1));
127 memset(wbytes, 0x00, 128 - 16);
128 state.w[14] = htobe64(state.lengthHigh);
129 state.w[15] = htobe64(state.lengthLow);
134 for (uint8_t posn = 0; posn < 8; ++posn)
135 state.w[posn] = htobe64(state.h[posn]);
136 state.finalized =
true;
142 memcpy(hash, state.w, len);
156 void SHA512::processChunk()
159 static uint64_t
const k[80] PROGMEM = {
160 0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL, 0xB5C0FBCFEC4D3B2FULL,
161 0xE9B5DBA58189DBBCULL, 0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
162 0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL, 0xD807AA98A3030242ULL,
163 0x12835B0145706FBEULL, 0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
164 0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL, 0x9BDC06A725C71235ULL,
165 0xC19BF174CF692694ULL, 0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
166 0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL, 0x2DE92C6F592B0275ULL,
167 0x4A7484AA6EA6E483ULL, 0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
168 0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL, 0xB00327C898FB213FULL,
169 0xBF597FC7BEEF0EE4ULL, 0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
170 0x06CA6351E003826FULL, 0x142929670A0E6E70ULL, 0x27B70A8546D22FFCULL,
171 0x2E1B21385C26C926ULL, 0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
172 0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL, 0x81C2C92E47EDAEE6ULL,
173 0x92722C851482353BULL, 0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
174 0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL, 0xD192E819D6EF5218ULL,
175 0xD69906245565A910ULL, 0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
176 0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL, 0x2748774CDF8EEB99ULL,
177 0x34B0BCB5E19B48A8ULL, 0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
178 0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL, 0x748F82EE5DEFB2FCULL,
179 0x78A5636F43172F60ULL, 0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
180 0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL, 0xBEF9A3F7B2C67915ULL,
181 0xC67178F2E372532BULL, 0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
182 0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL, 0x06F067AA72176FBAULL,
183 0x0A637DC5A2C898A6ULL, 0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
184 0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL, 0x3C9EBE0A15C9BEBCULL,
185 0x431D67C49C100D4CULL, 0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
186 0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
191 for (index = 0; index < 16; ++index)
192 state.w[index] = be64toh(state.w[index]);
195 uint64_t a = state.h[0];
196 uint64_t b = state.h[1];
197 uint64_t c = state.h[2];
198 uint64_t d = state.h[3];
199 uint64_t e = state.h[4];
200 uint64_t f = state.h[5];
201 uint64_t g = state.h[6];
202 uint64_t h = state.h[7];
205 uint64_t temp1, temp2;
206 for (index = 0; index < 16; ++index) {
207 temp1 = h + pgm_read_qword(k + index) + state.w[index] +
208 (rightRotate14_64(e) ^ rightRotate18_64(e) ^
209 rightRotate41_64(e)) + ((e & f) ^ ((~e) & g));
210 temp2 = (rightRotate28_64(a) ^ rightRotate34_64(a) ^
211 rightRotate39_64(a)) + ((a & b) ^ (a & c) ^ (b & c));
225 for (; index < 80; ++index) {
227 temp1 = state.w[(index - 15) & 0x0F];
228 temp2 = state.w[(index - 2) & 0x0F];
229 temp1 = state.w[index & 0x0F] =
230 state.w[(index - 16) & 0x0F] + state.w[(index - 7) & 0x0F] +
231 (rightRotate1_64(temp1) ^ rightRotate8_64(temp1) ^
233 (rightRotate19_64(temp2) ^ rightRotate61_64(temp2) ^
237 temp1 = h + pgm_read_qword(k + index) + temp1 +
238 (rightRotate14_64(e) ^ rightRotate18_64(e) ^
239 rightRotate41_64(e)) + ((e & f) ^ ((~e) & g));
240 temp2 = (rightRotate28_64(a) ^ rightRotate34_64(a) ^
241 rightRotate39_64(a)) + ((a & b) ^ (a & c) ^ (b & c));
263 a = b = c = d = e = f = g = h = temp1 = temp2 = 0;
size_t hashSize() const
Size of the hash result from finalize().
size_t blockSize() const
Size of the internal block used by the hash algorithm.
virtual ~SHA512()
Destroys this SHA-512 hash object after clearing sensitive information.
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.
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.
SHA512()
Constructs a SHA-512 hash object.