aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2009-06-03 12:49:48 +0000
committerlloyd <[email protected]>2009-06-03 12:49:48 +0000
commita96eae0b3394b64aea544f9f0ce4664d3b4a5c58 (patch)
tree5ae8d4cc57021cef52d29586852f7f0287e92f0c
parentab6eace5760deeff742d515e7d72389cdd2d974b (diff)
Small cleanups in the Skein-512 source, and add support for the
personalization option.
-rw-r--r--src/engine/def_engine/lookup_hash.cpp3
-rw-r--r--src/hash/skein/skein_512.cpp127
-rw-r--r--src/hash/skein/skein_512.h8
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;