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

randombit / botan / 6144099563

11 Sep 2023 08:48AM UTC coverage: 91.693% (-0.02%) from 91.711%
6144099563

push

github

web-flow
Merge pull request #3681 from randombit/span/bufcomp

std::span for Buffered_Computation

78567 of 85685 relevant lines covered (91.69%)

8524467.68 hits per line

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

99.22
/src/lib/hash/blake2/blake2b.cpp
1
/*
2
* BLAKE2b
3
* (C) 2016 cynecx
4
* (C) 2017 Jack Lloyd
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8

9
#include <botan/internal/blake2b.h>
10

11
#include <botan/exceptn.h>
12
#include <botan/mem_ops.h>
13
#include <botan/internal/fmt.h>
14
#include <botan/internal/loadstor.h>
15
#include <botan/internal/rotate.h>
16
#include <botan/internal/stl_util.h>
17
#include <algorithm>
18

19
namespace Botan {
20

21
namespace {
22

23
enum blake2b_constant { BLAKE2B_BLOCKBYTES = 128, BLAKE2B_IVU64COUNT = 8 };
24

25
const uint64_t blake2b_IV[BLAKE2B_IVU64COUNT] = {0x6a09e667f3bcc908,
26
                                                 0xbb67ae8584caa73b,
27
                                                 0x3c6ef372fe94f82b,
28
                                                 0xa54ff53a5f1d36f1,
29
                                                 0x510e527fade682d1,
30
                                                 0x9b05688c2b3e6c1f,
31
                                                 0x1f83d9abfb41bd6b,
32
                                                 0x5be0cd19137e2179};
33

34
}  // namespace
35

36
BLAKE2b::BLAKE2b(size_t output_bits) :
7,042✔
37
      m_output_bits(output_bits),
7,042✔
38
      m_buffer(BLAKE2B_BLOCKBYTES),
7,042✔
39
      m_bufpos(0),
7,042✔
40
      m_H(BLAKE2B_IVU64COUNT),
7,042✔
41
      m_T(),
21,126✔
42
      m_F(),
7,042✔
43
      m_key_size(0) {
14,084✔
44
   if(output_bits == 0 || output_bits > 512 || output_bits % 8 != 0) {
7,042✔
45
      throw Invalid_Argument("Bad output bits size for BLAKE2b");
1✔
46
   }
47

48
   state_init();
7,041✔
49
}
7,043✔
50

51
void BLAKE2b::state_init() {
232,289✔
52
   copy_mem(m_H.data(), blake2b_IV, BLAKE2B_IVU64COUNT);
232,289✔
53
   m_H[0] ^= (0x01010000 | (static_cast<uint8_t>(m_key_size) << 8) | static_cast<uint8_t>(output_length()));
232,289✔
54
   m_T[0] = m_T[1] = 0;
232,289✔
55
   m_F = 0;
232,289✔
56

57
   if(m_key_size == 0) {
232,289✔
58
      m_bufpos = 0;
228,238✔
59
   } else {
60
      BOTAN_ASSERT_NOMSG(m_padded_key_buffer.size() == m_buffer.size());
4,051✔
61
      copy_mem(m_buffer.data(), m_padded_key_buffer.data(), m_padded_key_buffer.size());
4,051✔
62
      m_bufpos = m_padded_key_buffer.size();
4,051✔
63
   }
64
}
232,289✔
65

66
namespace {
67

68
BOTAN_FORCE_INLINE void G(uint64_t& a, uint64_t& b, uint64_t& c, uint64_t& d, uint64_t M0, uint64_t M1) {
23,045,568✔
69
   a = a + b + M0;
23,045,568✔
70
   d = rotr<32>(d ^ a);
23,045,568✔
71
   c = c + d;
23,045,568✔
72
   b = rotr<24>(b ^ c);
23,045,568✔
73
   a = a + b + M1;
23,045,568✔
74
   d = rotr<16>(d ^ a);
23,045,568✔
75
   c = c + d;
23,045,568✔
76
   b = rotr<63>(b ^ c);
23,045,568✔
77
}
78

79
template <size_t i0,
80
          size_t i1,
81
          size_t i2,
82
          size_t i3,
83
          size_t i4,
84
          size_t i5,
85
          size_t i6,
86
          size_t i7,
87
          size_t i8,
88
          size_t i9,
89
          size_t iA,
90
          size_t iB,
91
          size_t iC,
92
          size_t iD,
93
          size_t iE,
94
          size_t iF>
95
BOTAN_FORCE_INLINE void ROUND(uint64_t* v, const uint64_t* M) {
2,880,696✔
96
   G(v[0], v[4], v[8], v[12], M[i0], M[i1]);
5,761,392✔
97
   G(v[1], v[5], v[9], v[13], M[i2], M[i3]);
2,880,696✔
98
   G(v[2], v[6], v[10], v[14], M[i4], M[i5]);
2,880,696✔
99
   G(v[3], v[7], v[11], v[15], M[i6], M[i7]);
2,880,696✔
100
   G(v[0], v[5], v[10], v[15], M[i8], M[i9]);
2,880,696✔
101
   G(v[1], v[6], v[11], v[12], M[iA], M[iB]);
2,880,696✔
102
   G(v[2], v[7], v[8], v[13], M[iC], M[iD]);
2,880,696✔
103
   G(v[3], v[4], v[9], v[14], M[iE], M[iF]);
2,880,696✔
104
}
105

106
}  // namespace
107

108
void BLAKE2b::compress(const uint8_t* input, size_t blocks, uint64_t increment) {
238,970✔
109
   for(size_t b = 0; b != blocks; ++b) {
479,028✔
110
      m_T[0] += increment;
240,058✔
111
      if(m_T[0] < increment) {
240,058✔
112
         m_T[1]++;
×
113
      }
114

115
      uint64_t M[16];
240,058✔
116
      uint64_t v[16];
240,058✔
117
      load_le(M, input, 16);
240,058✔
118

119
      input += BLAKE2B_BLOCKBYTES;
240,058✔
120

121
      for(size_t i = 0; i < 8; i++) {
2,160,522✔
122
         v[i] = m_H[i];
1,920,464✔
123
      }
124
      for(size_t i = 0; i != 8; ++i) {
2,160,522✔
125
         v[i + 8] = blake2b_IV[i];
1,920,464✔
126
      }
127

128
      v[12] ^= m_T[0];
240,058✔
129
      v[13] ^= m_T[1];
240,058✔
130
      v[14] ^= m_F;
240,058✔
131

132
      ROUND<0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15>(v, M);
240,058✔
133
      ROUND<14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3>(v, M);
240,058✔
134
      ROUND<11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4>(v, M);
240,058✔
135
      ROUND<7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8>(v, M);
240,058✔
136
      ROUND<9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13>(v, M);
240,058✔
137
      ROUND<2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9>(v, M);
240,058✔
138
      ROUND<12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11>(v, M);
240,058✔
139
      ROUND<13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10>(v, M);
240,058✔
140
      ROUND<6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5>(v, M);
240,058✔
141
      ROUND<10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0>(v, M);
240,058✔
142
      ROUND<0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15>(v, M);
240,058✔
143
      ROUND<14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3>(v, M);
240,058✔
144

145
      for(size_t i = 0; i < 8; i++) {
2,160,522✔
146
         m_H[i] ^= v[i] ^ v[i + 8];
1,920,464✔
147
      }
148
   }
149
}
238,970✔
150

151
void BLAKE2b::add_data(std::span<const uint8_t> input) {
411,899✔
152
   if(input.empty()) {
411,899✔
153
      return;
4,131✔
154
   }
155

156
   BufferSlicer in(input);
407,768✔
157

158
   if(m_bufpos > 0) {
407,768✔
159
      if(m_bufpos < BLAKE2B_BLOCKBYTES) {
188,149✔
160
         const auto part = in.take(std::min(BLAKE2B_BLOCKBYTES - m_bufpos, in.remaining()));
360,354✔
161
         copy_mem(&m_buffer[m_bufpos], part.data(), part.size());
185,361✔
162
         m_bufpos += part.size();
185,361✔
163
      }
164

165
      if(m_bufpos == m_buffer.size() && !in.empty()) {
188,149✔
166
         compress(m_buffer.data(), 1, BLAKE2B_BLOCKBYTES);
13,116✔
167
         m_bufpos = 0;
13,116✔
168
      }
169
   }
170

171
   if(in.remaining() > BLAKE2B_BLOCKBYTES) {
407,768✔
172
      const size_t full_blocks = ((in.remaining() - 1) / BLAKE2B_BLOCKBYTES);
4,078✔
173
      compress(in.take(BLAKE2B_BLOCKBYTES * full_blocks).data(), full_blocks, BLAKE2B_BLOCKBYTES);
4,078✔
174
   }
175

176
   if(!in.empty()) {
407,768✔
177
      const auto take = in.remaining();
232,735✔
178
      copy_mem(&m_buffer[m_bufpos], in.take(take).data(), take);
232,735✔
179
      m_bufpos += take;
232,735✔
180
   }
181

182
   BOTAN_ASSERT_NOMSG(in.empty());
407,768✔
183
}
184

185
void BLAKE2b::final_result(std::span<uint8_t> output) {
221,776✔
186
   if(m_bufpos != BLAKE2B_BLOCKBYTES) {
221,776✔
187
      clear_mem(&m_buffer[m_bufpos], BLAKE2B_BLOCKBYTES - m_bufpos);
221,590✔
188
   }
189
   m_F = 0xFFFFFFFFFFFFFFFF;
221,776✔
190
   compress(m_buffer.data(), 1, m_bufpos);
221,776✔
191
   copy_out_vec_le(output.data(), output_length(), m_H);
221,776✔
192
   state_init();
221,776✔
193
}
221,776✔
194

195
Key_Length_Specification BLAKE2b::key_spec() const {
3,778✔
196
   return Key_Length_Specification(1, 64);
3,778✔
197
}
198

199
std::string BLAKE2b::name() const {
4,749✔
200
   return fmt("BLAKE2b({})", m_output_bits);
4,749✔
201
}
202

203
std::unique_ptr<HashFunction> BLAKE2b::new_object() const {
1,037✔
204
   return std::make_unique<BLAKE2b>(m_output_bits);
1,037✔
205
}
206

207
std::unique_ptr<HashFunction> BLAKE2b::copy_state() const {
1,012✔
208
   return std::make_unique<BLAKE2b>(*this);
1,012✔
209
}
210

211
bool BLAKE2b::has_keying_material() const {
7,556✔
212
   return m_key_size > 0;
7,556✔
213
}
214

215
void BLAKE2b::key_schedule(const uint8_t key[], size_t length) {
1,889✔
216
   BOTAN_ASSERT_NOMSG(length <= m_buffer.size());
1,889✔
217

218
   m_key_size = length;
1,889✔
219
   m_padded_key_buffer.resize(m_buffer.size());
1,889✔
220

221
   if(m_padded_key_buffer.size() > length) {
1,889✔
222
      size_t padding = m_padded_key_buffer.size() - length;
1,889✔
223
      clear_mem(m_padded_key_buffer.data() + length, padding);
1,889✔
224
   }
225

226
   copy_mem(m_padded_key_buffer.data(), key, length);
1,889✔
227
   state_init();
1,889✔
228
}
1,889✔
229

230
void BLAKE2b::clear() {
1,583✔
231
   zeroise(m_H);
1,583✔
232
   zeroise(m_buffer);
1,583✔
233
   zeroise(m_padded_key_buffer);
1,583✔
234
   m_bufpos = 0;
1,583✔
235
   m_key_size = 0;
1,583✔
236
   state_init();
1,583✔
237
}
1,583✔
238

239
}  // 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