libclamunrar/blake2s.hpp
01eebc13
 // Based on public domain code written in 2012 by Samuel Neves
 #ifndef _RAR_BLAKE2_
 #define _RAR_BLAKE2_
 
 #define BLAKE2_DIGEST_SIZE 32
 
 enum blake2s_constant
 {
   BLAKE2S_BLOCKBYTES = 64,
   BLAKE2S_OUTBYTES   = 32
 };
 
 
 // Alignment to 64 improves performance of both SSE and non-SSE versions.
 // Alignment to n*16 is required for SSE version, so we selected 64.
 // We use the custom alignment scheme instead of __declspec(align(x)),
 // because it is less compiler dependent. Also the compiler directive
 // does not help if structure is a member of class allocated through
 // 'new' operator.
 struct blake2s_state
 {
   enum { BLAKE_ALIGNMENT = 64 };
 
   // buffer and uint32 h[8], t[2], f[2];
   enum { BLAKE_DATA_SIZE = 48 + 2 * BLAKE2S_BLOCKBYTES };
 
   byte ubuf[BLAKE_DATA_SIZE + BLAKE_ALIGNMENT];
 
   byte   *buf;       // byte   buf[2 * BLAKE2S_BLOCKBYTES].
   uint32 *h, *t, *f; // uint32 h[8], t[2], f[2].
 
   size_t   buflen;
   byte  last_node;
 
   blake2s_state()
   {
     set_pointers();
   }
 
   // Required when we declare and assign in the same command.
   blake2s_state(blake2s_state &st)
   {
     set_pointers();
     *this=st;
   }
 
   void set_pointers()
   {
     // Set aligned pointers. Must be done in constructor, not in Init(),
     // so assignments like 'blake2sp_state res=blake2ctx' work correctly
     // even if blake2sp_init is not called for 'res'.
     buf = (byte *) ALIGN_VALUE(ubuf, BLAKE_ALIGNMENT);
     h   = (uint32 *) (buf + 2 * BLAKE2S_BLOCKBYTES);
     t   = h + 8;
     f   = t + 2;
   }
 
   void init()
   {
     memset( ubuf, 0, sizeof( ubuf ) );
     buflen = 0;
     last_node = 0;
   }
 
   // Since we use pointers, the default = would work incorrectly.
   blake2s_state& operator = (blake2s_state &st)
   {
     if (this != &st)
     {
       memcpy(buf, st.buf, BLAKE_DATA_SIZE);
       buflen = st.buflen;
       last_node = st.last_node;
     }
     return *this;
   }
 };
 
 
 #ifdef RAR_SMP
 class ThreadPool;
 #endif
 
 struct blake2sp_state
 {
   blake2s_state S[8];
   blake2s_state R;
   byte buf[8 * BLAKE2S_BLOCKBYTES];
   size_t buflen;
 
 #ifdef RAR_SMP
   ThreadPool *ThPool;
   uint MaxThreads;
 #endif
 };
 
 void blake2sp_init( blake2sp_state *S );
 void blake2sp_update( blake2sp_state *S, const byte *in, size_t inlen );
 void blake2sp_final( blake2sp_state *S, byte *digest );
 
 #endif