Botan 3.11.0
Crypto and TLS for C&
sm3.cpp
Go to the documentation of this file.
1/*
2* SM3
3* (C) 2017 Ribose Inc.
4* (C) 2021 Jack Lloyd
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#include <botan/internal/sm3.h>
10
11#include <botan/internal/buffer_slicer.h>
12#include <botan/internal/loadstor.h>
13#include <botan/internal/sm3_fn.h>
14
15#if defined(BOTAN_HAS_CPUID)
16 #include <botan/internal/cpuid.h>
17#endif
18
19namespace Botan {
20
21/*
22* SM3 Compression Function
23*/
24void SM3::compress_n(digest_type& digest, std::span<const uint8_t> input, size_t blocks) {
25#if defined(BOTAN_HAS_SM3_ARMV8)
27 return compress_digest_armv8(digest, input, blocks);
28 }
29#endif
30
31#if defined(BOTAN_HAS_SM3_X86)
33 return compress_digest_x86(digest, input, blocks);
34 }
35#endif
36
37#if defined(BOTAN_HAS_SM3_X86_AVX2_BMI2)
39 return compress_digest_x86_avx2(digest, input, blocks);
40 }
41#endif
42
43 uint32_t A = digest[0];
44 uint32_t B = digest[1];
45 uint32_t C = digest[2];
46 uint32_t D = digest[3];
47 uint32_t E = digest[4];
48 uint32_t F = digest[5];
49 uint32_t G = digest[6];
50 uint32_t H = digest[7];
51 std::array<uint32_t, 16> W{};
52
53 BufferSlicer in(input);
54
55 for(size_t i = 0; i != blocks; ++i) {
56 load_be(W, in.take<block_bytes>());
57
58 // clang-format off
59
60 R1(A, B, C, D, E, F, G, H, 0x79CC4519, W[ 0], W[ 4]);
61 W[ 0] = SM3_E(W[ 0], W[ 7], W[13], W[ 3], W[10]);
62 R1(D, A, B, C, H, E, F, G, 0xF3988A32, W[ 1], W[ 5]);
63 W[ 1] = SM3_E(W[ 1], W[ 8], W[14], W[ 4], W[11]);
64 R1(C, D, A, B, G, H, E, F, 0xE7311465, W[ 2], W[ 6]);
65 W[ 2] = SM3_E(W[ 2], W[ 9], W[15], W[ 5], W[12]);
66 R1(B, C, D, A, F, G, H, E, 0xCE6228CB, W[ 3], W[ 7]);
67 W[ 3] = SM3_E(W[ 3], W[10], W[ 0], W[ 6], W[13]);
68 R1(A, B, C, D, E, F, G, H, 0x9CC45197, W[ 4], W[ 8]);
69 W[ 4] = SM3_E(W[ 4], W[11], W[ 1], W[ 7], W[14]);
70 R1(D, A, B, C, H, E, F, G, 0x3988A32F, W[ 5], W[ 9]);
71 W[ 5] = SM3_E(W[ 5], W[12], W[ 2], W[ 8], W[15]);
72 R1(C, D, A, B, G, H, E, F, 0x7311465E, W[ 6], W[10]);
73 W[ 6] = SM3_E(W[ 6], W[13], W[ 3], W[ 9], W[ 0]);
74 R1(B, C, D, A, F, G, H, E, 0xE6228CBC, W[ 7], W[11]);
75 W[ 7] = SM3_E(W[ 7], W[14], W[ 4], W[10], W[ 1]);
76 R1(A, B, C, D, E, F, G, H, 0xCC451979, W[ 8], W[12]);
77 W[ 8] = SM3_E(W[ 8], W[15], W[ 5], W[11], W[ 2]);
78 R1(D, A, B, C, H, E, F, G, 0x988A32F3, W[ 9], W[13]);
79 W[ 9] = SM3_E(W[ 9], W[ 0], W[ 6], W[12], W[ 3]);
80 R1(C, D, A, B, G, H, E, F, 0x311465E7, W[10], W[14]);
81 W[10] = SM3_E(W[10], W[ 1], W[ 7], W[13], W[ 4]);
82 R1(B, C, D, A, F, G, H, E, 0x6228CBCE, W[11], W[15]);
83 W[11] = SM3_E(W[11], W[ 2], W[ 8], W[14], W[ 5]);
84 R1(A, B, C, D, E, F, G, H, 0xC451979C, W[12], W[ 0]);
85 W[12] = SM3_E(W[12], W[ 3], W[ 9], W[15], W[ 6]);
86 R1(D, A, B, C, H, E, F, G, 0x88A32F39, W[13], W[ 1]);
87 W[13] = SM3_E(W[13], W[ 4], W[10], W[ 0], W[ 7]);
88 R1(C, D, A, B, G, H, E, F, 0x11465E73, W[14], W[ 2]);
89 W[14] = SM3_E(W[14], W[ 5], W[11], W[ 1], W[ 8]);
90 R1(B, C, D, A, F, G, H, E, 0x228CBCE6, W[15], W[ 3]);
91 W[15] = SM3_E(W[15], W[ 6], W[12], W[ 2], W[ 9]);
92 R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W[ 0], W[ 4]);
93 W[ 0] = SM3_E(W[ 0], W[ 7], W[13], W[ 3], W[10]);
94 R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W[ 1], W[ 5]);
95 W[ 1] = SM3_E(W[ 1], W[ 8], W[14], W[ 4], W[11]);
96 R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W[ 2], W[ 6]);
97 W[ 2] = SM3_E(W[ 2], W[ 9], W[15], W[ 5], W[12]);
98 R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W[ 3], W[ 7]);
99 W[ 3] = SM3_E(W[ 3], W[10], W[ 0], W[ 6], W[13]);
100 R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W[ 4], W[ 8]);
101 W[ 4] = SM3_E(W[ 4], W[11], W[ 1], W[ 7], W[14]);
102 R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W[ 5], W[ 9]);
103 W[ 5] = SM3_E(W[ 5], W[12], W[ 2], W[ 8], W[15]);
104 R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W[ 6], W[10]);
105 W[ 6] = SM3_E(W[ 6], W[13], W[ 3], W[ 9], W[ 0]);
106 R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W[ 7], W[11]);
107 W[ 7] = SM3_E(W[ 7], W[14], W[ 4], W[10], W[ 1]);
108 R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W[ 8], W[12]);
109 W[ 8] = SM3_E(W[ 8], W[15], W[ 5], W[11], W[ 2]);
110 R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W[ 9], W[13]);
111 W[ 9] = SM3_E(W[ 9], W[ 0], W[ 6], W[12], W[ 3]);
112 R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W[10], W[14]);
113 W[10] = SM3_E(W[10], W[ 1], W[ 7], W[13], W[ 4]);
114 R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W[11], W[15]);
115 W[11] = SM3_E(W[11], W[ 2], W[ 8], W[14], W[ 5]);
116 R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W[12], W[ 0]);
117 W[12] = SM3_E(W[12], W[ 3], W[ 9], W[15], W[ 6]);
118 R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W[13], W[ 1]);
119 W[13] = SM3_E(W[13], W[ 4], W[10], W[ 0], W[ 7]);
120 R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W[14], W[ 2]);
121 W[14] = SM3_E(W[14], W[ 5], W[11], W[ 1], W[ 8]);
122 R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W[15], W[ 3]);
123 W[15] = SM3_E(W[15], W[ 6], W[12], W[ 2], W[ 9]);
124 R2(A, B, C, D, E, F, G, H, 0x7A879D8A, W[ 0], W[ 4]);
125 W[ 0] = SM3_E(W[ 0], W[ 7], W[13], W[ 3], W[10]);
126 R2(D, A, B, C, H, E, F, G, 0xF50F3B14, W[ 1], W[ 5]);
127 W[ 1] = SM3_E(W[ 1], W[ 8], W[14], W[ 4], W[11]);
128 R2(C, D, A, B, G, H, E, F, 0xEA1E7629, W[ 2], W[ 6]);
129 W[ 2] = SM3_E(W[ 2], W[ 9], W[15], W[ 5], W[12]);
130 R2(B, C, D, A, F, G, H, E, 0xD43CEC53, W[ 3], W[ 7]);
131 W[ 3] = SM3_E(W[ 3], W[10], W[ 0], W[ 6], W[13]);
132 R2(A, B, C, D, E, F, G, H, 0xA879D8A7, W[ 4], W[ 8]);
133 W[ 4] = SM3_E(W[ 4], W[11], W[ 1], W[ 7], W[14]);
134 R2(D, A, B, C, H, E, F, G, 0x50F3B14F, W[ 5], W[ 9]);
135 W[ 5] = SM3_E(W[ 5], W[12], W[ 2], W[ 8], W[15]);
136 R2(C, D, A, B, G, H, E, F, 0xA1E7629E, W[ 6], W[10]);
137 W[ 6] = SM3_E(W[ 6], W[13], W[ 3], W[ 9], W[ 0]);
138 R2(B, C, D, A, F, G, H, E, 0x43CEC53D, W[ 7], W[11]);
139 W[ 7] = SM3_E(W[ 7], W[14], W[ 4], W[10], W[ 1]);
140 R2(A, B, C, D, E, F, G, H, 0x879D8A7A, W[ 8], W[12]);
141 W[ 8] = SM3_E(W[ 8], W[15], W[ 5], W[11], W[ 2]);
142 R2(D, A, B, C, H, E, F, G, 0x0F3B14F5, W[ 9], W[13]);
143 W[ 9] = SM3_E(W[ 9], W[ 0], W[ 6], W[12], W[ 3]);
144 R2(C, D, A, B, G, H, E, F, 0x1E7629EA, W[10], W[14]);
145 W[10] = SM3_E(W[10], W[ 1], W[ 7], W[13], W[ 4]);
146 R2(B, C, D, A, F, G, H, E, 0x3CEC53D4, W[11], W[15]);
147 W[11] = SM3_E(W[11], W[ 2], W[ 8], W[14], W[ 5]);
148 R2(A, B, C, D, E, F, G, H, 0x79D8A7A8, W[12], W[ 0]);
149 W[12] = SM3_E(W[12], W[ 3], W[ 9], W[15], W[ 6]);
150 R2(D, A, B, C, H, E, F, G, 0xF3B14F50, W[13], W[ 1]);
151 W[13] = SM3_E(W[13], W[ 4], W[10], W[ 0], W[ 7]);
152 R2(C, D, A, B, G, H, E, F, 0xE7629EA1, W[14], W[ 2]);
153 W[14] = SM3_E(W[14], W[ 5], W[11], W[ 1], W[ 8]);
154 R2(B, C, D, A, F, G, H, E, 0xCEC53D43, W[15], W[ 3]);
155 W[15] = SM3_E(W[15], W[ 6], W[12], W[ 2], W[ 9]);
156 R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W[ 0], W[ 4]);
157 W[ 0] = SM3_E(W[ 0], W[ 7], W[13], W[ 3], W[10]);
158 R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W[ 1], W[ 5]);
159 W[ 1] = SM3_E(W[ 1], W[ 8], W[14], W[ 4], W[11]);
160 R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W[ 2], W[ 6]);
161 W[ 2] = SM3_E(W[ 2], W[ 9], W[15], W[ 5], W[12]);
162 R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W[ 3], W[ 7]);
163 W[ 3] = SM3_E(W[ 3], W[10], W[ 0], W[ 6], W[13]);
164 R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W[ 4], W[ 8]);
165 R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W[ 5], W[ 9]);
166 R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W[ 6], W[10]);
167 R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W[ 7], W[11]);
168 R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W[ 8], W[12]);
169 R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W[ 9], W[13]);
170 R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W[10], W[14]);
171 R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W[11], W[15]);
172 R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W[12], W[ 0]);
173 R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W[13], W[ 1]);
174 R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W[14], W[ 2]);
175 R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W[15], W[ 3]);
176
177 // clang-format on
178
179 A = (digest[0] ^= A);
180 B = (digest[1] ^= B);
181 C = (digest[2] ^= C);
182 D = (digest[3] ^= D);
183 E = (digest[4] ^= E);
184 F = (digest[5] ^= F);
185 G = (digest[6] ^= G);
186 H = (digest[7] ^= H);
187 }
188}
189
190void SM3::init(digest_type& digest) {
191 digest.assign(
192 {0x7380166fUL, 0x4914b2b9UL, 0x172442d7UL, 0xda8a0600UL, 0xa96f30bcUL, 0x163138aaUL, 0xe38dee4dUL, 0xb0fb0e4eUL});
193}
194
195std::unique_ptr<HashFunction> SM3::new_object() const {
196 return std::make_unique<SM3>();
197}
198
199std::unique_ptr<HashFunction> SM3::copy_state() const {
200 return std::make_unique<SM3>(*this);
201}
202
203void SM3::add_data(std::span<const uint8_t> input) {
204 m_md.update(input);
205}
206
207void SM3::final_result(std::span<uint8_t> output) {
208 m_md.final(output);
209}
210
211std::string SM3::provider() const {
212#if defined(BOTAN_HAS_SM3_ARMV8)
213 if(auto feat = CPUID::check(CPUID::Feature::SM3)) {
214 return *feat;
215 }
216#endif
217
218#if defined(BOTAN_HAS_SM3_X86)
220 return *feat;
221 }
222#endif
223
224#if defined(BOTAN_HAS_SM3_X86_AVX2_BMI2)
226 return *feat;
227 }
228#endif
229
230 return "base";
231}
232
233} // namespace Botan
std::span< const uint8_t > take(const size_t count)
static std::optional< std::string > check(CPUID::Feature feat)
Definition cpuid.h:67
static bool has(CPUID::Feature feat)
Definition cpuid.h:94
std::unique_ptr< HashFunction > copy_state() const override
Definition sm3.cpp:199
std::unique_ptr< HashFunction > new_object() const override
Definition sm3.cpp:195
std::string provider() const override
Definition sm3.cpp:211
secure_vector< uint32_t > digest_type
Definition sm3.h:20
static constexpr size_t block_bytes
Definition sm3.h:24
static void compress_n(digest_type &digest, std::span< const uint8_t > input, size_t blocks)
Definition sm3.cpp:24
static void init(digest_type &digest)
Definition sm3.cpp:190
uint32_t SM3_E(uint32_t W0, uint32_t W7, uint32_t W13, uint32_t W3, uint32_t W10)
Definition sm3_fn.h:69
void R2(uint32_t A, uint32_t &B, uint32_t C, uint32_t &D, uint32_t E, uint32_t &F, uint32_t G, uint32_t &H, uint32_t TJ, uint32_t Wi, uint32_t Wj)
Definition sm3_fn.h:43
void R1(uint32_t A, uint32_t &B, uint32_t C, uint32_t &D, uint32_t E, uint32_t &F, uint32_t G, uint32_t &H, uint32_t TJ, uint32_t Wi, uint32_t Wj)
Definition sm3_fn.h:21
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:504