Example #1
0
/*
* Tiger Compression Function
*/
void Tiger::compress_n(const byte input[], size_t blocks)
   {
   u64bit A = digest[0], B = digest[1], C = digest[2];

   for(size_t i = 0; i != blocks; ++i)
      {
      load_le(&X[0], input, X.size());

      pass(A, B, C, X, 5); mix(X);
      pass(C, A, B, X, 7); mix(X);
      pass(B, C, A, X, 9);

      for(size_t j = 3; j != passes; ++j)
         {
         mix(X);
         pass(A, B, C, X, 9);
         u64bit T = A; A = C; C = B; B = T;
         }

      A = (digest[0] ^= A);
      B = digest[1] = B - digest[1];
      C = (digest[2] += C);

      input += hash_block_size();
      }
   }
Example #2
0
void Threefish_512::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
   {
   BOTAN_ASSERT(m_K.size() == 9, "Key was set");
   BOTAN_ASSERT(m_T.size() == 3, "Tweak was set");

#if defined(BOTAN_HAS_THREEFISH_512_AVX2)
   if(CPUID::has_avx2())
      {
      return avx2_encrypt_n(in, out, blocks);
      }
#endif

   BOTAN_PARALLEL_FOR(size_t i = 0; i < blocks; ++i)
      {
      uint64_t X0, X1, X2, X3, X4, X5, X6, X7;
      load_le(in + BLOCK_SIZE*i, X0, X1, X2, X3, X4, X5, X6, X7);

      THREEFISH_INJECT_KEY(0);

      THREEFISH_ENC_8_ROUNDS(1,2);
      THREEFISH_ENC_8_ROUNDS(3,4);
      THREEFISH_ENC_8_ROUNDS(5,6);
      THREEFISH_ENC_8_ROUNDS(7,8);
      THREEFISH_ENC_8_ROUNDS(9,10);
      THREEFISH_ENC_8_ROUNDS(11,12);
      THREEFISH_ENC_8_ROUNDS(13,14);
      THREEFISH_ENC_8_ROUNDS(15,16);
      THREEFISH_ENC_8_ROUNDS(17,18);

      store_le(out + BLOCK_SIZE*i, X0, X1, X2, X3, X4, X5, X6, X7);
      }
   }
Example #3
0
/*
* MD5 Compression Function
*/
void MD5::compress_n(const byte input[], size_t blocks)
   {
   u32bit A = digest[0], B = digest[1], C = digest[2], D = digest[3];

   for(size_t i = 0; i != blocks; ++i)
      {
      load_le(&M[0], input, M.size());

      FF(A,B,C,D,M[ 0], 7,0xD76AA478);   FF(D,A,B,C,M[ 1],12,0xE8C7B756);
      FF(C,D,A,B,M[ 2],17,0x242070DB);   FF(B,C,D,A,M[ 3],22,0xC1BDCEEE);
      FF(A,B,C,D,M[ 4], 7,0xF57C0FAF);   FF(D,A,B,C,M[ 5],12,0x4787C62A);
      FF(C,D,A,B,M[ 6],17,0xA8304613);   FF(B,C,D,A,M[ 7],22,0xFD469501);
      FF(A,B,C,D,M[ 8], 7,0x698098D8);   FF(D,A,B,C,M[ 9],12,0x8B44F7AF);
      FF(C,D,A,B,M[10],17,0xFFFF5BB1);   FF(B,C,D,A,M[11],22,0x895CD7BE);
      FF(A,B,C,D,M[12], 7,0x6B901122);   FF(D,A,B,C,M[13],12,0xFD987193);
      FF(C,D,A,B,M[14],17,0xA679438E);   FF(B,C,D,A,M[15],22,0x49B40821);

      GG(A,B,C,D,M[ 1], 5,0xF61E2562);   GG(D,A,B,C,M[ 6], 9,0xC040B340);
      GG(C,D,A,B,M[11],14,0x265E5A51);   GG(B,C,D,A,M[ 0],20,0xE9B6C7AA);
      GG(A,B,C,D,M[ 5], 5,0xD62F105D);   GG(D,A,B,C,M[10], 9,0x02441453);
      GG(C,D,A,B,M[15],14,0xD8A1E681);   GG(B,C,D,A,M[ 4],20,0xE7D3FBC8);
      GG(A,B,C,D,M[ 9], 5,0x21E1CDE6);   GG(D,A,B,C,M[14], 9,0xC33707D6);
      GG(C,D,A,B,M[ 3],14,0xF4D50D87);   GG(B,C,D,A,M[ 8],20,0x455A14ED);
      GG(A,B,C,D,M[13], 5,0xA9E3E905);   GG(D,A,B,C,M[ 2], 9,0xFCEFA3F8);
      GG(C,D,A,B,M[ 7],14,0x676F02D9);   GG(B,C,D,A,M[12],20,0x8D2A4C8A);

      HH(A,B,C,D,M[ 5], 4,0xFFFA3942);   HH(D,A,B,C,M[ 8],11,0x8771F681);
      HH(C,D,A,B,M[11],16,0x6D9D6122);   HH(B,C,D,A,M[14],23,0xFDE5380C);
      HH(A,B,C,D,M[ 1], 4,0xA4BEEA44);   HH(D,A,B,C,M[ 4],11,0x4BDECFA9);
      HH(C,D,A,B,M[ 7],16,0xF6BB4B60);   HH(B,C,D,A,M[10],23,0xBEBFBC70);
      HH(A,B,C,D,M[13], 4,0x289B7EC6);   HH(D,A,B,C,M[ 0],11,0xEAA127FA);
      HH(C,D,A,B,M[ 3],16,0xD4EF3085);   HH(B,C,D,A,M[ 6],23,0x04881D05);
      HH(A,B,C,D,M[ 9], 4,0xD9D4D039);   HH(D,A,B,C,M[12],11,0xE6DB99E5);
      HH(C,D,A,B,M[15],16,0x1FA27CF8);   HH(B,C,D,A,M[ 2],23,0xC4AC5665);

      II(A,B,C,D,M[ 0], 6,0xF4292244);   II(D,A,B,C,M[ 7],10,0x432AFF97);
      II(C,D,A,B,M[14],15,0xAB9423A7);   II(B,C,D,A,M[ 5],21,0xFC93A039);
      II(A,B,C,D,M[12], 6,0x655B59C3);   II(D,A,B,C,M[ 3],10,0x8F0CCC92);
      II(C,D,A,B,M[10],15,0xFFEFF47D);   II(B,C,D,A,M[ 1],21,0x85845DD1);
      II(A,B,C,D,M[ 8], 6,0x6FA87E4F);   II(D,A,B,C,M[15],10,0xFE2CE6E0);
      II(C,D,A,B,M[ 6],15,0xA3014314);   II(B,C,D,A,M[13],21,0x4E0811A1);
      II(A,B,C,D,M[ 4], 6,0xF7537E82);   II(D,A,B,C,M[11],10,0xBD3AF235);
      II(C,D,A,B,M[ 2],15,0x2AD7D2BB);   II(B,C,D,A,M[ 9],21,0xEB86D391);

      A = (digest[0] += A);
      B = (digest[1] += B);
      C = (digest[2] += C);
      D = (digest[3] += D);

      input += hash_block_size();
      }
   }
Example #4
0
/*
* AES-192 Key Schedule
*/
void AES_192_NI::key_schedule(const byte key[], size_t)
   {
   __m128i K0 = _mm_loadu_si128((const __m128i*)(key));
   __m128i K1 = _mm_loadu_si128((const __m128i*)(key + 8));
   K1 = _mm_srli_si128(K1, 8);

   load_le(&EK[0], key, 6);

#define AES_192_key_exp(RCON, EK_OFF)                         \
   aes_192_key_expansion(&K0, &K1,                            \
                         _mm_aeskeygenassist_si128(K1, RCON), \
                         EK + EK_OFF, EK_OFF == 48)

   AES_192_key_exp(0x01, 6);
   AES_192_key_exp(0x02, 12);
   AES_192_key_exp(0x04, 18);
   AES_192_key_exp(0x08, 24);
   AES_192_key_exp(0x10, 30);
   AES_192_key_exp(0x20, 36);
   AES_192_key_exp(0x40, 42);
   AES_192_key_exp(0x80, 48);

   // Now generate decryption keys
   const __m128i* EK_mm = (const __m128i*)&EK[0];
   __m128i* DK_mm = (__m128i*)&DK[0];
   _mm_storeu_si128(DK_mm     , _mm_loadu_si128(EK_mm + 12));
   _mm_storeu_si128(DK_mm +  1, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 11)));
   _mm_storeu_si128(DK_mm +  2, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 10)));
   _mm_storeu_si128(DK_mm +  3, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 9)));
   _mm_storeu_si128(DK_mm +  4, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 8)));
   _mm_storeu_si128(DK_mm +  5, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 7)));
   _mm_storeu_si128(DK_mm +  6, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 6)));
   _mm_storeu_si128(DK_mm +  7, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 5)));
   _mm_storeu_si128(DK_mm +  8, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 4)));
   _mm_storeu_si128(DK_mm +  9, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 3)));
   _mm_storeu_si128(DK_mm + 10, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 2)));
   _mm_storeu_si128(DK_mm + 11, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 1)));
   _mm_storeu_si128(DK_mm + 12, _mm_loadu_si128(EK_mm + 0));
   }
Example #5
0
/*
* RIPEMD-160 Compression Function
*/
void RIPEMD_160::compress_n(const uint8_t input[], size_t blocks)
   {
   const uint32_t MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1,
                MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0xA953FD4E,
                MAGIC6 = 0x50A28BE6, MAGIC7 = 0x5C4DD124,
                MAGIC8 = 0x6D703EF3, MAGIC9 = 0x7A6D76E9;

   for(size_t i = 0; i != blocks; ++i)
      {
      load_le(m_M.data(), input, m_M.size());

      uint32_t A1 = m_digest[0], A2 = A1, B1 = m_digest[1], B2 = B1,
             C1 = m_digest[2], C2 = C1, D1 = m_digest[3], D2 = D1,
             E1 = m_digest[4], E2 = E1;

      F1(A1,B1,C1,D1,E1,m_M[ 0],11       );  F5(A2,B2,C2,D2,E2,m_M[ 5], 8,MAGIC6);
      F1(E1,A1,B1,C1,D1,m_M[ 1],14       );  F5(E2,A2,B2,C2,D2,m_M[14], 9,MAGIC6);
      F1(D1,E1,A1,B1,C1,m_M[ 2],15       );  F5(D2,E2,A2,B2,C2,m_M[ 7], 9,MAGIC6);
      F1(C1,D1,E1,A1,B1,m_M[ 3],12       );  F5(C2,D2,E2,A2,B2,m_M[ 0],11,MAGIC6);
      F1(B1,C1,D1,E1,A1,m_M[ 4], 5       );  F5(B2,C2,D2,E2,A2,m_M[ 9],13,MAGIC6);
      F1(A1,B1,C1,D1,E1,m_M[ 5], 8       );  F5(A2,B2,C2,D2,E2,m_M[ 2],15,MAGIC6);
      F1(E1,A1,B1,C1,D1,m_M[ 6], 7       );  F5(E2,A2,B2,C2,D2,m_M[11],15,MAGIC6);
      F1(D1,E1,A1,B1,C1,m_M[ 7], 9       );  F5(D2,E2,A2,B2,C2,m_M[ 4], 5,MAGIC6);
      F1(C1,D1,E1,A1,B1,m_M[ 8],11       );  F5(C2,D2,E2,A2,B2,m_M[13], 7,MAGIC6);
      F1(B1,C1,D1,E1,A1,m_M[ 9],13       );  F5(B2,C2,D2,E2,A2,m_M[ 6], 7,MAGIC6);
      F1(A1,B1,C1,D1,E1,m_M[10],14       );  F5(A2,B2,C2,D2,E2,m_M[15], 8,MAGIC6);
      F1(E1,A1,B1,C1,D1,m_M[11],15       );  F5(E2,A2,B2,C2,D2,m_M[ 8],11,MAGIC6);
      F1(D1,E1,A1,B1,C1,m_M[12], 6       );  F5(D2,E2,A2,B2,C2,m_M[ 1],14,MAGIC6);
      F1(C1,D1,E1,A1,B1,m_M[13], 7       );  F5(C2,D2,E2,A2,B2,m_M[10],14,MAGIC6);
      F1(B1,C1,D1,E1,A1,m_M[14], 9       );  F5(B2,C2,D2,E2,A2,m_M[ 3],12,MAGIC6);
      F1(A1,B1,C1,D1,E1,m_M[15], 8       );  F5(A2,B2,C2,D2,E2,m_M[12], 6,MAGIC6);

      F2(E1,A1,B1,C1,D1,m_M[ 7], 7,MAGIC2);  F4(E2,A2,B2,C2,D2,m_M[ 6], 9,MAGIC7);
      F2(D1,E1,A1,B1,C1,m_M[ 4], 6,MAGIC2);  F4(D2,E2,A2,B2,C2,m_M[11],13,MAGIC7);
      F2(C1,D1,E1,A1,B1,m_M[13], 8,MAGIC2);  F4(C2,D2,E2,A2,B2,m_M[ 3],15,MAGIC7);
      F2(B1,C1,D1,E1,A1,m_M[ 1],13,MAGIC2);  F4(B2,C2,D2,E2,A2,m_M[ 7], 7,MAGIC7);
      F2(A1,B1,C1,D1,E1,m_M[10],11,MAGIC2);  F4(A2,B2,C2,D2,E2,m_M[ 0],12,MAGIC7);
      F2(E1,A1,B1,C1,D1,m_M[ 6], 9,MAGIC2);  F4(E2,A2,B2,C2,D2,m_M[13], 8,MAGIC7);
      F2(D1,E1,A1,B1,C1,m_M[15], 7,MAGIC2);  F4(D2,E2,A2,B2,C2,m_M[ 5], 9,MAGIC7);
      F2(C1,D1,E1,A1,B1,m_M[ 3],15,MAGIC2);  F4(C2,D2,E2,A2,B2,m_M[10],11,MAGIC7);
      F2(B1,C1,D1,E1,A1,m_M[12], 7,MAGIC2);  F4(B2,C2,D2,E2,A2,m_M[14], 7,MAGIC7);
      F2(A1,B1,C1,D1,E1,m_M[ 0],12,MAGIC2);  F4(A2,B2,C2,D2,E2,m_M[15], 7,MAGIC7);
      F2(E1,A1,B1,C1,D1,m_M[ 9],15,MAGIC2);  F4(E2,A2,B2,C2,D2,m_M[ 8],12,MAGIC7);
      F2(D1,E1,A1,B1,C1,m_M[ 5], 9,MAGIC2);  F4(D2,E2,A2,B2,C2,m_M[12], 7,MAGIC7);
      F2(C1,D1,E1,A1,B1,m_M[ 2],11,MAGIC2);  F4(C2,D2,E2,A2,B2,m_M[ 4], 6,MAGIC7);
      F2(B1,C1,D1,E1,A1,m_M[14], 7,MAGIC2);  F4(B2,C2,D2,E2,A2,m_M[ 9],15,MAGIC7);
      F2(A1,B1,C1,D1,E1,m_M[11],13,MAGIC2);  F4(A2,B2,C2,D2,E2,m_M[ 1],13,MAGIC7);
      F2(E1,A1,B1,C1,D1,m_M[ 8],12,MAGIC2);  F4(E2,A2,B2,C2,D2,m_M[ 2],11,MAGIC7);

      F3(D1,E1,A1,B1,C1,m_M[ 3],11,MAGIC3);  F3(D2,E2,A2,B2,C2,m_M[15], 9,MAGIC8);
      F3(C1,D1,E1,A1,B1,m_M[10],13,MAGIC3);  F3(C2,D2,E2,A2,B2,m_M[ 5], 7,MAGIC8);
      F3(B1,C1,D1,E1,A1,m_M[14], 6,MAGIC3);  F3(B2,C2,D2,E2,A2,m_M[ 1],15,MAGIC8);
      F3(A1,B1,C1,D1,E1,m_M[ 4], 7,MAGIC3);  F3(A2,B2,C2,D2,E2,m_M[ 3],11,MAGIC8);
      F3(E1,A1,B1,C1,D1,m_M[ 9],14,MAGIC3);  F3(E2,A2,B2,C2,D2,m_M[ 7], 8,MAGIC8);
      F3(D1,E1,A1,B1,C1,m_M[15], 9,MAGIC3);  F3(D2,E2,A2,B2,C2,m_M[14], 6,MAGIC8);
      F3(C1,D1,E1,A1,B1,m_M[ 8],13,MAGIC3);  F3(C2,D2,E2,A2,B2,m_M[ 6], 6,MAGIC8);
      F3(B1,C1,D1,E1,A1,m_M[ 1],15,MAGIC3);  F3(B2,C2,D2,E2,A2,m_M[ 9],14,MAGIC8);
      F3(A1,B1,C1,D1,E1,m_M[ 2],14,MAGIC3);  F3(A2,B2,C2,D2,E2,m_M[11],12,MAGIC8);
      F3(E1,A1,B1,C1,D1,m_M[ 7], 8,MAGIC3);  F3(E2,A2,B2,C2,D2,m_M[ 8],13,MAGIC8);
      F3(D1,E1,A1,B1,C1,m_M[ 0],13,MAGIC3);  F3(D2,E2,A2,B2,C2,m_M[12], 5,MAGIC8);
      F3(C1,D1,E1,A1,B1,m_M[ 6], 6,MAGIC3);  F3(C2,D2,E2,A2,B2,m_M[ 2],14,MAGIC8);
      F3(B1,C1,D1,E1,A1,m_M[13], 5,MAGIC3);  F3(B2,C2,D2,E2,A2,m_M[10],13,MAGIC8);
      F3(A1,B1,C1,D1,E1,m_M[11],12,MAGIC3);  F3(A2,B2,C2,D2,E2,m_M[ 0],13,MAGIC8);
      F3(E1,A1,B1,C1,D1,m_M[ 5], 7,MAGIC3);  F3(E2,A2,B2,C2,D2,m_M[ 4], 7,MAGIC8);
      F3(D1,E1,A1,B1,C1,m_M[12], 5,MAGIC3);  F3(D2,E2,A2,B2,C2,m_M[13], 5,MAGIC8);

      F4(C1,D1,E1,A1,B1,m_M[ 1],11,MAGIC4);  F2(C2,D2,E2,A2,B2,m_M[ 8],15,MAGIC9);
      F4(B1,C1,D1,E1,A1,m_M[ 9],12,MAGIC4);  F2(B2,C2,D2,E2,A2,m_M[ 6], 5,MAGIC9);
      F4(A1,B1,C1,D1,E1,m_M[11],14,MAGIC4);  F2(A2,B2,C2,D2,E2,m_M[ 4], 8,MAGIC9);
      F4(E1,A1,B1,C1,D1,m_M[10],15,MAGIC4);  F2(E2,A2,B2,C2,D2,m_M[ 1],11,MAGIC9);
      F4(D1,E1,A1,B1,C1,m_M[ 0],14,MAGIC4);  F2(D2,E2,A2,B2,C2,m_M[ 3],14,MAGIC9);
      F4(C1,D1,E1,A1,B1,m_M[ 8],15,MAGIC4);  F2(C2,D2,E2,A2,B2,m_M[11],14,MAGIC9);
      F4(B1,C1,D1,E1,A1,m_M[12], 9,MAGIC4);  F2(B2,C2,D2,E2,A2,m_M[15], 6,MAGIC9);
      F4(A1,B1,C1,D1,E1,m_M[ 4], 8,MAGIC4);  F2(A2,B2,C2,D2,E2,m_M[ 0],14,MAGIC9);
      F4(E1,A1,B1,C1,D1,m_M[13], 9,MAGIC4);  F2(E2,A2,B2,C2,D2,m_M[ 5], 6,MAGIC9);
      F4(D1,E1,A1,B1,C1,m_M[ 3],14,MAGIC4);  F2(D2,E2,A2,B2,C2,m_M[12], 9,MAGIC9);
      F4(C1,D1,E1,A1,B1,m_M[ 7], 5,MAGIC4);  F2(C2,D2,E2,A2,B2,m_M[ 2],12,MAGIC9);
      F4(B1,C1,D1,E1,A1,m_M[15], 6,MAGIC4);  F2(B2,C2,D2,E2,A2,m_M[13], 9,MAGIC9);
      F4(A1,B1,C1,D1,E1,m_M[14], 8,MAGIC4);  F2(A2,B2,C2,D2,E2,m_M[ 9],12,MAGIC9);
      F4(E1,A1,B1,C1,D1,m_M[ 5], 6,MAGIC4);  F2(E2,A2,B2,C2,D2,m_M[ 7], 5,MAGIC9);
      F4(D1,E1,A1,B1,C1,m_M[ 6], 5,MAGIC4);  F2(D2,E2,A2,B2,C2,m_M[10],15,MAGIC9);
      F4(C1,D1,E1,A1,B1,m_M[ 2],12,MAGIC4);  F2(C2,D2,E2,A2,B2,m_M[14], 8,MAGIC9);

      F5(B1,C1,D1,E1,A1,m_M[ 4], 9,MAGIC5);  F1(B2,C2,D2,E2,A2,m_M[12], 8       );
      F5(A1,B1,C1,D1,E1,m_M[ 0],15,MAGIC5);  F1(A2,B2,C2,D2,E2,m_M[15], 5       );
      F5(E1,A1,B1,C1,D1,m_M[ 5], 5,MAGIC5);  F1(E2,A2,B2,C2,D2,m_M[10],12       );
      F5(D1,E1,A1,B1,C1,m_M[ 9],11,MAGIC5);  F1(D2,E2,A2,B2,C2,m_M[ 4], 9       );
      F5(C1,D1,E1,A1,B1,m_M[ 7], 6,MAGIC5);  F1(C2,D2,E2,A2,B2,m_M[ 1],12       );
      F5(B1,C1,D1,E1,A1,m_M[12], 8,MAGIC5);  F1(B2,C2,D2,E2,A2,m_M[ 5], 5       );
      F5(A1,B1,C1,D1,E1,m_M[ 2],13,MAGIC5);  F1(A2,B2,C2,D2,E2,m_M[ 8],14       );
      F5(E1,A1,B1,C1,D1,m_M[10],12,MAGIC5);  F1(E2,A2,B2,C2,D2,m_M[ 7], 6       );
      F5(D1,E1,A1,B1,C1,m_M[14], 5,MAGIC5);  F1(D2,E2,A2,B2,C2,m_M[ 6], 8       );
      F5(C1,D1,E1,A1,B1,m_M[ 1],12,MAGIC5);  F1(C2,D2,E2,A2,B2,m_M[ 2],13       );
      F5(B1,C1,D1,E1,A1,m_M[ 3],13,MAGIC5);  F1(B2,C2,D2,E2,A2,m_M[13], 6       );
      F5(A1,B1,C1,D1,E1,m_M[ 8],14,MAGIC5);  F1(A2,B2,C2,D2,E2,m_M[14], 5       );
      F5(E1,A1,B1,C1,D1,m_M[11],11,MAGIC5);  F1(E2,A2,B2,C2,D2,m_M[ 0],15       );
      F5(D1,E1,A1,B1,C1,m_M[ 6], 8,MAGIC5);  F1(D2,E2,A2,B2,C2,m_M[ 3],13       );
      F5(C1,D1,E1,A1,B1,m_M[15], 5,MAGIC5);  F1(C2,D2,E2,A2,B2,m_M[ 9],11       );
      F5(B1,C1,D1,E1,A1,m_M[13], 6,MAGIC5);  F1(B2,C2,D2,E2,A2,m_M[11],11       );

      C1          = m_digest[1] + C1 + D2;
      m_digest[1] = m_digest[2] + D1 + E2;
      m_digest[2] = m_digest[3] + E1 + A2;
      m_digest[3] = m_digest[4] + A1 + B2;
      m_digest[4] = m_digest[0] + B1 + C2;
      m_digest[0] = C1;

      input += hash_block_size();
      }
   }
Example #6
0
void Threefish_512::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
   {
   BOTAN_ASSERT(m_K.size() == 9, "Key was set");
   BOTAN_ASSERT(m_T.size() == 3, "Tweak was set");

#if defined(BOTAN_HAS_THREEFISH_512_AVX2)
   if(CPUID::has_avx2())
      {
      return avx2_decrypt_n(in, out, blocks);
      }
#endif

#define THREEFISH_ROUND(X0,X1,X2,X3,X4,X5,X6,X7,ROT1,ROT2,ROT3,ROT4) \
   do {                                                              \
      X4 ^= X0;                                                      \
      X5 ^= X1;                                                      \
      X6 ^= X2;                                                      \
      X7 ^= X3;                                                      \
      X4 = rotate_right(X4, ROT1);                                   \
      X5 = rotate_right(X5, ROT2);                                   \
      X6 = rotate_right(X6, ROT3);                                   \
      X7 = rotate_right(X7, ROT4);                                   \
      X0 -= X4;                                                      \
      X1 -= X5;                                                      \
      X2 -= X6;                                                      \
      X3 -= X7;                                                      \
   } while(0)

#define THREEFISH_INJECT_KEY(r)              \
   do {                                      \
      X0 -= m_K[(r  ) % 9];                  \
      X1 -= m_K[(r+1) % 9];                  \
      X2 -= m_K[(r+2) % 9];                  \
      X3 -= m_K[(r+3) % 9];                  \
      X4 -= m_K[(r+4) % 9];                  \
      X5 -= m_K[(r+5) % 9] + m_T[(r  ) % 3]; \
      X6 -= m_K[(r+6) % 9] + m_T[(r+1) % 3]; \
      X7 -= m_K[(r+7) % 9] + (r);            \
   } while(0)

#define THREEFISH_DEC_8_ROUNDS(R1,R2)                         \
   do {                                                       \
      THREEFISH_ROUND(X6,X0,X2,X4, X1,X7,X5,X3,  8,35,56,22); \
      THREEFISH_ROUND(X4,X6,X0,X2, X1,X3,X5,X7, 25,29,39,43); \
      THREEFISH_ROUND(X2,X4,X6,X0, X1,X7,X5,X3, 13,50,10,17); \
      THREEFISH_ROUND(X0,X2,X4,X6, X1,X3,X5,X7, 39,30,34,24); \
      THREEFISH_INJECT_KEY(R1);                               \
                                                              \
      THREEFISH_ROUND(X6,X0,X2,X4, X1,X7,X5,X3, 44, 9,54,56); \
      THREEFISH_ROUND(X4,X6,X0,X2, X1,X3,X5,X7, 17,49,36,39); \
      THREEFISH_ROUND(X2,X4,X6,X0, X1,X7,X5,X3, 33,27,14,42); \
      THREEFISH_ROUND(X0,X2,X4,X6, X1,X3,X5,X7, 46,36,19,37); \
      THREEFISH_INJECT_KEY(R2);                               \
   } while(0)

   BOTAN_PARALLEL_FOR(size_t i = 0; i < blocks; ++i)
      {
      uint64_t X0, X1, X2, X3, X4, X5, X6, X7;
      load_le(in + BLOCK_SIZE*i, X0, X1, X2, X3, X4, X5, X6, X7);

      THREEFISH_INJECT_KEY(18);

      THREEFISH_DEC_8_ROUNDS(17,16);
      THREEFISH_DEC_8_ROUNDS(15,14);
      THREEFISH_DEC_8_ROUNDS(13,12);
      THREEFISH_DEC_8_ROUNDS(11,10);
      THREEFISH_DEC_8_ROUNDS(9,8);
      THREEFISH_DEC_8_ROUNDS(7,6);
      THREEFISH_DEC_8_ROUNDS(5,4);
      THREEFISH_DEC_8_ROUNDS(3,2);
      THREEFISH_DEC_8_ROUNDS(1,0);

      store_le(out + BLOCK_SIZE*i, X0, X1, X2, X3, X4, X5, X6, X7);
      }

#undef THREEFISH_DEC_8_ROUNDS
#undef THREEFISH_INJECT_KEY
#undef THREEFISH_ROUND
   }