aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2009-08-11 19:34:50 +0000
committerlloyd <[email protected]>2009-08-11 19:34:50 +0000
commitc8c3d7f6eecd753aa87a882b1458346682e606db (patch)
treecf902ddbe1b884fb1b7e91cd7cacf646fc5c66fc /src
parent13d50de7b7675d798437c0d465acedd23e08b092 (diff)
Make encrypt_n public for all BlockCipher implementations - unlike the
enc/dec functions it replaces, these are public interfaces. Add the first bits of a SSE2 implementation of Serpent. Currently incomplete.
Diffstat (limited to 'src')
-rw-r--r--src/block/aes/aes.h6
-rw-r--r--src/block/blowfish/blowfish.h6
-rw-r--r--src/block/cast/cast128.h6
-rw-r--r--src/block/cast/cast256.h6
-rw-r--r--src/block/des/des.h12
-rw-r--r--src/block/des/desx.h6
-rw-r--r--src/block/gost_28147/gost_28147.h5
-rw-r--r--src/block/idea/idea.h6
-rw-r--r--src/block/kasumi/kasumi.h5
-rw-r--r--src/block/lion/lion.h5
-rw-r--r--src/block/lubyrack/lubyrack.h6
-rw-r--r--src/block/mars/mars.h6
-rw-r--r--src/block/misty1/misty1.h6
-rw-r--r--src/block/noekeon/noekeon.h6
-rw-r--r--src/block/rc2/rc2.h6
-rw-r--r--src/block/rc5/rc5.h6
-rw-r--r--src/block/rc6/rc6.h6
-rw-r--r--src/block/safer/safer_sk.h7
-rw-r--r--src/block/seed/seed.h6
-rw-r--r--src/block/serpent/serpent.h5
-rw-r--r--src/block/serpent_ia32/serp_ia32.h5
-rw-r--r--src/block/serpent_sse2/info.txt27
-rw-r--r--src/block/serpent_sse2/serp_sse2.cpp170
-rw-r--r--src/block/serpent_sse2/serp_sse2.h29
-rw-r--r--src/block/skipjack/skipjack.h7
-rw-r--r--src/block/square/square.h6
-rw-r--r--src/block/tea/tea.h6
-rw-r--r--src/block/twofish/twofish.h6
-rw-r--r--src/block/xtea/xtea.h6
-rw-r--r--src/engine/sse2_eng/eng_sse2.cpp23
-rw-r--r--src/engine/sse2_eng/eng_sse2.h5
31 files changed, 355 insertions, 58 deletions
diff --git a/src/block/aes/aes.h b/src/block/aes/aes.h
index 940e11a48..768bb09e7 100644
--- a/src/block/aes/aes.h
+++ b/src/block/aes/aes.h
@@ -18,14 +18,16 @@ namespace Botan {
class BOTAN_DLL AES : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const { return "AES"; }
BlockCipher* clone() const { return new AES; }
+
AES() : BlockCipher(16, 16, 32, 8) { ROUNDS = 14; }
AES(u32bit);
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
static u32bit S(u32bit);
diff --git a/src/block/blowfish/blowfish.h b/src/block/blowfish/blowfish.h
index 3623c2087..345c1ce49 100644
--- a/src/block/blowfish/blowfish.h
+++ b/src/block/blowfish/blowfish.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL Blowfish : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const { return "Blowfish"; }
BlockCipher* clone() const { return new Blowfish; }
+
Blowfish() : BlockCipher(8, 1, 56) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
void generate_sbox(u32bit[], u32bit, u32bit&, u32bit&) const;
diff --git a/src/block/cast/cast128.h b/src/block/cast/cast128.h
index 092ee824b..864a4e47e 100644
--- a/src/block/cast/cast128.h
+++ b/src/block/cast/cast128.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL CAST_128 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { MK.clear(); RK.clear(); }
std::string name() const { return "CAST-128"; }
BlockCipher* clone() const { return new CAST_128; }
+
CAST_128() : BlockCipher(8, 11, 16) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
static void key_schedule(u32bit[16], u32bit[4]);
diff --git a/src/block/cast/cast256.h b/src/block/cast/cast256.h
index ea80df65d..1be7fa9cf 100644
--- a/src/block/cast/cast256.h
+++ b/src/block/cast/cast256.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL CAST_256 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { MK.clear(); RK.clear(); }
std::string name() const { return "CAST-256"; }
BlockCipher* clone() const { return new CAST_256; }
+
CAST_256() : BlockCipher(16, 4, 32, 4) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
static const u32bit KEY_MASK[192];
diff --git a/src/block/des/des.h b/src/block/des/des.h
index 39d1ac404..856aaf60c 100644
--- a/src/block/des/des.h
+++ b/src/block/des/des.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL DES : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { round_key.clear(); }
std::string name() const { return "DES"; }
BlockCipher* clone() const { return new DES; }
+
DES() : BlockCipher(8, 8) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 32> round_key;
@@ -36,13 +38,15 @@ class BOTAN_DLL DES : public BlockCipher
class BOTAN_DLL TripleDES : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { round_key.clear(); }
std::string name() const { return "TripleDES"; }
BlockCipher* clone() const { return new TripleDES; }
+
TripleDES() : BlockCipher(8, 16, 24, 8) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 96> round_key;
diff --git a/src/block/des/desx.h b/src/block/des/desx.h
index d71335071..d22895296 100644
--- a/src/block/des/desx.h
+++ b/src/block/des/desx.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL DESX : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { des.clear(); K1.clear(); K2.clear(); }
std::string name() const { return "DESX"; }
BlockCipher* clone() const { return new DESX; }
+
DESX() : BlockCipher(8, 24) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<byte, 8> K1, K2;
DES des;
diff --git a/src/block/gost_28147/gost_28147.h b/src/block/gost_28147/gost_28147.h
index 825e106a2..18c1d0a29 100644
--- a/src/block/gost_28147/gost_28147.h
+++ b/src/block/gost_28147/gost_28147.h
@@ -44,6 +44,9 @@ class GOST_28147_89_Params
class BOTAN_DLL GOST_28147_89 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { EK.clear(); }
std::string name() const { return "GOST-28147-89"; }
@@ -54,8 +57,6 @@ class BOTAN_DLL GOST_28147_89 : public BlockCipher
GOST_28147_89(const SecureBuffer<u32bit, 1024>& other_SBOX) :
BlockCipher(8, 32), SBOX(other_SBOX) {}
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 1024> SBOX;
diff --git a/src/block/idea/idea.h b/src/block/idea/idea.h
index a3384b667..59484531b 100644
--- a/src/block/idea/idea.h
+++ b/src/block/idea/idea.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL IDEA : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { EK.clear(); DK.clear(); }
std::string name() const { return "IDEA"; }
BlockCipher* clone() const { return new IDEA; }
+
IDEA() : BlockCipher(8, 16) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u16bit, 52> EK, DK;
};
diff --git a/src/block/kasumi/kasumi.h b/src/block/kasumi/kasumi.h
index 3b18e675b..0f5a5d182 100644
--- a/src/block/kasumi/kasumi.h
+++ b/src/block/kasumi/kasumi.h
@@ -18,14 +18,15 @@ namespace Botan {
class BOTAN_DLL KASUMI : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { EK.clear(); }
std::string name() const { return "KASUMI"; }
BlockCipher* clone() const { return new KASUMI; }
KASUMI() : BlockCipher(8, 16) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u16bit, 64> EK;
diff --git a/src/block/lion/lion.h b/src/block/lion/lion.h
index d9f933846..d421771d6 100644
--- a/src/block/lion/lion.h
+++ b/src/block/lion/lion.h
@@ -20,6 +20,9 @@ namespace Botan {
class BOTAN_DLL Lion : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const;
BlockCipher* clone() const;
@@ -27,8 +30,6 @@ class BOTAN_DLL Lion : public BlockCipher
Lion(HashFunction*, StreamCipher*, u32bit);
~Lion() { delete hash; delete cipher; }
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
const u32bit LEFT_SIZE, RIGHT_SIZE;
diff --git a/src/block/lubyrack/lubyrack.h b/src/block/lubyrack/lubyrack.h
index 1e83748a6..940b34603 100644
--- a/src/block/lubyrack/lubyrack.h
+++ b/src/block/lubyrack/lubyrack.h
@@ -19,6 +19,9 @@ namespace Botan {
class BOTAN_DLL LubyRackoff : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const;
BlockCipher* clone() const;
@@ -26,9 +29,8 @@ class BOTAN_DLL LubyRackoff : public BlockCipher
LubyRackoff(HashFunction* hash);
~LubyRackoff() { delete hash; }
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
+
HashFunction* hash;
SecureVector<byte> K1, K2;
};
diff --git a/src/block/mars/mars.h b/src/block/mars/mars.h
index b3d74b179..7d0bfe4fa 100644
--- a/src/block/mars/mars.h
+++ b/src/block/mars/mars.h
@@ -15,13 +15,15 @@ namespace Botan {
class BOTAN_DLL MARS : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { EK.clear(); }
std::string name() const { return "MARS"; }
BlockCipher* clone() const { return new MARS; }
+
MARS() : BlockCipher(16, 16, 32, 4) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
void encrypt_round(u32bit&, u32bit&, u32bit&, u32bit&, u32bit) const;
diff --git a/src/block/misty1/misty1.h b/src/block/misty1/misty1.h
index 14b7c8e45..8db6881de 100644
--- a/src/block/misty1/misty1.h
+++ b/src/block/misty1/misty1.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL MISTY1 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { EK.clear(); DK.clear(); }
std::string name() const { return "MISTY1"; }
BlockCipher* clone() const { return new MISTY1; }
+
MISTY1(u32bit = 8);
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u16bit, 100> EK, DK;
diff --git a/src/block/noekeon/noekeon.h b/src/block/noekeon/noekeon.h
index b4f3980d7..37b24fb7d 100644
--- a/src/block/noekeon/noekeon.h
+++ b/src/block/noekeon/noekeon.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL Noekeon : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const { return "Noekeon"; }
BlockCipher* clone() const { return new Noekeon; }
+
Noekeon() : BlockCipher(16, 16) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
static const byte RC[17];
diff --git a/src/block/rc2/rc2.h b/src/block/rc2/rc2.h
index 0d94d69a2..db623b385 100644
--- a/src/block/rc2/rc2.h
+++ b/src/block/rc2/rc2.h
@@ -18,15 +18,17 @@ namespace Botan {
class BOTAN_DLL RC2 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
static byte EKB_code(u32bit);
void clear() throw() { K.clear(); }
std::string name() const { return "RC2"; }
BlockCipher* clone() const { return new RC2; }
+
RC2() : BlockCipher(8, 1, 32) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u16bit, 64> K;
diff --git a/src/block/rc5/rc5.h b/src/block/rc5/rc5.h
index 1816994dc..ff9204710 100644
--- a/src/block/rc5/rc5.h
+++ b/src/block/rc5/rc5.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL RC5 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { S.clear(); }
std::string name() const;
BlockCipher* clone() const { return new RC5(ROUNDS); }
+
RC5(u32bit);
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
SecureVector<u32bit> S;
const u32bit ROUNDS;
diff --git a/src/block/rc6/rc6.h b/src/block/rc6/rc6.h
index f634ebcd9..5171006f5 100644
--- a/src/block/rc6/rc6.h
+++ b/src/block/rc6/rc6.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL RC6 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { S.clear(); }
std::string name() const { return "RC6"; }
BlockCipher* clone() const { return new RC6; }
+
RC6() : BlockCipher(16, 1, 32) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 44> S;
diff --git a/src/block/safer/safer_sk.h b/src/block/safer/safer_sk.h
index ae3d4f9a8..4d17bba51 100644
--- a/src/block/safer/safer_sk.h
+++ b/src/block/safer/safer_sk.h
@@ -18,19 +18,22 @@ namespace Botan {
class BOTAN_DLL SAFER_SK : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { EK.clear(); }
std::string name() const;
BlockCipher* clone() const;
+
SAFER_SK(u32bit);
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
static const byte EXP[256];
static const byte LOG[512];
static const byte BIAS[208];
static const byte KEY_INDEX[208];
+
SecureVector<byte> EK;
const u32bit ROUNDS;
};
diff --git a/src/block/seed/seed.h b/src/block/seed/seed.h
index 0c9c2c8af..5a5a512e7 100644
--- a/src/block/seed/seed.h
+++ b/src/block/seed/seed.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL SEED : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { K.clear(); }
std::string name() const { return "SEED"; }
BlockCipher* clone() const { return new SEED; }
+
SEED() : BlockCipher(16, 16) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
class G_FUNC
diff --git a/src/block/serpent/serpent.h b/src/block/serpent/serpent.h
index 9c9fb59f2..d919c3008 100644
--- a/src/block/serpent/serpent.h
+++ b/src/block/serpent/serpent.h
@@ -18,13 +18,14 @@ namespace Botan {
class BOTAN_DLL Serpent : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { round_key.clear(); }
std::string name() const { return "Serpent"; }
BlockCipher* clone() const { return new Serpent; }
Serpent() : BlockCipher(16, 16, 32, 8) {}
protected:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 132> round_key;
diff --git a/src/block/serpent_ia32/serp_ia32.h b/src/block/serpent_ia32/serp_ia32.h
index 2b4a95d3d..dc6beaf13 100644
--- a/src/block/serpent_ia32/serp_ia32.h
+++ b/src/block/serpent_ia32/serp_ia32.h
@@ -18,10 +18,11 @@ namespace Botan {
class BOTAN_DLL Serpent_IA32 : public Serpent
{
public:
- BlockCipher* clone() const { return new Serpent_IA32; }
- private:
void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ BlockCipher* clone() const { return new Serpent_IA32; }
+ private:
void key_schedule(const byte[], u32bit);
};
diff --git a/src/block/serpent_sse2/info.txt b/src/block/serpent_sse2/info.txt
new file mode 100644
index 000000000..ad8323f53
--- /dev/null
+++ b/src/block/serpent_sse2/info.txt
@@ -0,0 +1,27 @@
+realname "Serpent (SSE2)"
+
+define SERPENT_SSE2
+
+load_on auto
+
+<add>
+serp_sse2.cpp
+serp_sse2.h
+</add>
+
+<arch>
+pentium-m
+pentium4
+prescott
+amd64
+</arch>
+
+<cc>
+gcc
+icc
+</cc>
+
+<requires>
+serpent
+sse2_eng
+</requires>
diff --git a/src/block/serpent_sse2/serp_sse2.cpp b/src/block/serpent_sse2/serp_sse2.cpp
new file mode 100644
index 000000000..759f3e1d6
--- /dev/null
+++ b/src/block/serpent_sse2/serp_sse2.cpp
@@ -0,0 +1,170 @@
+/*
+* Serpent (SSE2)
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/serp_sse2.h>
+#include <botan/loadstor.h>
+#include <emmintrin.h>
+
+namespace Botan {
+
+namespace {
+
+#define SBoxE1(b0, b1, b2, b3, b4) \
+ do { \
+ b3 = _mm_xor_si128(b3, b0); \
+ b4 = b1; \
+ b1 = _mm_and_si128(b1, b3); \
+ b4 = _mm_xor_si128(b4, b2); \
+ b1 = _mm_xor_si128(b1, b0); \
+ b0 = _mm_or_si128(b0, b3); \
+ b0 = _mm_xor_si128(b0, b4); \
+ b4 = _mm_xor_si128(b4, b3); \
+ b3 = _mm_xor_si128(b3, b2); \
+ b2 = _mm_or_si128(b2, b1); \
+ b2 = _mm_xor_si128(b2, b4); \
+ b4 = _mm_andnot_si128(b4, all_ones); \
+ b4 = _mm_or_si128(b4, b1); \
+ b1 = _mm_xor_si128(b1, b3); \
+ b1 = _mm_xor_si128(b1, b4); \
+ b3 = _mm_or_si128(b3, b0); \
+ b1 = _mm_xor_si128(b1, b3); \
+ b4 = _mm_xor_si128(b4, b3); \
+ b3 = b0; b0 = b1; b1 = b4; \
+ } while(0);
+
+#define rotate_left_m128(vec, rot) \
+ _mm_or_si128(_mm_slli_epi32(vec, rot), _mm_srli_epi32(vec, 32-rot))
+
+#define key_xor(round, b0, b1, b2, b3) \
+ do { \
+ __m128i key = _mm_loadu_si128(keys + round); \
+ b0 = _mm_xor_si128(b0, _mm_shuffle_epi32(key, _MM_SHUFFLE(0,0,0,0))); \
+ b1 = _mm_xor_si128(b1, _mm_shuffle_epi32(key, _MM_SHUFFLE(1,1,1,1))); \
+ b2 = _mm_xor_si128(b2, _mm_shuffle_epi32(key, _MM_SHUFFLE(2,2,2,2))); \
+ b3 = _mm_xor_si128(b3, _mm_shuffle_epi32(key, _MM_SHUFFLE(3,3,3,3))); \
+ } while(0);
+
+#define transform(b0, b1, b2, b3) \
+ do \
+ { \
+ b0 = rotate_left_m128(b0, 13); \
+ b2 = rotate_left_m128(b2, 3); \
+ b1 = _mm_xor_si128(b1, _mm_xor_si128(b0, b2)); \
+ b3 = _mm_xor_si128(b3, _mm_xor_si128(b2, _mm_slli_epi32(b0, 3))); \
+ b1 = rotate_left_m128(b1, 1); \
+ b3 = rotate_left_m128(b3, 7); \
+ b0 = _mm_xor_si128(b0, _mm_xor_si128(b1, b3)); \
+ b2 = _mm_xor_si128(b2, _mm_xor_si128(b3, _mm_slli_epi32(b1, 7))); \
+ b0 = rotate_left_m128(b0, 5); \
+ b2 = rotate_left_m128(b2, 22); \
+ } while(0);
+
+void print_simd(const char* name, __m128i vec)
+ {
+ union { __m128i v; int32_t ints[4]; } u = { vec };
+
+ printf("%s: ", name);
+ for(u32bit i = 0; i != 4; ++i)
+ printf("%08X ", u.ints[i]);
+ printf("\n");
+ }
+
+void serpent_encrypt_4(const byte in[64],
+ byte out[64],
+ const u32bit keys_32[132])
+ {
+ const __m128i* keys = (const __m128i*)(keys_32);
+
+ /*
+ FIXME: figure out a fast way to do this with 4 loads with
+ _mm_loadu_si128 plus shuffle/interleave ops
+ */
+ union { __m128i v; u32bit u32[4]; } convert;
+
+ convert.u32[0] = load_le<u32bit>(in, 0);
+ convert.u32[1] = load_le<u32bit>(in, 4);
+ convert.u32[2] = load_le<u32bit>(in, 8);
+ convert.u32[3] = load_le<u32bit>(in, 12);
+
+ __m128i b0 = convert.v;
+
+ convert.u32[0] = load_le<u32bit>(in, 1);
+ convert.u32[1] = load_le<u32bit>(in, 5);
+ convert.u32[2] = load_le<u32bit>(in, 9);
+ convert.u32[3] = load_le<u32bit>(in, 13);
+
+ __m128i b1 = convert.v;
+
+ convert.u32[0] = load_le<u32bit>(in, 2);
+ convert.u32[1] = load_le<u32bit>(in, 6);
+ convert.u32[2] = load_le<u32bit>(in, 10);
+ convert.u32[3] = load_le<u32bit>(in, 14);
+
+ __m128i b2 = convert.v;
+
+ convert.u32[0] = load_le<u32bit>(in, 3);
+ convert.u32[1] = load_le<u32bit>(in, 7);
+ convert.u32[2] = load_le<u32bit>(in, 11);
+ convert.u32[3] = load_le<u32bit>(in, 15);
+
+
+ __m128i b3 = convert.v;
+
+ __m128i b4; // temp
+
+ const __m128i all_ones = _mm_set1_epi8(0xFF);
+
+ key_xor(0, b0, b1, b2, b3);
+ SBoxE1(b0, b1, b2, b3, b4);
+ transform(b0, b1, b2, b3);
+
+ key_xor(b0, b1, b2, b3, 1);
+
+ print_simd("b0", b0);
+ print_simd("b1", b1);
+ print_simd("b2", b2);
+ print_simd("b3", b3);
+ }
+
+}
+
+/*
+* Serpent Encryption
+*/
+void Serpent_SSE2::encrypt_n(const byte in[], byte out[], u32bit blocks) const
+ {
+ while(blocks >= 4)
+ {
+ serpent_encrypt_4(in, out, this->round_key);
+ //Serpent::encrypt_n(in, out, 4);
+ in += 4 * BLOCK_SIZE;
+ out += 4 * BLOCK_SIZE;
+ blocks -= 4;
+ }
+
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ Serpent::encrypt_n(in, out, 1);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
+ }
+
+/*
+* Serpent Decryption
+*/
+void Serpent_SSE2::decrypt_n(const byte in[], byte out[], u32bit blocks) const
+ {
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ Serpent::decrypt_n(in, out, 1);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
+ }
+
+}
diff --git a/src/block/serpent_sse2/serp_sse2.h b/src/block/serpent_sse2/serp_sse2.h
new file mode 100644
index 000000000..f1e5c2028
--- /dev/null
+++ b/src/block/serpent_sse2/serp_sse2.h
@@ -0,0 +1,29 @@
+/*
+* Serpent (SSE2)
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_SERPENT_SSE2_H__
+#define BOTAN_SERPENT_SSE2_H__
+
+#include <botan/serpent.h>
+
+namespace Botan {
+
+/*
+* Serpent
+*/
+class BOTAN_DLL Serpent_SSE2 : public Serpent
+ {
+ public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ BlockCipher* clone() const { return new Serpent_SSE2; }
+ };
+
+}
+
+#endif
diff --git a/src/block/skipjack/skipjack.h b/src/block/skipjack/skipjack.h
index ec071dfe7..f12032f36 100644
--- a/src/block/skipjack/skipjack.h
+++ b/src/block/skipjack/skipjack.h
@@ -18,18 +18,21 @@ namespace Botan {
class BOTAN_DLL Skipjack : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const { return "Skipjack"; }
BlockCipher* clone() const { return new Skipjack; }
+
Skipjack() : BlockCipher(8, 10) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
void step_A(u16bit&, u16bit&, u32bit) const;
void step_B(u16bit&, u16bit&, u32bit) const;
void step_Ai(u16bit&, u16bit&, u32bit) const;
void step_Bi(u16bit&, u16bit&, u32bit) const;
+
SecureBuffer<byte, 256> FTABLE[10];
};
diff --git a/src/block/square/square.h b/src/block/square/square.h
index 0de4c20bd..5d9cfc78c 100644
--- a/src/block/square/square.h
+++ b/src/block/square/square.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL Square : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const { return "Square"; }
BlockCipher* clone() const { return new Square; }
+
Square() : BlockCipher(16, 16) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
static void transform(u32bit[4]);
diff --git a/src/block/tea/tea.h b/src/block/tea/tea.h
index 141899e88..825a051aa 100644
--- a/src/block/tea/tea.h
+++ b/src/block/tea/tea.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL TEA : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { K.clear(); }
std::string name() const { return "TEA"; }
BlockCipher* clone() const { return new TEA; }
+
TEA() : BlockCipher(8, 16) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 4> K;
};
diff --git a/src/block/twofish/twofish.h b/src/block/twofish/twofish.h
index 640fb58ad..87b9aa626 100644
--- a/src/block/twofish/twofish.h
+++ b/src/block/twofish/twofish.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL Twofish : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const { return "Twofish"; }
BlockCipher* clone() const { return new Twofish; }
+
Twofish() : BlockCipher(16, 16, 32, 8) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
static void rs_mul(byte[4], byte, u32bit);
diff --git a/src/block/xtea/xtea.h b/src/block/xtea/xtea.h
index b50f487b4..de265818d 100644
--- a/src/block/xtea/xtea.h
+++ b/src/block/xtea/xtea.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL XTEA : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { EK.clear(); }
std::string name() const { return "XTEA"; }
BlockCipher* clone() const { return new XTEA; }
+
XTEA() : BlockCipher(8, 16) {}
private:
- void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
- void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 64> EK;
};
diff --git a/src/engine/sse2_eng/eng_sse2.cpp b/src/engine/sse2_eng/eng_sse2.cpp
index c738b3d96..9f68a070e 100644
--- a/src/engine/sse2_eng/eng_sse2.cpp
+++ b/src/engine/sse2_eng/eng_sse2.cpp
@@ -1,6 +1,6 @@
/**
* SSE2 Assembly Engine
-* (C) 1999-2008 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -11,10 +11,27 @@
#include <botan/sha1_sse2.h>
#endif
+#if defined(BOTAN_HAS_SERPENT_SSE2)
+ #include <botan/serp_sse2.h>
+#endif
+
namespace Botan {
-HashFunction* SSE2_Assembler_Engine::find_hash(const SCAN_Name& request,
- Algorithm_Factory&) const
+BlockCipher*
+SSE2_Assembler_Engine::find_block_cipher(const SCAN_Name& request,
+ Algorithm_Factory&) const
+ {
+#if defined(BOTAN_HAS_SERPENT_SSE2)
+ if(request.algo_name() == "Serpent")
+ return new Serpent_SSE2;
+#endif
+
+ return 0;
+ }
+
+HashFunction*
+SSE2_Assembler_Engine::find_hash(const SCAN_Name& request,
+ Algorithm_Factory&) const
{
#if defined(BOTAN_HAS_SHA1_SSE2)
if(request.algo_name() == "SHA-160")
diff --git a/src/engine/sse2_eng/eng_sse2.h b/src/engine/sse2_eng/eng_sse2.h
index 129697e8f..c6b0ce889 100644
--- a/src/engine/sse2_eng/eng_sse2.h
+++ b/src/engine/sse2_eng/eng_sse2.h
@@ -1,6 +1,6 @@
/**
* SSE2 Assembly Engine
-* (C) 1999-2008 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -17,6 +17,9 @@ class BOTAN_DLL SSE2_Assembler_Engine : public Engine
public:
std::string provider_name() const { return "sse2"; }
private:
+ BlockCipher* find_block_cipher(const SCAN_Name&,
+ Algorithm_Factory&) const;
+
HashFunction* find_hash(const SCAN_Name& reqeust,
Algorithm_Factory&) const;
};