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