14#include "arcane/utils/SHA1HashAlgorithm.h"
16#include "arcane/utils/Array.h"
17#include "arcane/utils/FatalErrorException.h"
18#include "arcane/utils/Ref.h"
49namespace Arcane::SHA1Algorithm
57 constexpr int sha1_block_size = 64;
58 constexpr int sha1_hash_size = 20;
61 constexpr uint32_t K0 = 0x5a827999;
62 constexpr uint32_t K1 = 0x6ed9eba1;
63 constexpr uint32_t K2 = 0x8f1bbcdc;
64 constexpr uint32_t K3 = 0xca62c1d6;
66 uint32_t bswap_32(uint32_t x)
68 x = ((x << 8) & 0xFF00FF00u) | ((x >> 8) & 0x00FF00FFu);
69 return (x >> 16) | (x << 16);
72 static uint32_t _rotateLeft(uint32_t dword,
int n)
74 return ((dword) << (n) ^ ((dword) >> (32 - (n))));
86 void _swap_copy_str_to_u32(
void* to,
int index,
const void* from,
size_t length)
89 if (0 == (((uintptr_t)to | (uintptr_t)from | (uintptr_t)index | length) & 3)) {
91 const uint32_t* src = (
const uint32_t*)from;
92 const uint32_t* end = (
const uint32_t*)((
const char*)src + length);
93 uint32_t* dst = (uint32_t*)((
char*)to + index);
94 for (; src < end; dst++, src++)
95 *dst = bswap_32(*src);
98 const char* src = (
const char*)from;
99 for (length += index; (size_t)index < length; index++)
100 ((
char*)to)[index ^ 3] = *(src++);
117 unsigned char message[sha1_block_size] = {};
121 unsigned hash[5] = {};
131 void reset()
override { sha1_init(); }
149 static void sha1_process_block(
unsigned* hash,
const unsigned* block);
157#define be2me_32(x) bswap_32(x)
158#define be32_copy(to, index, from, length) _swap_copy_str_to_u32((to), (index), (from), (length))
161#define IS_ALIGNED_32(p) (0 == (3 & (uintptr_t)(p)))
171 sha1_ctx* ctx = &m_context;
175 ctx->hash[0] = 0x67452301;
176 ctx->hash[1] = 0xefcdab89;
177 ctx->hash[2] = 0x98badcfe;
178 ctx->hash[3] = 0x10325476;
179 ctx->hash[4] = 0xc3d2e1f0;
183#define CHO(X, Y, Z) (((X) & (Y)) | ((~(X)) & (Z)))
184#define PAR(X, Y, Z) ((X) ^ (Y) ^ (Z))
185#define MAJ(X, Y, Z) (((X) & (Y)) | ((X) & (Z)) | ((Y) & (Z)))
187#define ROTL32(a, b) _rotateLeft(a, b)
188#define ROUND_0(a, b, c, d, e, FF, k, w) e += FF(b, c, d) + ROTL32(a, 5) + k + w
189#define ROUND_1(a, b, c, d, e, FF, k, w) e += FF(b, ROTL32(c, 30), d) + ROTL32(a, 5) + k + w
190#define ROUND_2(a, b, c, d, e, FF, k, w) e += FF(b, ROTL32(c, 30), ROTL32(d, 30)) + ROTL32(a, 5) + k + w
191#define ROUND(a, b, c, d, e, FF, k, w) e = ROTL32(e, 30) + FF(b, ROTL32(c, 30), ROTL32(d, 30)) + ROTL32(a, 5) + k + w
203sha1_process_block(
unsigned* hash,
const unsigned* block)
206 uint32_t A, B, C, D, E;
215 W[0] = be2me_32(block[0]);
216 ROUND_0(A, B, C, D, E, CHO, K0, W[0]);
217 W[1] = be2me_32(block[1]);
218 ROUND_1(E, A, B, C, D, CHO, K0, W[1]);
219 W[2] = be2me_32(block[2]);
220 ROUND_2(D, E, A, B, C, CHO, K0, W[2]);
221 W[3] = be2me_32(block[3]);
222 ROUND(C, D, E, A, B, CHO, K0, W[3]);
223 W[4] = be2me_32(block[4]);
224 ROUND(B, C, D, E, A, CHO, K0, W[4]);
226 W[5] = be2me_32(block[5]);
227 ROUND(A, B, C, D, E, CHO, K0, W[5]);
228 W[6] = be2me_32(block[6]);
229 ROUND(E, A, B, C, D, CHO, K0, W[6]);
230 W[7] = be2me_32(block[7]);
231 ROUND(D, E, A, B, C, CHO, K0, W[7]);
232 W[8] = be2me_32(block[8]);
233 ROUND(C, D, E, A, B, CHO, K0, W[8]);
234 W[9] = be2me_32(block[9]);
235 ROUND(B, C, D, E, A, CHO, K0, W[9]);
237 W[10] = be2me_32(block[10]);
238 ROUND(A, B, C, D, E, CHO, K0, W[10]);
239 W[11] = be2me_32(block[11]);
240 ROUND(E, A, B, C, D, CHO, K0, W[11]);
241 W[12] = be2me_32(block[12]);
242 ROUND(D, E, A, B, C, CHO, K0, W[12]);
243 W[13] = be2me_32(block[13]);
244 ROUND(C, D, E, A, B, CHO, K0, W[13]);
245 W[14] = be2me_32(block[14]);
246 ROUND(B, C, D, E, A, CHO, K0, W[14]);
248 W[15] = be2me_32(block[15]);
249 ROUND(A, B, C, D, E, CHO, K0, W[15]);
250 W[16] = ROTL32(W[13] ^ W[8] ^ W[2] ^ W[0], 1);
251 ROUND(E, A, B, C, D, CHO, K0, W[16]);
252 W[17] = ROTL32(W[14] ^ W[9] ^ W[3] ^ W[1], 1);
253 ROUND(D, E, A, B, C, CHO, K0, W[17]);
254 W[18] = ROTL32(W[15] ^ W[10] ^ W[4] ^ W[2], 1);
255 ROUND(C, D, E, A, B, CHO, K0, W[18]);
256 W[19] = ROTL32(W[16] ^ W[11] ^ W[5] ^ W[3], 1);
257 ROUND(B, C, D, E, A, CHO, K0, W[19]);
259 W[20] = ROTL32(W[17] ^ W[12] ^ W[6] ^ W[4], 1);
260 ROUND(A, B, C, D, E, PAR, K1, W[20]);
261 W[21] = ROTL32(W[18] ^ W[13] ^ W[7] ^ W[5], 1);
262 ROUND(E, A, B, C, D, PAR, K1, W[21]);
263 W[22] = ROTL32(W[19] ^ W[14] ^ W[8] ^ W[6], 1);
264 ROUND(D, E, A, B, C, PAR, K1, W[22]);
265 W[23] = ROTL32(W[20] ^ W[15] ^ W[9] ^ W[7], 1);
266 ROUND(C, D, E, A, B, PAR, K1, W[23]);
267 W[24] = ROTL32(W[21] ^ W[16] ^ W[10] ^ W[8], 1);
268 ROUND(B, C, D, E, A, PAR, K1, W[24]);
270 W[25] = ROTL32(W[22] ^ W[17] ^ W[11] ^ W[9], 1);
271 ROUND(A, B, C, D, E, PAR, K1, W[25]);
272 W[26] = ROTL32(W[23] ^ W[18] ^ W[12] ^ W[10], 1);
273 ROUND(E, A, B, C, D, PAR, K1, W[26]);
274 W[27] = ROTL32(W[24] ^ W[19] ^ W[13] ^ W[11], 1);
275 ROUND(D, E, A, B, C, PAR, K1, W[27]);
276 W[28] = ROTL32(W[25] ^ W[20] ^ W[14] ^ W[12], 1);
277 ROUND(C, D, E, A, B, PAR, K1, W[28]);
278 W[29] = ROTL32(W[26] ^ W[21] ^ W[15] ^ W[13], 1);
279 ROUND(B, C, D, E, A, PAR, K1, W[29]);
281 W[30] = ROTL32(W[27] ^ W[22] ^ W[16] ^ W[14], 1);
282 ROUND(A, B, C, D, E, PAR, K1, W[30]);
283 W[31] = ROTL32(W[28] ^ W[23] ^ W[17] ^ W[15], 1);
284 ROUND(E, A, B, C, D, PAR, K1, W[31]);
285 W[32] = ROTL32(W[29] ^ W[24] ^ W[18] ^ W[16], 1);
286 ROUND(D, E, A, B, C, PAR, K1, W[32]);
287 W[33] = ROTL32(W[30] ^ W[25] ^ W[19] ^ W[17], 1);
288 ROUND(C, D, E, A, B, PAR, K1, W[33]);
289 W[34] = ROTL32(W[31] ^ W[26] ^ W[20] ^ W[18], 1);
290 ROUND(B, C, D, E, A, PAR, K1, W[34]);
292 W[35] = ROTL32(W[32] ^ W[27] ^ W[21] ^ W[19], 1);
293 ROUND(A, B, C, D, E, PAR, K1, W[35]);
294 W[36] = ROTL32(W[33] ^ W[28] ^ W[22] ^ W[20], 1);
295 ROUND(E, A, B, C, D, PAR, K1, W[36]);
296 W[37] = ROTL32(W[34] ^ W[29] ^ W[23] ^ W[21], 1);
297 ROUND(D, E, A, B, C, PAR, K1, W[37]);
298 W[38] = ROTL32(W[35] ^ W[30] ^ W[24] ^ W[22], 1);
299 ROUND(C, D, E, A, B, PAR, K1, W[38]);
300 W[39] = ROTL32(W[36] ^ W[31] ^ W[25] ^ W[23], 1);
301 ROUND(B, C, D, E, A, PAR, K1, W[39]);
303 W[40] = ROTL32(W[37] ^ W[32] ^ W[26] ^ W[24], 1);
304 ROUND(A, B, C, D, E, MAJ, K2, W[40]);
305 W[41] = ROTL32(W[38] ^ W[33] ^ W[27] ^ W[25], 1);
306 ROUND(E, A, B, C, D, MAJ, K2, W[41]);
307 W[42] = ROTL32(W[39] ^ W[34] ^ W[28] ^ W[26], 1);
308 ROUND(D, E, A, B, C, MAJ, K2, W[42]);
309 W[43] = ROTL32(W[40] ^ W[35] ^ W[29] ^ W[27], 1);
310 ROUND(C, D, E, A, B, MAJ, K2, W[43]);
311 W[44] = ROTL32(W[41] ^ W[36] ^ W[30] ^ W[28], 1);
312 ROUND(B, C, D, E, A, MAJ, K2, W[44]);
314 W[45] = ROTL32(W[42] ^ W[37] ^ W[31] ^ W[29], 1);
315 ROUND(A, B, C, D, E, MAJ, K2, W[45]);
316 W[46] = ROTL32(W[43] ^ W[38] ^ W[32] ^ W[30], 1);
317 ROUND(E, A, B, C, D, MAJ, K2, W[46]);
318 W[47] = ROTL32(W[44] ^ W[39] ^ W[33] ^ W[31], 1);
319 ROUND(D, E, A, B, C, MAJ, K2, W[47]);
320 W[48] = ROTL32(W[45] ^ W[40] ^ W[34] ^ W[32], 1);
321 ROUND(C, D, E, A, B, MAJ, K2, W[48]);
322 W[49] = ROTL32(W[46] ^ W[41] ^ W[35] ^ W[33], 1);
323 ROUND(B, C, D, E, A, MAJ, K2, W[49]);
325 W[50] = ROTL32(W[47] ^ W[42] ^ W[36] ^ W[34], 1);
326 ROUND(A, B, C, D, E, MAJ, K2, W[50]);
327 W[51] = ROTL32(W[48] ^ W[43] ^ W[37] ^ W[35], 1);
328 ROUND(E, A, B, C, D, MAJ, K2, W[51]);
329 W[52] = ROTL32(W[49] ^ W[44] ^ W[38] ^ W[36], 1);
330 ROUND(D, E, A, B, C, MAJ, K2, W[52]);
331 W[53] = ROTL32(W[50] ^ W[45] ^ W[39] ^ W[37], 1);
332 ROUND(C, D, E, A, B, MAJ, K2, W[53]);
333 W[54] = ROTL32(W[51] ^ W[46] ^ W[40] ^ W[38], 1);
334 ROUND(B, C, D, E, A, MAJ, K2, W[54]);
336 W[55] = ROTL32(W[52] ^ W[47] ^ W[41] ^ W[39], 1);
337 ROUND(A, B, C, D, E, MAJ, K2, W[55]);
338 W[56] = ROTL32(W[53] ^ W[48] ^ W[42] ^ W[40], 1);
339 ROUND(E, A, B, C, D, MAJ, K2, W[56]);
340 W[57] = ROTL32(W[54] ^ W[49] ^ W[43] ^ W[41], 1);
341 ROUND(D, E, A, B, C, MAJ, K2, W[57]);
342 W[58] = ROTL32(W[55] ^ W[50] ^ W[44] ^ W[42], 1);
343 ROUND(C, D, E, A, B, MAJ, K2, W[58]);
344 W[59] = ROTL32(W[56] ^ W[51] ^ W[45] ^ W[43], 1);
345 ROUND(B, C, D, E, A, MAJ, K2, W[59]);
347 W[60] = ROTL32(W[57] ^ W[52] ^ W[46] ^ W[44], 1);
348 ROUND(A, B, C, D, E, PAR, K3, W[60]);
349 W[61] = ROTL32(W[58] ^ W[53] ^ W[47] ^ W[45], 1);
350 ROUND(E, A, B, C, D, PAR, K3, W[61]);
351 W[62] = ROTL32(W[59] ^ W[54] ^ W[48] ^ W[46], 1);
352 ROUND(D, E, A, B, C, PAR, K3, W[62]);
353 W[63] = ROTL32(W[60] ^ W[55] ^ W[49] ^ W[47], 1);
354 ROUND(C, D, E, A, B, PAR, K3, W[63]);
355 W[64] = ROTL32(W[61] ^ W[56] ^ W[50] ^ W[48], 1);
356 ROUND(B, C, D, E, A, PAR, K3, W[64]);
358 W[65] = ROTL32(W[62] ^ W[57] ^ W[51] ^ W[49], 1);
359 ROUND(A, B, C, D, E, PAR, K3, W[65]);
360 W[66] = ROTL32(W[63] ^ W[58] ^ W[52] ^ W[50], 1);
361 ROUND(E, A, B, C, D, PAR, K3, W[66]);
362 W[67] = ROTL32(W[64] ^ W[59] ^ W[53] ^ W[51], 1);
363 ROUND(D, E, A, B, C, PAR, K3, W[67]);
364 W[68] = ROTL32(W[65] ^ W[60] ^ W[54] ^ W[52], 1);
365 ROUND(C, D, E, A, B, PAR, K3, W[68]);
366 W[69] = ROTL32(W[66] ^ W[61] ^ W[55] ^ W[53], 1);
367 ROUND(B, C, D, E, A, PAR, K3, W[69]);
369 W[70] = ROTL32(W[67] ^ W[62] ^ W[56] ^ W[54], 1);
370 ROUND(A, B, C, D, E, PAR, K3, W[70]);
371 W[71] = ROTL32(W[68] ^ W[63] ^ W[57] ^ W[55], 1);
372 ROUND(E, A, B, C, D, PAR, K3, W[71]);
373 W[72] = ROTL32(W[69] ^ W[64] ^ W[58] ^ W[56], 1);
374 ROUND(D, E, A, B, C, PAR, K3, W[72]);
375 W[73] = ROTL32(W[70] ^ W[65] ^ W[59] ^ W[57], 1);
376 ROUND(C, D, E, A, B, PAR, K3, W[73]);
377 W[74] = ROTL32(W[71] ^ W[66] ^ W[60] ^ W[58], 1);
378 ROUND(B, C, D, E, A, PAR, K3, W[74]);
380 W[75] = ROTL32(W[72] ^ W[67] ^ W[61] ^ W[59], 1);
381 ROUND(A, B, C, D, E, PAR, K3, W[75]);
382 W[76] = ROTL32(W[73] ^ W[68] ^ W[62] ^ W[60], 1);
383 ROUND(E, A, B, C, D, PAR, K3, W[76]);
384 W[77] = ROTL32(W[74] ^ W[69] ^ W[63] ^ W[61], 1);
385 ROUND(D, E, A, B, C, PAR, K3, W[77]);
386 W[78] = ROTL32(W[75] ^ W[70] ^ W[64] ^ W[62], 1);
387 ROUND(C, D, E, A, B, PAR, K3, W[78]);
388 W[79] = ROTL32(W[76] ^ W[71] ^ W[65] ^ W[63], 1);
389 ROUND(B, C, D, E, A, PAR, K3, W[79]);
393 hash[2] += ROTL32(C, 30);
394 hash[3] += ROTL32(D, 30);
395 hash[4] += ROTL32(E, 30);
407sha1_update(Span<const std::byte> bytes)
409 sha1_ctx* ctx = &m_context;
410 const unsigned char* msg =
reinterpret_cast<const unsigned char*
>(bytes.data());
411 size_t size = bytes.size();
412 unsigned index = (unsigned)ctx->length & 63;
417 unsigned left = sha1_block_size - index;
418 memcpy(ctx->message + index, msg, (size < left ? size : left));
423 sha1_process_block(ctx->hash, (
unsigned*)ctx->message);
427 while (size >= sha1_block_size) {
428 unsigned* aligned_message_block;
429 if (IS_ALIGNED_32(msg)) {
432 aligned_message_block = (
unsigned*)msg;
435 memcpy(ctx->message, msg, sha1_block_size);
436 aligned_message_block = (
unsigned*)ctx->message;
439 sha1_process_block(ctx->hash, aligned_message_block);
440 msg += sha1_block_size;
441 size -= sha1_block_size;
445 memcpy(ctx->message, msg, size);
453sha1_final(HashAlgorithmValue& value)
455 value.setSize(sha1_hash_size);
457 unsigned char* result =
reinterpret_cast<unsigned char*
>(value.bytes().data());
458 sha1_ctx* ctx = &m_context;
459 unsigned index = (unsigned)ctx->length & 63;
460 unsigned* msg32 = (
unsigned*)ctx->message;
463 ctx->message[index++] = 0x80;
464 while ((index & 3) != 0) {
465 ctx->message[index++] = 0;
475 sha1_process_block(ctx->hash, msg32);
481 msg32[14] = be2me_32((
unsigned)(ctx->length >> 29));
482 msg32[15] = be2me_32((
unsigned)(ctx->length << 3));
483 sha1_process_block(ctx->hash, msg32);
486 be32_copy(result, 0, &ctx->hash, sha1_hash_size);
503void SHA1HashAlgorithm::
504_computeHash(Span<const std::byte> input, HashAlgorithmValue& value)
506 SHA1Algorithm::SHA1 sha1;
507 sha1.updateHash(input);
508 sha1.computeHashValue(value);
514void SHA1HashAlgorithm::
515_computeHash64(Span<const std::byte> input,
ByteArray& output)
517 HashAlgorithmValue value;
518 _computeHash(input, value);
519 output.addRange(value.asLegacyBytes());
528 _computeHash(input, value);
538 _computeHash64(asBytes(input64), output);
548 _computeHash64(bytes, output);
557 _computeHash64(input, output);
566 return createRef<SHA1Algorithm::SHA1>();
Valeur retournée par un algorithme de hashage.
Contexte pour calculer un hash de manière incrémentale.
void computeHashValue(HashAlgorithmValue &value) override
Calcule la valeur de hashage et la retourne dans hash_value.
void updateHash(Span< const std::byte > input) override
Ajoute le tableau input au hash calculé
void reset() override
Réinitialise l'instance pour calculer une nouvelle valeur de hash.
Ref< IHashAlgorithmContext > createContext() override
Créé un contexte pour calculer la valeur du hash de manière incrémentale.
void computeHash64(Span< const Byte > input, ByteArray &output) override
Calcule la valeur du hash pour le tableau input.
void computeHash(Span< const std::byte > input, HashAlgorithmValue &value) override
Calcule la valeur du hash pour le tableau input.
Classe de base des vecteurs 1D de données.
Vue constante d'un tableau de type T.
Vue d'un tableau d'éléments de type T.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Array< Byte > ByteArray
Tableau dynamique à une dimension de caractères.