LCOV - code coverage report
Current view: top level - src/jamidht/eth/libdevcore - SHA3.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 32 35 91.4 %
Date: 2024-03-19 07:58: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,
      57             :                                15, 23, 19, 13, 12, 2, 20, 14, 22, 9,  6,  1};
      58             : static const uint64_t RC[24] = {1ULL,
      59             :                                 0x8082ULL,
      60             :                                 0x800000000000808aULL,
      61             :                                 0x8000000080008000ULL,
      62             :                                 0x808bULL,
      63             :                                 0x80000001ULL,
      64             :                                 0x8000000080008081ULL,
      65             :                                 0x8000000000008009ULL,
      66             :                                 0x8aULL,
      67             :                                 0x88ULL,
      68             :                                 0x80008009ULL,
      69             :                                 0x8000000aULL,
      70             :                                 0x8000808bULL,
      71             :                                 0x800000000000008bULL,
      72             :                                 0x8000000000008089ULL,
      73             :                                 0x8000000000008003ULL,
      74             :                                 0x8000000000008002ULL,
      75             :                                 0x8000000000000080ULL,
      76             :                                 0x800aULL,
      77             :                                 0x800000008000000aULL,
      78             :                                 0x8000000080008081ULL,
      79             :                                 0x8000000000008080ULL,
      80             :                                 0x80000001ULL,
      81             :                                 0x8000000080008008ULL};
      82             : 
      83             : /*** Helper macros to unroll the permutation. ***/
      84             : #define rol(x, s)   (((x) << s) | ((x) >> (64 - s)))
      85             : #define REPEAT6(e)  e e e e e e
      86             : #define REPEAT24(e) REPEAT6(e e e e)
      87             : #define REPEAT5(e)  e e e e e
      88             : #define FOR5(v, s, e) \
      89             :     v = 0; \
      90             :     REPEAT5(e; v += s;)
      91             : 
      92             : /*** Keccak-f[1600] ***/
      93             : static inline void
      94        1549 : keccakf(void* state)
      95             : {
      96        1549 :     uint64_t* a = (uint64_t*) state;
      97        1549 :     uint64_t b[5] = {0};
      98        1549 :     uint64_t t = 0;
      99             :     uint8_t x, y;
     100             : 
     101       38725 :     for (int i = 0; i < 24; i++) {
     102             :         // Theta
     103       37176 :         FOR5(x, 1, b[x] = 0; FOR5(y, 5, b[x] ^= a[x + y];))
     104       37176 :         FOR5(x, 1, FOR5(y, 5, a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1);))
     105             :         // Rho and pi
     106       37176 :         t = a[1];
     107       37176 :         x = 0;
     108       37176 :         REPEAT24(b[0] = a[pi[x]]; a[pi[x]] = rol(t, rho[x]); t = b[0]; x++;)
     109             :         // Chi
     110       37176 :         FOR5(y,
     111             :              5,
     112             :              FOR5(x, 1, b[x] = a[y + x];)
     113             :                  FOR5(x, 1, a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]);))
     114             :         // Iota
     115       37176 :         a[0] ^= RC[i];
     116             :     }
     117        1549 : }
     118             : 
     119             : /******** The FIPS202-defined functions. ********/
     120             : 
     121             : /*** Some helper macros. ***/
     122             : 
     123             : #define _(S) \
     124             :     do { \
     125             :         S \
     126             :     } while (0)
     127             : #define FOR(i, ST, L, S) _(for (size_t i = 0; i < L; i += ST) { S; })
     128             : #define mkapply_ds(NAME, S) \
     129             :     static inline void NAME(uint8_t* dst, const uint8_t* src, size_t len) { FOR(i, 1, len, S); }
     130             : #define mkapply_sd(NAME, S) \
     131             :     static inline void NAME(const uint8_t* src, uint8_t* dst, size_t len) { FOR(i, 1, len, S); }
     132             : 
     133       97869 : mkapply_ds(xorin, dst[i] ^= src[i])     // xorin
     134       51117 :     mkapply_sd(setout, dst[i] = src[i]) // setout
     135             : 
     136             : #define P    keccakf
     137             : #define Plen 200
     138             : 
     139             : // Fold P*F over the full blocks of an input.
     140             : #define foldP(I, L, F) \
     141             :     while (L >= rate) { \
     142             :         F(a, I, rate); \
     143             :         P(a); \
     144             :         I += rate; \
     145             :         L -= rate; \
     146             :     }
     147             : 
     148             :     /** The sponge-based hash construction. **/
     149        1549 :     static inline int hash(
     150             :         uint8_t* out, size_t outlen, const uint8_t* in, size_t inlen, size_t rate, uint8_t delim)
     151             : {
     152        1549 :     if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
     153           0 :         return -1;
     154             :     }
     155        1549 :     uint8_t a[Plen] = {0};
     156             :     // Absorb input.
     157        1549 :     foldP(in, inlen, xorin);
     158             :     // Xor in the DS and pad frame.
     159        1549 :     a[inlen] ^= delim;
     160        1549 :     a[rate - 1] ^= 0x80;
     161             :     // Xor in the last block.
     162        1549 :     xorin(a, in, inlen);
     163             :     // Apply P
     164        1549 :     P(a);
     165             :     // Squeeze output.
     166        1549 :     foldP(out, outlen, setout);
     167        1549 :     setout(a, out, outlen);
     168        1549 :     memset(a, 0, 200);
     169        1549 :     return 0;
     170             : }
     171             : 
     172             : /*** Helper macros to define SHA3 and SHAKE instances. ***/
     173             : #define defshake(bits) \
     174             :     int shake##bits(uint8_t* out, size_t outlen, const uint8_t* in, size_t inlen) \
     175             :     { \
     176             :         return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x1f); \
     177             :     }
     178             : #define defsha3(bits) \
     179             :     int sha3_##bits(uint8_t* out, size_t outlen, const uint8_t* in, size_t inlen) \
     180             :     { \
     181             :         if (outlen > (bits / 8)) { \
     182             :             return -1; \
     183             :         } \
     184             :         return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \
     185             :     }
     186             : 
     187             : /*** FIPS202 SHAKE VOFs ***/
     188           0 : defshake(128) defshake(256)
     189             : 
     190             :     /*** FIPS202 SHA3 FOFs ***/
     191        1549 :     defsha3(224) defsha3(256) defsha3(384) defsha3(512)
     192             : 
     193             : } // namespace keccak
     194             : 
     195             : bool
     196        1549 : sha3(bytesConstRef _input, bytesRef o_output)
     197             : {
     198             :     // FIXME: What with unaligned memory?
     199        1549 :     if (o_output.size() != 32)
     200           0 :         return false;
     201        1549 :     keccak::sha3_256(o_output.data(), 32, _input.data(), _input.size());
     202             :     //  keccak::keccak(ret.data(), 32, (uint64_t const*)_input.data(), _input.size());
     203        1549 :     return true;
     204             : }
     205             : 
     206             : } // namespace dev

Generated by: LCOV version 1.14