LCOV - code coverage report
Current view: top level - foo/src/jamidht/eth/libdevcore - SHA3.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 32 35 91.4 %
Date: 2025-12-18 10:07:43 Functions: 6 11 54.5 %

          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        1543 : keccakf(void* state)
      94             : {
      95        1543 :     uint64_t* a = (uint64_t*) state;
      96        1543 :     uint64_t b[5] = {0};
      97        1543 :     uint64_t t = 0;
      98             :     uint8_t x, y;
      99             : 
     100       38575 :     for (int i = 0; i < 24; i++) {
     101             :         // Theta
     102       37032 :         FOR5(x, 1, b[x] = 0; FOR5(y, 5, b[x] ^= a[x + y];))
     103       37032 :         FOR5(x, 1, FOR5(y, 5, a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1);))
     104             :         // Rho and pi
     105       37032 :         t = a[1];
     106       37032 :         x = 0;
     107       37032 :         REPEAT24(b[0] = a[pi[x]]; a[pi[x]] = rol(t, rho[x]); t = b[0]; x++;)
     108             :         // Chi
     109       37032 :         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       37032 :         a[0] ^= RC[i];
     112             :     }
     113        1543 : }
     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       97735 : mkapply_ds(xorin, dst[i] ^= src[i])     // xorin
     136       50919 :     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        1543 :     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        1543 :     if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
     154           0 :         return -1;
     155             :     }
     156        1543 :     uint8_t a[Plen] = {0};
     157             :     // Absorb input.
     158        1543 :     foldP(in, inlen, xorin);
     159             :     // Xor in the DS and pad frame.
     160        1543 :     a[inlen] ^= delim;
     161        1543 :     a[rate - 1] ^= 0x80;
     162             :     // Xor in the last block.
     163        1543 :     xorin(a, in, inlen);
     164             :     // Apply P
     165        1543 :     P(a);
     166             :     // Squeeze output.
     167        1543 :     foldP(out, outlen, setout);
     168        1543 :     setout(a, out, outlen);
     169        1543 :     memset(a, 0, 200);
     170        1543 :     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        1543 :     defsha3(224) defsha3(256) defsha3(384) defsha3(512)
     193             : 
     194             : } // namespace keccak
     195             : 
     196             : bool
     197        1543 : sha3(bytesConstRef _input, bytesRef o_output)
     198             : {
     199             :     // FIXME: What with unaligned memory?
     200        1543 :     if (o_output.size() != 32)
     201           0 :         return false;
     202        1543 :     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        1543 :     return true;
     205             : }
     206             : 
     207             : } // namespace dev

Generated by: LCOV version 1.14