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 
Blake2s_Init0(CBlake2s * p)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 
Blake2s_Compress(CBlake2s * p)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 
Blake2s_Update(CBlake2s * p,const Byte * data,size_t size)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 
Blake2s_Final(CBlake2s * p,Byte * digest)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 
Blake2sp_Init_Spec(CBlake2s * p,unsigned node_offset,unsigned node_depth)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 
Blake2sp_Init(CBlake2sp * p)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 
Blake2sp_Update(CBlake2sp * p,const Byte * data,size_t size)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 
Blake2sp_Final(CBlake2sp * p,Byte * digest)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 }
245