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

randombit / botan / 6081318022

05 Sep 2023 07:06AM UTC coverage: 91.712% (-0.006%) from 91.718%
6081318022

Pull #3681

github

web-flow
Merge 0ed41ccbc into 2c2ff3c71
Pull Request #3681: std::span for Buffered_Computation

78574 of 85675 relevant lines covered (91.71%)

8482992.35 hits per line

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

97.78
/src/lib/hash/streebog/streebog.cpp
1
/*
2
* Streebog
3
* (C) 2017 Ribose Inc.
4
* (C) 2018 Jack Lloyd
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8

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

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

16
namespace Botan {
17

18
extern const uint64_t STREEBOG_Ax[8][256];
19
extern const uint64_t STREEBOG_C[12][8];
20

21
std::unique_ptr<HashFunction> Streebog::copy_state() const {
253✔
22
   return std::make_unique<Streebog>(*this);
253✔
23
}
24

25
Streebog::Streebog(size_t output_bits) :
801✔
26
      m_output_bits(output_bits), m_count(0), m_position(0), m_buffer(64), m_h(8), m_S(8) {
801✔
27
   if(output_bits != 256 && output_bits != 512) {
801✔
28
      throw Invalid_Argument(fmt("Streebog: Invalid output length {}", output_bits));
×
29
   }
30

31
   clear();
801✔
32
}
801✔
33

34
std::string Streebog::name() const {
801✔
35
   return fmt("Streebog-{}", m_output_bits);
801✔
36
}
37

38
/*
39
* Clear memory of sensitive data
40
*/
41
void Streebog::clear() {
3,166✔
42
   m_count = 0;
3,166✔
43
   m_position = 0;
3,166✔
44
   zeroise(m_buffer);
3,166✔
45
   zeroise(m_S);
3,166✔
46

47
   const uint64_t fill = (m_output_bits == 512) ? 0 : 0x0101010101010101;
3,166✔
48
   std::fill(m_h.begin(), m_h.end(), fill);
3,166✔
49
}
3,166✔
50

51
/*
52
* Update the hash
53
*/
54
void Streebog::add_data(std::span<const uint8_t> input) {
4,578✔
55
   const size_t block_size = m_buffer.size();
4,578✔
56

57
   if(m_position) {
4,578✔
58
      buffer_insert(m_buffer, m_position, input.data(), input.size());
2,194✔
59

60
      if(m_position + input.size() >= block_size) {
2,194✔
61
         compress(m_buffer.data());
278✔
62
         m_count += 512;
278✔
63
         input = input.last(input.size() - block_size + m_position);
278✔
64
         m_position = 0;
278✔
65
      }
66
   }
67

68
   BufferSlicer in(input);
4,578✔
69
   while(in.remaining() >= block_size) {
5,558✔
70
      compress(in.take(block_size).data());
980✔
71
      m_count += 512;
980✔
72
   }
73

74
   const auto remaining = in.take(in.remaining());
4,578✔
75
   buffer_insert(m_buffer, m_position, remaining.data(), remaining.size());
4,578✔
76
   m_position += remaining.size();
4,578✔
77
}
4,578✔
78

79
/*
80
* Finalize a hash
81
*/
82
void Streebog::final_result(std::span<uint8_t> output) {
2,100✔
83
   m_buffer[m_position++] = 0x01;
2,100✔
84

85
   if(m_position != m_buffer.size()) {
2,100✔
86
      clear_mem(&m_buffer[m_position], m_buffer.size() - m_position);
2,052✔
87
   }
88

89
   compress(m_buffer.data());
2,100✔
90
   m_count += (m_position - 1) * 8;
2,100✔
91

92
   zeroise(m_buffer);
2,100✔
93
   store_le(m_count, m_buffer.data());
2,100✔
94
   compress(m_buffer.data(), true);
4,200✔
95

96
   compress_64(m_S.data(), true);
2,100✔
97
   // FIXME
98
   std::memcpy(output.data(), &m_h[8 - output_length() / 8], output_length());
2,100✔
99
   clear();
2,100✔
100
}
2,100✔
101

102
namespace {
103

104
inline uint64_t force_le(uint64_t x) {
105
#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
106
   return x;
107
#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
108
   return reverse_bytes(x);
109
#else
110
   store_le(x, reinterpret_cast<uint8_t*>(&x));
111
   return x;
112
#endif
113
}
114

115
inline void lps(uint64_t block[8]) {
188,950✔
116
   uint8_t r[64];
188,950✔
117
   // FIXME
118
   std::memcpy(r, block, 64);
188,950✔
119

120
   for(int i = 0; i < 8; ++i) {
1,700,550✔
121
      block[i] = force_le(STREEBOG_Ax[0][r[i + 0 * 8]]) ^ force_le(STREEBOG_Ax[1][r[i + 1 * 8]]) ^
1,511,600✔
122
                 force_le(STREEBOG_Ax[2][r[i + 2 * 8]]) ^ force_le(STREEBOG_Ax[3][r[i + 3 * 8]]) ^
1,511,600✔
123
                 force_le(STREEBOG_Ax[4][r[i + 4 * 8]]) ^ force_le(STREEBOG_Ax[5][r[i + 5 * 8]]) ^
1,511,600✔
124
                 force_le(STREEBOG_Ax[6][r[i + 6 * 8]]) ^ force_le(STREEBOG_Ax[7][r[i + 7 * 8]]);
1,511,600✔
125
   }
126
}
188,950✔
127

128
}  //namespace
129

130
void Streebog::compress(const uint8_t input[], bool last_block) {
5,458✔
131
   uint64_t M[8];
5,458✔
132
   std::memcpy(M, input, 64);
3,358✔
133

134
   compress_64(M, last_block);
5,458✔
135
}
×
136

137
void Streebog::compress_64(const uint64_t M[], bool last_block) {
7,558✔
138
   const uint64_t N = last_block ? 0 : force_le(m_count);
7,558✔
139

140
   uint64_t hN[8];
7,558✔
141
   uint64_t A[8];
7,558✔
142

143
   copy_mem(hN, m_h.data(), 8);
7,558✔
144
   hN[0] ^= N;
7,558✔
145
   lps(hN);
7,558✔
146

147
   copy_mem(A, hN, 8);
7,558✔
148

149
   for(size_t i = 0; i != 8; ++i) {
68,022✔
150
      hN[i] ^= M[i];
60,464✔
151
   }
152

153
   for(size_t i = 0; i < 12; ++i) {
98,254✔
154
      for(size_t j = 0; j != 8; ++j) {
816,264✔
155
         A[j] ^= force_le(STREEBOG_C[i][j]);
725,568✔
156
      }
157
      lps(A);
90,696✔
158

159
      lps(hN);
90,696✔
160
      for(size_t j = 0; j != 8; ++j) {
816,264✔
161
         hN[j] ^= A[j];
725,568✔
162
      }
163
   }
164

165
   for(size_t i = 0; i != 8; ++i) {
68,022✔
166
      m_h[i] ^= hN[i] ^ M[i];
60,464✔
167
   }
168

169
   if(!last_block) {
7,558✔
170
      uint64_t carry = 0;
171
      for(int i = 0; i < 8; i++) {
30,222✔
172
         const uint64_t m = force_le(M[i]);
26,864✔
173
         const uint64_t hi = force_le(m_S[i]);
26,864✔
174
         const uint64_t t = hi + m + carry;
26,864✔
175

176
         m_S[i] = force_le(t);
26,864✔
177
         if(t != m) {
26,864✔
178
            carry = (t < m);
9,952✔
179
         }
180
      }
181
   }
182
}
7,558✔
183

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

© 2025 Coveralls, Inc