github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/mining/tensority/cgo_algorithm/lib/sha3-allInOne.h (about)

     1  /* sha3-allInOne.h */
     2  #ifndef RHASH_SHA3_H
     3  #define RHASH_SHA3_H
     4  #include "ustd.h"
     5  
     6  #ifdef __cplusplus
     7  extern "C" {
     8  #endif
     9  
    10  #define sha3_224_hash_size  28
    11  #define sha3_256_hash_size  32
    12  #define sha3_384_hash_size  48
    13  #define sha3_512_hash_size  64
    14  #define sha3_max_permutation_size 25
    15  #define sha3_max_rate_in_qwords 24
    16  
    17  /**
    18   * SHA3 Algorithm context.
    19   */
    20  typedef struct sha3_ctx
    21  {
    22  	/* 1600 bits algorithm hashing state */
    23  	uint64_t hash[sha3_max_permutation_size];
    24  	/* 1536-bit buffer for leftovers */
    25  	uint64_t message[sha3_max_rate_in_qwords];
    26  	/* count of bytes in the message[] buffer */
    27  	unsigned rest;
    28  	/* size of a message block processed at once */
    29  	unsigned block_size;
    30  } sha3_ctx;
    31  
    32  /* methods for calculating the hash function */
    33  
    34  // void rhash_sha3_224_init(sha3_ctx *ctx);
    35  // void rhash_sha3_256_init(sha3_ctx *ctx);
    36  // void rhash_sha3_384_init(sha3_ctx *ctx);
    37  // void rhash_sha3_512_init(sha3_ctx *ctx);
    38  // void rhash_sha3_update(sha3_ctx *ctx, const unsigned char* msg, size_t size);
    39  // void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result);
    40  
    41  #ifdef USE_KECCAK
    42  #define rhash_keccak_224_init rhash_sha3_224_init
    43  #define rhash_keccak_256_init rhash_sha3_256_init
    44  #define rhash_keccak_384_init rhash_sha3_384_init
    45  #define rhash_keccak_512_init rhash_sha3_512_init
    46  #define rhash_keccak_update rhash_sha3_update
    47  inline void rhash_keccak_final(sha3_ctx *ctx, unsigned char* result);
    48  #endif
    49  
    50  #ifdef __cplusplus
    51  } /* extern "C" */
    52  #endif /* __cplusplus */
    53  
    54  
    55  
    56  // Adpated from sha3.c
    57  /*--------------------------------------------------------------------------*/
    58  /* sha3.c - an implementation of Secure Hash Algorithm 3 (Keccak).
    59   * based on the
    60   * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011
    61   * by Guido Bertoni, Joan Daemen, Michaƫl Peeters and Gilles Van Assche
    62   *
    63   * Copyright: 2013 Aleksey Kravchenko <rhash.admin@gmail.com>
    64   *
    65   * Permission is hereby granted,  free of charge,  to any person  obtaining a
    66   * copy of this software and associated documentation files (the "Software"),
    67   * to deal in the Software without restriction,  including without limitation
    68   * the rights to  use, copy, modify,  merge, publish, distribute, sublicense,
    69   * and/or sell copies  of  the Software,  and to permit  persons  to whom the
    70   * Software is furnished to do so.
    71   *
    72   * This program  is  distributed  in  the  hope  that it will be useful,  but
    73   * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    74   * or FITNESS FOR A PARTICULAR PURPOSE.  Use this program  at  your own risk!
    75   */
    76  
    77  #include <assert.h>
    78  #include <string.h>
    79  #include "byte_order-allInOne.h"
    80  
    81  /* constants */
    82  #define NumberOfRounds 24
    83  
    84  /* SHA3 (Keccak) constants for 24 rounds */
    85  static uint64_t keccak_round_constants[NumberOfRounds] = {
    86      I64(0x0000000000000001), I64(0x0000000000008082), I64(0x800000000000808A), I64(0x8000000080008000),
    87      I64(0x000000000000808B), I64(0x0000000080000001), I64(0x8000000080008081), I64(0x8000000000008009),
    88      I64(0x000000000000008A), I64(0x0000000000000088), I64(0x0000000080008009), I64(0x000000008000000A),
    89      I64(0x000000008000808B), I64(0x800000000000008B), I64(0x8000000000008089), I64(0x8000000000008003),
    90      I64(0x8000000000008002), I64(0x8000000000000080), I64(0x000000000000800A), I64(0x800000008000000A),
    91      I64(0x8000000080008081), I64(0x8000000000008080), I64(0x0000000080000001), I64(0x8000000080008008)
    92  };
    93  
    94  /* Initializing a sha3 context for given number of output bits */
    95  inline void rhash_keccak_init(sha3_ctx *ctx, unsigned bits)
    96  {
    97      /* NB: The Keccak capacity parameter = bits * 2 */
    98      unsigned rate = 1600 - bits * 2;
    99  
   100      memset(ctx, 0, sizeof(sha3_ctx));
   101      ctx->block_size = rate / 8;
   102      assert(rate <= 1600 && (rate % 64) == 0);
   103  }
   104  
   105  /**
   106   * Initialize context before calculating hash.
   107   *
   108   * @param ctx context to initialize
   109   */
   110  inline void rhash_sha3_224_init(sha3_ctx *ctx)
   111  {
   112      rhash_keccak_init(ctx, 224);
   113  }
   114  
   115  /**
   116   * Initialize context before calculating hash.
   117   *
   118   * @param ctx context to initialize
   119   */
   120  inline void rhash_sha3_256_init(sha3_ctx *ctx)
   121  {
   122      rhash_keccak_init(ctx, 256);
   123  }
   124  
   125  /**
   126   * Initialize context before calculating hash.
   127   *
   128   * @param ctx context to initialize
   129   */
   130  inline void rhash_sha3_384_init(sha3_ctx *ctx)
   131  {
   132      rhash_keccak_init(ctx, 384);
   133  }
   134  
   135  /**
   136   * Initialize context before calculating hash.
   137   *
   138   * @param ctx context to initialize
   139   */
   140  inline void rhash_sha3_512_init(sha3_ctx *ctx)
   141  {
   142      rhash_keccak_init(ctx, 512);
   143  }
   144  
   145  /* Keccak theta() transformation */
   146  inline void keccak_theta(uint64_t *A)
   147  {
   148      unsigned int x;
   149      uint64_t C[5], D[5];
   150  
   151      for (x = 0; x < 5; x++) {
   152          C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20];
   153      }
   154      D[0] = ROTL64(C[1], 1) ^ C[4];
   155      D[1] = ROTL64(C[2], 1) ^ C[0];
   156      D[2] = ROTL64(C[3], 1) ^ C[1];
   157      D[3] = ROTL64(C[4], 1) ^ C[2];
   158      D[4] = ROTL64(C[0], 1) ^ C[3];
   159  
   160      for (x = 0; x < 5; x++) {
   161          A[x]      ^= D[x];
   162          A[x + 5]  ^= D[x];
   163          A[x + 10] ^= D[x];
   164          A[x + 15] ^= D[x];
   165          A[x + 20] ^= D[x];
   166      }
   167  }
   168  
   169  /* Keccak pi() transformation */
   170  inline void keccak_pi(uint64_t *A)
   171  {
   172      uint64_t A1;
   173      A1 = A[1];
   174      A[ 1] = A[ 6];
   175      A[ 6] = A[ 9];
   176      A[ 9] = A[22];
   177      A[22] = A[14];
   178      A[14] = A[20];
   179      A[20] = A[ 2];
   180      A[ 2] = A[12];
   181      A[12] = A[13];
   182      A[13] = A[19];
   183      A[19] = A[23];
   184      A[23] = A[15];
   185      A[15] = A[ 4];
   186      A[ 4] = A[24];
   187      A[24] = A[21];
   188      A[21] = A[ 8];
   189      A[ 8] = A[16];
   190      A[16] = A[ 5];
   191      A[ 5] = A[ 3];
   192      A[ 3] = A[18];
   193      A[18] = A[17];
   194      A[17] = A[11];
   195      A[11] = A[ 7];
   196      A[ 7] = A[10];
   197      A[10] = A1;
   198      /* note: A[ 0] is left as is */
   199  }
   200  
   201  /* Keccak chi() transformation */
   202  inline void keccak_chi(uint64_t *A)
   203  {
   204      int i;
   205      for (i = 0; i < 25; i += 5) {
   206          uint64_t A0 = A[0 + i], A1 = A[1 + i];
   207          A[0 + i] ^= ~A1 & A[2 + i];
   208          A[1 + i] ^= ~A[2 + i] & A[3 + i];
   209          A[2 + i] ^= ~A[3 + i] & A[4 + i];
   210          A[3 + i] ^= ~A[4 + i] & A0;
   211          A[4 + i] ^= ~A0 & A1;
   212      }
   213  }
   214  
   215  inline void rhash_sha3_permutation(uint64_t *state)
   216  {
   217      int round;
   218      for (round = 0; round < NumberOfRounds; round++)
   219      {
   220          keccak_theta(state);
   221  
   222          /* apply Keccak rho() transformation */
   223          state[ 1] = ROTL64(state[ 1],  1);
   224          state[ 2] = ROTL64(state[ 2], 62);
   225          state[ 3] = ROTL64(state[ 3], 28);
   226          state[ 4] = ROTL64(state[ 4], 27);
   227          state[ 5] = ROTL64(state[ 5], 36);
   228          state[ 6] = ROTL64(state[ 6], 44);
   229          state[ 7] = ROTL64(state[ 7],  6);
   230          state[ 8] = ROTL64(state[ 8], 55);
   231          state[ 9] = ROTL64(state[ 9], 20);
   232          state[10] = ROTL64(state[10],  3);
   233          state[11] = ROTL64(state[11], 10);
   234          state[12] = ROTL64(state[12], 43);
   235          state[13] = ROTL64(state[13], 25);
   236          state[14] = ROTL64(state[14], 39);
   237          state[15] = ROTL64(state[15], 41);
   238          state[16] = ROTL64(state[16], 45);
   239          state[17] = ROTL64(state[17], 15);
   240          state[18] = ROTL64(state[18], 21);
   241          state[19] = ROTL64(state[19],  8);
   242          state[20] = ROTL64(state[20], 18);
   243          state[21] = ROTL64(state[21],  2);
   244          state[22] = ROTL64(state[22], 61);
   245          state[23] = ROTL64(state[23], 56);
   246          state[24] = ROTL64(state[24], 14);
   247  
   248          keccak_pi(state);
   249          keccak_chi(state);
   250  
   251          /* apply iota(state, round) */
   252          *state ^= keccak_round_constants[round];
   253      }
   254  }
   255  
   256  /**
   257   * The core transformation. Process the specified block of data.
   258   *
   259   * @param hash the algorithm state
   260   * @param block the message block to process
   261   * @param block_size the size of the processed block in bytes
   262   */
   263  inline void rhash_sha3_process_block(uint64_t hash[25], const uint64_t *block, size_t block_size)
   264  {
   265      /* expanded loop */
   266      hash[ 0] ^= le2me_64(block[ 0]);
   267      hash[ 1] ^= le2me_64(block[ 1]);
   268      hash[ 2] ^= le2me_64(block[ 2]);
   269      hash[ 3] ^= le2me_64(block[ 3]);
   270      hash[ 4] ^= le2me_64(block[ 4]);
   271      hash[ 5] ^= le2me_64(block[ 5]);
   272      hash[ 6] ^= le2me_64(block[ 6]);
   273      hash[ 7] ^= le2me_64(block[ 7]);
   274      hash[ 8] ^= le2me_64(block[ 8]);
   275      /* if not sha3-512 */
   276      if (block_size > 72) {
   277          hash[ 9] ^= le2me_64(block[ 9]);
   278          hash[10] ^= le2me_64(block[10]);
   279          hash[11] ^= le2me_64(block[11]);
   280          hash[12] ^= le2me_64(block[12]);
   281          /* if not sha3-384 */
   282          if (block_size > 104) {
   283              hash[13] ^= le2me_64(block[13]);
   284              hash[14] ^= le2me_64(block[14]);
   285              hash[15] ^= le2me_64(block[15]);
   286              hash[16] ^= le2me_64(block[16]);
   287              /* if not sha3-256 */
   288              if (block_size > 136) {
   289                  hash[17] ^= le2me_64(block[17]);
   290  #ifdef FULL_SHA3_FAMILY_SUPPORT
   291                  /* if not sha3-224 */
   292                  if (block_size > 144) {
   293                      hash[18] ^= le2me_64(block[18]);
   294                      hash[19] ^= le2me_64(block[19]);
   295                      hash[20] ^= le2me_64(block[20]);
   296                      hash[21] ^= le2me_64(block[21]);
   297                      hash[22] ^= le2me_64(block[22]);
   298                      hash[23] ^= le2me_64(block[23]);
   299                      hash[24] ^= le2me_64(block[24]);
   300                  }
   301  #endif
   302              }
   303          }
   304      }
   305      /* make a permutation of the hash */
   306      rhash_sha3_permutation(hash);
   307  }
   308  
   309  #define SHA3_FINALIZED 0x80000000
   310  
   311  /**
   312   * Calculate message hash.
   313   * Can be called repeatedly with chunks of the message to be hashed.
   314   *
   315   * @param ctx the algorithm context containing current hashing state
   316   * @param msg message chunk
   317   * @param size length of the message chunk
   318   */
   319  inline void rhash_sha3_update(sha3_ctx *ctx, const unsigned char *msg, size_t size)
   320  {
   321      size_t index = (size_t)ctx->rest;
   322      size_t block_size = (size_t)ctx->block_size;
   323  
   324      if (ctx->rest & SHA3_FINALIZED) return; /* too late for additional input */
   325      ctx->rest = (unsigned)((ctx->rest + size) % block_size);
   326  
   327      /* fill partial block */
   328      if (index) {
   329          size_t left = block_size - index;
   330          memcpy((char*)ctx->message + index, msg, (size < left ? size : left));
   331          if (size < left) return;
   332  
   333          /* process partial block */
   334          rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
   335          msg  += left;
   336          size -= left;
   337      }
   338      while (size >= block_size) {
   339          uint64_t* aligned_message_block;
   340          if (IS_ALIGNED_64(msg)) {
   341              /* the most common case is processing of an already aligned message
   342              without copying it */
   343              aligned_message_block = (uint64_t*)msg;
   344          } else {
   345              memcpy(ctx->message, msg, block_size);
   346              aligned_message_block = ctx->message;
   347          }
   348  
   349          rhash_sha3_process_block(ctx->hash, aligned_message_block, block_size);
   350          msg  += block_size;
   351          size -= block_size;
   352      }
   353      if (size) {
   354          memcpy(ctx->message, msg, size); /* save leftovers */
   355      }
   356  }
   357  
   358  /**
   359   * Store calculated hash into the given array.
   360   *
   361   * @param ctx the algorithm context containing current hashing state
   362   * @param result calculated hash in binary form
   363   */
   364  inline void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result)
   365  {
   366      size_t digest_length = 100 - ctx->block_size / 2;
   367      const size_t block_size = ctx->block_size;
   368  
   369      if (!(ctx->rest & SHA3_FINALIZED))
   370      {
   371          /* clear the rest of the data queue */
   372          memset((char*)ctx->message + ctx->rest, 0, block_size - ctx->rest);
   373          ((char*)ctx->message)[ctx->rest] |= 0x06;
   374          ((char*)ctx->message)[block_size - 1] |= 0x80;
   375  
   376          /* process final block */
   377          rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
   378          ctx->rest = SHA3_FINALIZED; /* mark context as finalized */
   379      }
   380  
   381      assert(block_size > digest_length);
   382      if (result) me64_to_le_str(result, ctx->hash, digest_length);
   383  }
   384  
   385  #ifdef USE_KECCAK
   386  /**
   387  * Store calculated hash into the given array.
   388  *
   389  * @param ctx the algorithm context containing current hashing state
   390  * @param result calculated hash in binary form
   391  */
   392  inline void rhash_keccak_final(sha3_ctx *ctx, unsigned char* result)
   393  {
   394      size_t digest_length = 100 - ctx->block_size / 2;
   395      const size_t block_size = ctx->block_size;
   396  
   397      if (!(ctx->rest & SHA3_FINALIZED))
   398      {
   399          /* clear the rest of the data queue */
   400          memset((char*)ctx->message + ctx->rest, 0, block_size - ctx->rest);
   401          ((char*)ctx->message)[ctx->rest] |= 0x01;
   402          ((char*)ctx->message)[block_size - 1] |= 0x80;
   403  
   404          /* process final block */
   405          rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
   406          ctx->rest = SHA3_FINALIZED; /* mark context as finalized */
   407      }
   408  
   409      assert(block_size > digest_length);
   410      if (result) me64_to_le_str(result, ctx->hash, digest_length);
   411  }
   412  #endif /* USE_KECCAK */
   413  
   414  
   415  
   416  #endif /* RHASH_SHA3_H */