Exemplo n.º 1
0
void Stateful_RNG::randomize_with_ts_input(uint8_t output[], size_t output_len)
   {
   uint8_t additional_input[24] = { 0 };
   store_le(OS::get_system_timestamp_ns(), additional_input);
   store_le(OS::get_processor_timestamp(), additional_input + 8);
   store_le(m_last_pid, additional_input + 16);
   store_le(static_cast<uint32_t>(m_reseed_counter), additional_input + 20);

   randomize_with_input(output, output_len, additional_input, sizeof(additional_input));
   }
Exemplo n.º 2
0
void RandomNumberGenerator::randomize_with_ts_input(uint8_t output[], size_t output_len)
   {
   /*
   Form additional input which is provided to the PRNG implementation
   to paramaterize the KDF output.
   */
   uint8_t additional_input[16] = { 0 };
   store_le(OS::get_system_timestamp_ns(), additional_input);
   store_le(OS::get_high_resolution_clock(), additional_input + 8);

   randomize_with_input(output, output_len, additional_input, sizeof(additional_input));
   }
Exemplo n.º 3
0
/*
* GOST Decryption
*/
void GOST_28147_89::decrypt_n(const byte in[], byte out[], size_t blocks) const
   {
   for(size_t i = 0; i != blocks; ++i)
      {
      u32bit N1 = load_le<u32bit>(in, 0);
      u32bit N2 = load_le<u32bit>(in, 1);

      GOST_2ROUND(N1, N2, 0, 1);
      GOST_2ROUND(N1, N2, 2, 3);
      GOST_2ROUND(N1, N2, 4, 5);
      GOST_2ROUND(N1, N2, 6, 7);

      for(size_t j = 0; j != 3; ++j)
         {
         GOST_2ROUND(N1, N2, 7, 6);
         GOST_2ROUND(N1, N2, 5, 4);
         GOST_2ROUND(N1, N2, 3, 2);
         GOST_2ROUND(N1, N2, 1, 0);
         }

      store_le(out, N2, N1);
      in += BLOCK_SIZE;
      out += BLOCK_SIZE;
      }
   }
Exemplo n.º 4
0
void Threefish_512::encrypt_n(const byte in[], byte out[], size_t blocks) const
   {
   BOTAN_ASSERT(m_K.size() == 9, "Key was set");
   BOTAN_ASSERT(m_T.size() == 3, "Tweak was set");

   for(size_t i = 0; i != blocks; ++i)
      {
      u64bit X0 = load_le<u64bit>(in, 0);
      u64bit X1 = load_le<u64bit>(in, 1);
      u64bit X2 = load_le<u64bit>(in, 2);
      u64bit X3 = load_le<u64bit>(in, 3);
      u64bit X4 = load_le<u64bit>(in, 4);
      u64bit X5 = load_le<u64bit>(in, 5);
      u64bit X6 = load_le<u64bit>(in, 6);
      u64bit X7 = load_le<u64bit>(in, 7);

      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, X0, X1, X2, X3, X4, X5, X6, X7);

      in += 64;
      out += 64;
      }
   }
Exemplo n.º 5
0
/*
* RC2 Encryption
*/
void RC2::enc(const byte in[], byte out[]) const
   {
   u16bit R0 = load_le<u16bit>(in, 0);
   u16bit R1 = load_le<u16bit>(in, 1);
   u16bit R2 = load_le<u16bit>(in, 2);
   u16bit R3 = load_le<u16bit>(in, 3);

   for(u32bit j = 0; j != 16; ++j)
      {
      R0 += (R1 & ~R3) + (R2 & R3) + K[4*j];
      R0 = rotate_left(R0, 1);

      R1 += (R2 & ~R0) + (R3 & R0) + K[4*j + 1];
      R1 = rotate_left(R1, 2);

      R2 += (R3 & ~R1) + (R0 & R1) + K[4*j + 2];
      R2 = rotate_left(R2, 3);

      R3 += (R0 & ~R2) + (R1 & R2) + K[4*j + 3];
      R3 = rotate_left(R3, 5);

      if(j == 4 || j == 10)
         {
         R0 += K[R3 % 64];
         R1 += K[R0 % 64];
         R2 += K[R1 % 64];
         R3 += K[R2 % 64];
         }
      }

   store_le(out, R0, R1, R2, R3);
   }
Exemplo n.º 6
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);
      }
   }
Exemplo n.º 7
0
/*
* RC2 Decryption
*/
void RC2::dec(const byte in[], byte out[]) const
   {
   u16bit R0 = load_le<u16bit>(in, 0);
   u16bit R1 = load_le<u16bit>(in, 1);
   u16bit R2 = load_le<u16bit>(in, 2);
   u16bit R3 = load_le<u16bit>(in, 3);

   for(u32bit j = 0; j != 16; ++j)
      {
      R3 = rotate_right(R3, 5);
      R3 -= (R0 & ~R2) + (R1 & R2) + K[63 - (4*j + 0)];

      R2 = rotate_right(R2, 3);
      R2 -= (R3 & ~R1) + (R0 & R1) + K[63 - (4*j + 1)];

      R1 = rotate_right(R1, 2);
      R1 -= (R2 & ~R0) + (R3 & R0) + K[63 - (4*j + 2)];

      R0 = rotate_right(R0, 1);
      R0 -= (R1 & ~R3) + (R2 & R3) + K[63 - (4*j + 3)];

      if(j == 4 || j == 10)
         {
         R3 -= K[R2 % 64];
         R2 -= K[R1 % 64];
         R1 -= K[R0 % 64];
         R0 -= K[R3 % 64];
         }
      }

   store_le(out, R0, R1, R2, R3);
   }
Exemplo n.º 8
0
/*
* Write the count bits to the buffer
*/
void MDx_HashFunction::write_count(uint8_t out[])
   {
   if(COUNT_SIZE < 8)
      throw Invalid_State("MDx_HashFunction::write_count: COUNT_SIZE < 8");
   if(COUNT_SIZE >= output_length() || COUNT_SIZE >= hash_block_size())
      throw Invalid_Argument("MDx_HashFunction: COUNT_SIZE is too big");

   const uint64_t bit_count = m_count * 8;

   if(BIG_BYTE_ENDIAN)
      store_be(bit_count, out + COUNT_SIZE - 8);
   else
      store_le(bit_count, out + COUNT_SIZE - 8);
   }
Exemplo n.º 9
0
/*
* Twofish Encryption
*/
void Twofish::encrypt_n(const byte in[], byte out[], size_t blocks) const
   {
   for(size_t i = 0; i != blocks; ++i)
      {
      u32bit A = load_le<u32bit>(in, 0) ^ RK[0];
      u32bit B = load_le<u32bit>(in, 1) ^ RK[1];
      u32bit C = load_le<u32bit>(in, 2) ^ RK[2];
      u32bit D = load_le<u32bit>(in, 3) ^ RK[3];

      for(size_t j = 0; j != 16; j += 2)
         {
         u32bit X, Y;

         X = SB[    get_byte(3, A)] ^ SB[256+get_byte(2, A)] ^
             SB[512+get_byte(1, A)] ^ SB[768+get_byte(0, A)];
         Y = SB[    get_byte(0, B)] ^ SB[256+get_byte(3, B)] ^
             SB[512+get_byte(2, B)] ^ SB[768+get_byte(1, B)];
         X += Y;
         Y += X + RK[2*j + 9];
         X += RK[2*j + 8];

         C = rotate_right(C ^ X, 1);
         D = rotate_left(D, 1) ^ Y;

         X = SB[    get_byte(3, C)] ^ SB[256+get_byte(2, C)] ^
             SB[512+get_byte(1, C)] ^ SB[768+get_byte(0, C)];
         Y = SB[    get_byte(0, D)] ^ SB[256+get_byte(3, D)] ^
             SB[512+get_byte(2, D)] ^ SB[768+get_byte(1, D)];
         X += Y;
         Y += X + RK[2*j + 11];
         X += RK[2*j + 10];

         A = rotate_right(A ^ X, 1);
         B = rotate_left(B, 1) ^ Y;
         }

      C ^= RK[4];
      D ^= RK[5];
      A ^= RK[6];
      B ^= RK[7];

      store_le(out, C, D, A, B);

      in += BLOCK_SIZE;
      out += BLOCK_SIZE;
      }
   }
Exemplo n.º 10
0
/*
* Twofish Decryption
*/
void Twofish::decrypt_n(const byte in[], byte out[], size_t blocks) const
{
    for(size_t i = 0; i != blocks; ++i)
    {
        u32bit A = load_le<u32bit>(in, 0) ^ m_RK[4];
        u32bit B = load_le<u32bit>(in, 1) ^ m_RK[5];
        u32bit C = load_le<u32bit>(in, 2) ^ m_RK[6];
        u32bit D = load_le<u32bit>(in, 3) ^ m_RK[7];

        for(size_t j = 0; j != 16; j += 2)
        {
            u32bit X, Y;

            X = m_SB[    get_byte(3, A)] ^ m_SB[256+get_byte(2, A)] ^
                m_SB[512+get_byte(1, A)] ^ m_SB[768+get_byte(0, A)];
            Y = m_SB[    get_byte(0, B)] ^ m_SB[256+get_byte(3, B)] ^
                m_SB[512+get_byte(2, B)] ^ m_SB[768+get_byte(1, B)];
            X += Y;
            Y += X + m_RK[39 - 2*j];
            X += m_RK[38 - 2*j];

            C = rotate_left(C, 1) ^ X;
            D = rotate_right(D ^ Y, 1);

            X = m_SB[    get_byte(3, C)] ^ m_SB[256+get_byte(2, C)] ^
                m_SB[512+get_byte(1, C)] ^ m_SB[768+get_byte(0, C)];
            Y = m_SB[    get_byte(0, D)] ^ m_SB[256+get_byte(3, D)] ^
                m_SB[512+get_byte(2, D)] ^ m_SB[768+get_byte(1, D)];
            X += Y;
            Y += X + m_RK[37 - 2*j];
            X += m_RK[36 - 2*j];

            A = rotate_left(A, 1) ^ X;
            B = rotate_right(B ^ Y, 1);
        }

        C ^= m_RK[0];
        D ^= m_RK[1];
        A ^= m_RK[2];
        B ^= m_RK[3];

        store_le(out, C, D, A, B);

        in += BLOCK_SIZE;
        out += BLOCK_SIZE;
    }
}
Exemplo n.º 11
0
void RDRAND_RNG::randomize(uint8_t out[], size_t out_len)
   {
   while(out_len >= 4)
      {
      uint32_t r = RDRAND_RNG::rdrand();

      store_le(r, out);
      out += 4;
      out_len -= 4;
      }

   if(out_len) // between 1 and 3 trailing bytes
      {
      uint32_t r = RDRAND_RNG::rdrand();
      for(size_t i = 0; i != out_len; ++i)
         out[i] = get_byte(i, r);
      }
   }
Exemplo n.º 12
0
/*
* RC6 Encryption
*/
void RC6::encrypt_n(const byte in[], byte out[], size_t blocks) const
   {
   for(size_t i = 0; i != blocks; ++i)
      {
      u32bit A = load_le<u32bit>(in, 0);
      u32bit B = load_le<u32bit>(in, 1);
      u32bit C = load_le<u32bit>(in, 2);
      u32bit D = load_le<u32bit>(in, 3);

      B += S[0]; D += S[1];

      for(size_t j = 0; j != 20; j += 4)
         {
         u32bit T1, T2;

         T1 = rotate_left(B*(2*B+1), 5);
         T2 = rotate_left(D*(2*D+1), 5);
         A = rotate_left(A ^ T1, T2 % 32) + S[2*j+2];
         C = rotate_left(C ^ T2, T1 % 32) + S[2*j+3];

         T1 = rotate_left(C*(2*C+1), 5);
         T2 = rotate_left(A*(2*A+1), 5);
         B = rotate_left(B ^ T1, T2 % 32) + S[2*j+4];
         D = rotate_left(D ^ T2, T1 % 32) + S[2*j+5];

         T1 = rotate_left(D*(2*D+1), 5);
         T2 = rotate_left(B*(2*B+1), 5);
         C = rotate_left(C ^ T1, T2 % 32) + S[2*j+6];
         A = rotate_left(A ^ T2, T1 % 32) + S[2*j+7];

         T1 = rotate_left(A*(2*A+1), 5);
         T2 = rotate_left(C*(2*C+1), 5);
         D = rotate_left(D ^ T1, T2 % 32) + S[2*j+8];
         B = rotate_left(B ^ T2, T1 % 32) + S[2*j+9];
         }

      A += S[42]; C += S[43];

      store_le(out, A, B, C, D);

      in += BLOCK_SIZE;
      out += BLOCK_SIZE;
      }
   }
Exemplo n.º 13
0
/*
* RC6 Decryption
*/
void RC6::decrypt_n(const byte in[], byte out[], size_t blocks) const
   {
   for(size_t i = 0; i != blocks; ++i)
      {
      u32bit A = load_le<u32bit>(in, 0);
      u32bit B = load_le<u32bit>(in, 1);
      u32bit C = load_le<u32bit>(in, 2);
      u32bit D = load_le<u32bit>(in, 3);

      C -= S[43]; A -= S[42];

      for(size_t j = 0; j != 20; j += 4)
         {
         u32bit T1, T2;

         T1 = rotate_left(A*(2*A+1), 5);
         T2 = rotate_left(C*(2*C+1), 5);
         B = rotate_right(B - S[41 - 2*j], T1 % 32) ^ T2;
         D = rotate_right(D - S[40 - 2*j], T2 % 32) ^ T1;

         T1 = rotate_left(D*(2*D+1), 5);
         T2 = rotate_left(B*(2*B+1), 5);
         A = rotate_right(A - S[39 - 2*j], T1 % 32) ^ T2;
         C = rotate_right(C - S[38 - 2*j], T2 % 32) ^ T1;

         T1 = rotate_left(C*(2*C+1), 5);
         T2 = rotate_left(A*(2*A+1), 5);
         D = rotate_right(D - S[37 - 2*j], T1 % 32) ^ T2;
         B = rotate_right(B - S[36 - 2*j], T2 % 32) ^ T1;

         T1 = rotate_left(B*(2*B+1), 5);
         T2 = rotate_left(D*(2*D+1), 5);
         C = rotate_right(C - S[35 - 2*j], T1 % 32) ^ T2;
         A = rotate_right(A - S[34 - 2*j], T2 % 32) ^ T1;
         }

      D -= S[1]; B -= S[0];

      store_le(out, A, B, C, D);

      in += BLOCK_SIZE;
      out += BLOCK_SIZE;
      }
   }
Exemplo n.º 14
0
/*
* GOST Encryption
*/
void GOST_28147_89::enc(const byte in[], byte out[]) const
   {
   u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1);

   for(size_t i = 0; i != 3; ++i)
      {
      GOST_2ROUND(N1, N2, 0, 1);
      GOST_2ROUND(N1, N2, 2, 3);
      GOST_2ROUND(N1, N2, 4, 5);
      GOST_2ROUND(N1, N2, 6, 7);
      }

   GOST_2ROUND(N1, N2, 7, 6);
   GOST_2ROUND(N1, N2, 5, 4);
   GOST_2ROUND(N1, N2, 3, 2);
   GOST_2ROUND(N1, N2, 1, 0);

   store_le(out, N2, N1);
   }
Exemplo n.º 15
0
/*
* Finalize a hash
*/
void Streebog::final_result(uint8_t output[])
   {
   m_buffer[m_position++] = 0x01;

   if(m_position != m_buffer.size())
      clear_mem(&m_buffer[m_position], m_buffer.size() - m_position);

   compress(m_buffer.data());
   m_count += (m_position - 1) * 8;

   zeroise(m_buffer);
   store_le(m_count, m_buffer.data());
   compress(m_buffer.data(), true);

   compress_64(m_S.data(), true);
   // FIXME
   std::memcpy(output, &m_h[8 - output_length() / 8], output_length());
   clear();
   }
Exemplo n.º 16
0
void ChaCha::seek(u64bit offset)
   {
   if (m_state.size() == 0 && m_buffer.size() == 0)
      {
      throw Invalid_State("You have to setup the stream cipher (key and iv)");
      }

   // Find the block offset
   u64bit counter = offset / 64;

   byte out[8];

   store_le(counter, out);

   m_state[12] = load_le<u32bit>(out, 0);
   m_state[13] += load_le<u32bit>(out, 1);

   chacha_x4(m_buffer.data(), m_state.data(), m_rounds);
   m_position = offset % 64;
   }
Exemplo n.º 17
0
/**
* Produce the final GOST 34.11 output
*/
void GOST_34_11::final_result(uint8_t out[])
{
    if(m_position)
    {
        clear_mem(m_buffer.data() + m_position, m_buffer.size() - m_position);
        compress_n(m_buffer.data(), 1);
    }

    secure_vector<uint8_t> length_buf(32);
    const uint64_t bit_count = m_count * 8;
    store_le(bit_count, length_buf.data());

    secure_vector<uint8_t> sum_buf = m_sum;

    compress_n(length_buf.data(), 1);
    compress_n(sum_buf.data(), 1);

    copy_mem(out, m_hash.data(), 32);

    clear();
}
Exemplo n.º 18
0
/**
* Produce the final GOST 34.11 output
*/
void GOST_34_11::final_result(byte out[])
   {
   if(position)
      {
      clear_mem(buffer.begin() + position, buffer.size() - position);
      compress_n(buffer, 1);
      }

   SecureBuffer<byte, 32> length_buf;
   const u64bit bit_count = count * 8;
   store_le(bit_count, length_buf);

   SecureBuffer<byte, 32> sum_buf(sum);

   compress_n(length_buf, 1);
   compress_n(sum_buf, 1);

   copy_mem(out, hash.begin(), 32);

   clear();
   }
Exemplo n.º 19
0
/*
* RC6 Decryption
*/
void RC6::dec(const byte in[], byte out[]) const
   {
   u32bit A = load_le<u32bit>(in, 0);
   u32bit B = load_le<u32bit>(in, 1);
   u32bit C = load_le<u32bit>(in, 2);
   u32bit D = load_le<u32bit>(in, 3);

   C -= S[43]; A -= S[42];

   for(u32bit j = 0; j != 20; j += 4)
      {
      u32bit T1, T2;

      T1 = rotate_left(A*(2*A+1), 5);
      T2 = rotate_left(C*(2*C+1), 5);
      B = rotate_right(B - S[41 - 2*j], T1 % 32) ^ T2;
      D = rotate_right(D - S[40 - 2*j], T2 % 32) ^ T1;

      T1 = rotate_left(D*(2*D+1), 5);
      T2 = rotate_left(B*(2*B+1), 5);
      A = rotate_right(A - S[39 - 2*j], T1 % 32) ^ T2;
      C = rotate_right(C - S[38 - 2*j], T2 % 32) ^ T1;

      T1 = rotate_left(C*(2*C+1), 5);
      T2 = rotate_left(A*(2*A+1), 5);
      D = rotate_right(D - S[37 - 2*j], T1 % 32) ^ T2;
      B = rotate_right(B - S[36 - 2*j], T2 % 32) ^ T1;

      T1 = rotate_left(B*(2*B+1), 5);
      T2 = rotate_left(D*(2*D+1), 5);
      C = rotate_right(C - S[35 - 2*j], T1 % 32) ^ T2;
      A = rotate_right(A - S[34 - 2*j], T2 % 32) ^ T1;
      }

   D -= S[1]; B -= S[0];

   store_le(out, A, B, C, D);
   }
Exemplo n.º 20
0
/*
* RC6 Encryption
*/
void RC6::enc(const byte in[], byte out[]) const
   {
   u32bit A = load_le<u32bit>(in, 0);
   u32bit B = load_le<u32bit>(in, 1);
   u32bit C = load_le<u32bit>(in, 2);
   u32bit D = load_le<u32bit>(in, 3);

   B += S[0]; D += S[1];

   for(u32bit j = 0; j != 20; j += 4)
      {
      u32bit T1, T2;

      T1 = rotate_left(B*(2*B+1), 5);
      T2 = rotate_left(D*(2*D+1), 5);
      A = rotate_left(A ^ T1, T2 % 32) + S[2*j+2];
      C = rotate_left(C ^ T2, T1 % 32) + S[2*j+3];

      T1 = rotate_left(C*(2*C+1), 5);
      T2 = rotate_left(A*(2*A+1), 5);
      B = rotate_left(B ^ T1, T2 % 32) + S[2*j+4];
      D = rotate_left(D ^ T2, T1 % 32) + S[2*j+5];

      T1 = rotate_left(D*(2*D+1), 5);
      T2 = rotate_left(B*(2*B+1), 5);
      C = rotate_left(C ^ T1, T2 % 32) + S[2*j+6];
      A = rotate_left(A ^ T2, T1 % 32) + S[2*j+7];

      T1 = rotate_left(A*(2*A+1), 5);
      T2 = rotate_left(C*(2*C+1), 5);
      D = rotate_left(D ^ T1, T2 % 32) + S[2*j+8];
      B = rotate_left(B ^ T2, T1 % 32) + S[2*j+9];
      }

   A += S[42]; C += S[43];

   store_le(out, A, B, C, D);
   }
Exemplo n.º 21
0
Arquivo: rc2.cpp Projeto: AlexNk/botan
/*
* RC2 Decryption
*/
void RC2::decrypt_n(const byte in[], byte out[], size_t blocks) const
   {
   for(size_t i = 0; i != blocks; ++i)
      {
      u16bit R0 = load_le<u16bit>(in, 0);
      u16bit R1 = load_le<u16bit>(in, 1);
      u16bit R2 = load_le<u16bit>(in, 2);
      u16bit R3 = load_le<u16bit>(in, 3);

      for(size_t j = 0; j != 16; ++j)
         {
         R3 = rotate_right(R3, 5);
         R3 -= (R0 & ~R2) + (R1 & R2) + K[63 - (4*j + 0)];

         R2 = rotate_right(R2, 3);
         R2 -= (R3 & ~R1) + (R0 & R1) + K[63 - (4*j + 1)];

         R1 = rotate_right(R1, 2);
         R1 -= (R2 & ~R0) + (R3 & R0) + K[63 - (4*j + 2)];

         R0 = rotate_right(R0, 1);
         R0 -= (R1 & ~R3) + (R2 & R3) + K[63 - (4*j + 3)];

         if(j == 4 || j == 10)
            {
            R3 -= K[R2 % 64];
            R2 -= K[R1 % 64];
            R1 -= K[R0 % 64];
            R0 -= K[R3 % 64];
            }
         }

      store_le(out, R0, R1, R2, R3);

      in += BLOCK_SIZE;
      out += BLOCK_SIZE;
      }
   }
Exemplo n.º 22
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
   }
Exemplo n.º 23
0
/*
* Copy out the digest
*/
void MD5::copy_out(byte output[])
   {
   for(size_t i = 0; i != output_length(); i += 4)
      store_le(digest[i/4], output + i);
   }
Exemplo n.º 24
0
void ChaCha::chacha(byte output[64], const u32bit input[16])
   {
   u32bit x00 = input[ 0], x01 = input[ 1], x02 = input[ 2], x03 = input[ 3],
          x04 = input[ 4], x05 = input[ 5], x06 = input[ 6], x07 = input[ 7],
          x08 = input[ 8], x09 = input[ 9], x10 = input[10], x11 = input[11],
          x12 = input[12], x13 = input[13], x14 = input[14], x15 = input[15];

#define CHACHA_QUARTER_ROUND(a, b, c, d)   \
   do {                                    \
   a += b; d ^= a; d = rotate_left(d, 16); \
   c += d; b ^= c; b = rotate_left(b, 12); \
   a += b; d ^= a; d = rotate_left(d, 8);  \
   c += d; b ^= c; b = rotate_left(b, 7);  \
   } while(0)

   for(size_t i = 0; i != 10; ++i)
      {
      CHACHA_QUARTER_ROUND(x00, x04, x08, x12);
      CHACHA_QUARTER_ROUND(x01, x05, x09, x13);
      CHACHA_QUARTER_ROUND(x02, x06, x10, x14);
      CHACHA_QUARTER_ROUND(x03, x07, x11, x15);

      CHACHA_QUARTER_ROUND(x00, x05, x10, x15);
      CHACHA_QUARTER_ROUND(x01, x06, x11, x12);
      CHACHA_QUARTER_ROUND(x02, x07, x08, x13);
      CHACHA_QUARTER_ROUND(x03, x04, x09, x14);
      }

#undef CHACHA_QUARTER_ROUND

   store_le(x00 + input[ 0], output + 4 *  0);
   store_le(x01 + input[ 1], output + 4 *  1);
   store_le(x02 + input[ 2], output + 4 *  2);
   store_le(x03 + input[ 3], output + 4 *  3);
   store_le(x04 + input[ 4], output + 4 *  4);
   store_le(x05 + input[ 5], output + 4 *  5);
   store_le(x06 + input[ 6], output + 4 *  6);
   store_le(x07 + input[ 7], output + 4 *  7);
   store_le(x08 + input[ 8], output + 4 *  8);
   store_le(x09 + input[ 9], output + 4 *  9);
   store_le(x10 + input[10], output + 4 * 10);
   store_le(x11 + input[11], output + 4 * 11);
   store_le(x12 + input[12], output + 4 * 12);
   store_le(x13 + input[13], output + 4 * 13);
   store_le(x14 + input[14], output + 4 * 14);
   store_le(x15 + input[15], output + 4 * 15);
   }
Exemplo n.º 25
0
//static
void ChaCha::chacha_x4(byte output[64*4], u32bit input[16], size_t rounds)
   {
   BOTAN_ASSERT(rounds % 2 == 0, "Valid rounds");

#if defined(BOTAN_HAS_CHACHA_SSE2)
   if(CPUID::has_sse2())
      {
      return ChaCha::chacha_sse2_x4(output, input, rounds);
      }
#endif

   // TODO interleave rounds
   for(size_t i = 0; i != 4; ++i)
      {
      u32bit x00 = input[ 0], x01 = input[ 1], x02 = input[ 2], x03 = input[ 3],
             x04 = input[ 4], x05 = input[ 5], x06 = input[ 6], x07 = input[ 7],
             x08 = input[ 8], x09 = input[ 9], x10 = input[10], x11 = input[11],
             x12 = input[12], x13 = input[13], x14 = input[14], x15 = input[15];

#define CHACHA_QUARTER_ROUND(a, b, c, d)        \
      do {                                      \
      a += b; d ^= a; d = rotate_left(d, 16);   \
      c += d; b ^= c; b = rotate_left(b, 12);   \
      a += b; d ^= a; d = rotate_left(d, 8);    \
      c += d; b ^= c; b = rotate_left(b, 7);    \
      } while(0)

      for(size_t r = 0; r != rounds / 2; ++r)
         {
         CHACHA_QUARTER_ROUND(x00, x04, x08, x12);
         CHACHA_QUARTER_ROUND(x01, x05, x09, x13);
         CHACHA_QUARTER_ROUND(x02, x06, x10, x14);
         CHACHA_QUARTER_ROUND(x03, x07, x11, x15);

         CHACHA_QUARTER_ROUND(x00, x05, x10, x15);
         CHACHA_QUARTER_ROUND(x01, x06, x11, x12);
         CHACHA_QUARTER_ROUND(x02, x07, x08, x13);
         CHACHA_QUARTER_ROUND(x03, x04, x09, x14);
         }

#undef CHACHA_QUARTER_ROUND

      x00 += input[0];
      x01 += input[1];
      x02 += input[2];
      x03 += input[3];
      x04 += input[4];
      x05 += input[5];
      x06 += input[6];
      x07 += input[7];
      x08 += input[8];
      x09 += input[9];
      x10 += input[10];
      x11 += input[11];
      x12 += input[12];
      x13 += input[13];
      x14 += input[14];
      x15 += input[15];

      store_le(x00, output + 64 * i + 4 *  0);
      store_le(x01, output + 64 * i + 4 *  1);
      store_le(x02, output + 64 * i + 4 *  2);
      store_le(x03, output + 64 * i + 4 *  3);
      store_le(x04, output + 64 * i + 4 *  4);
      store_le(x05, output + 64 * i + 4 *  5);
      store_le(x06, output + 64 * i + 4 *  6);
      store_le(x07, output + 64 * i + 4 *  7);
      store_le(x08, output + 64 * i + 4 *  8);
      store_le(x09, output + 64 * i + 4 *  9);
      store_le(x10, output + 64 * i + 4 * 10);
      store_le(x11, output + 64 * i + 4 * 11);
      store_le(x12, output + 64 * i + 4 * 12);
      store_le(x13, output + 64 * i + 4 * 13);
      store_le(x14, output + 64 * i + 4 * 14);
      store_le(x15, output + 64 * i + 4 * 15);

      input[12]++;
      input[13] += input[12] < i; // carry?
      }
   }
Exemplo n.º 26
0
/*
* Copy out the digest
*/
void MD5::copy_out(byte output[])
   {
   for(u32bit j = 0; j != OUTPUT_LENGTH; j += 4)
      store_le(digest[j/4], output + j);
   }
Exemplo n.º 27
0
void Threefish_512::decrypt_n(const byte in[], byte out[], size_t blocks) const
   {
   BOTAN_ASSERT(m_K.size() == 9, "Key was set");
   BOTAN_ASSERT(m_T.size() == 3, "Tweak was set");

#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)

   for(size_t i = 0; i != blocks; ++i)
      {
      u64bit X0 = load_le<u64bit>(in, 0);
      u64bit X1 = load_le<u64bit>(in, 1);
      u64bit X2 = load_le<u64bit>(in, 2);
      u64bit X3 = load_le<u64bit>(in, 3);
      u64bit X4 = load_le<u64bit>(in, 4);
      u64bit X5 = load_le<u64bit>(in, 5);
      u64bit X6 = load_le<u64bit>(in, 6);
      u64bit X7 = load_le<u64bit>(in, 7);

      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, X0, X1, X2, X3, X4, X5, X6, X7);

      in += 64;
      out += 64;
      }

#undef THREEFISH_DEC_8_ROUNDS
#undef THREEFISH_INJECT_KEY
#undef THREEFISH_ROUND
   }