LCOV - code coverage report
Current view: top level - ezlibs - ezSha.hpp (source / functions) Coverage Total Hit
Test: Coverage (llvm-cov → lcov → genhtml) Lines: 95.4 % 194 185
Test Date: 2025-09-16 22:55:37 Functions: 92.3 % 13 12
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 87.5 % 24 21

             Branch data     Line data    Source code
       1                 :             : #pragma once
       2                 :             : 
       3                 :             : /*
       4                 :             : MIT License
       5                 :             : 
       6                 :             : Copyright (c) 2014-2024 Stephane Cuillerdier (aka aiekick)
       7                 :             : 
       8                 :             : Permission is hereby granted, free of charge, to any person obtaining a copy
       9                 :             : of this software and associated documentation files (the "Software"), to deal
      10                 :             : in the Software without restriction, including without limitation the rights
      11                 :             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      12                 :             : copies of the Software, and to permit persons to whom the Software is
      13                 :             : furnished to do so, subject to the following conditions:
      14                 :             : 
      15                 :             : The above copyright notice and this permission notice shall be included in all
      16                 :             : copies or substantial portions of the Software.
      17                 :             : 
      18                 :             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      19                 :             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      20                 :             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      21                 :             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      22                 :             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      23                 :             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      24                 :             : SOFTWARE.
      25                 :             : */
      26                 :             : 
      27                 :             : // ezSha is part of the ezLibs project : https://github.com/aiekick/ezLibs.git
      28                 :             : // and base on https://github.com/983/SHA1.git - Unlicense
      29                 :             : 
      30                 :             : #include <cstdint>
      31                 :             : #include <cstring>
      32                 :             : #include <sstream>
      33                 :             : #include <string>
      34                 :             : #include <array>
      35                 :             : 
      36                 :             : namespace ez {
      37                 :             : 
      38                 :             : class sha1 {
      39                 :             : public:
      40                 :             :     static size_t constexpr SHA1_HEX_SIZE{40};
      41                 :             : 
      42                 :             : private:
      43                 :             :     std::array<uint32_t, 5> m_state{};
      44                 :             :     std::array<uint8_t, 64> m_buf{};
      45                 :             :     uint32_t m_index{};
      46                 :             :     uint64_t m_countBits{};
      47                 :             : 
      48                 :             : public:
      49                 :           4 :     sha1() : m_index(0), m_countBits(0) {
      50                 :           4 :         m_state[0] = 0x67452301;
      51                 :           4 :         m_state[1] = 0xEFCDAB89;
      52                 :           4 :         m_state[2] = 0x98BADCFE;
      53                 :           4 :         m_state[3] = 0x10325476;
      54                 :           4 :         m_state[4] = 0xC3D2E1F0;
      55                 :           4 :     }
      56                 :           0 :     explicit sha1(const std::string &vText) : sha1() { add(vText); }
      57                 :           4 :     explicit sha1(const char *vText) : sha1() { add(vText); }
      58                 :             : 
      59                 :             :     /*
      60                 :             :     sha1 &add(char c) { return add(*(uint8_t *)&c); }
      61                 :             :     */
      62                 :             : 
      63                 :          10 :     sha1 &add(const void *data, uint32_t n) {
      64         [ -  + ]:          10 :         if (!data) {
      65                 :           0 :             return *this;
      66                 :           0 :         }
      67                 :             : 
      68                 :          10 :         const uint8_t *ptr = (const uint8_t *)data;
      69                 :             : 
      70                 :             :         // fill up block if not full
      71 [ +  + ][ +  + ]:          30 :         for (; n && m_index % sizeof(m_buf); n--) {
      72                 :          20 :             m_add(*ptr++);
      73                 :          20 :         }
      74                 :             : 
      75                 :             :         // process full blocks
      76         [ -  + ]:          10 :         for (; n >= sizeof(m_buf); n -= sizeof(m_buf)) {
      77                 :           0 :             m_processBlock(ptr);
      78                 :           0 :             ptr += sizeof(m_buf);
      79                 :           0 :             m_countBits += sizeof(m_buf) * 8;
      80                 :           0 :         }
      81                 :             : 
      82                 :             :         // process remaining part of block
      83         [ +  + ]:          26 :         for (; n; n--) {
      84                 :          16 :             m_add(*ptr++);
      85                 :          16 :         }
      86                 :             : 
      87                 :          10 :         return *this;
      88                 :          10 :     }
      89                 :             : 
      90                 :          10 :     sha1 &add(const std::string &vText) {
      91         [ -  + ]:          10 :         if (vText.empty()) {
      92                 :           0 :             return *this;
      93                 :           0 :         }
      94                 :          10 :         return add(vText.data(), static_cast<uint32_t>(vText.size()));
      95                 :          10 :     }
      96                 :             : 
      97                 :             :     template <typename T>
      98                 :           2 :     sha1 &addValue(const T &vValue) {
      99                 :           2 :         std::stringstream ss;
     100                 :           2 :         ss << vValue;
     101                 :           2 :         return add(ss.str());
     102                 :           2 :     }
     103                 :             : 
     104                 :           4 :     sha1 &finalize() {
     105                 :             :         // hashed text ends with 0x80, some padding 0x00 and the length in bits
     106                 :           4 :         m_addByteDontCountBits(0x80);
     107         [ +  + ]:         188 :         while (m_index % 64 != 56) {
     108                 :         184 :             m_addByteDontCountBits(0x00);
     109                 :         184 :         }
     110         [ +  + ]:          36 :         for (int32_t j = 7; j >= 0; j--) {
     111                 :          32 :             m_addByteDontCountBits(static_cast<uint8_t>(m_countBits >> j * 8));
     112                 :          32 :         }
     113                 :             : 
     114                 :           4 :         return *this;
     115                 :           4 :     }
     116                 :             : 
     117                 :           4 :     const std::string getHex(const char *alphabet = "0123456789abcdef") {
     118                 :           4 :         std::string ret(SHA1_HEX_SIZE, 0);
     119                 :           4 :         int k = 0;
     120         [ +  + ]:          24 :         for (int m_index = 0; m_index < 5; m_index++) {
     121         [ +  + ]:         180 :             for (int j = 7; j >= 0; j--) {
     122                 :         160 :                 ret[k++] = alphabet[(m_state[m_index] >> j * 4) & 0xf];
     123                 :         160 :             }
     124                 :          20 :         }
     125                 :           4 :         return ret;
     126                 :           4 :     }
     127                 :             : 
     128                 :             : private:
     129                 :          36 :     sha1 &m_add(uint8_t x) {
     130                 :          36 :         m_addByteDontCountBits(x);
     131                 :          36 :         m_countBits += 8;
     132                 :          36 :         return *this;
     133                 :          36 :     }
     134                 :         256 :     void m_addByteDontCountBits(uint8_t x) {
     135                 :         256 :         m_buf[m_index++] = x;
     136         [ +  + ]:         256 :         if (m_index >= sizeof(m_buf)) {
     137                 :           4 :             m_index = 0;
     138                 :           4 :             m_processBlock(m_buf.data());
     139                 :           4 :         }
     140                 :         256 :     }
     141                 :             : 
     142                 :         896 :     static uint32_t m_rol32(uint32_t x, uint32_t n) { return (x << n) | (x >> (32 - n)); }
     143                 :             : 
     144                 :          64 :     static uint32_t m_makeWord(const uint8_t *p) { return ((uint32_t)p[0] << 3 * 8) | ((uint32_t)p[1] << 2 * 8) | ((uint32_t)p[2] << 1 * 8) | ((uint32_t)p[3] << 0 * 8); }
     145                 :             : 
     146                 :           4 :     void m_processBlock(const uint8_t *ptr) {
     147                 :           4 :         const uint32_t c0 = 0x5a827999;
     148                 :           4 :         const uint32_t c1 = 0x6ed9eba1;
     149                 :           4 :         const uint32_t c2 = 0x8f1bbcdc;
     150                 :           4 :         const uint32_t c3 = 0xca62c1d6;
     151                 :             : 
     152                 :           4 :         uint32_t a = m_state[0];
     153                 :           4 :         uint32_t b = m_state[1];
     154                 :           4 :         uint32_t c = m_state[2];
     155                 :           4 :         uint32_t d = m_state[3];
     156                 :           4 :         uint32_t e = m_state[4];
     157                 :             : 
     158                 :           4 :         uint32_t w[16];
     159                 :             : 
     160         [ +  + ]:          68 :         for (int m_index = 0; m_index < 16; m_index++) {
     161                 :          64 :             w[m_index] = m_makeWord(ptr + m_index * 4);
     162                 :          64 :         }
     163                 :             : 
     164                 :         256 : #define SHA1_LOAD(m_index) w[m_index & 15] = m_rol32(w[(m_index + 13) & 15] ^ w[(m_index + 8) & 15] ^ w[(m_index + 2) & 15] ^ w[m_index & 15], 1);
     165                 :           4 : #define SHA1_ROUND_0(v, u, x, y, z, m_index)                         \
     166                 :          64 :     z += ((u & (x ^ y)) ^ y) + w[m_index & 15] + c0 + m_rol32(v, 5); \
     167                 :          64 :     u = m_rol32(u, 30);
     168                 :           4 : #define SHA1_ROUND_1(v, u, x, y, z, m_index)                                            \
     169                 :          16 :     SHA1_LOAD(m_index) z += ((u & (x ^ y)) ^ y) + w[m_index & 15] + c0 + m_rol32(v, 5); \
     170                 :          16 :     u = m_rol32(u, 30);
     171                 :           4 : #define SHA1_ROUND_2(v, u, x, y, z, m_index)                                    \
     172                 :          80 :     SHA1_LOAD(m_index) z += (u ^ x ^ y) + w[m_index & 15] + c1 + m_rol32(v, 5); \
     173                 :          80 :     u = m_rol32(u, 30);
     174                 :           4 : #define SHA1_ROUND_3(v, u, x, y, z, m_index)                                                  \
     175                 :          80 :     SHA1_LOAD(m_index) z += (((u | x) & y) | (u & x)) + w[m_index & 15] + c2 + m_rol32(v, 5); \
     176                 :          80 :     u = m_rol32(u, 30);
     177                 :           4 : #define SHA1_ROUND_4(v, u, x, y, z, m_index)                                    \
     178                 :          80 :     SHA1_LOAD(m_index) z += (u ^ x ^ y) + w[m_index & 15] + c3 + m_rol32(v, 5); \
     179                 :          80 :     u = m_rol32(u, 30);
     180                 :             : 
     181                 :           4 :         SHA1_ROUND_0(a, b, c, d, e, 0);
     182                 :           4 :         SHA1_ROUND_0(e, a, b, c, d, 1);
     183                 :           4 :         SHA1_ROUND_0(d, e, a, b, c, 2);
     184                 :           4 :         SHA1_ROUND_0(c, d, e, a, b, 3);
     185                 :           4 :         SHA1_ROUND_0(b, c, d, e, a, 4);
     186                 :           4 :         SHA1_ROUND_0(a, b, c, d, e, 5);
     187                 :           4 :         SHA1_ROUND_0(e, a, b, c, d, 6);
     188                 :           4 :         SHA1_ROUND_0(d, e, a, b, c, 7);
     189                 :           4 :         SHA1_ROUND_0(c, d, e, a, b, 8);
     190                 :           4 :         SHA1_ROUND_0(b, c, d, e, a, 9);
     191                 :           4 :         SHA1_ROUND_0(a, b, c, d, e, 10);
     192                 :           4 :         SHA1_ROUND_0(e, a, b, c, d, 11);
     193                 :           4 :         SHA1_ROUND_0(d, e, a, b, c, 12);
     194                 :           4 :         SHA1_ROUND_0(c, d, e, a, b, 13);
     195                 :           4 :         SHA1_ROUND_0(b, c, d, e, a, 14);
     196                 :           4 :         SHA1_ROUND_0(a, b, c, d, e, 15);
     197                 :           4 :         SHA1_ROUND_1(e, a, b, c, d, 16);
     198                 :           4 :         SHA1_ROUND_1(d, e, a, b, c, 17);
     199                 :           4 :         SHA1_ROUND_1(c, d, e, a, b, 18);
     200                 :           4 :         SHA1_ROUND_1(b, c, d, e, a, 19);
     201                 :           4 :         SHA1_ROUND_2(a, b, c, d, e, 20);
     202                 :           4 :         SHA1_ROUND_2(e, a, b, c, d, 21);
     203                 :           4 :         SHA1_ROUND_2(d, e, a, b, c, 22);
     204                 :           4 :         SHA1_ROUND_2(c, d, e, a, b, 23);
     205                 :           4 :         SHA1_ROUND_2(b, c, d, e, a, 24);
     206                 :           4 :         SHA1_ROUND_2(a, b, c, d, e, 25);
     207                 :           4 :         SHA1_ROUND_2(e, a, b, c, d, 26);
     208                 :           4 :         SHA1_ROUND_2(d, e, a, b, c, 27);
     209                 :           4 :         SHA1_ROUND_2(c, d, e, a, b, 28);
     210                 :           4 :         SHA1_ROUND_2(b, c, d, e, a, 29);
     211                 :           4 :         SHA1_ROUND_2(a, b, c, d, e, 30);
     212                 :           4 :         SHA1_ROUND_2(e, a, b, c, d, 31);
     213                 :           4 :         SHA1_ROUND_2(d, e, a, b, c, 32);
     214                 :           4 :         SHA1_ROUND_2(c, d, e, a, b, 33);
     215                 :           4 :         SHA1_ROUND_2(b, c, d, e, a, 34);
     216                 :           4 :         SHA1_ROUND_2(a, b, c, d, e, 35);
     217                 :           4 :         SHA1_ROUND_2(e, a, b, c, d, 36);
     218                 :           4 :         SHA1_ROUND_2(d, e, a, b, c, 37);
     219                 :           4 :         SHA1_ROUND_2(c, d, e, a, b, 38);
     220                 :           4 :         SHA1_ROUND_2(b, c, d, e, a, 39);
     221                 :           4 :         SHA1_ROUND_3(a, b, c, d, e, 40);
     222                 :           4 :         SHA1_ROUND_3(e, a, b, c, d, 41);
     223                 :           4 :         SHA1_ROUND_3(d, e, a, b, c, 42);
     224                 :           4 :         SHA1_ROUND_3(c, d, e, a, b, 43);
     225                 :           4 :         SHA1_ROUND_3(b, c, d, e, a, 44);
     226                 :           4 :         SHA1_ROUND_3(a, b, c, d, e, 45);
     227                 :           4 :         SHA1_ROUND_3(e, a, b, c, d, 46);
     228                 :           4 :         SHA1_ROUND_3(d, e, a, b, c, 47);
     229                 :           4 :         SHA1_ROUND_3(c, d, e, a, b, 48);
     230                 :           4 :         SHA1_ROUND_3(b, c, d, e, a, 49);
     231                 :           4 :         SHA1_ROUND_3(a, b, c, d, e, 50);
     232                 :           4 :         SHA1_ROUND_3(e, a, b, c, d, 51);
     233                 :           4 :         SHA1_ROUND_3(d, e, a, b, c, 52);
     234                 :           4 :         SHA1_ROUND_3(c, d, e, a, b, 53);
     235                 :           4 :         SHA1_ROUND_3(b, c, d, e, a, 54);
     236                 :           4 :         SHA1_ROUND_3(a, b, c, d, e, 55);
     237                 :           4 :         SHA1_ROUND_3(e, a, b, c, d, 56);
     238                 :           4 :         SHA1_ROUND_3(d, e, a, b, c, 57);
     239                 :           4 :         SHA1_ROUND_3(c, d, e, a, b, 58);
     240                 :           4 :         SHA1_ROUND_3(b, c, d, e, a, 59);
     241                 :           4 :         SHA1_ROUND_4(a, b, c, d, e, 60);
     242                 :           4 :         SHA1_ROUND_4(e, a, b, c, d, 61);
     243                 :           4 :         SHA1_ROUND_4(d, e, a, b, c, 62);
     244                 :           4 :         SHA1_ROUND_4(c, d, e, a, b, 63);
     245                 :           4 :         SHA1_ROUND_4(b, c, d, e, a, 64);
     246                 :           4 :         SHA1_ROUND_4(a, b, c, d, e, 65);
     247                 :           4 :         SHA1_ROUND_4(e, a, b, c, d, 66);
     248                 :           4 :         SHA1_ROUND_4(d, e, a, b, c, 67);
     249                 :           4 :         SHA1_ROUND_4(c, d, e, a, b, 68);
     250                 :           4 :         SHA1_ROUND_4(b, c, d, e, a, 69);
     251                 :           4 :         SHA1_ROUND_4(a, b, c, d, e, 70);
     252                 :           4 :         SHA1_ROUND_4(e, a, b, c, d, 71);
     253                 :           4 :         SHA1_ROUND_4(d, e, a, b, c, 72);
     254                 :           4 :         SHA1_ROUND_4(c, d, e, a, b, 73);
     255                 :           4 :         SHA1_ROUND_4(b, c, d, e, a, 74);
     256                 :           4 :         SHA1_ROUND_4(a, b, c, d, e, 75);
     257                 :           4 :         SHA1_ROUND_4(e, a, b, c, d, 76);
     258                 :           4 :         SHA1_ROUND_4(d, e, a, b, c, 77);
     259                 :           4 :         SHA1_ROUND_4(c, d, e, a, b, 78);
     260                 :           4 :         SHA1_ROUND_4(b, c, d, e, a, 79);
     261                 :             : 
     262                 :           4 : #undef SHA1_LOAD
     263                 :           4 : #undef SHA1_ROUND_0
     264                 :           4 : #undef SHA1_ROUND_1
     265                 :           4 : #undef SHA1_ROUND_2
     266                 :           4 : #undef SHA1_ROUND_3
     267                 :           4 : #undef SHA1_ROUND_4
     268                 :             : 
     269                 :           4 :         m_state[0] += a;
     270                 :           4 :         m_state[1] += b;
     271                 :           4 :         m_state[2] += c;
     272                 :           4 :         m_state[3] += d;
     273                 :           4 :         m_state[4] += e;
     274                 :           4 :     }
     275                 :             : };
     276                 :             : 
     277                 :             : }  // namespace ez
        

Generated by: LCOV version 2.0-1