Fossil SCM

Optimizations to the SHA3 algorithm.

drh 2017-02-25 20:33 trunk
Commit 493321d44f314d33d44cd779ce430e4d80c5b582
1 file changed +58 -9
+58 -9
--- src/sha3.c
+++ src/sha3.c
@@ -1,10 +1,33 @@
11
/*
22
** This file contains an implementation of SHA3 (Keccak) hashing.
33
*/
44
#include "config.h"
55
#include "sha3.h"
6
+
7
+/*
8
+** Macros to determine whether the machine is big or little endian,
9
+** and whether or not that determination is run-time or compile-time.
10
+**
11
+** For best performance, an attempt is made to guess at the byte-order
12
+** using C-preprocessor macros. If that is unsuccessful, or if
13
+** -DSHA3_BYTEORDER=0 is set, then byte-order is determined
14
+** at run-time.
15
+*/
16
+#ifndef SHA3_BYTEORDER
17
+# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
18
+ defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
19
+ defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
20
+ defined(__arm__)
21
+# define SHA3_BYTEORDER 1234
22
+# elif defined(sparc) || defined(__ppc__)
23
+# define SHA3_BYTEORDER 4321
24
+# else
25
+# define SHA3_BYTEORDER 0
26
+# endif
27
+#endif
28
+
629
730
/*
831
** State structure for a SHA3 hash in progress
932
*/
1033
typedef struct SHA3Context SHA3Context;
@@ -342,24 +365,32 @@
342365
** Initialize a new hash. iSize determines the size of the hash
343366
** in bits and should be one of 224, 256, 384, or 512. Or iSize
344367
** can be zero to use the default hash size of 224 bits.
345368
*/
346369
static void SHA3Init(SHA3Context *p, int iSize){
347
- static unsigned int one = 1;
348370
memset(p, 0, sizeof(*p));
349371
if( iSize>=256 && iSize<=512 ){
350372
p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
351373
}else{
352374
p->nRate = 144;
353375
}
354
- if( 1==*(unsigned char*)&one ){
355
- /* Little endian. No byte swapping. */
356
- p->ixMask = 0;
357
- }else{
358
- /* Big endian. Byte swap. */
359
- p->ixMask = 7;
376
+#if SHA3_BYTEORDER==1234
377
+ /* Known to be little-endian at compile-time. No-op */
378
+#elif SHA3_BYTEORDER==4321
379
+ p->ixMask = 7; /* Big-endian */
380
+#else
381
+ {
382
+ static unsigned int one = 1;
383
+ if( 1==*(unsigned char*)&one ){
384
+ /* Little endian. No byte swapping. */
385
+ p->ixMask = 0;
386
+ }else{
387
+ /* Big endian. Byte swap. */
388
+ p->ixMask = 7;
389
+ }
360390
}
391
+#endif
361392
}
362393
363394
/*
364395
** Make consecutive calls to the SHA3Update function to add new content
365396
** to the hash
@@ -367,13 +398,31 @@
367398
static void SHA3Update(
368399
SHA3Context *p,
369400
const unsigned char *aData,
370401
unsigned int nData
371402
){
372
- unsigned int i;
373
- for(i=0; i<nData; i++){
403
+ unsigned int i = 0;
404
+#if SHA3_BYTEORDER==1234
405
+ if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){
406
+ for(; i<nData-7; i+=8){
407
+ p->u.s[p->nLoaded/8] ^= *(u64*)&aData[i];
408
+ p->nLoaded += 8;
409
+ if( p->nLoaded>=p->nRate ){
410
+ KeccakF1600Step(p);
411
+ p->nLoaded = 0;
412
+ }
413
+ }
414
+ }
415
+#endif
416
+ for(; i<nData; i++){
417
+#if SHA1_BYTEORDER==1234
418
+ p->u.x[p->nLoaded] ^= aData[i];
419
+#elif SHA3_BYTEORDER==4321
420
+ p->u.x[p->nLoaded^0x07] ^= aData[i];
421
+#else
374422
p->u.x[p->nLoaded^p->ixMask] ^= aData[i];
423
+#endif
375424
p->nLoaded++;
376425
if( p->nLoaded==p->nRate ){
377426
KeccakF1600Step(p);
378427
p->nLoaded = 0;
379428
}
380429
--- src/sha3.c
+++ src/sha3.c
@@ -1,10 +1,33 @@
1 /*
2 ** This file contains an implementation of SHA3 (Keccak) hashing.
3 */
4 #include "config.h"
5 #include "sha3.h"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
7 /*
8 ** State structure for a SHA3 hash in progress
9 */
10 typedef struct SHA3Context SHA3Context;
@@ -342,24 +365,32 @@
342 ** Initialize a new hash. iSize determines the size of the hash
343 ** in bits and should be one of 224, 256, 384, or 512. Or iSize
344 ** can be zero to use the default hash size of 224 bits.
345 */
346 static void SHA3Init(SHA3Context *p, int iSize){
347 static unsigned int one = 1;
348 memset(p, 0, sizeof(*p));
349 if( iSize>=256 && iSize<=512 ){
350 p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
351 }else{
352 p->nRate = 144;
353 }
354 if( 1==*(unsigned char*)&one ){
355 /* Little endian. No byte swapping. */
356 p->ixMask = 0;
357 }else{
358 /* Big endian. Byte swap. */
359 p->ixMask = 7;
 
 
 
 
 
 
 
 
360 }
 
361 }
362
363 /*
364 ** Make consecutive calls to the SHA3Update function to add new content
365 ** to the hash
@@ -367,13 +398,31 @@
367 static void SHA3Update(
368 SHA3Context *p,
369 const unsigned char *aData,
370 unsigned int nData
371 ){
372 unsigned int i;
373 for(i=0; i<nData; i++){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374 p->u.x[p->nLoaded^p->ixMask] ^= aData[i];
 
375 p->nLoaded++;
376 if( p->nLoaded==p->nRate ){
377 KeccakF1600Step(p);
378 p->nLoaded = 0;
379 }
380
--- src/sha3.c
+++ src/sha3.c
@@ -1,10 +1,33 @@
1 /*
2 ** This file contains an implementation of SHA3 (Keccak) hashing.
3 */
4 #include "config.h"
5 #include "sha3.h"
6
7 /*
8 ** Macros to determine whether the machine is big or little endian,
9 ** and whether or not that determination is run-time or compile-time.
10 **
11 ** For best performance, an attempt is made to guess at the byte-order
12 ** using C-preprocessor macros. If that is unsuccessful, or if
13 ** -DSHA3_BYTEORDER=0 is set, then byte-order is determined
14 ** at run-time.
15 */
16 #ifndef SHA3_BYTEORDER
17 # if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
18 defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
19 defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
20 defined(__arm__)
21 # define SHA3_BYTEORDER 1234
22 # elif defined(sparc) || defined(__ppc__)
23 # define SHA3_BYTEORDER 4321
24 # else
25 # define SHA3_BYTEORDER 0
26 # endif
27 #endif
28
29
30 /*
31 ** State structure for a SHA3 hash in progress
32 */
33 typedef struct SHA3Context SHA3Context;
@@ -342,24 +365,32 @@
365 ** Initialize a new hash. iSize determines the size of the hash
366 ** in bits and should be one of 224, 256, 384, or 512. Or iSize
367 ** can be zero to use the default hash size of 224 bits.
368 */
369 static void SHA3Init(SHA3Context *p, int iSize){
 
370 memset(p, 0, sizeof(*p));
371 if( iSize>=256 && iSize<=512 ){
372 p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
373 }else{
374 p->nRate = 144;
375 }
376 #if SHA3_BYTEORDER==1234
377 /* Known to be little-endian at compile-time. No-op */
378 #elif SHA3_BYTEORDER==4321
379 p->ixMask = 7; /* Big-endian */
380 #else
381 {
382 static unsigned int one = 1;
383 if( 1==*(unsigned char*)&one ){
384 /* Little endian. No byte swapping. */
385 p->ixMask = 0;
386 }else{
387 /* Big endian. Byte swap. */
388 p->ixMask = 7;
389 }
390 }
391 #endif
392 }
393
394 /*
395 ** Make consecutive calls to the SHA3Update function to add new content
396 ** to the hash
@@ -367,13 +398,31 @@
398 static void SHA3Update(
399 SHA3Context *p,
400 const unsigned char *aData,
401 unsigned int nData
402 ){
403 unsigned int i = 0;
404 #if SHA3_BYTEORDER==1234
405 if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){
406 for(; i<nData-7; i+=8){
407 p->u.s[p->nLoaded/8] ^= *(u64*)&aData[i];
408 p->nLoaded += 8;
409 if( p->nLoaded>=p->nRate ){
410 KeccakF1600Step(p);
411 p->nLoaded = 0;
412 }
413 }
414 }
415 #endif
416 for(; i<nData; i++){
417 #if SHA1_BYTEORDER==1234
418 p->u.x[p->nLoaded] ^= aData[i];
419 #elif SHA3_BYTEORDER==4321
420 p->u.x[p->nLoaded^0x07] ^= aData[i];
421 #else
422 p->u.x[p->nLoaded^p->ixMask] ^= aData[i];
423 #endif
424 p->nLoaded++;
425 if( p->nLoaded==p->nRate ){
426 KeccakF1600Step(p);
427 p->nLoaded = 0;
428 }
429

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button