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++);
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);
548 _computeHash64(bytes,
output);
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.
Référence à une instance.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Array< Byte > ByteArray
Tableau dynamique à une dimension de caractères.