diff options
author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2024-11-29 00:00:00 +0000 |
---|---|---|
committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2024-11-30 15:27:15 +0500 |
commit | e5431fa6f5505e385c6f9367260717e9c47dc2ee (patch) | |
tree | 4cd2c2c3b225b48c8e7053432c41d7b6b6a3d5f8 /C/Sha256.c | |
parent | e008ce3976c087bfd21344af8f00a23cf69d4174 (diff) | |
download | 7zip-main.tar.gz 7zip-main.tar.bz2 7zip-main.zip |
Diffstat (limited to 'C/Sha256.c')
-rw-r--r-- | C/Sha256.c | 162 |
1 files changed, 70 insertions, 92 deletions
@@ -1,18 +1,14 @@ | |||
1 | /* Sha256.c -- SHA-256 Hash | 1 | /* Sha256.c -- SHA-256 Hash |
2 | 2024-03-01 : Igor Pavlov : Public domain | 2 | : Igor Pavlov : Public domain |
3 | This code is based on public domain code from Wei Dai's Crypto++ library. */ | 3 | This code is based on public domain code from Wei Dai's Crypto++ library. */ |
4 | 4 | ||
5 | #include "Precomp.h" | 5 | #include "Precomp.h" |
6 | 6 | ||
7 | #include <string.h> | 7 | #include <string.h> |
8 | 8 | ||
9 | #include "CpuArch.h" | ||
10 | #include "RotateDefs.h" | ||
11 | #include "Sha256.h" | 9 | #include "Sha256.h" |
12 | 10 | #include "RotateDefs.h" | |
13 | #if defined(_MSC_VER) && (_MSC_VER < 1900) | 11 | #include "CpuArch.h" |
14 | // #define USE_MY_MM | ||
15 | #endif | ||
16 | 12 | ||
17 | #ifdef MY_CPU_X86_OR_AMD64 | 13 | #ifdef MY_CPU_X86_OR_AMD64 |
18 | #if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \ | 14 | #if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \ |
@@ -56,7 +52,7 @@ void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t n | |||
56 | static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS = Sha256_UpdateBlocks; | 52 | static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS = Sha256_UpdateBlocks; |
57 | static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS_HW; | 53 | static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS_HW; |
58 | 54 | ||
59 | #define SHA256_UPDATE_BLOCKS(p) p->func_UpdateBlocks | 55 | #define SHA256_UPDATE_BLOCKS(p) p->v.vars.func_UpdateBlocks |
60 | #else | 56 | #else |
61 | #define SHA256_UPDATE_BLOCKS(p) Sha256_UpdateBlocks | 57 | #define SHA256_UPDATE_BLOCKS(p) Sha256_UpdateBlocks |
62 | #endif | 58 | #endif |
@@ -85,7 +81,7 @@ BoolInt Sha256_SetFunction(CSha256 *p, unsigned algo) | |||
85 | return False; | 81 | return False; |
86 | #endif | 82 | #endif |
87 | 83 | ||
88 | p->func_UpdateBlocks = func; | 84 | p->v.vars.func_UpdateBlocks = func; |
89 | return True; | 85 | return True; |
90 | } | 86 | } |
91 | 87 | ||
@@ -111,7 +107,7 @@ BoolInt Sha256_SetFunction(CSha256 *p, unsigned algo) | |||
111 | 107 | ||
112 | void Sha256_InitState(CSha256 *p) | 108 | void Sha256_InitState(CSha256 *p) |
113 | { | 109 | { |
114 | p->count = 0; | 110 | p->v.vars.count = 0; |
115 | p->state[0] = 0x6a09e667; | 111 | p->state[0] = 0x6a09e667; |
116 | p->state[1] = 0xbb67ae85; | 112 | p->state[1] = 0xbb67ae85; |
117 | p->state[2] = 0x3c6ef372; | 113 | p->state[2] = 0x3c6ef372; |
@@ -122,9 +118,16 @@ void Sha256_InitState(CSha256 *p) | |||
122 | p->state[7] = 0x5be0cd19; | 118 | p->state[7] = 0x5be0cd19; |
123 | } | 119 | } |
124 | 120 | ||
121 | |||
122 | |||
123 | |||
124 | |||
125 | |||
126 | |||
127 | |||
125 | void Sha256_Init(CSha256 *p) | 128 | void Sha256_Init(CSha256 *p) |
126 | { | 129 | { |
127 | p->func_UpdateBlocks = | 130 | p->v.vars.func_UpdateBlocks = |
128 | #ifdef Z7_COMPILER_SHA256_SUPPORTED | 131 | #ifdef Z7_COMPILER_SHA256_SUPPORTED |
129 | g_SHA256_FUNC_UPDATE_BLOCKS; | 132 | g_SHA256_FUNC_UPDATE_BLOCKS; |
130 | #else | 133 | #else |
@@ -133,10 +136,10 @@ void Sha256_Init(CSha256 *p) | |||
133 | Sha256_InitState(p); | 136 | Sha256_InitState(p); |
134 | } | 137 | } |
135 | 138 | ||
136 | #define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22)) | 139 | #define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x,22)) |
137 | #define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25)) | 140 | #define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x,25)) |
138 | #define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3)) | 141 | #define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3)) |
139 | #define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10)) | 142 | #define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >>10)) |
140 | 143 | ||
141 | #define Ch(x,y,z) (z^(x&(y^z))) | 144 | #define Ch(x,y,z) (z^(x&(y^z))) |
142 | #define Maj(x,y,z) ((x&y)|(z&(x|y))) | 145 | #define Maj(x,y,z) ((x&y)|(z&(x|y))) |
@@ -224,12 +227,10 @@ void Sha256_Init(CSha256 *p) | |||
224 | 227 | ||
225 | #endif | 228 | #endif |
226 | 229 | ||
227 | // static | ||
228 | extern MY_ALIGN(64) | ||
229 | const UInt32 SHA256_K_ARRAY[64]; | ||
230 | 230 | ||
231 | MY_ALIGN(64) | 231 | extern |
232 | const UInt32 SHA256_K_ARRAY[64] = { | 232 | MY_ALIGN(64) const UInt32 SHA256_K_ARRAY[64]; |
233 | MY_ALIGN(64) const UInt32 SHA256_K_ARRAY[64] = { | ||
233 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, | 234 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, |
234 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, | 235 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, |
235 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, | 236 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, |
@@ -248,27 +249,29 @@ const UInt32 SHA256_K_ARRAY[64] = { | |||
248 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 | 249 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 |
249 | }; | 250 | }; |
250 | 251 | ||
251 | #define K SHA256_K_ARRAY | ||
252 | 252 | ||
253 | 253 | ||
254 | |||
255 | |||
256 | #define K SHA256_K_ARRAY | ||
257 | |||
254 | Z7_NO_INLINE | 258 | Z7_NO_INLINE |
255 | void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks) | 259 | void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks) |
256 | { | 260 | { |
257 | UInt32 W | 261 | UInt32 W |
258 | #ifdef Z7_SHA256_BIG_W | 262 | #ifdef Z7_SHA256_BIG_W |
259 | [64]; | 263 | [64]; |
260 | #else | 264 | #else |
261 | [16]; | 265 | [16]; |
262 | #endif | 266 | #endif |
263 | |||
264 | unsigned j; | 267 | unsigned j; |
265 | |||
266 | UInt32 a,b,c,d,e,f,g,h; | 268 | UInt32 a,b,c,d,e,f,g,h; |
267 | 269 | #if !defined(Z7_SHA256_UNROLL) || (STEP_MAIN <= 4) || (STEP_PRE <= 4) | |
268 | #if !defined(Z7_SHA256_UNROLL) || (STEP_MAIN <= 4) || (STEP_PRE <= 4) | ||
269 | UInt32 tmp; | 270 | UInt32 tmp; |
270 | #endif | 271 | #endif |
271 | 272 | ||
273 | if (numBlocks == 0) return; | ||
274 | |||
272 | a = state[0]; | 275 | a = state[0]; |
273 | b = state[1]; | 276 | b = state[1]; |
274 | c = state[2]; | 277 | c = state[2]; |
@@ -278,7 +281,7 @@ void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t n | |||
278 | g = state[6]; | 281 | g = state[6]; |
279 | h = state[7]; | 282 | h = state[7]; |
280 | 283 | ||
281 | while (numBlocks) | 284 | do |
282 | { | 285 | { |
283 | 286 | ||
284 | for (j = 0; j < 16; j += STEP_PRE) | 287 | for (j = 0; j < 16; j += STEP_PRE) |
@@ -352,19 +355,11 @@ void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t n | |||
352 | g += state[6]; state[6] = g; | 355 | g += state[6]; state[6] = g; |
353 | h += state[7]; state[7] = h; | 356 | h += state[7]; state[7] = h; |
354 | 357 | ||
355 | data += 64; | 358 | data += SHA256_BLOCK_SIZE; |
356 | numBlocks--; | ||
357 | } | 359 | } |
358 | 360 | while (--numBlocks); | |
359 | /* Wipe variables */ | ||
360 | /* memset(W, 0, sizeof(W)); */ | ||
361 | } | 361 | } |
362 | 362 | ||
363 | #undef S0 | ||
364 | #undef S1 | ||
365 | #undef s0 | ||
366 | #undef s1 | ||
367 | #undef K | ||
368 | 363 | ||
369 | #define Sha256_UpdateBlock(p) SHA256_UPDATE_BLOCKS(p)(p->state, p->buffer, 1) | 364 | #define Sha256_UpdateBlock(p) SHA256_UPDATE_BLOCKS(p)(p->state, p->buffer, 1) |
370 | 365 | ||
@@ -372,20 +367,15 @@ void Sha256_Update(CSha256 *p, const Byte *data, size_t size) | |||
372 | { | 367 | { |
373 | if (size == 0) | 368 | if (size == 0) |
374 | return; | 369 | return; |
375 | |||
376 | { | 370 | { |
377 | unsigned pos = (unsigned)p->count & 0x3F; | 371 | const unsigned pos = (unsigned)p->v.vars.count & (SHA256_BLOCK_SIZE - 1); |
378 | unsigned num; | 372 | const unsigned num = SHA256_BLOCK_SIZE - pos; |
379 | 373 | p->v.vars.count += size; | |
380 | p->count += size; | ||
381 | |||
382 | num = 64 - pos; | ||
383 | if (num > size) | 374 | if (num > size) |
384 | { | 375 | { |
385 | memcpy(p->buffer + pos, data, size); | 376 | memcpy(p->buffer + pos, data, size); |
386 | return; | 377 | return; |
387 | } | 378 | } |
388 | |||
389 | if (pos != 0) | 379 | if (pos != 0) |
390 | { | 380 | { |
391 | size -= num; | 381 | size -= num; |
@@ -395,9 +385,10 @@ void Sha256_Update(CSha256 *p, const Byte *data, size_t size) | |||
395 | } | 385 | } |
396 | } | 386 | } |
397 | { | 387 | { |
398 | size_t numBlocks = size >> 6; | 388 | const size_t numBlocks = size >> 6; |
389 | // if (numBlocks) | ||
399 | SHA256_UPDATE_BLOCKS(p)(p->state, data, numBlocks); | 390 | SHA256_UPDATE_BLOCKS(p)(p->state, data, numBlocks); |
400 | size &= 0x3F; | 391 | size &= SHA256_BLOCK_SIZE - 1; |
401 | if (size == 0) | 392 | if (size == 0) |
402 | return; | 393 | return; |
403 | data += (numBlocks << 6); | 394 | data += (numBlocks << 6); |
@@ -408,82 +399,69 @@ void Sha256_Update(CSha256 *p, const Byte *data, size_t size) | |||
408 | 399 | ||
409 | void Sha256_Final(CSha256 *p, Byte *digest) | 400 | void Sha256_Final(CSha256 *p, Byte *digest) |
410 | { | 401 | { |
411 | unsigned pos = (unsigned)p->count & 0x3F; | 402 | unsigned pos = (unsigned)p->v.vars.count & (SHA256_BLOCK_SIZE - 1); |
412 | unsigned i; | ||
413 | |||
414 | p->buffer[pos++] = 0x80; | 403 | p->buffer[pos++] = 0x80; |
415 | 404 | if (pos > (SHA256_BLOCK_SIZE - 4 * 2)) | |
416 | if (pos > (64 - 8)) | ||
417 | { | 405 | { |
418 | while (pos != 64) { p->buffer[pos++] = 0; } | 406 | while (pos != SHA256_BLOCK_SIZE) { p->buffer[pos++] = 0; } |
419 | // memset(&p->buf.buffer[pos], 0, 64 - pos); | 407 | // memset(&p->buf.buffer[pos], 0, SHA256_BLOCK_SIZE - pos); |
420 | Sha256_UpdateBlock(p); | 408 | Sha256_UpdateBlock(p); |
421 | pos = 0; | 409 | pos = 0; |
422 | } | 410 | } |
423 | 411 | memset(&p->buffer[pos], 0, (SHA256_BLOCK_SIZE - 4 * 2) - pos); | |
424 | /* | ||
425 | if (pos & 3) | ||
426 | { | 412 | { |
427 | p->buffer[pos] = 0; | 413 | const UInt64 numBits = p->v.vars.count << 3; |
428 | p->buffer[pos + 1] = 0; | 414 | SetBe32(p->buffer + SHA256_BLOCK_SIZE - 4 * 2, (UInt32)(numBits >> 32)) |
429 | p->buffer[pos + 2] = 0; | 415 | SetBe32(p->buffer + SHA256_BLOCK_SIZE - 4 * 1, (UInt32)(numBits)) |
430 | pos += 3; | ||
431 | pos &= ~3; | ||
432 | } | 416 | } |
417 | Sha256_UpdateBlock(p); | ||
418 | #if 1 && defined(MY_CPU_BE) | ||
419 | memcpy(digest, p->state, SHA256_DIGEST_SIZE); | ||
420 | #else | ||
433 | { | 421 | { |
434 | for (; pos < 64 - 8; pos += 4) | 422 | unsigned i; |
435 | *(UInt32 *)(&p->buffer[pos]) = 0; | 423 | for (i = 0; i < 8; i += 2) |
424 | { | ||
425 | const UInt32 v0 = p->state[i]; | ||
426 | const UInt32 v1 = p->state[(size_t)i + 1]; | ||
427 | SetBe32(digest , v0) | ||
428 | SetBe32(digest + 4, v1) | ||
429 | digest += 4 * 2; | ||
430 | } | ||
436 | } | 431 | } |
437 | */ | ||
438 | 432 | ||
439 | memset(&p->buffer[pos], 0, (64 - 8) - pos); | ||
440 | 433 | ||
441 | { | ||
442 | UInt64 numBits = (p->count << 3); | ||
443 | SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32)) | ||
444 | SetBe32(p->buffer + 64 - 4, (UInt32)(numBits)) | ||
445 | } | ||
446 | |||
447 | Sha256_UpdateBlock(p); | ||
448 | 434 | ||
449 | for (i = 0; i < 8; i += 2) | 435 | |
450 | { | 436 | #endif |
451 | UInt32 v0 = p->state[i]; | ||
452 | UInt32 v1 = p->state[(size_t)i + 1]; | ||
453 | SetBe32(digest , v0) | ||
454 | SetBe32(digest + 4, v1) | ||
455 | digest += 8; | ||
456 | } | ||
457 | |||
458 | Sha256_InitState(p); | 437 | Sha256_InitState(p); |
459 | } | 438 | } |
460 | 439 | ||
461 | 440 | ||
462 | void Sha256Prepare(void) | 441 | void Sha256Prepare(void) |
463 | { | 442 | { |
464 | #ifdef Z7_COMPILER_SHA256_SUPPORTED | 443 | #ifdef Z7_COMPILER_SHA256_SUPPORTED |
465 | SHA256_FUNC_UPDATE_BLOCKS f, f_hw; | 444 | SHA256_FUNC_UPDATE_BLOCKS f, f_hw; |
466 | f = Sha256_UpdateBlocks; | 445 | f = Sha256_UpdateBlocks; |
467 | f_hw = NULL; | 446 | f_hw = NULL; |
468 | #ifdef MY_CPU_X86_OR_AMD64 | 447 | #ifdef MY_CPU_X86_OR_AMD64 |
469 | #ifndef USE_MY_MM | ||
470 | if (CPU_IsSupported_SHA() | 448 | if (CPU_IsSupported_SHA() |
471 | && CPU_IsSupported_SSSE3() | 449 | && CPU_IsSupported_SSSE3() |
472 | // && CPU_IsSupported_SSE41() | ||
473 | ) | 450 | ) |
474 | #endif | 451 | #else |
475 | #else | ||
476 | if (CPU_IsSupported_SHA2()) | 452 | if (CPU_IsSupported_SHA2()) |
477 | #endif | 453 | #endif |
478 | { | 454 | { |
479 | // printf("\n========== HW SHA256 ======== \n"); | 455 | // printf("\n========== HW SHA256 ======== \n"); |
480 | f = f_hw = Sha256_UpdateBlocks_HW; | 456 | f = f_hw = Sha256_UpdateBlocks_HW; |
481 | } | 457 | } |
482 | g_SHA256_FUNC_UPDATE_BLOCKS = f; | 458 | g_SHA256_FUNC_UPDATE_BLOCKS = f; |
483 | g_SHA256_FUNC_UPDATE_BLOCKS_HW = f_hw; | 459 | g_SHA256_FUNC_UPDATE_BLOCKS_HW = f_hw; |
484 | #endif | 460 | #endif |
485 | } | 461 | } |
486 | 462 | ||
463 | #undef U64C | ||
464 | #undef K | ||
487 | #undef S0 | 465 | #undef S0 |
488 | #undef S1 | 466 | #undef S1 |
489 | #undef s0 | 467 | #undef s0 |