diff options
author | lloyd <[email protected]> | 2009-06-03 12:49:48 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2009-06-03 12:49:48 +0000 |
commit | a96eae0b3394b64aea544f9f0ce4664d3b4a5c58 (patch) | |
tree | 5ae8d4cc57021cef52d29586852f7f0287e92f0c | |
parent | ab6eace5760deeff742d515e7d72389cdd2d974b (diff) |
Small cleanups in the Skein-512 source, and add support for the
personalization option.
-rw-r--r-- | src/engine/def_engine/lookup_hash.cpp | 3 | ||||
-rw-r--r-- | src/hash/skein/skein_512.cpp | 127 | ||||
-rw-r--r-- | src/hash/skein/skein_512.h | 8 |
3 files changed, 67 insertions, 71 deletions
diff --git a/src/engine/def_engine/lookup_hash.cpp b/src/engine/def_engine/lookup_hash.cpp index d1a8e4503..58136fc5a 100644 --- a/src/engine/def_engine/lookup_hash.cpp +++ b/src/engine/def_engine/lookup_hash.cpp @@ -167,7 +167,8 @@ Default_Engine::find_hash(const SCAN_Name& request, #if defined(BOTAN_HAS_SKEIN_512) if(request.algo_name() == "Skein-512") - return new Skein_512(request.arg_as_u32bit(0, 512)); + return new Skein_512(request.arg_as_u32bit(0, 512), + request.arg(1, "")); #endif #if defined(BOTAN_HAS_WHIRLPOOL) diff --git a/src/hash/skein/skein_512.cpp b/src/hash/skein/skein_512.cpp index 266465b98..c8a26ae82 100644 --- a/src/hash/skein/skein_512.cpp +++ b/src/hash/skein/skein_512.cpp @@ -8,8 +8,8 @@ #include <botan/skein_512.h> #include <botan/loadstor.h> #include <botan/parsing.h> +#include <botan/exceptn.h> #include <algorithm> -#include <stdexcept> namespace Botan { @@ -28,11 +28,8 @@ enum type_code { void ubi_512(u64bit H[9], u64bit T[], const byte msg[], u64bit msg_len) { - bool first = true; - - while(msg_len || first) + do { - first = false; const u64bit to_proc = std::min<u64bit>(msg_len, 64); T[0] += to_proc; @@ -51,33 +48,24 @@ void ubi_512(u64bit H[9], u64bit T[], const byte msg[], u64bit msg_len) T[2] = T[0] ^ T[1]; - const u64bit K0 = H[0]; - const u64bit K1 = H[1]; - const u64bit K2 = H[2]; - const u64bit K3 = H[3]; - const u64bit K4 = H[4]; - const u64bit K5 = H[5]; - const u64bit K6 = H[6]; - const u64bit K7 = H[7]; - - u64bit X0 = M[0] + K0; - u64bit X1 = M[1] + K1; - u64bit X2 = M[2] + K2; - u64bit X3 = M[3] + K3; - u64bit X4 = M[4] + K4; - u64bit X5 = M[5] + K5 + T[0]; - u64bit X6 = M[6] + K6 + T[1]; - u64bit X7 = M[7] + K7; - -#define SKEIN_ROUND(I1,I2,I3,I4,I5,I6,I7,I8,ROT1,ROT2,ROT3,ROT4) \ - do { \ - X##I1 += X##I2; X##I2 = rotate_left(X##I2, ROT1) ^ X##I1; \ - X##I3 += X##I4; X##I4 = rotate_left(X##I4, ROT2) ^ X##I3; \ - X##I5 += X##I6; X##I6 = rotate_left(X##I6, ROT3) ^ X##I5; \ - X##I7 += X##I8; X##I8 = rotate_left(X##I8, ROT4) ^ X##I7; \ + u64bit X0 = M[0] + H[0]; + u64bit X1 = M[1] + H[1]; + u64bit X2 = M[2] + H[2]; + u64bit X3 = M[3] + H[3]; + u64bit X4 = M[4] + H[4]; + u64bit X5 = M[5] + H[5] + T[0]; + u64bit X6 = M[6] + H[6] + T[1]; + u64bit X7 = M[7] + H[7]; + +#define THREEFISH_ROUND(I1,I2,I3,I4,I5,I6,I7,I8,ROT1,ROT2,ROT3,ROT4) \ + do { \ + X##I1 += X##I2; X##I2 = rotate_left(X##I2, ROT1) ^ X##I1; \ + X##I3 += X##I4; X##I4 = rotate_left(X##I4, ROT2) ^ X##I3; \ + X##I5 += X##I6; X##I6 = rotate_left(X##I6, ROT3) ^ X##I5; \ + X##I7 += X##I8; X##I8 = rotate_left(X##I8, ROT4) ^ X##I7; \ } while(0); -#define SKEIN_INJECT_KEY(r) \ +#define THREEFISH_INJECT_KEY(r) \ do { \ X0 += H[(r ) % 9]; \ X1 += H[(r+1) % 9]; \ @@ -89,32 +77,32 @@ void ubi_512(u64bit H[9], u64bit T[], const byte msg[], u64bit msg_len) X7 += H[(r+7) % 9] + (r); \ } while(0); -#define SKEIN_8_ROUNDS(R1,R2) \ - do { \ - SKEIN_ROUND(0,1,2,3,4,5,6,7,38,30,50,53); \ - SKEIN_ROUND(2,1,4,7,6,5,0,3,48,20,43,31); \ - SKEIN_ROUND(4,1,6,3,0,5,2,7,34,14,15,27); \ - SKEIN_ROUND(6,1,0,7,2,5,4,3,26,12,58, 7); \ - \ - SKEIN_INJECT_KEY(R1); \ - \ - SKEIN_ROUND(0,1,2,3,4,5,6,7,33,49, 8,42); \ - SKEIN_ROUND(2,1,4,7,6,5,0,3,39,27,41,14); \ - SKEIN_ROUND(4,1,6,3,0,5,2,7,29,26,11, 9); \ - SKEIN_ROUND(6,1,0,7,2,5,4,3,33,51,39,35); \ - \ - SKEIN_INJECT_KEY(R2); \ +#define THREEFISH_8_ROUNDS(R1,R2) \ + do { \ + THREEFISH_ROUND(0,1,2,3,4,5,6,7, 38,30,50,53); \ + THREEFISH_ROUND(2,1,4,7,6,5,0,3, 48,20,43,31); \ + THREEFISH_ROUND(4,1,6,3,0,5,2,7, 34,14,15,27); \ + THREEFISH_ROUND(6,1,0,7,2,5,4,3, 26,12,58, 7); \ + \ + THREEFISH_INJECT_KEY(R1); \ + \ + THREEFISH_ROUND(0,1,2,3,4,5,6,7, 33,49, 8,42); \ + THREEFISH_ROUND(2,1,4,7,6,5,0,3, 39,27,41,14); \ + THREEFISH_ROUND(4,1,6,3,0,5,2,7, 29,26,11, 9); \ + THREEFISH_ROUND(6,1,0,7,2,5,4,3, 33,51,39,35); \ + \ + THREEFISH_INJECT_KEY(R2); \ } while(0); - SKEIN_8_ROUNDS(1,2); - SKEIN_8_ROUNDS(3,4); - SKEIN_8_ROUNDS(5,6); - SKEIN_8_ROUNDS(7,8); - SKEIN_8_ROUNDS(9,10); - SKEIN_8_ROUNDS(11,12); - SKEIN_8_ROUNDS(13,14); - SKEIN_8_ROUNDS(15,16); - SKEIN_8_ROUNDS(17,18); + THREEFISH_8_ROUNDS(1,2); + THREEFISH_8_ROUNDS(3,4); + THREEFISH_8_ROUNDS(5,6); + THREEFISH_8_ROUNDS(7,8); + THREEFISH_8_ROUNDS(9,10); + THREEFISH_8_ROUNDS(11,12); + THREEFISH_8_ROUNDS(13,14); + THREEFISH_8_ROUNDS(15,16); + THREEFISH_8_ROUNDS(17,18); // message feed forward H[0] = X0 ^ M[0]; @@ -130,7 +118,7 @@ void ubi_512(u64bit H[9], u64bit T[], const byte msg[], u64bit msg_len) msg_len -= to_proc; msg += to_proc; - } + } while(msg_len); } void reset_tweak(u64bit T[3], type_code type, bool final) @@ -139,7 +127,8 @@ void reset_tweak(u64bit T[3], type_code type, bool final) T[1] = ((u64bit)type << 56) | ((u64bit)1 << 62) | ((u64bit)final << 63); } -void initial_block(u64bit H[9], u64bit T[3], u32bit output_bits) +void initial_block(u64bit H[9], u64bit T[3], u32bit output_bits, + const std::string& personalization) { clear_mem(H, 9); @@ -149,32 +138,33 @@ void initial_block(u64bit H[9], u64bit T[3], u32bit output_bits) reset_tweak(T, SKEIN_CONFIG, true); ubi_512(H, T, config_str, sizeof(config_str)); -#if 0 if(personalization != "") { - const byte* bits = reinterpret_cast<const byte*>(personalization.data()); + if(personalization.length() > 64) + throw Invalid_Argument("Skein personalization must be <= 64 bytes"); - // FIXME: will be wrong if personalization > 64 bytes b/c final - // bit is set for all blocks + const byte* bits = reinterpret_cast<const byte*>(personalization.data()); reset_tweak(T, SKEIN_PERSONALIZATION, true); ubi_512(H, T, bits, personalization.length()); } -#endif reset_tweak(T, SKEIN_MSG, false); } } -Skein_512::Skein_512(u32bit arg_output_bits) : +Skein_512::Skein_512(u32bit arg_output_bits, + const std::string& arg_personalization) : HashFunction(arg_output_bits / 8, 64), - output_bits(arg_output_bits), buf_pos(0) + personalization(arg_personalization), + output_bits(arg_output_bits) { if(output_bits == 0 || output_bits % 8 != 0) - throw std::invalid_argument("Bad output bits size for Skein-512"); + throw Invalid_Argument("Bad output bits size for Skein-512"); - initial_block(H, T, output_bits); + buf_pos = 0; + initial_block(H, T, output_bits, personalization); } std::string Skein_512::name() const @@ -182,6 +172,11 @@ std::string Skein_512::name() const return "Skein-512(" + to_string(output_bits) + ")"; } +HashFunction* Skein_512::clone() const + { + return new Skein_512(output_bits, personalization); + } + void Skein_512::clear() throw() { H.clear(); @@ -252,7 +247,7 @@ void Skein_512::final_result(byte out[]) } buf_pos = 0; - initial_block(H, T, output_bits); + initial_block(H, T, output_bits, personalization); } } diff --git a/src/hash/skein/skein_512.h b/src/hash/skein/skein_512.h index a585ff47f..2192767ca 100644 --- a/src/hash/skein/skein_512.h +++ b/src/hash/skein/skein_512.h @@ -17,17 +17,17 @@ namespace Botan { class Skein_512 : public HashFunction { public: - Skein_512(u32bit output_bits = 512); - - HashFunction* clone() const { return new Skein_512(output_bits); } + Skein_512(u32bit output_bits = 512, + const std::string& personalization = ""); + HashFunction* clone() const; std::string name() const; - void clear() throw(); private: void add_data(const byte input[], u32bit length); void final_result(byte out[]); + std::string personalization; u32bit output_bits; SecureBuffer<u64bit, 9> H; SecureBuffer<u64bit, 3> T; |