diff options
author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2021-12-27 00:00:00 +0000 |
---|---|---|
committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2022-03-18 15:35:13 +0500 |
commit | f19f813537c7aea1c20749c914e756b54a9c3cf5 (patch) | |
tree | 816ba62ca7c0fa19f2eb46d9e9d6f7dd7c3a744d /C/Blake2s.c | |
parent | 98e06a519b63b81986abe76d28887f6984a7732b (diff) | |
download | 7zip-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.c | 244 |
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 | ||
2 | 2021-02-09 : Igor Pavlov : Public domain | ||
3 | 2015 : 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 | |||
16 | static const UInt32 k_Blake2s_IV[8] = | ||
17 | { | ||
18 | 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, | ||
19 | 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL | ||
20 | }; | ||
21 | |||
22 | static 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 | |||
37 | static 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 | |||
51 | static 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 | |||
118 | static 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 | |||
142 | static 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 | /* | ||
160 | typedef 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 | |||
176 | static 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 | |||
196 | void 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 | |||
209 | void 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 | |||
228 | void 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 | } | ||