Fossil

Check-in [493321d4]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Optimizations to the SHA3 algorithm.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:493321d44f314d33d44cd779ce430e4d80c5b582
User & Date: drh 2017-02-25 20:33:50
Context
2017-02-26
16:30
Add the --size argument to the sha3sum command. check-in: ccdafa2a user: drh tags: trunk
2017-02-25
20:33
Optimizations to the SHA3 algorithm. check-in: 493321d4 user: drh tags: trunk
20:14
Updates to the "sha3sum" help text. check-in: b015ad71 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/sha3.c.

1
2
3
4
5























6
7
8
9
10
11
12
...
340
341
342
343
344
345
346
347
348
349
350
351
352
353







354
355
356
357
358
359
360


361
362
363
364
365
366
367
368
369
370
371
372












373





374

375
376
377
378
379
380
381
/*
** This file contains an implementation of SHA3 (Keccak) hashing.
*/
#include "config.h"
#include "sha3.h"
























/*
** State structure for a SHA3 hash in progress
*/ 
typedef struct SHA3Context SHA3Context;
struct SHA3Context {
  union {
................................................................................

/*
** Initialize a new hash.  iSize determines the size of the hash
** in bits and should be one of 224, 256, 384, or 512.  Or iSize
** can be zero to use the default hash size of 224 bits.
*/
static void SHA3Init(SHA3Context *p, int iSize){
  static unsigned int one = 1;
  memset(p, 0, sizeof(*p));
  if( iSize>=256 && iSize<=512 ){
    p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
  }else{
    p->nRate = 144;
  }







  if( 1==*(unsigned char*)&one ){
    /* Little endian.  No byte swapping. */
    p->ixMask = 0;
  }else{
    /* Big endian.  Byte swap. */
    p->ixMask = 7;
  }


}

/*
** Make consecutive calls to the SHA3Update function to add new content
** to the hash
*/
static void SHA3Update(
  SHA3Context *p,
  const unsigned char *aData,
  unsigned int nData
){
  unsigned int i;












  for(i=0; i<nData; i++){





    p->u.x[p->nLoaded^p->ixMask] ^= aData[i];

    p->nLoaded++;
    if( p->nLoaded==p->nRate ){
      KeccakF1600Step(p);
      p->nLoaded = 0;
    }
  }
}





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<






>
>
>
>
>
>
>
|
|
|
|
|
|
|
>
>











|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>

>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
/*
** This file contains an implementation of SHA3 (Keccak) hashing.
*/
#include "config.h"
#include "sha3.h"

/*
** Macros to determine whether the machine is big or little endian,
** and whether or not that determination is run-time or compile-time.
**
** For best performance, an attempt is made to guess at the byte-order
** using C-preprocessor macros.  If that is unsuccessful, or if
** -DSHA3_BYTEORDER=0 is set, then byte-order is determined
** at run-time.
*/
#ifndef SHA3_BYTEORDER
# if defined(i386)     || defined(__i386__)   || defined(_M_IX86) ||    \
     defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)  ||    \
     defined(_M_AMD64) || defined(_M_ARM)     || defined(__x86)   ||    \
     defined(__arm__)
#   define SHA3_BYTEORDER    1234
# elif defined(sparc)    || defined(__ppc__)
#   define SHA3_BYTEORDER    4321
# else
#   define SHA3_BYTEORDER 0
# endif
#endif


/*
** State structure for a SHA3 hash in progress
*/ 
typedef struct SHA3Context SHA3Context;
struct SHA3Context {
  union {
................................................................................

/*
** Initialize a new hash.  iSize determines the size of the hash
** in bits and should be one of 224, 256, 384, or 512.  Or iSize
** can be zero to use the default hash size of 224 bits.
*/
static void SHA3Init(SHA3Context *p, int iSize){

  memset(p, 0, sizeof(*p));
  if( iSize>=256 && iSize<=512 ){
    p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
  }else{
    p->nRate = 144;
  }
#if SHA3_BYTEORDER==1234
  /* Known to be little-endian at compile-time. No-op */
#elif SHA3_BYTEORDER==4321
  p->ixMask = 7;  /* Big-endian */
#else
  {
    static unsigned int one = 1;
    if( 1==*(unsigned char*)&one ){
      /* Little endian.  No byte swapping. */
      p->ixMask = 0;
    }else{
      /* Big endian.  Byte swap. */
      p->ixMask = 7;
    }
  }
#endif
}

/*
** Make consecutive calls to the SHA3Update function to add new content
** to the hash
*/
static void SHA3Update(
  SHA3Context *p,
  const unsigned char *aData,
  unsigned int nData
){
  unsigned int i = 0;
#if SHA3_BYTEORDER==1234
  if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){
    for(; i<nData-7; i+=8){
      p->u.s[p->nLoaded/8] ^= *(u64*)&aData[i];
      p->nLoaded += 8;
      if( p->nLoaded>=p->nRate ){
        KeccakF1600Step(p);
        p->nLoaded = 0;
      }
    }
  }
#endif
  for(; i<nData; i++){
#if SHA1_BYTEORDER==1234
    p->u.x[p->nLoaded] ^= aData[i];
#elif SHA3_BYTEORDER==4321
    p->u.x[p->nLoaded^0x07] ^= aData[i];
#else
    p->u.x[p->nLoaded^p->ixMask] ^= aData[i];
#endif
    p->nLoaded++;
    if( p->nLoaded==p->nRate ){
      KeccakF1600Step(p);
      p->nLoaded = 0;
    }
  }
}