digestpp 1.0
C++11 header-only message digest library
Loading...
Searching...
No Matches
sm3_provider.hpp
Go to the documentation of this file.
1/*
2This code is written by kerukuro and released into public domain.
3*/
4
5#ifndef DIGESTPP_PROVIDERS_SM3_HPP
6#define DIGESTPP_PROVIDERS_SM3_HPP
7
10#include <array>
11
12namespace digestpp
13{
14
15namespace detail
16{
17
18namespace sm3_functions
19{
20 static inline uint32_t xorf(uint32_t x, uint32_t y, uint32_t z)
21 {
22 return x ^ y ^ z;
23 }
24
25 static inline uint32_t ff1(uint32_t x, uint32_t y, uint32_t z)
26 {
27 return (x & y) ^ (x & z) ^ (y & z);
28 }
29
30 static inline uint32_t gg1(uint32_t x, uint32_t y, uint32_t z)
31 {
32 return (x & y) ^ (~x & z);
33 }
34
35 static inline uint32_t p0(uint32_t x)
36 {
37 return x ^ rotate_left(x, 9) ^ rotate_left(x, 17);
38 }
39
40 static inline uint32_t p1(uint32_t x)
41 {
42 return x ^ rotate_left(x, 15) ^ rotate_left(x, 23);
43 }
44}
45
47{
48public:
49 static const bool is_xof = false;
50
52 {
53 }
54
56 {
57 clear();
58 }
59
60 inline void init()
61 {
62 H[0] = 0x7380166f;
63 H[1] = 0x4914b2b9;
64 H[2] = 0x172442d7;
65 H[3] = 0xda8a0600;
66 H[4] = 0xa96f30bc;
67 H[5] = 0x163138aa;
68 H[6] = 0xe38dee4d;
69 H[7] = 0xb0fb0e4e;
70 pos = 0;
71 total = 0;
72 }
73
74 inline void update(const unsigned char* data, size_t len)
75 {
76 detail::absorb_bytes(data, len, 64, 64, m.data(), pos, total,
77 [this](const unsigned char* data, size_t len) { transform(data, len); });
78 }
79
80 inline void final(unsigned char* hash)
81 {
82 total += pos * 8;
83 m[pos++] = 0x80;
84 if (pos > 56)
85 {
86 if (pos != 64)
87 memset(&m[pos], 0, 64 - pos);
88 transform(m.data(), 1);
89 pos = 0;
90 }
91 memset(&m[pos], 0, 56 - pos);
92 uint64_t mlen = byteswap(total);
93 memcpy(&m[64 - 8], &mlen, 64 / 8);
94 transform(m.data(), 1);
95 for (int i = 0; i < 8; i++)
96 H[i] = byteswap(H[i]);
97 memcpy(hash, H.data(), 32);
98 }
99
100 inline void clear()
101 {
102 zero_memory(H);
103 zero_memory(m);
104 }
105
106 inline size_t hash_size() const { return 256; }
107
108private:
109 inline void transform(const unsigned char* data, size_t num_blks)
110 {
111 for (uint64_t blk = 0; blk < num_blks; blk++)
112 {
113 uint32_t M[16];
114 for (uint32_t i = 0; i < 64 / 4; i++)
115 M[i] = byteswap(reinterpret_cast<const uint32_t*>(data)[blk * 16 + i]);
116
117 uint32_t W[68];
118 uint32_t W2[64];
119 for (int t = 0; t <= 15; t++)
120 W[t] = M[t];
121 for (int t = 16; t <= 67; t++)
122 W[t] = sm3_functions::p1(W[t - 16] ^ W[t - 9] ^ rotate_left(W[t - 3], 15)) ^ rotate_left(W[t - 13], 7) ^ W[t - 6];
123 for (int t = 0; t <= 63; t++)
124 W2[t] = W[t] ^ W[t + 4];
125
126 uint32_t a = H[0];
127 uint32_t b = H[1];
128 uint32_t c = H[2];
129 uint32_t d = H[3];
130 uint32_t e = H[4];
131 uint32_t f = H[5];
132 uint32_t g = H[6];
133 uint32_t h = H[7];
134
135 for (int t = 0; t <= 15; t++)
136 {
137 uint32_t ss1 = rotate_left((rotate_left(a, 12) + e + rotate_left(0x79cc4519U, t)), 7);
138 uint32_t ss2 = ss1 ^ rotate_left(a, 12);
139 uint32_t tt1 = sm3_functions::xorf(a, b, c) + d + ss2 + W2[t];
140 uint32_t tt2 = sm3_functions::xorf(e, f, g) + h + ss1 + W[t];
141 d = c;
142 c = rotate_left(b, 9);
143 b = a;
144 a = tt1;
145 h = g;
146 g = rotate_left(f, 19);
147 f = e;
148 e = sm3_functions::p0(tt2);
149 }
150
151 for (int t = 16; t <= 63; t++)
152 {
153 uint32_t ss1 = rotate_left((rotate_left(a, 12) + e + rotate_left(0x7a879d8aU, t)), 7);
154 uint32_t ss2 = ss1 ^ rotate_left(a, 12);
155 uint32_t tt1 = sm3_functions::ff1(a, b, c) + d + ss2 + W2[t];
156 uint32_t tt2 = sm3_functions::gg1(e, f, g) + h + ss1 + W[t];
157 d = c;
158 c = rotate_left(b, 9);
159 b = a;
160 a = tt1;
161 h = g;
162 g = rotate_left(f, 19);
163 f = e;
164 e = sm3_functions::p0(tt2);
165 }
166
167 H[0] ^= a;
168 H[1] ^= b;
169 H[2] ^= c;
170 H[3] ^= d;
171 H[4] ^= e;
172 H[5] ^= f;
173 H[6] ^= g;
174 H[7] ^= h;
175 }
176 }
177
178 std::array<uint32_t, 8> H;
179 std::array<unsigned char, 64> m;
180 size_t pos;
181 uint64_t total;
182};
183
184} // namespace detail
185
186} // namespace digestpp
187
188#endif
Definition sm3_provider.hpp:47
void init()
Definition sm3_provider.hpp:60
size_t hash_size() const
Definition sm3_provider.hpp:106
void update(const unsigned char *data, size_t len)
Definition sm3_provider.hpp:74
void clear()
Definition sm3_provider.hpp:100
~sm3_provider()
Definition sm3_provider.hpp:55
sm3_provider()
Definition sm3_provider.hpp:51
static uint32_t p1(uint32_t x)
Definition sm3_provider.hpp:40
static uint32_t xorf(uint32_t x, uint32_t y, uint32_t z)
Definition sm3_provider.hpp:20
static uint32_t gg1(uint32_t x, uint32_t y, uint32_t z)
Definition sm3_provider.hpp:30
static uint32_t ff1(uint32_t x, uint32_t y, uint32_t z)
Definition sm3_provider.hpp:25
static uint32_t p0(uint32_t x)
Definition sm3_provider.hpp:35
uint16_t byteswap(uint16_t val)
Definition functions.hpp:16
uint32_t rotate_left(uint32_t x, unsigned n)
Definition functions.hpp:67
void zero_memory(void *v, size_t n)
Definition functions.hpp:85
void absorb_bytes(const unsigned char *data, size_t len, size_t bs, size_t bschk, unsigned char *m, size_t &pos, T &total, TF transform)
Definition absorb_data.hpp:16
digestpp namespace
Definition ascon.hpp:14
Definition traits.hpp:17