• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 16395825001

19 Jul 2025 11:30PM UTC coverage: 90.635% (-0.07%) from 90.708%
16395825001

push

github

web-flow
Merge pull request #4998 from randombit/jack/fix-clang-tidy-readability-isolate-declaration

Enable and fix clang-tidy warning readability-isolate-declaration

99940 of 110266 relevant lines covered (90.64%)

12341110.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.57
/src/lib/hash/blake2s/blake2s.cpp
1
/*
2
 * BLAKE2s
3
 * (C) 2023           Richard Huveneers
4
 *
5
 * Based on the RFC7693 reference implementation
6
 *
7
 * Botan is released under the Simplified BSD License (see license.txt)
8
 */
9

10
#include <botan/internal/blake2s.h>
11

12
#include <botan/exceptn.h>
13
#include <botan/internal/fmt.h>
14
#include <botan/internal/loadstor.h>
15
#include <botan/internal/rotate.h>
16

17
namespace Botan {
18

19
namespace {
20

21
// Initialization Vector.
22

23
const uint32_t blake2s_iv[8] = {
24
   0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19};
25

26
// Mixing function G.
27

28
inline void B2S_G(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint32_t x, uint32_t y, uint32_t* v) {
407,120✔
29
   v[a] = v[a] + v[b] + x;
407,120✔
30
   v[d] = rotr<16>(v[d] ^ v[a]);
407,120✔
31
   v[c] = v[c] + v[d];
407,120✔
32
   v[b] = rotr<12>(v[b] ^ v[c]);
407,120✔
33
   v[a] = v[a] + v[b] + y;
407,120✔
34
   v[d] = rotr<8>(v[d] ^ v[a]);
407,120✔
35
   v[c] = v[c] + v[d];
407,120✔
36
   v[b] = rotr<7>(v[b] ^ v[c]);
407,120✔
37
}
407,120✔
38

39
}  // namespace
40

41
std::string BLAKE2s::name() const {
771✔
42
   return fmt("BLAKE2s({})", m_outlen << 3);
771✔
43
}
44

45
//      Secret key (also <= 32 bytes) is optional (keylen = 0).
46
//      (keylen=0: no key)
47

48
void BLAKE2s::state_init(size_t outlen, const uint8_t* key, size_t keylen) {
3,319✔
49
   for(size_t i = 0; i < 8; i++) {  // state, "param block"
29,871✔
50
      m_h[i] = blake2s_iv[i];
26,552✔
51
   }
52
   m_h[0] ^= 0x01010000 ^ (keylen << 8) ^ outlen;
3,319✔
53

54
   m_t[0] = 0;  // input count low word
3,319✔
55
   m_t[1] = 0;  // input count high word
3,319✔
56
   m_c = 0;     // pointer within buffer
3,319✔
57
   m_outlen = outlen;
3,319✔
58

59
   for(size_t i = keylen; i < 64; i++) {  // zero input block
215,735✔
60
      m_b[i] = 0;
212,416✔
61
   }
62
   if(keylen > 0) {
3,319✔
63
      add_data(std::span<const uint8_t>(key, keylen));
×
64
      m_c = 64;  // at the end
×
65
   }
66
}
3,319✔
67

68
// Compression function. "last" flag indicates last block.
69

70
void BLAKE2s::compress(bool last) {
5,089✔
71
   const uint8_t sigma[10][16] = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
5,089✔
72
                                  {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
73
                                  {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
74
                                  {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
75
                                  {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
76
                                  {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
77
                                  {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
78
                                  {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
79
                                  {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
80
                                  {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}};
81
   uint32_t v[16];
5,089✔
82
   uint32_t m[16];
5,089✔
83

84
   for(size_t i = 0; i < 8; i++) {  // init work variables
45,801✔
85
      v[i] = m_h[i];
40,712✔
86
      v[i + 8] = blake2s_iv[i];
40,712✔
87
   }
88

89
   v[12] ^= m_t[0];  // low 32 bits of offset
5,089✔
90
   v[13] ^= m_t[1];  // high 32 bits
5,089✔
91
   if(last) {        // last block flag set ?
5,089✔
92
      v[14] = ~v[14];
2,041✔
93
   }
94
   load_le<uint32_t>(m, m_b, 16);  // get little-endian words
5,089✔
95

96
   // NOLINTNEXTLINE(modernize-loop-convert) TODO clean this up
97
   for(size_t i = 0; i < 10; i++) {  // ten rounds
55,979✔
98
      B2S_G(0, 4, 8, 12, m[sigma[i][0]], m[sigma[i][1]], v);
50,890✔
99
      B2S_G(1, 5, 9, 13, m[sigma[i][2]], m[sigma[i][3]], v);
50,890✔
100
      B2S_G(2, 6, 10, 14, m[sigma[i][4]], m[sigma[i][5]], v);
50,890✔
101
      B2S_G(3, 7, 11, 15, m[sigma[i][6]], m[sigma[i][7]], v);
50,890✔
102
      B2S_G(0, 5, 10, 15, m[sigma[i][8]], m[sigma[i][9]], v);
50,890✔
103
      B2S_G(1, 6, 11, 12, m[sigma[i][10]], m[sigma[i][11]], v);
50,890✔
104
      B2S_G(2, 7, 8, 13, m[sigma[i][12]], m[sigma[i][13]], v);
50,890✔
105
      B2S_G(3, 4, 9, 14, m[sigma[i][14]], m[sigma[i][15]], v);
50,890✔
106
   }
107

108
   for(size_t i = 0; i < 8; ++i) {
45,801✔
109
      m_h[i] ^= v[i] ^ v[i + 8];
40,712✔
110
   }
111
}
5,089✔
112

113
/*
114
 * Clear memory of sensitive data
115
 */
116
void BLAKE2s::clear() {
2,298✔
117
   state_init(m_outlen, nullptr, 0);
257✔
118
}
257✔
119

120
void BLAKE2s::add_data(std::span<const uint8_t> in) {
4,663✔
121
   // NOLINTNEXTLINE(modernize-loop-convert) TODO optimize this
122
   for(size_t i = 0; i < in.size(); i++) {
270,661✔
123
      if(m_c == 64) {        // buffer full ?
265,998✔
124
         m_t[0] += m_c;      // add counters
3,048✔
125
         if(m_t[0] < m_c) {  // carry overflow ?
3,048✔
126
            m_t[1]++;        // high word
×
127
         }
128
         compress(false);  // compress (not last)
3,048✔
129
         m_c = 0;          // counter to zero
3,048✔
130
      }
131
      m_b[m_c++] = in[i];
265,998✔
132
   }
133
}
4,663✔
134

135
void BLAKE2s::final_result(std::span<uint8_t> out) {
2,041✔
136
   m_t[0] += m_c;      // mark last block offset
2,041✔
137
   if(m_t[0] < m_c) {  // carry overflow
2,041✔
138
      m_t[1]++;        // high word
×
139
   }
140

141
   while(m_c < 64) {  // fill up with zeros
66,629✔
142
      m_b[m_c++] = 0;
64,588✔
143
   }
144
   compress(true);  // final block flag = 1
2,041✔
145

146
   // little endian convert and store
147
   copy_out_le(out.first(output_length()), m_h);
2,041✔
148

149
   clear();
2,041✔
150
}
2,041✔
151

152
std::unique_ptr<HashFunction> BLAKE2s::copy_state() const {
250✔
153
   std::unique_ptr<BLAKE2s> h = std::make_unique<BLAKE2s>(m_outlen << 3);
250✔
154
   std::memcpy(h->m_b, m_b, sizeof(m_b));
250✔
155
   std::memcpy(h->m_h, m_h, sizeof(m_h));
250✔
156
   std::memcpy(h->m_t, m_t, sizeof(m_t));
250✔
157
   h->m_c = m_c;
250✔
158
   return h;
250✔
159
}
250✔
160

161
/*
162
 * BLAKE2s Constructor
163
 */
164
BLAKE2s::BLAKE2s(size_t output_bits) {
1,021✔
165
   if(output_bits == 0 || output_bits > 256 || output_bits % 8 != 0) {
1,021✔
166
      throw Invalid_Argument("Bad output bits size for BLAKE2s");
×
167
   };
1,021✔
168
   state_init(output_bits >> 3, nullptr, 0);
1,021✔
169
}
1,021✔
170

171
BLAKE2s::~BLAKE2s() {
2,042✔
172
   secure_scrub_memory(m_b, sizeof(m_b));
1,021✔
173
   secure_scrub_memory(m_h, sizeof(m_h));
1,021✔
174
   secure_scrub_memory(m_t, sizeof(m_t));
1,021✔
175
}
2,042✔
176

177
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc