Coverage Report

Created: 2023-12-08 07:00

/src/mcl/include/cybozu/sha2.hpp
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
/**
3
  @file
4
  @brief SHA-256, SHA-512 class
5
  @author MITSUNARI Shigeo(@herumi)
6
  @license modified new BSD license
7
  http://opensource.org/licenses/BSD-3-Clause
8
*/
9
#if !defined(CYBOZU_DONT_USE_OPENSSL) && !defined(MCL_DONT_USE_OPENSSL)
10
  #define CYBOZU_USE_OPENSSL_SHA
11
#endif
12
13
#ifndef CYBOZU_DONT_USE_STRING
14
#include <string>
15
#endif
16
#include <memory.h>
17
18
#ifdef CYBOZU_USE_OPENSSL_SHA
19
20
#ifndef CYBOZU_USE_OPENSSL_NEW_HASH
21
#ifndef _MSC_VER
22
#define CYBOZU_USE_OPENSSL_NEW_HASH 1
23
#endif
24
#endif
25
26
#ifdef __APPLE__
27
  #pragma GCC diagnostic push
28
  #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
29
#endif
30
#if CYBOZU_USE_OPENSSL_NEW_HASH == 1
31
#include <openssl/evp.h>
32
#include <assert.h>
33
#else
34
#include <openssl/sha.h>
35
#endif
36
#ifdef _MSC_VER
37
  #include <cybozu/link_libeay32.hpp>
38
#endif
39
40
#ifdef __APPLE__
41
  #pragma GCC diagnostic pop
42
#endif
43
44
namespace cybozu {
45
46
#if CYBOZU_USE_OPENSSL_NEW_HASH == 1
47
namespace local {
48
49
template<size_t MD_SIZE_>
50
struct NewHash {
51
  static const size_t MD_SIZE = MD_SIZE_;
52
  EVP_MD_CTX *mdctx_;
53
  const EVP_MD *md_;
54
  explicit NewHash(const char *name)
55
    : mdctx_(EVP_MD_CTX_new())
56
    , md_(EVP_get_digestbyname(name))
57
  {
58
    if (md_ == 0) {
59
      fprintf(stderr, "fatail error NewHash %s\n", name);
60
    }
61
    assert(md_);
62
  }
63
  ~NewHash()
64
  {
65
    EVP_MD_CTX_free(mdctx_);
66
  }
67
  void clear()
68
  {
69
    EVP_MD_CTX_reset(mdctx_);
70
    EVP_DigestInit_ex(mdctx_, md_, NULL);
71
  }
72
  void update(const void *buf, size_t bufSize)
73
  {
74
    EVP_DigestUpdate(mdctx_, buf, bufSize);
75
  }
76
  size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize)
77
  {
78
    if (mdSize < MD_SIZE) return 0;
79
    update(buf, bufSize);
80
    unsigned int len;
81
    EVP_DigestFinal_ex(mdctx_, (unsigned char*)md, &len);
82
    assert(len == MD_SIZE);
83
    return MD_SIZE;
84
  }
85
};
86
87
} // local
88
#endif
89
90
class Sha256 {
91
#if CYBOZU_USE_OPENSSL_NEW_HASH == 1
92
  local::NewHash<32> ctx_;
93
#else
94
  SHA256_CTX ctx_;
95
#endif
96
public:
97
  Sha256()
98
#if CYBOZU_USE_OPENSSL_NEW_HASH == 1
99
    : ctx_("sha256")
100
#endif
101
  {
102
    clear();
103
  }
104
  void clear()
105
  {
106
#if CYBOZU_USE_OPENSSL_NEW_HASH == 1
107
    ctx_.clear();
108
#else
109
    SHA256_Init(&ctx_);
110
#endif
111
  }
112
  void update(const void *buf, size_t bufSize)
113
  {
114
#if CYBOZU_USE_OPENSSL_NEW_HASH == 1
115
    ctx_.update(buf, bufSize);
116
#else
117
    SHA256_Update(&ctx_, buf, bufSize);
118
#endif
119
  }
120
  size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize)
121
  {
122
#if CYBOZU_USE_OPENSSL_NEW_HASH == 1
123
    return ctx_.digest(md, mdSize, buf, bufSize);
124
#else
125
    if (mdSize < SHA256_DIGEST_LENGTH) return 0;
126
    update(buf, bufSize);
127
    SHA256_Final(reinterpret_cast<uint8_t*>(md), &ctx_);
128
    return SHA256_DIGEST_LENGTH;
129
#endif
130
  }
131
#ifndef CYBOZU_DONT_USE_STRING
132
  void update(const std::string& buf)
133
  {
134
    update(buf.c_str(), buf.size());
135
  }
136
  std::string digest(const std::string& buf)
137
  {
138
    return digest(buf.c_str(), buf.size());
139
  }
140
  std::string digest(const void *buf, size_t bufSize)
141
  {
142
#if CYBOZU_USE_OPENSSL_NEW_HASH == 1
143
    std::string md(ctx_.MD_SIZE, 0);
144
#else
145
    std::string md(SHA256_DIGEST_LENGTH, 0);
146
#endif
147
    digest(&md[0], md.size(), buf, bufSize);
148
    return md;
149
  }
150
#endif
151
};
152
153
class Sha512 {
154
#if CYBOZU_USE_OPENSSL_NEW_HASH == 1
155
  local::NewHash<64> ctx_;
156
#else
157
  SHA512_CTX ctx_;
158
#endif
159
public:
160
  Sha512()
161
#if CYBOZU_USE_OPENSSL_NEW_HASH == 1
162
    : ctx_("sha512")
163
#endif
164
  {
165
    clear();
166
  }
167
  void clear()
168
  {
169
#if CYBOZU_USE_OPENSSL_NEW_HASH == 1
170
    ctx_.clear();
171
#else
172
    SHA512_Init(&ctx_);
173
#endif
174
  }
175
  void update(const void *buf, size_t bufSize)
176
  {
177
#if CYBOZU_USE_OPENSSL_NEW_HASH == 1
178
    ctx_.update(buf, bufSize);
179
#else
180
    SHA512_Update(&ctx_, buf, bufSize);
181
#endif
182
  }
183
  size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize)
184
  {
185
#if CYBOZU_USE_OPENSSL_NEW_HASH == 1
186
    return ctx_.digest(md, mdSize, buf, bufSize);
187
#else
188
    if (mdSize < SHA512_DIGEST_LENGTH) return 0;
189
    update(buf, bufSize);
190
    SHA512_Final(reinterpret_cast<uint8_t*>(md), &ctx_);
191
    return SHA512_DIGEST_LENGTH;
192
#endif
193
  }
194
#ifndef CYBOZU_DONT_USE_STRING
195
  void update(const std::string& buf)
196
  {
197
    update(buf.c_str(), buf.size());
198
  }
199
  std::string digest(const std::string& buf)
200
  {
201
    return digest(buf.c_str(), buf.size());
202
  }
203
  std::string digest(const void *buf, size_t bufSize)
204
  {
205
#if CYBOZU_USE_OPENSSL_NEW_HASH == 1
206
    std::string md(ctx_.MD_SIZE, 0);
207
#else
208
    std::string md(SHA512_DIGEST_LENGTH, 0);
209
#endif
210
    digest(&md[0], md.size(), buf, bufSize);
211
    return md;
212
  }
213
#endif
214
};
215
216
} // cybozu
217
218
#else
219
220
#include <cybozu/endian.hpp>
221
#include <memory.h>
222
#include <assert.h>
223
224
namespace cybozu {
225
226
namespace sha2_local {
227
228
template<class T>
229
16.9k
T min_(T x, T y) { return x < y ? x : y;; }
230
231
inline uint32_t rot32(uint32_t x, int s)
232
9.14M
{
233
#ifdef _MSC_VER
234
  return _rotr(x, s);
235
#else
236
9.14M
  return (x >> s) | (x << (32 - s));
237
9.14M
#endif
238
9.14M
}
239
240
inline uint64_t rot64(uint64_t x, int s)
241
0
{
242
#ifdef _MSC_VER
243
  return _rotr64(x, s);
244
#else
245
0
  return (x >> s) | (x << (64 - s));
246
0
#endif
247
0
}
248
249
template<class T>
250
struct Common {
251
  void term(uint8_t *buf, size_t bufSize)
252
6.25k
  {
253
6.25k
    assert(bufSize < T::blockSize_);
254
0
    T& self = static_cast<T&>(*this);
255
6.25k
    const uint64_t totalSize = self.totalSize_ + bufSize;
256
257
6.25k
    buf[bufSize] = uint8_t(0x80); /* top bit = 1 */
258
6.25k
    memset(&buf[bufSize + 1], 0, T::blockSize_ - bufSize - 1);
259
6.25k
    if (bufSize >= T::blockSize_ - T::msgLenByte_) {
260
0
      self.round(buf);
261
0
      memset(buf, 0, T::blockSize_ - 8); // clear stack
262
0
    }
263
6.25k
    cybozu::Set64bitAsBE(&buf[T::blockSize_ - 8], totalSize * 8);
264
6.25k
    self.round(buf);
265
6.25k
  }
cybozu::sha2_local::Common<cybozu::Sha256>::term(unsigned char*, unsigned long)
Line
Count
Source
252
6.25k
  {
253
6.25k
    assert(bufSize < T::blockSize_);
254
0
    T& self = static_cast<T&>(*this);
255
6.25k
    const uint64_t totalSize = self.totalSize_ + bufSize;
256
257
6.25k
    buf[bufSize] = uint8_t(0x80); /* top bit = 1 */
258
6.25k
    memset(&buf[bufSize + 1], 0, T::blockSize_ - bufSize - 1);
259
6.25k
    if (bufSize >= T::blockSize_ - T::msgLenByte_) {
260
0
      self.round(buf);
261
0
      memset(buf, 0, T::blockSize_ - 8); // clear stack
262
0
    }
263
6.25k
    cybozu::Set64bitAsBE(&buf[T::blockSize_ - 8], totalSize * 8);
264
6.25k
    self.round(buf);
265
6.25k
  }
Unexecuted instantiation: cybozu::sha2_local::Common<cybozu::Sha512>::term(unsigned char*, unsigned long)
266
  void inner_update(const uint8_t *buf, size_t bufSize)
267
26.4k
  {
268
26.4k
    T& self = static_cast<T&>(*this);
269
26.4k
    if (bufSize == 0) return;
270
24.0k
    if (self.roundBufSize_ > 0) {
271
16.9k
      size_t size = sha2_local::min_(T::blockSize_ - self.roundBufSize_, bufSize);
272
16.9k
      memcpy(self.roundBuf_ + self.roundBufSize_, buf, size);
273
16.9k
      self.roundBufSize_ += size;
274
16.9k
      buf += size;
275
16.9k
      bufSize -= size;
276
16.9k
    }
277
24.0k
    if (self.roundBufSize_ == T::blockSize_) {
278
2.22k
      self.round(self.roundBuf_);
279
2.22k
      self.roundBufSize_ = 0;
280
2.22k
    }
281
31.1k
    while (bufSize >= T::blockSize_) {
282
7.14k
      assert(self.roundBufSize_ == 0);
283
0
      self.round(buf);
284
7.14k
      buf += T::blockSize_;
285
7.14k
      bufSize -= T::blockSize_;
286
7.14k
    }
287
24.0k
    if (bufSize > 0) {
288
8.43k
      assert(bufSize < T::blockSize_);
289
0
      assert(self.roundBufSize_ == 0);
290
0
      memcpy(self.roundBuf_, buf, bufSize);
291
8.43k
      self.roundBufSize_ = bufSize;
292
8.43k
    }
293
0
    assert(self.roundBufSize_ < T::blockSize_);
294
24.0k
  }
cybozu::sha2_local::Common<cybozu::Sha256>::inner_update(unsigned char const*, unsigned long)
Line
Count
Source
267
26.4k
  {
268
26.4k
    T& self = static_cast<T&>(*this);
269
26.4k
    if (bufSize == 0) return;
270
24.0k
    if (self.roundBufSize_ > 0) {
271
16.9k
      size_t size = sha2_local::min_(T::blockSize_ - self.roundBufSize_, bufSize);
272
16.9k
      memcpy(self.roundBuf_ + self.roundBufSize_, buf, size);
273
16.9k
      self.roundBufSize_ += size;
274
16.9k
      buf += size;
275
16.9k
      bufSize -= size;
276
16.9k
    }
277
24.0k
    if (self.roundBufSize_ == T::blockSize_) {
278
2.22k
      self.round(self.roundBuf_);
279
2.22k
      self.roundBufSize_ = 0;
280
2.22k
    }
281
31.1k
    while (bufSize >= T::blockSize_) {
282
7.14k
      assert(self.roundBufSize_ == 0);
283
0
      self.round(buf);
284
7.14k
      buf += T::blockSize_;
285
7.14k
      bufSize -= T::blockSize_;
286
7.14k
    }
287
24.0k
    if (bufSize > 0) {
288
8.43k
      assert(bufSize < T::blockSize_);
289
0
      assert(self.roundBufSize_ == 0);
290
0
      memcpy(self.roundBuf_, buf, bufSize);
291
8.43k
      self.roundBufSize_ = bufSize;
292
8.43k
    }
293
0
    assert(self.roundBufSize_ < T::blockSize_);
294
24.0k
  }
Unexecuted instantiation: cybozu::sha2_local::Common<cybozu::Sha512>::inner_update(unsigned char const*, unsigned long)
295
};
296
297
} // cybozu::sha2_local
298
299
class Sha256 : public sha2_local::Common<Sha256> {
300
  friend struct sha2_local::Common<Sha256>;
301
private:
302
  static const size_t blockSize_ = 64;
303
  static const size_t hSize_ = 8;
304
  static const size_t msgLenByte_ = 8;
305
  uint64_t totalSize_;
306
  size_t roundBufSize_;
307
  uint8_t roundBuf_[blockSize_];
308
  uint32_t h_[hSize_];
309
  static const size_t outByteSize_ = hSize_ * sizeof(uint32_t);
310
  const uint32_t *k_;
311
312
  template<size_t i0, size_t i1, size_t i2, size_t i3, size_t i4, size_t i5, size_t i6, size_t i7>
313
  void round1(uint32_t *s, uint32_t *w, int i)
314
1.01M
  {
315
1.01M
    using namespace sha2_local;
316
1.01M
    uint32_t e = s[i4];
317
1.01M
    uint32_t h = s[i7];
318
1.01M
    h += rot32(e, 6) ^ rot32(e, 11) ^ rot32(e, 25);
319
1.01M
    uint32_t f = s[i5];
320
1.01M
    uint32_t g = s[i6];
321
1.01M
    h += g ^ (e & (f ^ g));
322
1.01M
    h += k_[i];
323
1.01M
    h += w[i];
324
1.01M
    s[i3] += h;
325
1.01M
    uint32_t a = s[i0];
326
1.01M
    uint32_t b = s[i1];
327
1.01M
    uint32_t c = s[i2];
328
1.01M
    h += rot32(a, 2) ^ rot32(a, 13) ^ rot32(a, 22);
329
1.01M
    h += ((a | b) & c) | (a & b);
330
1.01M
    s[i7] = h;
331
1.01M
  }
void cybozu::Sha256::round1<0ul, 1ul, 2ul, 3ul, 4ul, 5ul, 6ul, 7ul>(unsigned int*, unsigned int*, int)
Line
Count
Source
314
127k
  {
315
127k
    using namespace sha2_local;
316
127k
    uint32_t e = s[i4];
317
127k
    uint32_t h = s[i7];
318
127k
    h += rot32(e, 6) ^ rot32(e, 11) ^ rot32(e, 25);
319
127k
    uint32_t f = s[i5];
320
127k
    uint32_t g = s[i6];
321
127k
    h += g ^ (e & (f ^ g));
322
127k
    h += k_[i];
323
127k
    h += w[i];
324
127k
    s[i3] += h;
325
127k
    uint32_t a = s[i0];
326
127k
    uint32_t b = s[i1];
327
127k
    uint32_t c = s[i2];
328
127k
    h += rot32(a, 2) ^ rot32(a, 13) ^ rot32(a, 22);
329
127k
    h += ((a | b) & c) | (a & b);
330
127k
    s[i7] = h;
331
127k
  }
void cybozu::Sha256::round1<7ul, 0ul, 1ul, 2ul, 3ul, 4ul, 5ul, 6ul>(unsigned int*, unsigned int*, int)
Line
Count
Source
314
127k
  {
315
127k
    using namespace sha2_local;
316
127k
    uint32_t e = s[i4];
317
127k
    uint32_t h = s[i7];
318
127k
    h += rot32(e, 6) ^ rot32(e, 11) ^ rot32(e, 25);
319
127k
    uint32_t f = s[i5];
320
127k
    uint32_t g = s[i6];
321
127k
    h += g ^ (e & (f ^ g));
322
127k
    h += k_[i];
323
127k
    h += w[i];
324
127k
    s[i3] += h;
325
127k
    uint32_t a = s[i0];
326
127k
    uint32_t b = s[i1];
327
127k
    uint32_t c = s[i2];
328
127k
    h += rot32(a, 2) ^ rot32(a, 13) ^ rot32(a, 22);
329
127k
    h += ((a | b) & c) | (a & b);
330
127k
    s[i7] = h;
331
127k
  }
void cybozu::Sha256::round1<6ul, 7ul, 0ul, 1ul, 2ul, 3ul, 4ul, 5ul>(unsigned int*, unsigned int*, int)
Line
Count
Source
314
127k
  {
315
127k
    using namespace sha2_local;
316
127k
    uint32_t e = s[i4];
317
127k
    uint32_t h = s[i7];
318
127k
    h += rot32(e, 6) ^ rot32(e, 11) ^ rot32(e, 25);
319
127k
    uint32_t f = s[i5];
320
127k
    uint32_t g = s[i6];
321
127k
    h += g ^ (e & (f ^ g));
322
127k
    h += k_[i];
323
127k
    h += w[i];
324
127k
    s[i3] += h;
325
127k
    uint32_t a = s[i0];
326
127k
    uint32_t b = s[i1];
327
127k
    uint32_t c = s[i2];
328
127k
    h += rot32(a, 2) ^ rot32(a, 13) ^ rot32(a, 22);
329
127k
    h += ((a | b) & c) | (a & b);
330
127k
    s[i7] = h;
331
127k
  }
void cybozu::Sha256::round1<5ul, 6ul, 7ul, 0ul, 1ul, 2ul, 3ul, 4ul>(unsigned int*, unsigned int*, int)
Line
Count
Source
314
127k
  {
315
127k
    using namespace sha2_local;
316
127k
    uint32_t e = s[i4];
317
127k
    uint32_t h = s[i7];
318
127k
    h += rot32(e, 6) ^ rot32(e, 11) ^ rot32(e, 25);
319
127k
    uint32_t f = s[i5];
320
127k
    uint32_t g = s[i6];
321
127k
    h += g ^ (e & (f ^ g));
322
127k
    h += k_[i];
323
127k
    h += w[i];
324
127k
    s[i3] += h;
325
127k
    uint32_t a = s[i0];
326
127k
    uint32_t b = s[i1];
327
127k
    uint32_t c = s[i2];
328
127k
    h += rot32(a, 2) ^ rot32(a, 13) ^ rot32(a, 22);
329
127k
    h += ((a | b) & c) | (a & b);
330
127k
    s[i7] = h;
331
127k
  }
void cybozu::Sha256::round1<4ul, 5ul, 6ul, 7ul, 0ul, 1ul, 2ul, 3ul>(unsigned int*, unsigned int*, int)
Line
Count
Source
314
127k
  {
315
127k
    using namespace sha2_local;
316
127k
    uint32_t e = s[i4];
317
127k
    uint32_t h = s[i7];
318
127k
    h += rot32(e, 6) ^ rot32(e, 11) ^ rot32(e, 25);
319
127k
    uint32_t f = s[i5];
320
127k
    uint32_t g = s[i6];
321
127k
    h += g ^ (e & (f ^ g));
322
127k
    h += k_[i];
323
127k
    h += w[i];
324
127k
    s[i3] += h;
325
127k
    uint32_t a = s[i0];
326
127k
    uint32_t b = s[i1];
327
127k
    uint32_t c = s[i2];
328
127k
    h += rot32(a, 2) ^ rot32(a, 13) ^ rot32(a, 22);
329
127k
    h += ((a | b) & c) | (a & b);
330
127k
    s[i7] = h;
331
127k
  }
void cybozu::Sha256::round1<3ul, 4ul, 5ul, 6ul, 7ul, 0ul, 1ul, 2ul>(unsigned int*, unsigned int*, int)
Line
Count
Source
314
127k
  {
315
127k
    using namespace sha2_local;
316
127k
    uint32_t e = s[i4];
317
127k
    uint32_t h = s[i7];
318
127k
    h += rot32(e, 6) ^ rot32(e, 11) ^ rot32(e, 25);
319
127k
    uint32_t f = s[i5];
320
127k
    uint32_t g = s[i6];
321
127k
    h += g ^ (e & (f ^ g));
322
127k
    h += k_[i];
323
127k
    h += w[i];
324
127k
    s[i3] += h;
325
127k
    uint32_t a = s[i0];
326
127k
    uint32_t b = s[i1];
327
127k
    uint32_t c = s[i2];
328
127k
    h += rot32(a, 2) ^ rot32(a, 13) ^ rot32(a, 22);
329
127k
    h += ((a | b) & c) | (a & b);
330
127k
    s[i7] = h;
331
127k
  }
void cybozu::Sha256::round1<2ul, 3ul, 4ul, 5ul, 6ul, 7ul, 0ul, 1ul>(unsigned int*, unsigned int*, int)
Line
Count
Source
314
127k
  {
315
127k
    using namespace sha2_local;
316
127k
    uint32_t e = s[i4];
317
127k
    uint32_t h = s[i7];
318
127k
    h += rot32(e, 6) ^ rot32(e, 11) ^ rot32(e, 25);
319
127k
    uint32_t f = s[i5];
320
127k
    uint32_t g = s[i6];
321
127k
    h += g ^ (e & (f ^ g));
322
127k
    h += k_[i];
323
127k
    h += w[i];
324
127k
    s[i3] += h;
325
127k
    uint32_t a = s[i0];
326
127k
    uint32_t b = s[i1];
327
127k
    uint32_t c = s[i2];
328
127k
    h += rot32(a, 2) ^ rot32(a, 13) ^ rot32(a, 22);
329
127k
    h += ((a | b) & c) | (a & b);
330
127k
    s[i7] = h;
331
127k
  }
void cybozu::Sha256::round1<1ul, 2ul, 3ul, 4ul, 5ul, 6ul, 7ul, 0ul>(unsigned int*, unsigned int*, int)
Line
Count
Source
314
127k
  {
315
127k
    using namespace sha2_local;
316
127k
    uint32_t e = s[i4];
317
127k
    uint32_t h = s[i7];
318
127k
    h += rot32(e, 6) ^ rot32(e, 11) ^ rot32(e, 25);
319
127k
    uint32_t f = s[i5];
320
127k
    uint32_t g = s[i6];
321
127k
    h += g ^ (e & (f ^ g));
322
127k
    h += k_[i];
323
127k
    h += w[i];
324
127k
    s[i3] += h;
325
127k
    uint32_t a = s[i0];
326
127k
    uint32_t b = s[i1];
327
127k
    uint32_t c = s[i2];
328
127k
    h += rot32(a, 2) ^ rot32(a, 13) ^ rot32(a, 22);
329
127k
    h += ((a | b) & c) | (a & b);
330
127k
    s[i7] = h;
331
127k
  }
332
  /**
333
    @param buf [in] buffer(64byte)
334
  */
335
  void round(const uint8_t *buf)
336
15.8k
  {
337
15.8k
    using namespace sha2_local;
338
15.8k
    uint32_t w[64];
339
269k
    for (int i = 0; i < 16; i++) {
340
254k
      w[i] = cybozu::Get32bitAsBE(&buf[i * 4]);
341
254k
    }
342
778k
    for (int i = 16 ; i < 64; i++) {
343
762k
      uint32_t t = w[i - 15];
344
762k
      uint32_t s0 = rot32(t, 7) ^ rot32(t, 18) ^ (t >> 3);
345
762k
      t = w[i - 2];
346
762k
      uint32_t s1 = rot32(t, 17) ^ rot32(t, 19) ^ (t >> 10);
347
762k
      w[i] = w[i - 16] + s0 + w[i - 7] + s1;
348
762k
    }
349
15.8k
    uint32_t s[8];
350
142k
    for (int i = 0; i < 8; i++) {
351
127k
      s[i] = h_[i];
352
127k
    }
353
142k
    for (int i = 0; i < 64; i += 8) {
354
127k
      round1<0, 1, 2, 3, 4, 5, 6, 7>(s, w, i + 0);
355
127k
      round1<7, 0, 1, 2, 3, 4, 5, 6>(s, w, i + 1);
356
127k
      round1<6, 7, 0, 1, 2, 3, 4, 5>(s, w, i + 2);
357
127k
      round1<5, 6, 7, 0, 1, 2, 3, 4>(s, w, i + 3);
358
127k
      round1<4, 5, 6, 7, 0, 1, 2, 3>(s, w, i + 4);
359
127k
      round1<3, 4, 5, 6, 7, 0, 1, 2>(s, w, i + 5);
360
127k
      round1<2, 3, 4, 5, 6, 7, 0, 1>(s, w, i + 6);
361
127k
      round1<1, 2, 3, 4, 5, 6, 7, 0>(s, w, i + 7);
362
127k
    }
363
142k
    for (int i = 0; i < 8; i++) {
364
127k
      h_[i] += s[i];
365
127k
    }
366
15.8k
    totalSize_ += blockSize_;
367
15.8k
  }
368
public:
369
  Sha256()
370
797
  {
371
797
    clear();
372
797
  }
373
  void clear()
374
6.25k
  {
375
6.25k
    static const uint32_t kTbl[] = {
376
6.25k
      0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
377
6.25k
      0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
378
6.25k
      0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
379
6.25k
      0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
380
6.25k
      0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
381
6.25k
      0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
382
6.25k
      0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
383
6.25k
      0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
384
6.25k
    };
385
6.25k
    k_ = kTbl;
386
6.25k
    totalSize_ = 0;
387
6.25k
    roundBufSize_ = 0;
388
6.25k
    h_[0] = 0x6a09e667;
389
6.25k
    h_[1] = 0xbb67ae85;
390
6.25k
    h_[2] = 0x3c6ef372;
391
6.25k
    h_[3] = 0xa54ff53a;
392
6.25k
    h_[4] = 0x510e527f;
393
6.25k
    h_[5] = 0x9b05688c;
394
6.25k
    h_[6] = 0x1f83d9ab;
395
6.25k
    h_[7] = 0x5be0cd19;
396
6.25k
  }
397
  void update(const void *buf, size_t bufSize)
398
26.4k
  {
399
26.4k
    inner_update(reinterpret_cast<const uint8_t*>(buf), bufSize);
400
26.4k
  }
401
  size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize)
402
6.25k
  {
403
6.25k
    if (mdSize < outByteSize_) return 0;
404
6.25k
    update(buf, bufSize);
405
6.25k
    term(roundBuf_, roundBufSize_);
406
6.25k
    char *p = reinterpret_cast<char*>(md);
407
56.2k
    for (size_t i = 0; i < hSize_; i++) {
408
50.0k
      cybozu::Set32bitAsBE(&p[i * sizeof(h_[0])], h_[i]);
409
50.0k
    }
410
6.25k
    return outByteSize_;
411
6.25k
  }
412
#ifndef CYBOZU_DONT_USE_STRING
413
  void update(const std::string& buf)
414
0
  {
415
0
    update(buf.c_str(), buf.size());
416
0
  }
417
  std::string digest(const std::string& buf)
418
0
  {
419
0
    return digest(buf.c_str(), buf.size());
420
0
  }
421
  std::string digest(const void *buf, size_t bufSize)
422
0
  {
423
0
    std::string md(outByteSize_, 0);
424
0
    digest(&md[0], md.size(), buf, bufSize);
425
0
    return md;
426
0
  }
427
#endif
428
};
429
430
class Sha512 : public sha2_local::Common<Sha512> {
431
  friend struct sha2_local::Common<Sha512>;
432
private:
433
  static const size_t blockSize_ = 128;
434
  static const size_t hSize_ = 8;
435
  static const size_t msgLenByte_ = 16;
436
  uint64_t totalSize_;
437
  size_t roundBufSize_;
438
  uint8_t roundBuf_[blockSize_];
439
  uint64_t h_[hSize_];
440
  static const size_t outByteSize_ = hSize_ * sizeof(uint64_t);
441
  const uint64_t *k_;
442
443
  template<size_t i0, size_t i1, size_t i2, size_t i3, size_t i4, size_t i5, size_t i6, size_t i7>
444
  void round1(uint64_t *S, const uint64_t *w, size_t i)
445
0
  {
446
0
    using namespace sha2_local;
447
0
    uint64_t& a = S[i0];
448
0
    uint64_t& b = S[i1];
449
0
    uint64_t& c = S[i2];
450
0
    uint64_t& d = S[i3];
451
0
    uint64_t& e = S[i4];
452
0
    uint64_t& f = S[i5];
453
0
    uint64_t& g = S[i6];
454
0
    uint64_t& h = S[i7];
455
456
0
    uint64_t s1 = rot64(e, 14) ^ rot64(e, 18) ^ rot64(e, 41);
457
0
    uint64_t ch = g ^ (e & (f ^ g));
458
0
    uint64_t t0 = h + s1 + ch + k_[i] + w[i];
459
0
    uint64_t s0 = rot64(a, 28) ^ rot64(a, 34) ^ rot64(a, 39);
460
0
    uint64_t maj = ((a | b) & c) | (a & b);
461
0
    uint64_t t1 = s0 + maj;
462
0
    d += t0;
463
0
    h = t0 + t1;
464
0
  }
Unexecuted instantiation: void cybozu::Sha512::round1<0ul, 1ul, 2ul, 3ul, 4ul, 5ul, 6ul, 7ul>(unsigned long*, unsigned long const*, unsigned long)
Unexecuted instantiation: void cybozu::Sha512::round1<7ul, 0ul, 1ul, 2ul, 3ul, 4ul, 5ul, 6ul>(unsigned long*, unsigned long const*, unsigned long)
Unexecuted instantiation: void cybozu::Sha512::round1<6ul, 7ul, 0ul, 1ul, 2ul, 3ul, 4ul, 5ul>(unsigned long*, unsigned long const*, unsigned long)
Unexecuted instantiation: void cybozu::Sha512::round1<5ul, 6ul, 7ul, 0ul, 1ul, 2ul, 3ul, 4ul>(unsigned long*, unsigned long const*, unsigned long)
Unexecuted instantiation: void cybozu::Sha512::round1<4ul, 5ul, 6ul, 7ul, 0ul, 1ul, 2ul, 3ul>(unsigned long*, unsigned long const*, unsigned long)
Unexecuted instantiation: void cybozu::Sha512::round1<3ul, 4ul, 5ul, 6ul, 7ul, 0ul, 1ul, 2ul>(unsigned long*, unsigned long const*, unsigned long)
Unexecuted instantiation: void cybozu::Sha512::round1<2ul, 3ul, 4ul, 5ul, 6ul, 7ul, 0ul, 1ul>(unsigned long*, unsigned long const*, unsigned long)
Unexecuted instantiation: void cybozu::Sha512::round1<1ul, 2ul, 3ul, 4ul, 5ul, 6ul, 7ul, 0ul>(unsigned long*, unsigned long const*, unsigned long)
465
  /**
466
    @param buf [in] buffer(64byte)
467
  */
468
  void round(const uint8_t *buf)
469
0
  {
470
0
    using namespace sha2_local;
471
0
    uint64_t w[80];
472
0
    for (int i = 0; i < 16; i++) {
473
0
      w[i] = cybozu::Get64bitAsBE(&buf[i * 8]);
474
0
    }
475
0
    for (int i = 16 ; i < 80; i++) {
476
0
      uint64_t t = w[i - 15];
477
0
      uint64_t s0 = rot64(t, 1) ^ rot64(t, 8) ^ (t >> 7);
478
0
      t = w[i - 2];
479
0
      uint64_t s1 = rot64(t, 19) ^ rot64(t, 61) ^ (t >> 6);
480
0
      w[i] = w[i - 16] + s0 + w[i - 7] + s1;
481
0
    }
482
0
    uint64_t s[8];
483
0
    for (int i = 0; i < 8; i++) {
484
0
      s[i] = h_[i];
485
0
    }
486
0
    for (int i = 0; i < 80; i += 8) {
487
0
      round1<0, 1, 2, 3, 4, 5, 6, 7>(s, w, i + 0);
488
0
      round1<7, 0, 1, 2, 3, 4, 5, 6>(s, w, i + 1);
489
0
      round1<6, 7, 0, 1, 2, 3, 4, 5>(s, w, i + 2);
490
0
      round1<5, 6, 7, 0, 1, 2, 3, 4>(s, w, i + 3);
491
0
      round1<4, 5, 6, 7, 0, 1, 2, 3>(s, w, i + 4);
492
0
      round1<3, 4, 5, 6, 7, 0, 1, 2>(s, w, i + 5);
493
0
      round1<2, 3, 4, 5, 6, 7, 0, 1>(s, w, i + 6);
494
0
      round1<1, 2, 3, 4, 5, 6, 7, 0>(s, w, i + 7);
495
0
    }
496
0
    for (int i = 0; i < 8; i++) {
497
0
      h_[i] += s[i];
498
0
    }
499
0
    totalSize_ += blockSize_;
500
0
  }
501
public:
502
  Sha512()
503
0
  {
504
0
    clear();
505
0
  }
506
  void clear()
507
0
  {
508
0
    static const uint64_t kTbl[] = {
509
0
        0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL,
510
0
        0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
511
0
        0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
512
0
        0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
513
0
        0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL,
514
0
        0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
515
0
        0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL,
516
0
        0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
517
0
        0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
518
0
        0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
519
0
        0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL,
520
0
        0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
521
0
        0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL,
522
0
        0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
523
0
        0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
524
0
        0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
525
0
    };
526
0
    k_ = kTbl;
527
0
    totalSize_ = 0;
528
0
    roundBufSize_ = 0;
529
0
    h_[0] = 0x6a09e667f3bcc908ull;
530
0
    h_[1] = 0xbb67ae8584caa73bull;
531
0
    h_[2] = 0x3c6ef372fe94f82bull;
532
0
    h_[3] = 0xa54ff53a5f1d36f1ull;
533
0
    h_[4] = 0x510e527fade682d1ull;
534
0
    h_[5] = 0x9b05688c2b3e6c1full;
535
0
    h_[6] = 0x1f83d9abfb41bd6bull;
536
0
    h_[7] = 0x5be0cd19137e2179ull;
537
0
  }
538
  void update(const void *buf, size_t bufSize)
539
0
  {
540
0
    inner_update(reinterpret_cast<const uint8_t*>(buf), bufSize);
541
0
  }
542
  size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize)
543
0
  {
544
0
    if (mdSize < outByteSize_) return 0;
545
0
    update(buf, bufSize);
546
0
    term(roundBuf_, roundBufSize_);
547
0
    char *p = reinterpret_cast<char*>(md);
548
0
    for (size_t i = 0; i < hSize_; i++) {
549
0
      cybozu::Set64bitAsBE(&p[i * sizeof(h_[0])], h_[i]);
550
0
    }
551
0
    return outByteSize_;
552
0
  }
553
#ifndef CYBOZU_DONT_USE_STRING
554
  void update(const std::string& buf)
555
0
  {
556
0
    update(buf.c_str(), buf.size());
557
0
  }
558
  std::string digest(const std::string& buf)
559
0
  {
560
0
    return digest(buf.c_str(), buf.size());
561
0
  }
562
  std::string digest(const void *buf, size_t bufSize)
563
0
  {
564
0
    std::string md(outByteSize_, 0);
565
0
    digest(&md[0], md.size(), buf, bufSize);
566
0
    return md;
567
0
  }
568
#endif
569
};
570
571
} // cybozu
572
573
#endif
574
575
namespace cybozu {
576
577
/*
578
  HMAC-SHA-256
579
  hmac must have 32 bytes buffer
580
*/
581
inline void hmac256(void *hmac, const void *key, size_t keySize, const void *msg, size_t msgSize)
582
0
{
583
0
  const uint8_t ipad = 0x36;
584
0
  const uint8_t opad = 0x5c;
585
0
  uint8_t k[64];
586
0
  Sha256 hash;
587
0
  if (keySize > 64) {
588
0
    hash.digest(k, 32, key, keySize);
589
0
    hash.clear();
590
0
    keySize = 32;
591
0
  } else {
592
0
    memcpy(k, key, keySize);
593
0
  }
594
0
  for (size_t i = 0; i < keySize; i++) {
595
0
    k[i] = k[i] ^ ipad;
596
0
  }
597
0
  memset(k + keySize, ipad, 64 - keySize);
598
0
  hash.update(k, 64);
599
0
  hash.digest(hmac, 32, msg, msgSize);
600
0
  hash.clear();
601
0
  for (size_t i = 0; i < 64; i++) {
602
0
    k[i] = k[i] ^ (ipad ^ opad);
603
0
  }
604
0
  hash.update(k, 64);
605
0
  hash.digest(hmac, 32, hmac, 32);
606
0
}
607
608
} // cybozu