8 #include <botan/skein_512.h>     9 #include <botan/loadstor.h>    10 #include <botan/parsing.h>    11 #include <botan/exceptn.h>    12 #include <botan/rotate.h>    22    SKEIN_PERSONALIZATION = 8,
    23    SKEIN_PUBLIC_KEY = 12,
    24    SKEIN_KEY_IDENTIFIER = 16,
    32              const byte msg[], 
size_t msg_len)
    36       const size_t to_proc = std::min<size_t>(msg_len, 64);
    45          for(
size_t j = 0; j != to_proc % 8; ++j)
    46            M[to_proc/8] |= static_cast<u64bit>(msg[8*(to_proc/8)+j]) << (8*j);
    49       H[8] = H[0] ^ H[1] ^ H[2] ^ H[3] ^
    50              H[4] ^ H[5] ^ H[6] ^ H[7] ^ 0x1BD11BDAA9FC1A22;
    59       u64bit X5 = M[5] + H[5] + T[0];
    60       u64bit X6 = M[6] + H[6] + T[1];
    63 #define THREEFISH_ROUND(I1,I2,I3,I4,I5,I6,I7,I8,ROT1,ROT2,ROT3,ROT4)   \    65          X##I1 += X##I2; X##I2 = rotate_left(X##I2, ROT1) ^ X##I1;     \    66          X##I3 += X##I4; X##I4 = rotate_left(X##I4, ROT2) ^ X##I3;     \    67          X##I5 += X##I6; X##I6 = rotate_left(X##I6, ROT3) ^ X##I5;     \    68          X##I7 += X##I8; X##I8 = rotate_left(X##I8, ROT4) ^ X##I7;     \    71 #define THREEFISH_INJECT_KEY(r)                 \    78          X5 += H[(r+5) % 9] + T[(r  ) % 3];     \    79          X6 += H[(r+6) % 9] + T[(r+1) % 3];     \    80          X7 += H[(r+7) % 9] + (r);              \    83 #define THREEFISH_8_ROUNDS(R1,R2)                         \    85          THREEFISH_ROUND(0,1,2,3,4,5,6,7, 46,36,19,37);   \    86          THREEFISH_ROUND(2,1,4,7,6,5,0,3, 33,27,14,42);   \    87          THREEFISH_ROUND(4,1,6,3,0,5,2,7, 17,49,36,39);   \    88          THREEFISH_ROUND(6,1,0,7,2,5,4,3, 44, 9,54,56);   \    90          THREEFISH_INJECT_KEY(R1);                        \    92          THREEFISH_ROUND(0,1,2,3,4,5,6,7, 39,30,34,24);   \    93          THREEFISH_ROUND(2,1,4,7,6,5,0,3, 13,50,10,17);   \    94          THREEFISH_ROUND(4,1,6,3,0,5,2,7, 25,29,39,43);   \    95          THREEFISH_ROUND(6,1,0,7,2,5,4,3,  8,35,56,22);   \    97          THREEFISH_INJECT_KEY(R2);                        \   121       T[1] &= ~(
static_cast<u64bit>(1) << 62);
   133    T[1] = (
static_cast<u64bit>(type) << 56) |
   134           (
static_cast<u64bit>(1) << 62) |
   135           (
static_cast<u64bit>(
final) << 63);
   141                    const std::string& personalization)
   146    byte config_str[32] = { 0x53, 0x48, 0x41, 0x33, 0x01, 0x00, 0 };
   149    reset_tweak(T, SKEIN_CONFIG, 
true);
   150    ubi_512(H, T, config_str, 
sizeof(config_str));
   152    if(personalization != 
"")
   159       if(personalization.length() > 64)
   162       const byte* bits = 
reinterpret_cast<const byte*
>(personalization.data());
   164       reset_tweak(T, SKEIN_PERSONALIZATION, 
true);
   165       ubi_512(H, T, bits, personalization.length());
   168    reset_tweak(T, SKEIN_MSG, 
false);
   174                      const std::string& arg_personalization) :
   175    personalization(arg_personalization),
   176    output_bits(arg_output_bits),
   177    H(9), T(3), buffer(64), buf_pos(0)
   179    if(output_bits == 0 || output_bits % 8 != 0 || output_bits > 64*1024)
   182    initial_block(H, T, output_bits, personalization);
   187    if(personalization != 
"")
   188       return "Skein-512(" + 
to_string(output_bits) + 
"," + personalization + 
")";
   189    return "Skein-512(" + 
to_string(output_bits) + 
")";
   194    return new Skein_512(output_bits, personalization);
   205 void Skein_512::add_data(
const byte input[], 
size_t length)
   212       buffer.
copy(buf_pos, input, length);
   213       if(buf_pos + length > 64)
   215          ubi_512(H, T, &buffer[0], buffer.
size());
   217          input += (64 - buf_pos);
   218          length -= (64 - buf_pos);
   223    const size_t full_blocks = (length - 1) / 64;
   226       ubi_512(H, T, input, 64*full_blocks);
   228    length -= full_blocks * 64;
   230    buffer.
copy(buf_pos, input + full_blocks * 64, length);
   234 void Skein_512::final_result(
byte out[])
   236    T[1] |= (
static_cast<u64bit>(1) << 63); 
   238    for(
size_t i = buf_pos; i != buffer.
size(); ++i)
   241    ubi_512(H, T, &buffer[0], buf_pos);
   243    byte counter[8] = { 0 };
   245    size_t out_bytes = output_bits / 8;
   251       const size_t to_proc = std::min<size_t>(out_bytes, 64);
   253       H_out.
copy(&H[0], 8);
   255       reset_tweak(T, SKEIN_OUTPUT, 
true);
   256       ubi_512(H_out, T, counter, 
sizeof(counter));
   258       for(
size_t i = 0; i != to_proc; ++i)
   259          out[i] = 
get_byte(7-i%8, H_out[i/8]);
   261       out_bytes -= to_proc;
   264       for(
size_t i = 0; i != 
sizeof(counter); ++i)
   270    initial_block(H, T, output_bits, personalization);
 T load_le(const byte in[], size_t off)
void store_le(u16bit in, byte out[2])
std::invalid_argument Invalid_Argument
byte get_byte(size_t byte_num, T input)
void copy(const T in[], size_t n)
unsigned long long u64bit
#define THREEFISH_8_ROUNDS(R1, R2)
Skein_512(size_t output_bits=512, const std::string &personalization="")
std::string to_string(u64bit n, size_t min_len)
HashFunction * clone() const
void zeroise(MemoryRegion< T > &vec)