xref: /aosp_15_r20/external/lzma/C/Sha3.c (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker /* Sha3.c -- SHA-3 Hash
2*f6dc9357SAndroid Build Coastguard Worker : Igor Pavlov : Public domain
3*f6dc9357SAndroid Build Coastguard Worker This code is based on public domain code from Wei Dai's Crypto++ library. */
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "Precomp.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include <string.h>
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker #include "Sha3.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "RotateDefs.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "CpuArch.h"
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker #define U64C(x) UINT64_CONST(x)
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker static
16*f6dc9357SAndroid Build Coastguard Worker MY_ALIGN(64)
17*f6dc9357SAndroid Build Coastguard Worker const UInt64 SHA3_K_ARRAY[24] =
18*f6dc9357SAndroid Build Coastguard Worker {
19*f6dc9357SAndroid Build Coastguard Worker   U64C(0x0000000000000001), U64C(0x0000000000008082),
20*f6dc9357SAndroid Build Coastguard Worker   U64C(0x800000000000808a), U64C(0x8000000080008000),
21*f6dc9357SAndroid Build Coastguard Worker   U64C(0x000000000000808b), U64C(0x0000000080000001),
22*f6dc9357SAndroid Build Coastguard Worker   U64C(0x8000000080008081), U64C(0x8000000000008009),
23*f6dc9357SAndroid Build Coastguard Worker   U64C(0x000000000000008a), U64C(0x0000000000000088),
24*f6dc9357SAndroid Build Coastguard Worker   U64C(0x0000000080008009), U64C(0x000000008000000a),
25*f6dc9357SAndroid Build Coastguard Worker   U64C(0x000000008000808b), U64C(0x800000000000008b),
26*f6dc9357SAndroid Build Coastguard Worker   U64C(0x8000000000008089), U64C(0x8000000000008003),
27*f6dc9357SAndroid Build Coastguard Worker   U64C(0x8000000000008002), U64C(0x8000000000000080),
28*f6dc9357SAndroid Build Coastguard Worker   U64C(0x000000000000800a), U64C(0x800000008000000a),
29*f6dc9357SAndroid Build Coastguard Worker   U64C(0x8000000080008081), U64C(0x8000000000008080),
30*f6dc9357SAndroid Build Coastguard Worker   U64C(0x0000000080000001), U64C(0x8000000080008008)
31*f6dc9357SAndroid Build Coastguard Worker };
32*f6dc9357SAndroid Build Coastguard Worker 
Sha3_Init(CSha3 * p)33*f6dc9357SAndroid Build Coastguard Worker void Sha3_Init(CSha3 *p)
34*f6dc9357SAndroid Build Coastguard Worker {
35*f6dc9357SAndroid Build Coastguard Worker   p->count = 0;
36*f6dc9357SAndroid Build Coastguard Worker   memset(p->state, 0, sizeof(p->state));
37*f6dc9357SAndroid Build Coastguard Worker }
38*f6dc9357SAndroid Build Coastguard Worker 
39*f6dc9357SAndroid Build Coastguard Worker #define GET_state(i, a)   UInt64 a = state[i];
40*f6dc9357SAndroid Build Coastguard Worker #define SET_state(i, a)   state[i] = a;
41*f6dc9357SAndroid Build Coastguard Worker 
42*f6dc9357SAndroid Build Coastguard Worker #define LS_5(M, i, a0,a1,a2,a3,a4) \
43*f6dc9357SAndroid Build Coastguard Worker         M ((i) * 5    , a0) \
44*f6dc9357SAndroid Build Coastguard Worker         M ((i) * 5 + 1, a1) \
45*f6dc9357SAndroid Build Coastguard Worker         M ((i) * 5 + 2, a2) \
46*f6dc9357SAndroid Build Coastguard Worker         M ((i) * 5 + 3, a3) \
47*f6dc9357SAndroid Build Coastguard Worker         M ((i) * 5 + 4, a4) \
48*f6dc9357SAndroid Build Coastguard Worker 
49*f6dc9357SAndroid Build Coastguard Worker #define LS_25(M) \
50*f6dc9357SAndroid Build Coastguard Worker         LS_5 (M, 0, a50, a51, a52, a53, a54) \
51*f6dc9357SAndroid Build Coastguard Worker         LS_5 (M, 1, a60, a61, a62, a63, a64) \
52*f6dc9357SAndroid Build Coastguard Worker         LS_5 (M, 2, a70, a71, a72, a73, a74) \
53*f6dc9357SAndroid Build Coastguard Worker         LS_5 (M, 3, a80, a81, a82, a83, a84) \
54*f6dc9357SAndroid Build Coastguard Worker         LS_5 (M, 4, a90, a91, a92, a93, a94) \
55*f6dc9357SAndroid Build Coastguard Worker 
56*f6dc9357SAndroid Build Coastguard Worker 
57*f6dc9357SAndroid Build Coastguard Worker #define XOR_1(i, a0) \
58*f6dc9357SAndroid Build Coastguard Worker         a0 ^= GetUi64(data + (i) * 8); \
59*f6dc9357SAndroid Build Coastguard Worker 
60*f6dc9357SAndroid Build Coastguard Worker #define XOR_4(i, a0,a1,a2,a3) \
61*f6dc9357SAndroid Build Coastguard Worker         XOR_1 ((i)    , a0); \
62*f6dc9357SAndroid Build Coastguard Worker         XOR_1 ((i) + 1, a1); \
63*f6dc9357SAndroid Build Coastguard Worker         XOR_1 ((i) + 2, a2); \
64*f6dc9357SAndroid Build Coastguard Worker         XOR_1 ((i) + 3, a3); \
65*f6dc9357SAndroid Build Coastguard Worker 
66*f6dc9357SAndroid Build Coastguard Worker #define D(d,b1,b2) \
67*f6dc9357SAndroid Build Coastguard Worker         d = b1 ^ Z7_ROTL64(b2, 1);
68*f6dc9357SAndroid Build Coastguard Worker 
69*f6dc9357SAndroid Build Coastguard Worker #define D5 \
70*f6dc9357SAndroid Build Coastguard Worker         D (d0, c4, c1) \
71*f6dc9357SAndroid Build Coastguard Worker         D (d1, c0, c2) \
72*f6dc9357SAndroid Build Coastguard Worker         D (d2, c1, c3) \
73*f6dc9357SAndroid Build Coastguard Worker         D (d3, c2, c4) \
74*f6dc9357SAndroid Build Coastguard Worker         D (d4, c3, c0) \
75*f6dc9357SAndroid Build Coastguard Worker 
76*f6dc9357SAndroid Build Coastguard Worker #define C0(c,a,d) \
77*f6dc9357SAndroid Build Coastguard Worker         c = a ^ d; \
78*f6dc9357SAndroid Build Coastguard Worker 
79*f6dc9357SAndroid Build Coastguard Worker #define C(c,a,d,k) \
80*f6dc9357SAndroid Build Coastguard Worker         c = a ^ d; \
81*f6dc9357SAndroid Build Coastguard Worker         c = Z7_ROTL64(c, k); \
82*f6dc9357SAndroid Build Coastguard Worker 
83*f6dc9357SAndroid Build Coastguard Worker #define E4(e1,e2,e3,e4) \
84*f6dc9357SAndroid Build Coastguard Worker         e1 = c1 ^ (~c2 & c3); \
85*f6dc9357SAndroid Build Coastguard Worker         e2 = c2 ^ (~c3 & c4); \
86*f6dc9357SAndroid Build Coastguard Worker         e3 = c3 ^ (~c4 & c0); \
87*f6dc9357SAndroid Build Coastguard Worker         e4 = c4 ^ (~c0 & c1); \
88*f6dc9357SAndroid Build Coastguard Worker 
89*f6dc9357SAndroid Build Coastguard Worker #define CK(   v0,w0,    \
90*f6dc9357SAndroid Build Coastguard Worker               v1,w1,k1, \
91*f6dc9357SAndroid Build Coastguard Worker               v2,w2,k2, \
92*f6dc9357SAndroid Build Coastguard Worker               v3,w3,k3, \
93*f6dc9357SAndroid Build Coastguard Worker               v4,w4,k4, e0,e1,e2,e3,e4, keccak_c) \
94*f6dc9357SAndroid Build Coastguard Worker         C0(c0,v0,w0)    \
95*f6dc9357SAndroid Build Coastguard Worker         C (c1,v1,w1,k1) \
96*f6dc9357SAndroid Build Coastguard Worker         C (c2,v2,w2,k2) \
97*f6dc9357SAndroid Build Coastguard Worker         C (c3,v3,w3,k3) \
98*f6dc9357SAndroid Build Coastguard Worker         C (c4,v4,w4,k4) \
99*f6dc9357SAndroid Build Coastguard Worker         e0 = c0 ^ (~c1 & c2) ^ keccak_c; \
100*f6dc9357SAndroid Build Coastguard Worker         E4(e1,e2,e3,e4) \
101*f6dc9357SAndroid Build Coastguard Worker 
102*f6dc9357SAndroid Build Coastguard Worker #define CE(   v0,w0,k0, \
103*f6dc9357SAndroid Build Coastguard Worker               v1,w1,k1, \
104*f6dc9357SAndroid Build Coastguard Worker               v2,w2,k2, \
105*f6dc9357SAndroid Build Coastguard Worker               v3,w3,k3, \
106*f6dc9357SAndroid Build Coastguard Worker               v4,w4,k4, e0,e1,e2,e3,e4) \
107*f6dc9357SAndroid Build Coastguard Worker         C (c0,v0,w0,k0) \
108*f6dc9357SAndroid Build Coastguard Worker         C (c1,v1,w1,k1) \
109*f6dc9357SAndroid Build Coastguard Worker         C (c2,v2,w2,k2) \
110*f6dc9357SAndroid Build Coastguard Worker         C (c3,v3,w3,k3) \
111*f6dc9357SAndroid Build Coastguard Worker         C (c4,v4,w4,k4) \
112*f6dc9357SAndroid Build Coastguard Worker         e0 = c0 ^ (~c1 & c2); \
113*f6dc9357SAndroid Build Coastguard Worker         E4(e1,e2,e3,e4) \
114*f6dc9357SAndroid Build Coastguard Worker 
115*f6dc9357SAndroid Build Coastguard Worker // numBlocks != 0
116*f6dc9357SAndroid Build Coastguard Worker static
117*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE
Sha3_UpdateBlocks(UInt64 state[SHA3_NUM_STATE_WORDS],const Byte * data,size_t numBlocks,size_t blockSize)118*f6dc9357SAndroid Build Coastguard Worker void Z7_FASTCALL Sha3_UpdateBlocks(UInt64 state[SHA3_NUM_STATE_WORDS],
119*f6dc9357SAndroid Build Coastguard Worker     const Byte *data, size_t numBlocks, size_t blockSize)
120*f6dc9357SAndroid Build Coastguard Worker {
121*f6dc9357SAndroid Build Coastguard Worker   LS_25 (GET_state)
122*f6dc9357SAndroid Build Coastguard Worker 
123*f6dc9357SAndroid Build Coastguard Worker   do
124*f6dc9357SAndroid Build Coastguard Worker   {
125*f6dc9357SAndroid Build Coastguard Worker     unsigned round;
126*f6dc9357SAndroid Build Coastguard Worker                               XOR_4 ( 0, a50, a51, a52, a53)
127*f6dc9357SAndroid Build Coastguard Worker                               XOR_4 ( 4, a54, a60, a61, a62)
128*f6dc9357SAndroid Build Coastguard Worker                               XOR_1 ( 8, a63)
129*f6dc9357SAndroid Build Coastguard Worker     if (blockSize > 8 *  9) { XOR_4 ( 9, a64, a70, a71, a72)  // sha3-384
130*f6dc9357SAndroid Build Coastguard Worker     if (blockSize > 8 * 13) { XOR_4 (13, a73, a74, a80, a81)  // sha3-256
131*f6dc9357SAndroid Build Coastguard Worker     if (blockSize > 8 * 17) { XOR_1 (17, a82)                 // sha3-224
132*f6dc9357SAndroid Build Coastguard Worker     if (blockSize > 8 * 18) { XOR_1 (18, a83)                 // shake128
133*f6dc9357SAndroid Build Coastguard Worker                               XOR_1 (19, a84)
134*f6dc9357SAndroid Build Coastguard Worker                               XOR_1 (20, a90) }}}}
135*f6dc9357SAndroid Build Coastguard Worker     data += blockSize;
136*f6dc9357SAndroid Build Coastguard Worker 
137*f6dc9357SAndroid Build Coastguard Worker     for (round = 0; round < 24; round += 2)
138*f6dc9357SAndroid Build Coastguard Worker     {
139*f6dc9357SAndroid Build Coastguard Worker       UInt64 c0, c1, c2, c3, c4;
140*f6dc9357SAndroid Build Coastguard Worker       UInt64 d0, d1, d2, d3, d4;
141*f6dc9357SAndroid Build Coastguard Worker       UInt64 e50, e51, e52, e53, e54;
142*f6dc9357SAndroid Build Coastguard Worker       UInt64 e60, e61, e62, e63, e64;
143*f6dc9357SAndroid Build Coastguard Worker       UInt64 e70, e71, e72, e73, e74;
144*f6dc9357SAndroid Build Coastguard Worker       UInt64 e80, e81, e82, e83, e84;
145*f6dc9357SAndroid Build Coastguard Worker       UInt64 e90, e91, e92, e93, e94;
146*f6dc9357SAndroid Build Coastguard Worker 
147*f6dc9357SAndroid Build Coastguard Worker       c0 = a50^a60^a70^a80^a90;
148*f6dc9357SAndroid Build Coastguard Worker       c1 = a51^a61^a71^a81^a91;
149*f6dc9357SAndroid Build Coastguard Worker       c2 = a52^a62^a72^a82^a92;
150*f6dc9357SAndroid Build Coastguard Worker       c3 = a53^a63^a73^a83^a93;
151*f6dc9357SAndroid Build Coastguard Worker       c4 = a54^a64^a74^a84^a94;
152*f6dc9357SAndroid Build Coastguard Worker       D5
153*f6dc9357SAndroid Build Coastguard Worker       CK( a50, d0,
154*f6dc9357SAndroid Build Coastguard Worker           a61, d1, 44,
155*f6dc9357SAndroid Build Coastguard Worker           a72, d2, 43,
156*f6dc9357SAndroid Build Coastguard Worker           a83, d3, 21,
157*f6dc9357SAndroid Build Coastguard Worker           a94, d4, 14, e50, e51, e52, e53, e54, SHA3_K_ARRAY[round])
158*f6dc9357SAndroid Build Coastguard Worker       CE( a53, d3, 28,
159*f6dc9357SAndroid Build Coastguard Worker           a64, d4, 20,
160*f6dc9357SAndroid Build Coastguard Worker           a70, d0,  3,
161*f6dc9357SAndroid Build Coastguard Worker           a81, d1, 45,
162*f6dc9357SAndroid Build Coastguard Worker           a92, d2, 61, e60, e61, e62, e63, e64)
163*f6dc9357SAndroid Build Coastguard Worker       CE( a51, d1,  1,
164*f6dc9357SAndroid Build Coastguard Worker           a62, d2,  6,
165*f6dc9357SAndroid Build Coastguard Worker           a73, d3, 25,
166*f6dc9357SAndroid Build Coastguard Worker           a84, d4,  8,
167*f6dc9357SAndroid Build Coastguard Worker           a90, d0, 18, e70, e71, e72, e73, e74)
168*f6dc9357SAndroid Build Coastguard Worker       CE( a54, d4, 27,
169*f6dc9357SAndroid Build Coastguard Worker           a60, d0, 36,
170*f6dc9357SAndroid Build Coastguard Worker           a71, d1, 10,
171*f6dc9357SAndroid Build Coastguard Worker           a82, d2, 15,
172*f6dc9357SAndroid Build Coastguard Worker           a93, d3, 56, e80, e81, e82, e83, e84)
173*f6dc9357SAndroid Build Coastguard Worker       CE( a52, d2, 62,
174*f6dc9357SAndroid Build Coastguard Worker           a63, d3, 55,
175*f6dc9357SAndroid Build Coastguard Worker           a74, d4, 39,
176*f6dc9357SAndroid Build Coastguard Worker           a80, d0, 41,
177*f6dc9357SAndroid Build Coastguard Worker           a91, d1,  2, e90, e91, e92, e93, e94)
178*f6dc9357SAndroid Build Coastguard Worker 
179*f6dc9357SAndroid Build Coastguard Worker       // ---------- ROUND + 1 ----------
180*f6dc9357SAndroid Build Coastguard Worker 
181*f6dc9357SAndroid Build Coastguard Worker       c0 = e50^e60^e70^e80^e90;
182*f6dc9357SAndroid Build Coastguard Worker       c1 = e51^e61^e71^e81^e91;
183*f6dc9357SAndroid Build Coastguard Worker       c2 = e52^e62^e72^e82^e92;
184*f6dc9357SAndroid Build Coastguard Worker       c3 = e53^e63^e73^e83^e93;
185*f6dc9357SAndroid Build Coastguard Worker       c4 = e54^e64^e74^e84^e94;
186*f6dc9357SAndroid Build Coastguard Worker       D5
187*f6dc9357SAndroid Build Coastguard Worker       CK( e50, d0,
188*f6dc9357SAndroid Build Coastguard Worker           e61, d1, 44,
189*f6dc9357SAndroid Build Coastguard Worker           e72, d2, 43,
190*f6dc9357SAndroid Build Coastguard Worker           e83, d3, 21,
191*f6dc9357SAndroid Build Coastguard Worker           e94, d4, 14, a50, a51, a52, a53, a54, SHA3_K_ARRAY[(size_t)round + 1])
192*f6dc9357SAndroid Build Coastguard Worker       CE( e53, d3, 28,
193*f6dc9357SAndroid Build Coastguard Worker           e64, d4, 20,
194*f6dc9357SAndroid Build Coastguard Worker           e70, d0,  3,
195*f6dc9357SAndroid Build Coastguard Worker           e81, d1, 45,
196*f6dc9357SAndroid Build Coastguard Worker           e92, d2, 61, a60, a61, a62, a63, a64)
197*f6dc9357SAndroid Build Coastguard Worker       CE( e51, d1,  1,
198*f6dc9357SAndroid Build Coastguard Worker           e62, d2,  6,
199*f6dc9357SAndroid Build Coastguard Worker           e73, d3, 25,
200*f6dc9357SAndroid Build Coastguard Worker           e84, d4,  8,
201*f6dc9357SAndroid Build Coastguard Worker           e90, d0, 18, a70, a71, a72, a73, a74)
202*f6dc9357SAndroid Build Coastguard Worker       CE (e54, d4, 27,
203*f6dc9357SAndroid Build Coastguard Worker           e60, d0, 36,
204*f6dc9357SAndroid Build Coastguard Worker           e71, d1, 10,
205*f6dc9357SAndroid Build Coastguard Worker           e82, d2, 15,
206*f6dc9357SAndroid Build Coastguard Worker           e93, d3, 56, a80, a81, a82, a83, a84)
207*f6dc9357SAndroid Build Coastguard Worker       CE (e52, d2, 62,
208*f6dc9357SAndroid Build Coastguard Worker           e63, d3, 55,
209*f6dc9357SAndroid Build Coastguard Worker           e74, d4, 39,
210*f6dc9357SAndroid Build Coastguard Worker           e80, d0, 41,
211*f6dc9357SAndroid Build Coastguard Worker           e91, d1,  2, a90, a91, a92, a93, a94)
212*f6dc9357SAndroid Build Coastguard Worker     }
213*f6dc9357SAndroid Build Coastguard Worker   }
214*f6dc9357SAndroid Build Coastguard Worker   while (--numBlocks);
215*f6dc9357SAndroid Build Coastguard Worker 
216*f6dc9357SAndroid Build Coastguard Worker   LS_25 (SET_state)
217*f6dc9357SAndroid Build Coastguard Worker }
218*f6dc9357SAndroid Build Coastguard Worker 
219*f6dc9357SAndroid Build Coastguard Worker 
220*f6dc9357SAndroid Build Coastguard Worker #define Sha3_UpdateBlock(p) \
221*f6dc9357SAndroid Build Coastguard Worker         Sha3_UpdateBlocks(p->state, p->buffer, 1, p->blockSize)
222*f6dc9357SAndroid Build Coastguard Worker 
Sha3_Update(CSha3 * p,const Byte * data,size_t size)223*f6dc9357SAndroid Build Coastguard Worker void Sha3_Update(CSha3 *p, const Byte *data, size_t size)
224*f6dc9357SAndroid Build Coastguard Worker {
225*f6dc9357SAndroid Build Coastguard Worker /*
226*f6dc9357SAndroid Build Coastguard Worker   for (;;)
227*f6dc9357SAndroid Build Coastguard Worker   {
228*f6dc9357SAndroid Build Coastguard Worker     if (size == 0)
229*f6dc9357SAndroid Build Coastguard Worker       return;
230*f6dc9357SAndroid Build Coastguard Worker     unsigned cur = p->blockSize - p->count;
231*f6dc9357SAndroid Build Coastguard Worker     if (cur > size)
232*f6dc9357SAndroid Build Coastguard Worker       cur = (unsigned)size;
233*f6dc9357SAndroid Build Coastguard Worker     size -= cur;
234*f6dc9357SAndroid Build Coastguard Worker     unsigned pos = p->count;
235*f6dc9357SAndroid Build Coastguard Worker     p->count = pos + cur;
236*f6dc9357SAndroid Build Coastguard Worker     while (pos & 7)
237*f6dc9357SAndroid Build Coastguard Worker     {
238*f6dc9357SAndroid Build Coastguard Worker       if (cur == 0)
239*f6dc9357SAndroid Build Coastguard Worker         return;
240*f6dc9357SAndroid Build Coastguard Worker       Byte *pb = &(((Byte *)p->state)[pos]);
241*f6dc9357SAndroid Build Coastguard Worker       *pb = (Byte)(*pb ^ *data++);
242*f6dc9357SAndroid Build Coastguard Worker       cur--;
243*f6dc9357SAndroid Build Coastguard Worker       pos++;
244*f6dc9357SAndroid Build Coastguard Worker     }
245*f6dc9357SAndroid Build Coastguard Worker     if (cur >= 8)
246*f6dc9357SAndroid Build Coastguard Worker     {
247*f6dc9357SAndroid Build Coastguard Worker       do
248*f6dc9357SAndroid Build Coastguard Worker       {
249*f6dc9357SAndroid Build Coastguard Worker         *(UInt64 *)(void *)&(((Byte *)p->state)[pos]) ^= GetUi64(data);
250*f6dc9357SAndroid Build Coastguard Worker         data += 8;
251*f6dc9357SAndroid Build Coastguard Worker         pos += 8;
252*f6dc9357SAndroid Build Coastguard Worker         cur -= 8;
253*f6dc9357SAndroid Build Coastguard Worker       }
254*f6dc9357SAndroid Build Coastguard Worker       while (cur >= 8);
255*f6dc9357SAndroid Build Coastguard Worker     }
256*f6dc9357SAndroid Build Coastguard Worker     if (pos != p->blockSize)
257*f6dc9357SAndroid Build Coastguard Worker     {
258*f6dc9357SAndroid Build Coastguard Worker       if (cur)
259*f6dc9357SAndroid Build Coastguard Worker       {
260*f6dc9357SAndroid Build Coastguard Worker         Byte *pb = &(((Byte *)p->state)[pos]);
261*f6dc9357SAndroid Build Coastguard Worker         do
262*f6dc9357SAndroid Build Coastguard Worker         {
263*f6dc9357SAndroid Build Coastguard Worker           *pb = (Byte)(*pb ^ *data++);
264*f6dc9357SAndroid Build Coastguard Worker           pb++;
265*f6dc9357SAndroid Build Coastguard Worker         }
266*f6dc9357SAndroid Build Coastguard Worker         while (--cur);
267*f6dc9357SAndroid Build Coastguard Worker       }
268*f6dc9357SAndroid Build Coastguard Worker       return;
269*f6dc9357SAndroid Build Coastguard Worker     }
270*f6dc9357SAndroid Build Coastguard Worker     Sha3_UpdateBlock(p->state);
271*f6dc9357SAndroid Build Coastguard Worker     p->count = 0;
272*f6dc9357SAndroid Build Coastguard Worker   }
273*f6dc9357SAndroid Build Coastguard Worker */
274*f6dc9357SAndroid Build Coastguard Worker   if (size == 0)
275*f6dc9357SAndroid Build Coastguard Worker     return;
276*f6dc9357SAndroid Build Coastguard Worker   {
277*f6dc9357SAndroid Build Coastguard Worker     const unsigned pos = p->count;
278*f6dc9357SAndroid Build Coastguard Worker     const unsigned num = p->blockSize - pos;
279*f6dc9357SAndroid Build Coastguard Worker     if (num > size)
280*f6dc9357SAndroid Build Coastguard Worker     {
281*f6dc9357SAndroid Build Coastguard Worker       p->count = pos + (unsigned)size;
282*f6dc9357SAndroid Build Coastguard Worker       memcpy(p->buffer + pos, data, size);
283*f6dc9357SAndroid Build Coastguard Worker       return;
284*f6dc9357SAndroid Build Coastguard Worker     }
285*f6dc9357SAndroid Build Coastguard Worker     if (pos != 0)
286*f6dc9357SAndroid Build Coastguard Worker     {
287*f6dc9357SAndroid Build Coastguard Worker       size -= num;
288*f6dc9357SAndroid Build Coastguard Worker       memcpy(p->buffer + pos, data, num);
289*f6dc9357SAndroid Build Coastguard Worker       data += num;
290*f6dc9357SAndroid Build Coastguard Worker       Sha3_UpdateBlock(p);
291*f6dc9357SAndroid Build Coastguard Worker     }
292*f6dc9357SAndroid Build Coastguard Worker   }
293*f6dc9357SAndroid Build Coastguard Worker   if (size >= p->blockSize)
294*f6dc9357SAndroid Build Coastguard Worker   {
295*f6dc9357SAndroid Build Coastguard Worker     const size_t numBlocks = size / p->blockSize;
296*f6dc9357SAndroid Build Coastguard Worker     const Byte *dataOld = data;
297*f6dc9357SAndroid Build Coastguard Worker     data += numBlocks * p->blockSize;
298*f6dc9357SAndroid Build Coastguard Worker     size = (size_t)(dataOld + size - data);
299*f6dc9357SAndroid Build Coastguard Worker     Sha3_UpdateBlocks(p->state, dataOld, numBlocks, p->blockSize);
300*f6dc9357SAndroid Build Coastguard Worker   }
301*f6dc9357SAndroid Build Coastguard Worker   p->count = (unsigned)size;
302*f6dc9357SAndroid Build Coastguard Worker   if (size)
303*f6dc9357SAndroid Build Coastguard Worker     memcpy(p->buffer, data, size);
304*f6dc9357SAndroid Build Coastguard Worker }
305*f6dc9357SAndroid Build Coastguard Worker 
306*f6dc9357SAndroid Build Coastguard Worker 
307*f6dc9357SAndroid Build Coastguard Worker // we support only (digestSize % 4 == 0) cases
Sha3_Final(CSha3 * p,Byte * digest,unsigned digestSize,unsigned shake)308*f6dc9357SAndroid Build Coastguard Worker void Sha3_Final(CSha3 *p, Byte *digest, unsigned digestSize, unsigned shake)
309*f6dc9357SAndroid Build Coastguard Worker {
310*f6dc9357SAndroid Build Coastguard Worker   memset(p->buffer + p->count, 0, p->blockSize - p->count);
311*f6dc9357SAndroid Build Coastguard Worker   // we write bits markers from low to higher in current byte:
312*f6dc9357SAndroid Build Coastguard Worker   //   - if sha-3 : 2 bits : 0,1
313*f6dc9357SAndroid Build Coastguard Worker   //   - if shake : 4 bits : 1111
314*f6dc9357SAndroid Build Coastguard Worker   // then we write bit 1 to same byte.
315*f6dc9357SAndroid Build Coastguard Worker   // And we write bit 1 to highest bit of last byte of block.
316*f6dc9357SAndroid Build Coastguard Worker   p->buffer[p->count] = (Byte)(shake ? 0x1f : 0x06);
317*f6dc9357SAndroid Build Coastguard Worker   // we need xor operation (^= 0x80) here because we must write 0x80 bit
318*f6dc9357SAndroid Build Coastguard Worker   // to same byte as (0x1f : 0x06), if (p->count == p->blockSize - 1) !!!
319*f6dc9357SAndroid Build Coastguard Worker   p->buffer[p->blockSize - 1] ^= 0x80;
320*f6dc9357SAndroid Build Coastguard Worker /*
321*f6dc9357SAndroid Build Coastguard Worker   ((Byte *)p->state)[p->count] ^= (Byte)(shake ? 0x1f : 0x06);
322*f6dc9357SAndroid Build Coastguard Worker   ((Byte *)p->state)[p->blockSize - 1] ^= 0x80;
323*f6dc9357SAndroid Build Coastguard Worker */
324*f6dc9357SAndroid Build Coastguard Worker   Sha3_UpdateBlock(p);
325*f6dc9357SAndroid Build Coastguard Worker #if 1 && defined(MY_CPU_LE)
326*f6dc9357SAndroid Build Coastguard Worker   memcpy(digest, p->state, digestSize);
327*f6dc9357SAndroid Build Coastguard Worker #else
328*f6dc9357SAndroid Build Coastguard Worker   {
329*f6dc9357SAndroid Build Coastguard Worker     const unsigned numWords = digestSize >> 3;
330*f6dc9357SAndroid Build Coastguard Worker     unsigned i;
331*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numWords; i++)
332*f6dc9357SAndroid Build Coastguard Worker     {
333*f6dc9357SAndroid Build Coastguard Worker       const UInt64 v = p->state[i];
334*f6dc9357SAndroid Build Coastguard Worker       SetUi64(digest, v)
335*f6dc9357SAndroid Build Coastguard Worker       digest += 8;
336*f6dc9357SAndroid Build Coastguard Worker     }
337*f6dc9357SAndroid Build Coastguard Worker     if (digestSize & 4) // for SHA3-224
338*f6dc9357SAndroid Build Coastguard Worker     {
339*f6dc9357SAndroid Build Coastguard Worker       const UInt32 v = (UInt32)p->state[numWords];
340*f6dc9357SAndroid Build Coastguard Worker       SetUi32(digest, v)
341*f6dc9357SAndroid Build Coastguard Worker     }
342*f6dc9357SAndroid Build Coastguard Worker   }
343*f6dc9357SAndroid Build Coastguard Worker #endif
344*f6dc9357SAndroid Build Coastguard Worker   Sha3_Init(p);
345*f6dc9357SAndroid Build Coastguard Worker }
346*f6dc9357SAndroid Build Coastguard Worker 
347*f6dc9357SAndroid Build Coastguard Worker #undef GET_state
348*f6dc9357SAndroid Build Coastguard Worker #undef SET_state
349*f6dc9357SAndroid Build Coastguard Worker #undef LS_5
350*f6dc9357SAndroid Build Coastguard Worker #undef LS_25
351*f6dc9357SAndroid Build Coastguard Worker #undef XOR_1
352*f6dc9357SAndroid Build Coastguard Worker #undef XOR_4
353*f6dc9357SAndroid Build Coastguard Worker #undef D
354*f6dc9357SAndroid Build Coastguard Worker #undef D5
355*f6dc9357SAndroid Build Coastguard Worker #undef C0
356*f6dc9357SAndroid Build Coastguard Worker #undef C
357*f6dc9357SAndroid Build Coastguard Worker #undef E4
358*f6dc9357SAndroid Build Coastguard Worker #undef CK
359*f6dc9357SAndroid Build Coastguard Worker #undef CE
360