aboutsummaryrefslogtreecommitdiff
path: root/C/Blake2s.c
diff options
context:
space:
mode:
authorIgor Pavlov <87184205+ip7z@users.noreply.github.com>2021-12-27 00:00:00 +0000
committerIgor Pavlov <87184205+ip7z@users.noreply.github.com>2022-03-18 15:35:13 +0500
commitf19f813537c7aea1c20749c914e756b54a9c3cf5 (patch)
tree816ba62ca7c0fa19f2eb46d9e9d6f7dd7c3a744d /C/Blake2s.c
parent98e06a519b63b81986abe76d28887f6984a7732b (diff)
download7zip-21.07.tar.gz
7zip-21.07.tar.bz2
7zip-21.07.zip
'21.07'21.07
Diffstat (limited to 'C/Blake2s.c')
-rw-r--r--C/Blake2s.c244
1 files changed, 244 insertions, 0 deletions
diff --git a/C/Blake2s.c b/C/Blake2s.c
new file mode 100644
index 0000000..3c56a8b
--- /dev/null
+++ b/C/Blake2s.c
@@ -0,0 +1,244 @@
1/* Blake2s.c -- BLAKE2s and BLAKE2sp Hash
22021-02-09 : Igor Pavlov : Public domain
32015 : Samuel Neves : Public domain */
4
5#include <string.h>
6
7#include "Blake2.h"
8#include "CpuArch.h"
9#include "RotateDefs.h"
10
11#define rotr32 rotrFixed
12
13#define BLAKE2S_NUM_ROUNDS 10
14#define BLAKE2S_FINAL_FLAG (~(UInt32)0)
15
16static const UInt32 k_Blake2s_IV[8] =
17{
18 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
19 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
20};
21
22static const Byte k_Blake2s_Sigma[BLAKE2S_NUM_ROUNDS][16] =
23{
24 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
25 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
26 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
27 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
28 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
29 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
30 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
31 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
32 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
33 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
34};
35
36
37static void Blake2s_Init0(CBlake2s *p)
38{
39 unsigned i;
40 for (i = 0; i < 8; i++)
41 p->h[i] = k_Blake2s_IV[i];
42 p->t[0] = 0;
43 p->t[1] = 0;
44 p->f[0] = 0;
45 p->f[1] = 0;
46 p->bufPos = 0;
47 p->lastNode_f1 = 0;
48}
49
50
51static void Blake2s_Compress(CBlake2s *p)
52{
53 UInt32 m[16];
54 UInt32 v[16];
55
56 {
57 unsigned i;
58
59 for (i = 0; i < 16; i++)
60 m[i] = GetUi32(p->buf + i * sizeof(m[i]));
61
62 for (i = 0; i < 8; i++)
63 v[i] = p->h[i];
64 }
65
66 v[ 8] = k_Blake2s_IV[0];
67 v[ 9] = k_Blake2s_IV[1];
68 v[10] = k_Blake2s_IV[2];
69 v[11] = k_Blake2s_IV[3];
70
71 v[12] = p->t[0] ^ k_Blake2s_IV[4];
72 v[13] = p->t[1] ^ k_Blake2s_IV[5];
73 v[14] = p->f[0] ^ k_Blake2s_IV[6];
74 v[15] = p->f[1] ^ k_Blake2s_IV[7];
75
76 #define G(r,i,a,b,c,d) \
77 a += b + m[sigma[2*i+0]]; d ^= a; d = rotr32(d, 16); c += d; b ^= c; b = rotr32(b, 12); \
78 a += b + m[sigma[2*i+1]]; d ^= a; d = rotr32(d, 8); c += d; b ^= c; b = rotr32(b, 7); \
79
80 #define R(r) \
81 G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
82 G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
83 G(r,2,v[ 2],v[ 6],v[10],v[14]); \
84 G(r,3,v[ 3],v[ 7],v[11],v[15]); \
85 G(r,4,v[ 0],v[ 5],v[10],v[15]); \
86 G(r,5,v[ 1],v[ 6],v[11],v[12]); \
87 G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
88 G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
89
90 {
91 unsigned r;
92 for (r = 0; r < BLAKE2S_NUM_ROUNDS; r++)
93 {
94 const Byte *sigma = k_Blake2s_Sigma[r];
95 R(r);
96 }
97 /* R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); R(8); R(9); */
98 }
99
100 #undef G
101 #undef R
102
103 {
104 unsigned i;
105 for (i = 0; i < 8; i++)
106 p->h[i] ^= v[i] ^ v[i + 8];
107 }
108}
109
110
111#define Blake2s_Increment_Counter(S, inc) \
112 { p->t[0] += (inc); p->t[1] += (p->t[0] < (inc)); }
113
114#define Blake2s_Set_LastBlock(p) \
115 { p->f[0] = BLAKE2S_FINAL_FLAG; p->f[1] = p->lastNode_f1; }
116
117
118static void Blake2s_Update(CBlake2s *p, const Byte *data, size_t size)
119{
120 while (size != 0)
121 {
122 unsigned pos = (unsigned)p->bufPos;
123 unsigned rem = BLAKE2S_BLOCK_SIZE - pos;
124
125 if (size <= rem)
126 {
127 memcpy(p->buf + pos, data, size);
128 p->bufPos += (UInt32)size;
129 return;
130 }
131
132 memcpy(p->buf + pos, data, rem);
133 Blake2s_Increment_Counter(S, BLAKE2S_BLOCK_SIZE);
134 Blake2s_Compress(p);
135 p->bufPos = 0;
136 data += rem;
137 size -= rem;
138 }
139}
140
141
142static void Blake2s_Final(CBlake2s *p, Byte *digest)
143{
144 unsigned i;
145
146 Blake2s_Increment_Counter(S, (UInt32)p->bufPos);
147 Blake2s_Set_LastBlock(p);
148 memset(p->buf + p->bufPos, 0, BLAKE2S_BLOCK_SIZE - p->bufPos);
149 Blake2s_Compress(p);
150
151 for (i = 0; i < 8; i++)
152 SetUi32(digest + sizeof(p->h[i]) * i, p->h[i]);
153}
154
155
156/* ---------- BLAKE2s ---------- */
157
158/* we need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() */
159/*
160typedef struct
161{
162 Byte digest_length;
163 Byte key_length;
164 Byte fanout;
165 Byte depth;
166 UInt32 leaf_length;
167 Byte node_offset[6];
168 Byte node_depth;
169 Byte inner_length;
170 Byte salt[BLAKE2S_SALTBYTES];
171 Byte personal[BLAKE2S_PERSONALBYTES];
172} CBlake2sParam;
173*/
174
175
176static void Blake2sp_Init_Spec(CBlake2s *p, unsigned node_offset, unsigned node_depth)
177{
178 Blake2s_Init0(p);
179
180 p->h[0] ^= (BLAKE2S_DIGEST_SIZE | ((UInt32)BLAKE2SP_PARALLEL_DEGREE << 16) | ((UInt32)2 << 24));
181 p->h[2] ^= ((UInt32)node_offset);
182 p->h[3] ^= ((UInt32)node_depth << 16) | ((UInt32)BLAKE2S_DIGEST_SIZE << 24);
183 /*
184 P->digest_length = BLAKE2S_DIGEST_SIZE;
185 P->key_length = 0;
186 P->fanout = BLAKE2SP_PARALLEL_DEGREE;
187 P->depth = 2;
188 P->leaf_length = 0;
189 store48(P->node_offset, node_offset);
190 P->node_depth = node_depth;
191 P->inner_length = BLAKE2S_DIGEST_SIZE;
192 */
193}
194
195
196void Blake2sp_Init(CBlake2sp *p)
197{
198 unsigned i;
199
200 p->bufPos = 0;
201
202 for (i = 0; i < BLAKE2SP_PARALLEL_DEGREE; i++)
203 Blake2sp_Init_Spec(&p->S[i], i, 0);
204
205 p->S[BLAKE2SP_PARALLEL_DEGREE - 1].lastNode_f1 = BLAKE2S_FINAL_FLAG;
206}
207
208
209void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size)
210{
211 unsigned pos = p->bufPos;
212 while (size != 0)
213 {
214 unsigned index = pos / BLAKE2S_BLOCK_SIZE;
215 unsigned rem = BLAKE2S_BLOCK_SIZE - (pos & (BLAKE2S_BLOCK_SIZE - 1));
216 if (rem > size)
217 rem = (unsigned)size;
218 Blake2s_Update(&p->S[index], data, rem);
219 size -= rem;
220 data += rem;
221 pos += rem;
222 pos &= (BLAKE2S_BLOCK_SIZE * BLAKE2SP_PARALLEL_DEGREE - 1);
223 }
224 p->bufPos = pos;
225}
226
227
228void Blake2sp_Final(CBlake2sp *p, Byte *digest)
229{
230 CBlake2s R;
231 unsigned i;
232
233 Blake2sp_Init_Spec(&R, 0, 1);
234 R.lastNode_f1 = BLAKE2S_FINAL_FLAG;
235
236 for (i = 0; i < BLAKE2SP_PARALLEL_DEGREE; i++)
237 {
238 Byte hash[BLAKE2S_DIGEST_SIZE];
239 Blake2s_Final(&p->S[i], hash);
240 Blake2s_Update(&R, hash, BLAKE2S_DIGEST_SIZE);
241 }
242
243 Blake2s_Final(&R, digest);
244}