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));
82 uint64_t temp = state.lengthLow;
83 state.lengthLow += (((uint64_t)len) << 3);
84 state.lengthHigh += (((uint64_t)len) >> 61);
85 if (state.lengthLow < temp)
89 const uint8_t *d = (
const uint8_t *)data;
91 uint8_t size = 128 - state.chunkSize;
94 memcpy(((uint8_t *)state.w) + state.chunkSize, d, size);
95 state.chunkSize += size;
98 if (state.chunkSize == 128) {
109 uint8_t *wbytes = (uint8_t *)state.w;
110 if (state.chunkSize <= (128 - 17)) {
111 wbytes[state.chunkSize] = 0x80;
112 memset(wbytes + state.chunkSize + 1, 0x00, 128 - 16 - (state.chunkSize + 1));
113 state.w[14] = htobe64(state.lengthHigh);
114 state.w[15] = htobe64(state.lengthLow);
117 wbytes[state.chunkSize] = 0x80;
118 memset(wbytes + state.chunkSize + 1, 0x00, 128 - (state.chunkSize + 1));
120 memset(wbytes, 0x00, 128 - 16);
121 state.w[14] = htobe64(state.lengthHigh);
122 state.w[15] = htobe64(state.lengthLow);
127 for (uint8_t posn = 0; posn < 8; ++posn)
128 state.w[posn] = htobe64(state.h[posn]);
133 memcpy(hash, state.w, len);
147 void SHA512::processChunk()
150 static uint64_t
const k[80] PROGMEM = {
151 0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL, 0xB5C0FBCFEC4D3B2FULL,
152 0xE9B5DBA58189DBBCULL, 0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
153 0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL, 0xD807AA98A3030242ULL,
154 0x12835B0145706FBEULL, 0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
155 0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL, 0x9BDC06A725C71235ULL,
156 0xC19BF174CF692694ULL, 0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
157 0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL, 0x2DE92C6F592B0275ULL,
158 0x4A7484AA6EA6E483ULL, 0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
159 0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL, 0xB00327C898FB213FULL,
160 0xBF597FC7BEEF0EE4ULL, 0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
161 0x06CA6351E003826FULL, 0x142929670A0E6E70ULL, 0x27B70A8546D22FFCULL,
162 0x2E1B21385C26C926ULL, 0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
163 0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL, 0x81C2C92E47EDAEE6ULL,
164 0x92722C851482353BULL, 0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
165 0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL, 0xD192E819D6EF5218ULL,
166 0xD69906245565A910ULL, 0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
167 0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL, 0x2748774CDF8EEB99ULL,
168 0x34B0BCB5E19B48A8ULL, 0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
169 0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL, 0x748F82EE5DEFB2FCULL,
170 0x78A5636F43172F60ULL, 0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
171 0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL, 0xBEF9A3F7B2C67915ULL,
172 0xC67178F2E372532BULL, 0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
173 0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL, 0x06F067AA72176FBAULL,
174 0x0A637DC5A2C898A6ULL, 0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
175 0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL, 0x3C9EBE0A15C9BEBCULL,
176 0x431D67C49C100D4CULL, 0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
177 0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
182 for (index = 0; index < 16; ++index)
183 state.w[index] = be64toh(state.w[index]);
186 uint64_t a = state.h[0];
187 uint64_t b = state.h[1];
188 uint64_t c = state.h[2];
189 uint64_t d = state.h[3];
190 uint64_t e = state.h[4];
191 uint64_t f = state.h[5];
192 uint64_t g = state.h[6];
193 uint64_t h = state.h[7];
196 uint64_t temp1, temp2;
197 for (index = 0; index < 16; ++index) {
198 temp1 = h + pgm_read_qword(k + index) + state.w[index] +
199 (rightRotate14_64(e) ^ rightRotate18_64(e) ^
200 rightRotate41_64(e)) + ((e & f) ^ ((~e) & g));
201 temp2 = (rightRotate28_64(a) ^ rightRotate34_64(a) ^
202 rightRotate39_64(a)) + ((a & b) ^ (a & c) ^ (b & c));
216 for (; index < 80; ++index) {
218 temp1 = state.w[(index - 15) & 0x0F];
219 temp2 = state.w[(index - 2) & 0x0F];
220 temp1 = state.w[index & 0x0F] =
221 state.w[(index - 16) & 0x0F] + state.w[(index - 7) & 0x0F] +
222 (rightRotate1_64(temp1) ^ rightRotate8_64(temp1) ^
224 (rightRotate19_64(temp2) ^ rightRotate61_64(temp2) ^
228 temp1 = h + pgm_read_qword(k + index) + temp1 +
229 (rightRotate14_64(e) ^ rightRotate18_64(e) ^
230 rightRotate41_64(e)) + ((e & f) ^ ((~e) & g));
231 temp2 = (rightRotate28_64(a) ^ rightRotate34_64(a) ^
232 rightRotate39_64(a)) + ((a & b) ^ (a & c) ^ (b & c));
254 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.