aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/block/serpent
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/block/serpent')
-rw-r--r--src/lib/block/serpent/serpent.cpp30
-rw-r--r--src/lib/block/serpent/serpent.h20
2 files changed, 48 insertions, 2 deletions
diff --git a/src/lib/block/serpent/serpent.cpp b/src/lib/block/serpent/serpent.cpp
index c35e3e338..1e3699914 100644
--- a/src/lib/block/serpent/serpent.cpp
+++ b/src/lib/block/serpent/serpent.cpp
@@ -9,6 +9,10 @@
#include <botan/loadstor.h>
#include <botan/internal/serpent_sbox.h>
+#if defined(BOTAN_HAS_SERPENT_SIMD)
+ #include <botan/cpuid.h>
+#endif
+
namespace Botan {
namespace {
@@ -53,6 +57,19 @@ inline void i_transform(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
*/
void Serpent::encrypt_n(const byte in[], byte out[], size_t blocks) const
{
+#if defined(BOTAN_HAS_SERPENT_SIMD)
+ if(CPUID::has_simd_32())
+ {
+ while(blocks >= 4)
+ {
+ simd_encrypt_4(in, out);
+ in += 4 * BLOCK_SIZE;
+ out += 4 * BLOCK_SIZE;
+ blocks -= 4;
+ }
+ }
+#endif
+
for(size_t i = 0; i != blocks; ++i)
{
u32bit B0 = load_le<u32bit>(in, 0);
@@ -105,6 +122,19 @@ void Serpent::encrypt_n(const byte in[], byte out[], size_t blocks) const
*/
void Serpent::decrypt_n(const byte in[], byte out[], size_t blocks) const
{
+#if defined(BOTAN_HAS_SERPENT_SIMD)
+ if(CPUID::has_simd_32())
+ {
+ while(blocks >= 4)
+ {
+ simd_decrypt_4(in, out);
+ in += 4 * BLOCK_SIZE;
+ out += 4 * BLOCK_SIZE;
+ blocks -= 4;
+ }
+ }
+#endif
+
for(size_t i = 0; i != blocks; ++i)
{
u32bit B0 = load_le<u32bit>(in, 0);
diff --git a/src/lib/block/serpent/serpent.h b/src/lib/block/serpent/serpent.h
index b9864cf89..8f854678a 100644
--- a/src/lib/block/serpent/serpent.h
+++ b/src/lib/block/serpent/serpent.h
@@ -13,9 +13,10 @@
namespace Botan {
/**
-* Serpent, an AES finalist
+* Serpent is the most conservative of the AES finalists
+* http://www.cl.cam.ac.uk/~rja14/serpent.html
*/
-class BOTAN_DLL Serpent : public Block_Cipher_Fixed_Params<16, 16, 32, 8>
+class BOTAN_DLL Serpent final : public Block_Cipher_Fixed_Params<16, 16, 32, 8>
{
public:
void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
@@ -24,7 +25,22 @@ class BOTAN_DLL Serpent : public Block_Cipher_Fixed_Params<16, 16, 32, 8>
void clear() override;
std::string name() const override { return "Serpent"; }
BlockCipher* clone() const override { return new Serpent; }
+
+ size_t parallelism() const override { return 4; }
+
protected:
+#if defined(BOTAN_HAS_SERPENT_SIMD)
+ /**
+ * Encrypt 4 blocks in parallel using SSE2 or AltiVec
+ */
+ void simd_encrypt_4(const byte in[64], byte out[64]) const;
+
+ /**
+ * Decrypt 4 blocks in parallel using SSE2 or AltiVec
+ */
+ void simd_decrypt_4(const byte in[64], byte out[64]) const;
+#endif
+
/**
* For use by subclasses using SIMD, asm, etc
* @return const reference to the key schedule