LCOV - code coverage report
Current view: top level - src/jamidht/eth/libdevcore - SHA3.cpp (source / functions) Coverage Total Hit
Test: jami-coverage-filtered.info Lines: 91.4 % 35 32
Test Date: 2026-06-13 09:18:46 Functions: 54.5 % 11 6

            Line data    Source code
       1              : /*
       2              :     This file is part of cpp-ethereum.
       3              : 
       4              :     cpp-ethereum is free software: you can redistribute it and/or modify
       5              :     it under the terms of the GNU General Public License as published by
       6              :     the Free Software Foundation, either version 3 of the License, or
       7              :     (at your option) any later version.
       8              : 
       9              :     cpp-ethereum is distributed in the hope that it will be useful,
      10              :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11              :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12              :     GNU General Public License for more details.
      13              : 
      14              :     You should have received a copy of the GNU General Public License
      15              :     along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
      16              : */
      17              : /** @file SHA3.cpp
      18              :  * @author Gav Wood <i@gavwood.com>
      19              :  * @date 2014
      20              :  */
      21              : 
      22              : #include "SHA3.h"
      23              : #include <cstdint>
      24              : #include <cstdio>
      25              : #include <cstdlib>
      26              : #include <cstring>
      27              : using namespace std;
      28              : using namespace dev;
      29              : 
      30              : namespace dev {
      31              : 
      32              : h256 EmptySHA3 = sha3(bytesConstRef());
      33              : 
      34              : namespace keccak {
      35              : 
      36              : /** libkeccak-tiny
      37              :  *
      38              :  * A single-file implementation of SHA-3 and SHAKE.
      39              :  *
      40              :  * Implementor: David Leon Gil
      41              :  * License: CC0, attribution kindly requested. Blame taken too,
      42              :  * but not liability.
      43              :  */
      44              : 
      45              : #define decshake(bits) int shake##bits(uint8_t*, size_t, const uint8_t*, size_t);
      46              : 
      47              : #define decsha3(bits) int sha3_##bits(uint8_t*, size_t, const uint8_t*, size_t);
      48              : 
      49              : decshake(128) decshake(256) decsha3(224) decsha3(256) decsha3(384) decsha3(512)
      50              : 
      51              :     /******** The Keccak-f[1600] permutation ********/
      52              : 
      53              :     /*** Constants. ***/
      54              :     static const uint8_t rho[24]
      55              :     = {1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44};
      56              : static const uint8_t pi[24] = {10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1};
      57              : static const uint64_t RC[24] = {1ULL,
      58              :                                 0x8082ULL,
      59              :                                 0x800000000000808aULL,
      60              :                                 0x8000000080008000ULL,
      61              :                                 0x808bULL,
      62              :                                 0x80000001ULL,
      63              :                                 0x8000000080008081ULL,
      64              :                                 0x8000000000008009ULL,
      65              :                                 0x8aULL,
      66              :                                 0x88ULL,
      67              :                                 0x80008009ULL,
      68              :                                 0x8000000aULL,
      69              :                                 0x8000808bULL,
      70              :                                 0x800000000000008bULL,
      71              :                                 0x8000000000008089ULL,
      72              :                                 0x8000000000008003ULL,
      73              :                                 0x8000000000008002ULL,
      74              :                                 0x8000000000000080ULL,
      75              :                                 0x800aULL,
      76              :                                 0x800000008000000aULL,
      77              :                                 0x8000000080008081ULL,
      78              :                                 0x8000000000008080ULL,
      79              :                                 0x80000001ULL,
      80              :                                 0x8000000080008008ULL};
      81              : 
      82              : /*** Helper macros to unroll the permutation. ***/
      83              : #define rol(x, s)   (((x) << s) | ((x) >> (64 - s)))
      84              : #define REPEAT6(e)  e e e e e e
      85              : #define REPEAT24(e) REPEAT6(e e e e)
      86              : #define REPEAT5(e)  e e e e e
      87              : #define FOR5(v, s, e) \
      88              :     v = 0; \
      89              :     REPEAT5(e; v += s;)
      90              : 
      91              : /*** Keccak-f[1600] ***/
      92              : static inline void
      93         1545 : keccakf(void* state)
      94              : {
      95         1545 :     uint64_t* a = (uint64_t*) state;
      96         1545 :     uint64_t b[5] = {0};
      97         1545 :     uint64_t t = 0;
      98              :     uint8_t x, y;
      99              : 
     100        38625 :     for (int i = 0; i < 24; i++) {
     101              :         // Theta
     102        37080 :         FOR5(x, 1, b[x] = 0; FOR5(y, 5, b[x] ^= a[x + y];))
     103        37080 :         FOR5(x, 1, FOR5(y, 5, a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1);))
     104              :         // Rho and pi
     105        37080 :         t = a[1];
     106        37080 :         x = 0;
     107        37080 :         REPEAT24(b[0] = a[pi[x]]; a[pi[x]] = rol(t, rho[x]); t = b[0]; x++;)
     108              :         // Chi
     109        37080 :         FOR5(y, 5, FOR5(x, 1, b[x] = a[y + x];) FOR5(x, 1, a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]);))
     110              :         // Iota
     111        37080 :         a[0] ^= RC[i];
     112              :     }
     113         1545 : }
     114              : 
     115              : /******** The FIPS202-defined functions. ********/
     116              : 
     117              : /*** Some helper macros. ***/
     118              : 
     119              : #define _(S) \
     120              :     do { \
     121              :         S \
     122              :     } while (0)
     123              : #define FOR(i, ST, L, S) _(for (size_t i = 0; i < L; i += ST) { S; })
     124              : #define mkapply_ds(NAME, S) \
     125              :     static inline void NAME(uint8_t* dst, const uint8_t* src, size_t len) \
     126              :     { \
     127              :         FOR(i, 1, len, S); \
     128              :     }
     129              : #define mkapply_sd(NAME, S) \
     130              :     static inline void NAME(const uint8_t* src, uint8_t* dst, size_t len) \
     131              :     { \
     132              :         FOR(i, 1, len, S); \
     133              :     }
     134              : 
     135        97865 : mkapply_ds(xorin, dst[i] ^= src[i])     // xorin
     136        50985 :     mkapply_sd(setout, dst[i] = src[i]) // setout
     137              : 
     138              : #define P    keccakf
     139              : #define Plen 200
     140              : 
     141              : // Fold P*F over the full blocks of an input.
     142              : #define foldP(I, L, F) \
     143              :     while (L >= rate) { \
     144              :         F(a, I, rate); \
     145              :         P(a); \
     146              :         I += rate; \
     147              :         L -= rate; \
     148              :     }
     149              : 
     150              :     /** The sponge-based hash construction. **/
     151         1545 :     static inline int hash(uint8_t* out, size_t outlen, const uint8_t* in, size_t inlen, size_t rate, uint8_t delim)
     152              : {
     153         1545 :     if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
     154            0 :         return -1;
     155              :     }
     156         1545 :     uint8_t a[Plen] = {0};
     157              :     // Absorb input.
     158         1545 :     foldP(in, inlen, xorin);
     159              :     // Xor in the DS and pad frame.
     160         1545 :     a[inlen] ^= delim;
     161         1545 :     a[rate - 1] ^= 0x80;
     162              :     // Xor in the last block.
     163         1545 :     xorin(a, in, inlen);
     164              :     // Apply P
     165         1545 :     P(a);
     166              :     // Squeeze output.
     167         1545 :     foldP(out, outlen, setout);
     168         1545 :     setout(a, out, outlen);
     169         1545 :     memset(a, 0, 200);
     170         1545 :     return 0;
     171              : }
     172              : 
     173              : /*** Helper macros to define SHA3 and SHAKE instances. ***/
     174              : #define defshake(bits) \
     175              :     int shake##bits(uint8_t* out, size_t outlen, const uint8_t* in, size_t inlen) \
     176              :     { \
     177              :         return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x1f); \
     178              :     }
     179              : #define defsha3(bits) \
     180              :     int sha3_##bits(uint8_t* out, size_t outlen, const uint8_t* in, size_t inlen) \
     181              :     { \
     182              :         if (outlen > (bits / 8)) { \
     183              :             return -1; \
     184              :         } \
     185              :         return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \
     186              :     }
     187              : 
     188              : /*** FIPS202 SHAKE VOFs ***/
     189            0 : defshake(128) defshake(256)
     190              : 
     191              :     /*** FIPS202 SHA3 FOFs ***/
     192         1545 :     defsha3(224) defsha3(256) defsha3(384) defsha3(512)
     193              : 
     194              : } // namespace keccak
     195              : 
     196              : bool
     197         1545 : sha3(bytesConstRef _input, bytesRef o_output)
     198              : {
     199              :     // FIXME: What with unaligned memory?
     200         1545 :     if (o_output.size() != 32)
     201            0 :         return false;
     202         1545 :     keccak::sha3_256(o_output.data(), 32, _input.data(), _input.size());
     203              :     //  keccak::keccak(ret.data(), 32, (uint64_t const*)_input.data(), _input.size());
     204         1545 :     return true;
     205              : }
     206              : 
     207              : } // namespace dev
        

Generated by: LCOV version 2.0-1