1 // Based on public domain code written in 2012 by Samuel Neves
2 #ifndef _RAR_BLAKE2_
3 #define _RAR_BLAKE2_
4 
5 #define BLAKE2_DIGEST_SIZE 32
6 #define BLAKE2_THREADS_NUMBER 8
7 
8 enum blake2s_constant
9 {
10   BLAKE2S_BLOCKBYTES = 64,
11   BLAKE2S_OUTBYTES   = 32
12 };
13 
14 
15 // Alignment to 64 improves performance of both SSE and non-SSE versions.
16 // Alignment to n*16 is required for SSE version, so we selected 64.
17 // We use the custom alignment scheme instead of __declspec(align(x)),
18 // because it is less compiler dependent. Also the compiler directive
19 // does not help if structure is a member of class allocated through
20 // 'new' operator.
21 struct blake2s_state
22 {
23   enum { BLAKE_ALIGNMENT = 64 };
24 
25   // buffer and uint32 h[8], t[2], f[2];
26   enum { BLAKE_DATA_SIZE = 48 + 2 * BLAKE2S_BLOCKBYTES };
27 
28   byte ubuf[BLAKE_DATA_SIZE + BLAKE_ALIGNMENT];
29 
30   byte   *buf;       // byte   buf[2 * BLAKE2S_BLOCKBYTES].
31   uint32 *h, *t, *f; // uint32 h[8], t[2], f[2].
32 
33   size_t   buflen;
34   byte  last_node;
35 
blake2s_stateblake2s_state36   blake2s_state()
37   {
38     set_pointers();
39   }
40 
41   // Required when we declare and assign in the same command.
blake2s_stateblake2s_state42   blake2s_state(blake2s_state &st)
43   {
44     set_pointers();
45     *this=st;
46   }
47 
set_pointersblake2s_state48   void set_pointers()
49   {
50     // Set aligned pointers. Must be done in constructor, not in Init(),
51     // so assignments like 'blake2sp_state res=blake2ctx' work correctly
52     // even if blake2sp_init is not called for 'res'.
53     buf = (byte *) ALIGN_VALUE(ubuf, BLAKE_ALIGNMENT);
54     h   = (uint32 *) (buf + 2 * BLAKE2S_BLOCKBYTES);
55     t   = h + 8;
56     f   = t + 2;
57   }
58 
initblake2s_state59   void init()
60   {
61     memset( ubuf, 0, sizeof( ubuf ) );
62     buflen = 0;
63     last_node = 0;
64   }
65 
66   // Since we use pointers, the default = would work incorrectly.
operator =blake2s_state67   blake2s_state& operator = (blake2s_state &st)
68   {
69     if (this != &st)
70     {
71       memcpy(buf, st.buf, BLAKE_DATA_SIZE);
72       buflen = st.buflen;
73       last_node = st.last_node;
74     }
75     return *this;
76   }
77 };
78 
79 
80 #ifdef RAR_SMP
81 class ThreadPool;
82 #endif
83 
84 struct blake2sp_state
85 {
86   blake2s_state S[8];
87   blake2s_state R;
88   byte buf[8 * BLAKE2S_BLOCKBYTES];
89   size_t buflen;
90 
91 #ifdef RAR_SMP
92   ThreadPool *ThPool;
93   uint MaxThreads;
94 #endif
95 };
96 
97 void blake2sp_init( blake2sp_state *S );
98 void blake2sp_update( blake2sp_state *S, const byte *in, size_t inlen );
99 void blake2sp_final( blake2sp_state *S, byte *digest );
100 
101 #endif
102 
103