PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/hash - hash_sha3.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 9 9 100.0 %
Date: 2022-01-29 Functions: 13 13 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2018 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Author: Sara Golemon <pollita@php.net>                               |
      16             :    +----------------------------------------------------------------------+
      17             : */
      18             : 
      19             : #include "php_hash.h"
      20             : #include "php_hash_sha3.h"
      21             : 
      22             : #ifdef HAVE_SLOW_HASH3
      23             : // ================= slow algo ==============================================
      24             : 
      25             : #if (defined(__APPLE__) || defined(__APPLE_CC__)) && \
      26             :     (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__))
      27             : # if defined(__LITTLE_ENDIAN__)
      28             : #  undef WORDS_BIGENDIAN
      29             : # else
      30             : #  if defined(__BIG_ENDIAN__)
      31             : #   define WORDS_BIGENDIAN
      32             : #  endif
      33             : # endif
      34             : #endif
      35             : 
      36             : static inline uint64_t rol64(uint64_t v, unsigned char b) {
      37             :         return (v << b) | (v >> (64 - b));
      38             : }
      39             : static inline unsigned char idx(unsigned char x, unsigned char y) {
      40             :         return x + (5 * y);
      41             : }
      42             : 
      43             : #ifdef WORDS_BIGENDIAN
      44             : static inline uint64_t load64(const unsigned char* x) {
      45             :         signed char i;
      46             :         uint64_t ret = 0;
      47             :         for (i = 7; i >= 0; --i) {
      48             :                 ret <<= 8;
      49             :                 ret |= x[i];
      50             :         }
      51             :         return ret;
      52             : }
      53             : static inline void store64(unsigned char* x, uint64_t val) {
      54             :         char i;
      55             :         for (i = 0; i < 8; ++i) {
      56             :                 x[i] = val & 0xFF;
      57             :                 val >>= 8;
      58             :         }
      59             : }
      60             : static inline void xor64(unsigned char* x, uint64_t val) {
      61             :         char i;
      62             :         for (i = 0; i < 8; ++i) {
      63             :                 x[i] ^= val & 0xFF;
      64             :                 val >>= 8;
      65             :         }
      66             : }
      67             : # define readLane(x, y)     load64(ctx->state+sizeof(uint64_t)*idx(x, y))
      68             : # define writeLane(x, y, v) store64(ctx->state+sizeof(uint64_t)*idx(x, y), v)
      69             : # define XORLane(x, y, v)   xor64(ctx->state+sizeof(uint64_t)*idx(x, y), v)
      70             : #else
      71             : # define readLane(x, y)     (((uint64_t*)ctx->state)[idx(x,y)])
      72             : # define writeLane(x, y, v) (((uint64_t*)ctx->state)[idx(x,y)] = v)
      73             : # define XORLane(x, y, v)   (((uint64_t*)ctx->state)[idx(x,y)] ^= v)
      74             : #endif
      75             : 
      76             : static inline char LFSR86540(unsigned char* pLFSR)
      77             : {
      78             :         unsigned char LFSR = *pLFSR;
      79             :         char result = LFSR & 0x01;
      80             :         if (LFSR & 0x80) {
      81             :                 // Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1
      82             :                 LFSR = (LFSR << 1) ^ 0x71;
      83             :         } else {
      84             :                 LFSR <<= 1;
      85             :         }
      86             :         *pLFSR = LFSR;
      87             :         return result;
      88             : }
      89             : 
      90             : static void permute(PHP_SHA3_CTX* ctx) {
      91             :         unsigned char LFSRstate = 0x01;
      92             :         unsigned char round;
      93             : 
      94             :         for (round = 0; round < 24; ++round) {
      95             :                 { // Theta step (see [Keccak Reference, Section 2.3.2])
      96             :                         uint64_t C[5], D;
      97             :                         unsigned char x, y;
      98             :                         for (x = 0; x < 5; ++x) {
      99             :                                 C[x] = readLane(x, 0) ^ readLane(x, 1) ^
     100             :                                 readLane(x, 2) ^ readLane(x, 3) ^ readLane(x, 4);
     101             :                         }
     102             :                         for (x = 0; x < 5; ++x) {
     103             :                                 D = C[(x+4)%5] ^ rol64(C[(x+1)%5], 1);
     104             :                                 for (y = 0; y < 5; ++y) {
     105             :                                         XORLane(x, y, D);
     106             :                                 }
     107             :                         }
     108             :                 }
     109             : 
     110             :                 { // p and Pi steps (see [Keccak Reference, Sections 2.3.3 and 2.3.4])
     111             :                         unsigned char x = 1, y = 0, t;
     112             :                         uint64_t current = readLane(x, y);
     113             :                         for (t = 0; t < 24; ++t) {
     114             :                                 unsigned char r = ((t + 1) * (t + 2) / 2) % 64;
     115             :                                 unsigned char Y = (2*x + 3*y) % 5;
     116             :                                 uint64_t temp;
     117             :                                 x = y;
     118             :                                 y = Y;
     119             :                                 temp = readLane(x, y);
     120             :                                 writeLane(x, y, rol64(current, r));
     121             :                                 current = temp;
     122             :                         }
     123             :                 }
     124             : 
     125             :                 { // X step (see [Keccak Reference, Section 2.3.1])
     126             :                         unsigned char x, y;
     127             :                         for (y = 0; y < 5; ++y) {
     128             :                                 uint64_t temp[5];
     129             :                                 for (x = 0; x < 5; ++x) {
     130             :                                         temp[x] = readLane(x, y);
     131             :                                 }
     132             :                                 for (x = 0; x < 5; ++x) {
     133             :                                         writeLane(x, y, temp[x] ^((~temp[(x+1)%5]) & temp[(x+2)%5]));
     134             :                                 }
     135             :                         }
     136             :                 }
     137             : 
     138             :                 { // i step (see [Keccak Reference, Section 2.3.5])
     139             :                         unsigned char j;
     140             :                         for (j = 0; j < 7; ++j) {
     141             :                                 if (LFSR86540(&LFSRstate)) {
     142             :                                         uint64_t bitPos = (1<<j) - 1;
     143             :                                         XORLane(0, 0, (uint64_t)1 << bitPos);
     144             :                                 }
     145             :                         }
     146             :                 }
     147             :         }
     148             : }
     149             : 
     150             : // ==========================================================================
     151             : 
     152             : static void PHP_SHA3_Init(PHP_SHA3_CTX* ctx,
     153             :                           int bits) {
     154             :         memset(ctx, 0, sizeof(PHP_SHA3_CTX));
     155             : }
     156             : 
     157             : static void PHP_SHA3_Update(PHP_SHA3_CTX* ctx,
     158             :                             const unsigned char* buf,
     159             :                             unsigned int count,
     160             :                             size_t block_size) {
     161             :         while (count > 0) {
     162             :                 unsigned int len = block_size - ctx->pos;
     163             :                 if (len > count) len = count;
     164             :                 count -= len;
     165             :                 while (len-- > 0) {
     166             :                         ctx->state[ctx->pos++] ^= *(buf++);
     167             :                 }
     168             :                 if (ctx->pos >= block_size) {
     169             :                         permute(ctx);
     170             :                         ctx->pos = 0;
     171             :                 }
     172             :         }
     173             : }
     174             : 
     175             : static void PHP_SHA3_Final(unsigned char* digest,
     176             :                            PHP_SHA3_CTX* ctx,
     177             :                            int block_size,
     178             :                            int digest_size) {
     179             :         int len = digest_size;
     180             : 
     181             :         // Pad state to finalize
     182             :         ctx->state[ctx->pos++] ^= 0x06;
     183             :         ctx->state[block_size-1] ^= 0x80;
     184             :         permute(ctx);
     185             : 
     186             :         // Square output for digest
     187             :         for(;;) {
     188             :                 int bs = (len < block_size) ? len : block_size;
     189             :                 memcpy(digest, ctx->state, bs);
     190             :                 digest += bs;
     191             :                 len -= bs;
     192             :                 if (!len) break;
     193             :                 permute(ctx);
     194             :         }
     195             : 
     196             :         // Zero out context
     197             :         ZEND_SECURE_ZERO(ctx, sizeof(PHP_SHA3_CTX));
     198             : }
     199             : 
     200             : // ==========================================================================
     201             : 
     202             : #define DECLARE_SHA3_OPS(bits) \
     203             : void PHP_SHA3##bits##Init(PHP_SHA3_##bits##_CTX* ctx) { \
     204             :         PHP_SHA3_Init(ctx, bits); \
     205             : } \
     206             : void PHP_SHA3##bits##Update(PHP_SHA3_##bits##_CTX* ctx, \
     207             :                             const unsigned char* input, \
     208             :                             unsigned int inputLen) { \
     209             :         PHP_SHA3_Update(ctx, input, inputLen, \
     210             :                     (1600 - (2 * bits)) >> 3); \
     211             : } \
     212             : void PHP_SHA3##bits##Final(unsigned char* digest, \
     213             :                            PHP_SHA3_##bits##_CTX* ctx) { \
     214             :         PHP_SHA3_Final(digest, ctx, \
     215             :                    (1600 - (2 * bits)) >> 3, \
     216             :                    bits >> 3); \
     217             : } \
     218             : const php_hash_ops php_hash_sha3_##bits##_ops = { \
     219             :         (php_hash_init_func_t) PHP_SHA3##bits##Init, \
     220             :         (php_hash_update_func_t) PHP_SHA3##bits##Update, \
     221             :         (php_hash_final_func_t) PHP_SHA3##bits##Final, \
     222             :         php_hash_copy, \
     223             :         bits >> 3, \
     224             :         (1600 - (2 * bits)) >> 3, \
     225             :         sizeof(PHP_SHA3_##bits##_CTX), \
     226             :         1 \
     227             : }
     228             : 
     229             : #else
     230             : 
     231             : // ================= fast algo ==============================================
     232             : 
     233             : #define SUCCESS SHA3_SUCCESS /* Avoid conflict between KeccacHash.h and zend_types.h */
     234             : #include "KeccakHash.h"
     235             : 
     236             : 
     237             : // ==========================================================================
     238             : 
     239          16 : static int hash_sha3_copy(const void *ops, void *orig_context, void *dest_context)
     240             : {
     241          16 :         PHP_SHA3_CTX* orig = (PHP_SHA3_CTX*)orig_context;
     242          16 :         PHP_SHA3_CTX* dest = (PHP_SHA3_CTX*)dest_context;
     243          16 :         memcpy(dest->hashinstance, orig->hashinstance, sizeof(Keccak_HashInstance));
     244          16 :         return SUCCESS;
     245             : }
     246             : 
     247             : #define DECLARE_SHA3_OPS(bits) \
     248             : void PHP_SHA3##bits##Init(PHP_SHA3_##bits##_CTX* ctx) { \
     249             :         ctx->hashinstance = emalloc(sizeof(Keccak_HashInstance)); \
     250             :         Keccak_HashInitialize_SHA3_##bits((Keccak_HashInstance *)ctx->hashinstance); \
     251             : } \
     252             : void PHP_SHA3##bits##Update(PHP_SHA3_##bits##_CTX* ctx, \
     253             :                             const unsigned char* input, \
     254             :                             unsigned int inputLen) { \
     255             :         Keccak_HashUpdate((Keccak_HashInstance *)ctx->hashinstance, input, inputLen * 8); \
     256             : } \
     257             : void PHP_SHA3##bits##Final(unsigned char* digest, \
     258             :                            PHP_SHA3_##bits##_CTX* ctx) { \
     259             :         Keccak_HashFinal((Keccak_HashInstance *)ctx->hashinstance, digest); \
     260             :         efree(ctx->hashinstance); \
     261             :         ctx->hashinstance = NULL; \
     262             : } \
     263             : const php_hash_ops php_hash_sha3_##bits##_ops = { \
     264             :         (php_hash_init_func_t) PHP_SHA3##bits##Init, \
     265             :         (php_hash_update_func_t) PHP_SHA3##bits##Update, \
     266             :         (php_hash_final_func_t) PHP_SHA3##bits##Final, \
     267             :         hash_sha3_copy, \
     268             :         bits >> 3, \
     269             :         (1600 - (2 * bits)) >> 3, \
     270             :         sizeof(PHP_SHA3_##bits##_CTX), \
     271             :         1 \
     272             : }
     273             : 
     274             : #endif
     275             : // ================= both algo ==============================================
     276             : 
     277          40 : DECLARE_SHA3_OPS(224);
     278          40 : DECLARE_SHA3_OPS(256);
     279          40 : DECLARE_SHA3_OPS(384);
     280          40 : DECLARE_SHA3_OPS(512);
     281             : 
     282             : #undef DECLARE_SHA3_OPS
     283             : 
     284             : /*
     285             :  * Local variables:
     286             :  * tab-width: 4
     287             :  * c-basic-offset: 4
     288             :  * End:
     289             :  * vim600: sw=4 ts=4 fdm=marker
     290             :  * vim<600: sw=4 ts=4
     291             :  */

Generated by: LCOV version 1.10

Generated at Sat, 29 Jan 2022 07:14:32 +0000 (28 minutes ago)

Copyright © 2005-2022 The PHP Group
All rights reserved.