diff options
Diffstat (limited to 'src/lib/block/serpent')
-rw-r--r-- | src/lib/block/serpent/serpent.cpp | 30 | ||||
-rw-r--r-- | src/lib/block/serpent/serpent.h | 20 |
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 |