xref: /third_party/lzma/C/Sha256.c (revision 370b324c)
1370b324cSopenharmony_ci/* Sha256.c -- SHA-256 Hash
2370b324cSopenharmony_ci2023-04-02 : Igor Pavlov : Public domain
3370b324cSopenharmony_ciThis code is based on public domain code from Wei Dai's Crypto++ library. */
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include "Precomp.h"
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#include <string.h>
8370b324cSopenharmony_ci
9370b324cSopenharmony_ci#include "CpuArch.h"
10370b324cSopenharmony_ci#include "RotateDefs.h"
11370b324cSopenharmony_ci#include "Sha256.h"
12370b324cSopenharmony_ci
13370b324cSopenharmony_ci#if defined(_MSC_VER) && (_MSC_VER < 1900)
14370b324cSopenharmony_ci// #define USE_MY_MM
15370b324cSopenharmony_ci#endif
16370b324cSopenharmony_ci
17370b324cSopenharmony_ci#ifdef MY_CPU_X86_OR_AMD64
18370b324cSopenharmony_ci  #ifdef _MSC_VER
19370b324cSopenharmony_ci    #if _MSC_VER >= 1200
20370b324cSopenharmony_ci      #define Z7_COMPILER_SHA256_SUPPORTED
21370b324cSopenharmony_ci    #endif
22370b324cSopenharmony_ci  #elif defined(__clang__)
23370b324cSopenharmony_ci    #if (__clang_major__ >= 8) // fix that check
24370b324cSopenharmony_ci      #define Z7_COMPILER_SHA256_SUPPORTED
25370b324cSopenharmony_ci    #endif
26370b324cSopenharmony_ci  #elif defined(__GNUC__)
27370b324cSopenharmony_ci    #if (__GNUC__ >= 8) // fix that check
28370b324cSopenharmony_ci      #define Z7_COMPILER_SHA256_SUPPORTED
29370b324cSopenharmony_ci    #endif
30370b324cSopenharmony_ci  #elif defined(__INTEL_COMPILER)
31370b324cSopenharmony_ci    #if (__INTEL_COMPILER >= 1800) // fix that check
32370b324cSopenharmony_ci      #define Z7_COMPILER_SHA256_SUPPORTED
33370b324cSopenharmony_ci    #endif
34370b324cSopenharmony_ci  #endif
35370b324cSopenharmony_ci#elif defined(MY_CPU_ARM_OR_ARM64)
36370b324cSopenharmony_ci  #ifdef _MSC_VER
37370b324cSopenharmony_ci    #if _MSC_VER >= 1910
38370b324cSopenharmony_ci      #define Z7_COMPILER_SHA256_SUPPORTED
39370b324cSopenharmony_ci    #endif
40370b324cSopenharmony_ci  #elif defined(__clang__)
41370b324cSopenharmony_ci    #if (__clang_major__ >= 8) // fix that check
42370b324cSopenharmony_ci      #define Z7_COMPILER_SHA256_SUPPORTED
43370b324cSopenharmony_ci    #endif
44370b324cSopenharmony_ci  #elif defined(__GNUC__)
45370b324cSopenharmony_ci    #if (__GNUC__ >= 6) // fix that check
46370b324cSopenharmony_ci      #define Z7_COMPILER_SHA256_SUPPORTED
47370b324cSopenharmony_ci    #endif
48370b324cSopenharmony_ci  #endif
49370b324cSopenharmony_ci#endif
50370b324cSopenharmony_ci
51370b324cSopenharmony_civoid Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks);
52370b324cSopenharmony_ci
53370b324cSopenharmony_ci#ifdef Z7_COMPILER_SHA256_SUPPORTED
54370b324cSopenharmony_ci  void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks);
55370b324cSopenharmony_ci
56370b324cSopenharmony_ci  static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS = Sha256_UpdateBlocks;
57370b324cSopenharmony_ci  static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS_HW;
58370b324cSopenharmony_ci
59370b324cSopenharmony_ci  #define SHA256_UPDATE_BLOCKS(p) p->func_UpdateBlocks
60370b324cSopenharmony_ci#else
61370b324cSopenharmony_ci  #define SHA256_UPDATE_BLOCKS(p) Sha256_UpdateBlocks
62370b324cSopenharmony_ci#endif
63370b324cSopenharmony_ci
64370b324cSopenharmony_ci
65370b324cSopenharmony_ciBoolInt Sha256_SetFunction(CSha256 *p, unsigned algo)
66370b324cSopenharmony_ci{
67370b324cSopenharmony_ci  SHA256_FUNC_UPDATE_BLOCKS func = Sha256_UpdateBlocks;
68370b324cSopenharmony_ci
69370b324cSopenharmony_ci  #ifdef Z7_COMPILER_SHA256_SUPPORTED
70370b324cSopenharmony_ci    if (algo != SHA256_ALGO_SW)
71370b324cSopenharmony_ci    {
72370b324cSopenharmony_ci      if (algo == SHA256_ALGO_DEFAULT)
73370b324cSopenharmony_ci        func = g_SHA256_FUNC_UPDATE_BLOCKS;
74370b324cSopenharmony_ci      else
75370b324cSopenharmony_ci      {
76370b324cSopenharmony_ci        if (algo != SHA256_ALGO_HW)
77370b324cSopenharmony_ci          return False;
78370b324cSopenharmony_ci        func = g_SHA256_FUNC_UPDATE_BLOCKS_HW;
79370b324cSopenharmony_ci        if (!func)
80370b324cSopenharmony_ci          return False;
81370b324cSopenharmony_ci      }
82370b324cSopenharmony_ci    }
83370b324cSopenharmony_ci  #else
84370b324cSopenharmony_ci    if (algo > 1)
85370b324cSopenharmony_ci      return False;
86370b324cSopenharmony_ci  #endif
87370b324cSopenharmony_ci
88370b324cSopenharmony_ci  p->func_UpdateBlocks = func;
89370b324cSopenharmony_ci  return True;
90370b324cSopenharmony_ci}
91370b324cSopenharmony_ci
92370b324cSopenharmony_ci
93370b324cSopenharmony_ci/* define it for speed optimization */
94370b324cSopenharmony_ci
95370b324cSopenharmony_ci#ifdef Z7_SFX
96370b324cSopenharmony_ci  #define STEP_PRE 1
97370b324cSopenharmony_ci  #define STEP_MAIN 1
98370b324cSopenharmony_ci#else
99370b324cSopenharmony_ci  #define STEP_PRE 2
100370b324cSopenharmony_ci  #define STEP_MAIN 4
101370b324cSopenharmony_ci  // #define Z7_SHA256_UNROLL
102370b324cSopenharmony_ci#endif
103370b324cSopenharmony_ci
104370b324cSopenharmony_ci#undef Z7_SHA256_BIG_W
105370b324cSopenharmony_ci#if STEP_MAIN != 16
106370b324cSopenharmony_ci  #define Z7_SHA256_BIG_W
107370b324cSopenharmony_ci#endif
108370b324cSopenharmony_ci
109370b324cSopenharmony_ci
110370b324cSopenharmony_ci
111370b324cSopenharmony_ci
112370b324cSopenharmony_civoid Sha256_InitState(CSha256 *p)
113370b324cSopenharmony_ci{
114370b324cSopenharmony_ci  p->count = 0;
115370b324cSopenharmony_ci  p->state[0] = 0x6a09e667;
116370b324cSopenharmony_ci  p->state[1] = 0xbb67ae85;
117370b324cSopenharmony_ci  p->state[2] = 0x3c6ef372;
118370b324cSopenharmony_ci  p->state[3] = 0xa54ff53a;
119370b324cSopenharmony_ci  p->state[4] = 0x510e527f;
120370b324cSopenharmony_ci  p->state[5] = 0x9b05688c;
121370b324cSopenharmony_ci  p->state[6] = 0x1f83d9ab;
122370b324cSopenharmony_ci  p->state[7] = 0x5be0cd19;
123370b324cSopenharmony_ci}
124370b324cSopenharmony_ci
125370b324cSopenharmony_civoid Sha256_Init(CSha256 *p)
126370b324cSopenharmony_ci{
127370b324cSopenharmony_ci  p->func_UpdateBlocks =
128370b324cSopenharmony_ci  #ifdef Z7_COMPILER_SHA256_SUPPORTED
129370b324cSopenharmony_ci      g_SHA256_FUNC_UPDATE_BLOCKS;
130370b324cSopenharmony_ci  #else
131370b324cSopenharmony_ci      NULL;
132370b324cSopenharmony_ci  #endif
133370b324cSopenharmony_ci  Sha256_InitState(p);
134370b324cSopenharmony_ci}
135370b324cSopenharmony_ci
136370b324cSopenharmony_ci#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22))
137370b324cSopenharmony_ci#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25))
138370b324cSopenharmony_ci#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3))
139370b324cSopenharmony_ci#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
140370b324cSopenharmony_ci
141370b324cSopenharmony_ci#define Ch(x,y,z) (z^(x&(y^z)))
142370b324cSopenharmony_ci#define Maj(x,y,z) ((x&y)|(z&(x|y)))
143370b324cSopenharmony_ci
144370b324cSopenharmony_ci
145370b324cSopenharmony_ci#define W_PRE(i) (W[(i) + (size_t)(j)] = GetBe32(data + ((size_t)(j) + i) * 4))
146370b324cSopenharmony_ci
147370b324cSopenharmony_ci#define blk2_main(j, i)  s1(w(j, (i)-2)) + w(j, (i)-7) + s0(w(j, (i)-15))
148370b324cSopenharmony_ci
149370b324cSopenharmony_ci#ifdef Z7_SHA256_BIG_W
150370b324cSopenharmony_ci    // we use +i instead of +(i) to change the order to solve CLANG compiler warning for signed/unsigned.
151370b324cSopenharmony_ci    #define w(j, i)     W[(size_t)(j) + i]
152370b324cSopenharmony_ci    #define blk2(j, i)  (w(j, i) = w(j, (i)-16) + blk2_main(j, i))
153370b324cSopenharmony_ci#else
154370b324cSopenharmony_ci    #if STEP_MAIN == 16
155370b324cSopenharmony_ci        #define w(j, i)  W[(i) & 15]
156370b324cSopenharmony_ci    #else
157370b324cSopenharmony_ci        #define w(j, i)  W[((size_t)(j) + (i)) & 15]
158370b324cSopenharmony_ci    #endif
159370b324cSopenharmony_ci    #define blk2(j, i)  (w(j, i) += blk2_main(j, i))
160370b324cSopenharmony_ci#endif
161370b324cSopenharmony_ci
162370b324cSopenharmony_ci#define W_MAIN(i)  blk2(j, i)
163370b324cSopenharmony_ci
164370b324cSopenharmony_ci
165370b324cSopenharmony_ci#define T1(wx, i) \
166370b324cSopenharmony_ci    tmp = h + S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \
167370b324cSopenharmony_ci    h = g; \
168370b324cSopenharmony_ci    g = f; \
169370b324cSopenharmony_ci    f = e; \
170370b324cSopenharmony_ci    e = d + tmp; \
171370b324cSopenharmony_ci    tmp += S0(a) + Maj(a, b, c); \
172370b324cSopenharmony_ci    d = c; \
173370b324cSopenharmony_ci    c = b; \
174370b324cSopenharmony_ci    b = a; \
175370b324cSopenharmony_ci    a = tmp; \
176370b324cSopenharmony_ci
177370b324cSopenharmony_ci#define R1_PRE(i)  T1( W_PRE, i)
178370b324cSopenharmony_ci#define R1_MAIN(i) T1( W_MAIN, i)
179370b324cSopenharmony_ci
180370b324cSopenharmony_ci#if (!defined(Z7_SHA256_UNROLL) || STEP_MAIN < 8) && (STEP_MAIN >= 4)
181370b324cSopenharmony_ci#define R2_MAIN(i) \
182370b324cSopenharmony_ci    R1_MAIN(i) \
183370b324cSopenharmony_ci    R1_MAIN(i + 1) \
184370b324cSopenharmony_ci
185370b324cSopenharmony_ci#endif
186370b324cSopenharmony_ci
187370b324cSopenharmony_ci
188370b324cSopenharmony_ci
189370b324cSopenharmony_ci#if defined(Z7_SHA256_UNROLL) && STEP_MAIN >= 8
190370b324cSopenharmony_ci
191370b324cSopenharmony_ci#define T4( a,b,c,d,e,f,g,h, wx, i) \
192370b324cSopenharmony_ci    h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \
193370b324cSopenharmony_ci    tmp = h; \
194370b324cSopenharmony_ci    h += d; \
195370b324cSopenharmony_ci    d = tmp + S0(a) + Maj(a, b, c); \
196370b324cSopenharmony_ci
197370b324cSopenharmony_ci#define R4( wx, i) \
198370b324cSopenharmony_ci    T4 ( a,b,c,d,e,f,g,h, wx, (i  )); \
199370b324cSopenharmony_ci    T4 ( d,a,b,c,h,e,f,g, wx, (i+1)); \
200370b324cSopenharmony_ci    T4 ( c,d,a,b,g,h,e,f, wx, (i+2)); \
201370b324cSopenharmony_ci    T4 ( b,c,d,a,f,g,h,e, wx, (i+3)); \
202370b324cSopenharmony_ci
203370b324cSopenharmony_ci#define R4_PRE(i)  R4( W_PRE, i)
204370b324cSopenharmony_ci#define R4_MAIN(i) R4( W_MAIN, i)
205370b324cSopenharmony_ci
206370b324cSopenharmony_ci
207370b324cSopenharmony_ci#define T8( a,b,c,d,e,f,g,h, wx, i) \
208370b324cSopenharmony_ci    h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \
209370b324cSopenharmony_ci    d += h; \
210370b324cSopenharmony_ci    h += S0(a) + Maj(a, b, c); \
211370b324cSopenharmony_ci
212370b324cSopenharmony_ci#define R8( wx, i) \
213370b324cSopenharmony_ci    T8 ( a,b,c,d,e,f,g,h, wx, i  ); \
214370b324cSopenharmony_ci    T8 ( h,a,b,c,d,e,f,g, wx, i+1); \
215370b324cSopenharmony_ci    T8 ( g,h,a,b,c,d,e,f, wx, i+2); \
216370b324cSopenharmony_ci    T8 ( f,g,h,a,b,c,d,e, wx, i+3); \
217370b324cSopenharmony_ci    T8 ( e,f,g,h,a,b,c,d, wx, i+4); \
218370b324cSopenharmony_ci    T8 ( d,e,f,g,h,a,b,c, wx, i+5); \
219370b324cSopenharmony_ci    T8 ( c,d,e,f,g,h,a,b, wx, i+6); \
220370b324cSopenharmony_ci    T8 ( b,c,d,e,f,g,h,a, wx, i+7); \
221370b324cSopenharmony_ci
222370b324cSopenharmony_ci#define R8_PRE(i)  R8( W_PRE, i)
223370b324cSopenharmony_ci#define R8_MAIN(i) R8( W_MAIN, i)
224370b324cSopenharmony_ci
225370b324cSopenharmony_ci#endif
226370b324cSopenharmony_ci
227370b324cSopenharmony_civoid Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks);
228370b324cSopenharmony_ci
229370b324cSopenharmony_ci// static
230370b324cSopenharmony_ciextern MY_ALIGN(64)
231370b324cSopenharmony_ciconst UInt32 SHA256_K_ARRAY[64];
232370b324cSopenharmony_ci
233370b324cSopenharmony_ciMY_ALIGN(64)
234370b324cSopenharmony_ciconst UInt32 SHA256_K_ARRAY[64] = {
235370b324cSopenharmony_ci  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
236370b324cSopenharmony_ci  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
237370b324cSopenharmony_ci  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
238370b324cSopenharmony_ci  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
239370b324cSopenharmony_ci  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
240370b324cSopenharmony_ci  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
241370b324cSopenharmony_ci  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
242370b324cSopenharmony_ci  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
243370b324cSopenharmony_ci  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
244370b324cSopenharmony_ci  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
245370b324cSopenharmony_ci  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
246370b324cSopenharmony_ci  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
247370b324cSopenharmony_ci  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
248370b324cSopenharmony_ci  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
249370b324cSopenharmony_ci  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
250370b324cSopenharmony_ci  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
251370b324cSopenharmony_ci};
252370b324cSopenharmony_ci
253370b324cSopenharmony_ci#define K SHA256_K_ARRAY
254370b324cSopenharmony_ci
255370b324cSopenharmony_ci
256370b324cSopenharmony_ciZ7_NO_INLINE
257370b324cSopenharmony_civoid Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks)
258370b324cSopenharmony_ci{
259370b324cSopenharmony_ci  UInt32 W
260370b324cSopenharmony_ci  #ifdef Z7_SHA256_BIG_W
261370b324cSopenharmony_ci      [64];
262370b324cSopenharmony_ci  #else
263370b324cSopenharmony_ci      [16];
264370b324cSopenharmony_ci  #endif
265370b324cSopenharmony_ci
266370b324cSopenharmony_ci  unsigned j;
267370b324cSopenharmony_ci
268370b324cSopenharmony_ci  UInt32 a,b,c,d,e,f,g,h;
269370b324cSopenharmony_ci
270370b324cSopenharmony_ci  #if !defined(Z7_SHA256_UNROLL) || (STEP_MAIN <= 4) || (STEP_PRE <= 4)
271370b324cSopenharmony_ci  UInt32 tmp;
272370b324cSopenharmony_ci  #endif
273370b324cSopenharmony_ci
274370b324cSopenharmony_ci  a = state[0];
275370b324cSopenharmony_ci  b = state[1];
276370b324cSopenharmony_ci  c = state[2];
277370b324cSopenharmony_ci  d = state[3];
278370b324cSopenharmony_ci  e = state[4];
279370b324cSopenharmony_ci  f = state[5];
280370b324cSopenharmony_ci  g = state[6];
281370b324cSopenharmony_ci  h = state[7];
282370b324cSopenharmony_ci
283370b324cSopenharmony_ci  while (numBlocks)
284370b324cSopenharmony_ci  {
285370b324cSopenharmony_ci
286370b324cSopenharmony_ci  for (j = 0; j < 16; j += STEP_PRE)
287370b324cSopenharmony_ci  {
288370b324cSopenharmony_ci    #if STEP_PRE > 4
289370b324cSopenharmony_ci
290370b324cSopenharmony_ci      #if STEP_PRE < 8
291370b324cSopenharmony_ci      R4_PRE(0);
292370b324cSopenharmony_ci      #else
293370b324cSopenharmony_ci      R8_PRE(0);
294370b324cSopenharmony_ci      #if STEP_PRE == 16
295370b324cSopenharmony_ci      R8_PRE(8);
296370b324cSopenharmony_ci      #endif
297370b324cSopenharmony_ci      #endif
298370b324cSopenharmony_ci
299370b324cSopenharmony_ci    #else
300370b324cSopenharmony_ci
301370b324cSopenharmony_ci      R1_PRE(0)
302370b324cSopenharmony_ci      #if STEP_PRE >= 2
303370b324cSopenharmony_ci      R1_PRE(1)
304370b324cSopenharmony_ci      #if STEP_PRE >= 4
305370b324cSopenharmony_ci      R1_PRE(2)
306370b324cSopenharmony_ci      R1_PRE(3)
307370b324cSopenharmony_ci      #endif
308370b324cSopenharmony_ci      #endif
309370b324cSopenharmony_ci
310370b324cSopenharmony_ci    #endif
311370b324cSopenharmony_ci  }
312370b324cSopenharmony_ci
313370b324cSopenharmony_ci  for (j = 16; j < 64; j += STEP_MAIN)
314370b324cSopenharmony_ci  {
315370b324cSopenharmony_ci    #if defined(Z7_SHA256_UNROLL) && STEP_MAIN >= 8
316370b324cSopenharmony_ci
317370b324cSopenharmony_ci      #if STEP_MAIN < 8
318370b324cSopenharmony_ci      R4_MAIN(0)
319370b324cSopenharmony_ci      #else
320370b324cSopenharmony_ci      R8_MAIN(0)
321370b324cSopenharmony_ci      #if STEP_MAIN == 16
322370b324cSopenharmony_ci      R8_MAIN(8)
323370b324cSopenharmony_ci      #endif
324370b324cSopenharmony_ci      #endif
325370b324cSopenharmony_ci
326370b324cSopenharmony_ci    #else
327370b324cSopenharmony_ci
328370b324cSopenharmony_ci      R1_MAIN(0)
329370b324cSopenharmony_ci      #if STEP_MAIN >= 2
330370b324cSopenharmony_ci      R1_MAIN(1)
331370b324cSopenharmony_ci      #if STEP_MAIN >= 4
332370b324cSopenharmony_ci      R2_MAIN(2)
333370b324cSopenharmony_ci      #if STEP_MAIN >= 8
334370b324cSopenharmony_ci      R2_MAIN(4)
335370b324cSopenharmony_ci      R2_MAIN(6)
336370b324cSopenharmony_ci      #if STEP_MAIN >= 16
337370b324cSopenharmony_ci      R2_MAIN(8)
338370b324cSopenharmony_ci      R2_MAIN(10)
339370b324cSopenharmony_ci      R2_MAIN(12)
340370b324cSopenharmony_ci      R2_MAIN(14)
341370b324cSopenharmony_ci      #endif
342370b324cSopenharmony_ci      #endif
343370b324cSopenharmony_ci      #endif
344370b324cSopenharmony_ci      #endif
345370b324cSopenharmony_ci    #endif
346370b324cSopenharmony_ci  }
347370b324cSopenharmony_ci
348370b324cSopenharmony_ci  a += state[0]; state[0] = a;
349370b324cSopenharmony_ci  b += state[1]; state[1] = b;
350370b324cSopenharmony_ci  c += state[2]; state[2] = c;
351370b324cSopenharmony_ci  d += state[3]; state[3] = d;
352370b324cSopenharmony_ci  e += state[4]; state[4] = e;
353370b324cSopenharmony_ci  f += state[5]; state[5] = f;
354370b324cSopenharmony_ci  g += state[6]; state[6] = g;
355370b324cSopenharmony_ci  h += state[7]; state[7] = h;
356370b324cSopenharmony_ci
357370b324cSopenharmony_ci  data += 64;
358370b324cSopenharmony_ci  numBlocks--;
359370b324cSopenharmony_ci  }
360370b324cSopenharmony_ci
361370b324cSopenharmony_ci  /* Wipe variables */
362370b324cSopenharmony_ci  /* memset(W, 0, sizeof(W)); */
363370b324cSopenharmony_ci}
364370b324cSopenharmony_ci
365370b324cSopenharmony_ci#undef S0
366370b324cSopenharmony_ci#undef S1
367370b324cSopenharmony_ci#undef s0
368370b324cSopenharmony_ci#undef s1
369370b324cSopenharmony_ci#undef K
370370b324cSopenharmony_ci
371370b324cSopenharmony_ci#define Sha256_UpdateBlock(p) SHA256_UPDATE_BLOCKS(p)(p->state, p->buffer, 1)
372370b324cSopenharmony_ci
373370b324cSopenharmony_civoid Sha256_Update(CSha256 *p, const Byte *data, size_t size)
374370b324cSopenharmony_ci{
375370b324cSopenharmony_ci  if (size == 0)
376370b324cSopenharmony_ci    return;
377370b324cSopenharmony_ci
378370b324cSopenharmony_ci  {
379370b324cSopenharmony_ci    unsigned pos = (unsigned)p->count & 0x3F;
380370b324cSopenharmony_ci    unsigned num;
381370b324cSopenharmony_ci
382370b324cSopenharmony_ci    p->count += size;
383370b324cSopenharmony_ci
384370b324cSopenharmony_ci    num = 64 - pos;
385370b324cSopenharmony_ci    if (num > size)
386370b324cSopenharmony_ci    {
387370b324cSopenharmony_ci      memcpy(p->buffer + pos, data, size);
388370b324cSopenharmony_ci      return;
389370b324cSopenharmony_ci    }
390370b324cSopenharmony_ci
391370b324cSopenharmony_ci    if (pos != 0)
392370b324cSopenharmony_ci    {
393370b324cSopenharmony_ci      size -= num;
394370b324cSopenharmony_ci      memcpy(p->buffer + pos, data, num);
395370b324cSopenharmony_ci      data += num;
396370b324cSopenharmony_ci      Sha256_UpdateBlock(p);
397370b324cSopenharmony_ci    }
398370b324cSopenharmony_ci  }
399370b324cSopenharmony_ci  {
400370b324cSopenharmony_ci    size_t numBlocks = size >> 6;
401370b324cSopenharmony_ci    SHA256_UPDATE_BLOCKS(p)(p->state, data, numBlocks);
402370b324cSopenharmony_ci    size &= 0x3F;
403370b324cSopenharmony_ci    if (size == 0)
404370b324cSopenharmony_ci      return;
405370b324cSopenharmony_ci    data += (numBlocks << 6);
406370b324cSopenharmony_ci    memcpy(p->buffer, data, size);
407370b324cSopenharmony_ci  }
408370b324cSopenharmony_ci}
409370b324cSopenharmony_ci
410370b324cSopenharmony_ci
411370b324cSopenharmony_civoid Sha256_Final(CSha256 *p, Byte *digest)
412370b324cSopenharmony_ci{
413370b324cSopenharmony_ci  unsigned pos = (unsigned)p->count & 0x3F;
414370b324cSopenharmony_ci  unsigned i;
415370b324cSopenharmony_ci
416370b324cSopenharmony_ci  p->buffer[pos++] = 0x80;
417370b324cSopenharmony_ci
418370b324cSopenharmony_ci  if (pos > (64 - 8))
419370b324cSopenharmony_ci  {
420370b324cSopenharmony_ci    while (pos != 64) { p->buffer[pos++] = 0; }
421370b324cSopenharmony_ci    // memset(&p->buf.buffer[pos], 0, 64 - pos);
422370b324cSopenharmony_ci    Sha256_UpdateBlock(p);
423370b324cSopenharmony_ci    pos = 0;
424370b324cSopenharmony_ci  }
425370b324cSopenharmony_ci
426370b324cSopenharmony_ci  /*
427370b324cSopenharmony_ci  if (pos & 3)
428370b324cSopenharmony_ci  {
429370b324cSopenharmony_ci    p->buffer[pos] = 0;
430370b324cSopenharmony_ci    p->buffer[pos + 1] = 0;
431370b324cSopenharmony_ci    p->buffer[pos + 2] = 0;
432370b324cSopenharmony_ci    pos += 3;
433370b324cSopenharmony_ci    pos &= ~3;
434370b324cSopenharmony_ci  }
435370b324cSopenharmony_ci  {
436370b324cSopenharmony_ci    for (; pos < 64 - 8; pos += 4)
437370b324cSopenharmony_ci      *(UInt32 *)(&p->buffer[pos]) = 0;
438370b324cSopenharmony_ci  }
439370b324cSopenharmony_ci  */
440370b324cSopenharmony_ci
441370b324cSopenharmony_ci  memset(&p->buffer[pos], 0, (64 - 8) - pos);
442370b324cSopenharmony_ci
443370b324cSopenharmony_ci  {
444370b324cSopenharmony_ci    UInt64 numBits = (p->count << 3);
445370b324cSopenharmony_ci    SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32))
446370b324cSopenharmony_ci    SetBe32(p->buffer + 64 - 4, (UInt32)(numBits))
447370b324cSopenharmony_ci  }
448370b324cSopenharmony_ci
449370b324cSopenharmony_ci  Sha256_UpdateBlock(p);
450370b324cSopenharmony_ci
451370b324cSopenharmony_ci  for (i = 0; i < 8; i += 2)
452370b324cSopenharmony_ci  {
453370b324cSopenharmony_ci    UInt32 v0 = p->state[i];
454370b324cSopenharmony_ci    UInt32 v1 = p->state[(size_t)i + 1];
455370b324cSopenharmony_ci    SetBe32(digest    , v0)
456370b324cSopenharmony_ci    SetBe32(digest + 4, v1)
457370b324cSopenharmony_ci    digest += 8;
458370b324cSopenharmony_ci  }
459370b324cSopenharmony_ci
460370b324cSopenharmony_ci  Sha256_InitState(p);
461370b324cSopenharmony_ci}
462370b324cSopenharmony_ci
463370b324cSopenharmony_ci
464370b324cSopenharmony_civoid Sha256Prepare(void)
465370b324cSopenharmony_ci{
466370b324cSopenharmony_ci  #ifdef Z7_COMPILER_SHA256_SUPPORTED
467370b324cSopenharmony_ci  SHA256_FUNC_UPDATE_BLOCKS f, f_hw;
468370b324cSopenharmony_ci  f = Sha256_UpdateBlocks;
469370b324cSopenharmony_ci  f_hw = NULL;
470370b324cSopenharmony_ci  #ifdef MY_CPU_X86_OR_AMD64
471370b324cSopenharmony_ci  #ifndef USE_MY_MM
472370b324cSopenharmony_ci  if (CPU_IsSupported_SHA()
473370b324cSopenharmony_ci      && CPU_IsSupported_SSSE3()
474370b324cSopenharmony_ci      // && CPU_IsSupported_SSE41()
475370b324cSopenharmony_ci      )
476370b324cSopenharmony_ci  #endif
477370b324cSopenharmony_ci  #else
478370b324cSopenharmony_ci  if (CPU_IsSupported_SHA2())
479370b324cSopenharmony_ci  #endif
480370b324cSopenharmony_ci  {
481370b324cSopenharmony_ci    // printf("\n========== HW SHA256 ======== \n");
482370b324cSopenharmony_ci    f = f_hw = Sha256_UpdateBlocks_HW;
483370b324cSopenharmony_ci  }
484370b324cSopenharmony_ci  g_SHA256_FUNC_UPDATE_BLOCKS    = f;
485370b324cSopenharmony_ci  g_SHA256_FUNC_UPDATE_BLOCKS_HW = f_hw;
486370b324cSopenharmony_ci  #endif
487370b324cSopenharmony_ci}
488370b324cSopenharmony_ci
489370b324cSopenharmony_ci#undef S0
490370b324cSopenharmony_ci#undef S1
491370b324cSopenharmony_ci#undef s0
492370b324cSopenharmony_ci#undef s1
493370b324cSopenharmony_ci#undef Ch
494370b324cSopenharmony_ci#undef Maj
495370b324cSopenharmony_ci#undef W_MAIN
496370b324cSopenharmony_ci#undef W_PRE
497370b324cSopenharmony_ci#undef w
498370b324cSopenharmony_ci#undef blk2_main
499370b324cSopenharmony_ci#undef blk2
500370b324cSopenharmony_ci#undef T1
501370b324cSopenharmony_ci#undef T4
502370b324cSopenharmony_ci#undef T8
503370b324cSopenharmony_ci#undef R1_PRE
504370b324cSopenharmony_ci#undef R1_MAIN
505370b324cSopenharmony_ci#undef R2_MAIN
506370b324cSopenharmony_ci#undef R4
507370b324cSopenharmony_ci#undef R4_PRE
508370b324cSopenharmony_ci#undef R4_MAIN
509370b324cSopenharmony_ci#undef R8
510370b324cSopenharmony_ci#undef R8_PRE
511370b324cSopenharmony_ci#undef R8_MAIN
512370b324cSopenharmony_ci#undef STEP_PRE
513370b324cSopenharmony_ci#undef STEP_MAIN
514370b324cSopenharmony_ci#undef Z7_SHA256_BIG_W
515370b324cSopenharmony_ci#undef Z7_SHA256_UNROLL
516370b324cSopenharmony_ci#undef Z7_COMPILER_SHA256_SUPPORTED
517