summaryrefslogtreecommitdiff
path: root/strciphr.h
diff options
context:
space:
mode:
authorweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2007-04-15 22:54:31 +0000
committerweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2007-04-15 22:54:31 +0000
commit851f567904d2e6ef236fede79b02d638c71e4e2f (patch)
treed7c8c74edd548369be89d8f6e88d055995ecd95a /strciphr.h
parent6da041704487c4c8d90b3caa5112ff1ecbb62fb2 (diff)
downloadcryptopp-851f567904d2e6ef236fede79b02d638c71e4e2f.tar.gz
SSE2 optimizations
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@282 57ff6487-cd31-0410-9ec3-f628ee90f5f0
Diffstat (limited to 'strciphr.h')
-rw-r--r--strciphr.h96
1 files changed, 54 insertions, 42 deletions
diff --git a/strciphr.h b/strciphr.h
index d46f9eb..e9bcf2e 100644
--- a/strciphr.h
+++ b/strciphr.h
@@ -53,14 +53,23 @@ protected:
POLICY_INTERFACE & AccessPolicy() {return *this;}
};
-enum KeystreamOperation {WRITE_KEYSTREAM, XOR_KEYSTREAM, XOR_KEYSTREAM_INPLACE};
+enum KeystreamOperationFlags {OUTPUT_ALIGNED=1, INPUT_ALIGNED=2, INPUT_NULL = 4};
+enum KeystreamOperation {
+ WRITE_KEYSTREAM = INPUT_NULL,
+ WRITE_KEYSTREAM_ALIGNED = INPUT_NULL | OUTPUT_ALIGNED,
+ XOR_KEYSTREAM = 0,
+ XOR_KEYSTREAM_INPUT_ALIGNED = INPUT_ALIGNED,
+ XOR_KEYSTREAM_OUTPUT_ALIGNED= OUTPUT_ALIGNED,
+ XOR_KEYSTREAM_BOTH_ALIGNED = OUTPUT_ALIGNED | INPUT_ALIGNED};
struct CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AdditiveCipherAbstractPolicy
{
- virtual unsigned int GetAlignment() const =0;
+ virtual unsigned int GetAlignment() const {return 1;}
virtual unsigned int GetBytesPerIteration() const =0;
+ virtual unsigned int GetOptimalBlockSize() const {return GetBytesPerIteration();}
virtual unsigned int GetIterationsToBuffer() const =0;
- virtual void WriteKeystream(byte *keystreamBuffer, size_t iterationCount) =0;
+ virtual void WriteKeystream(byte *keystream, size_t iterationCount)
+ {OperateKeystream(KeystreamOperation(INPUT_NULL | (KeystreamOperationFlags)IsAlignedOn(keystream, GetAlignment())), keystream, NULL, iterationCount);}
virtual bool CanOperateKeystream() const {return false;}
virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) {assert(false);}
virtual void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length) =0;
@@ -74,59 +83,62 @@ template <typename WT, unsigned int W, unsigned int X = 1, class BASE = Additive
struct CRYPTOPP_NO_VTABLE AdditiveCipherConcretePolicy : public BASE
{
typedef WT WordType;
+ CRYPTOPP_CONSTANT(BYTES_PER_ITERATION = sizeof(WordType) * W);
- unsigned int GetAlignment() const {return sizeof(WordType);}
- unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;}
+#if !(CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64)
+ unsigned int GetAlignment() const {return GetAlignmentOf<WordType>();}
+#endif
+ unsigned int GetBytesPerIteration() const {return BYTES_PER_ITERATION;}
unsigned int GetIterationsToBuffer() const {return X;}
- void WriteKeystream(byte *buffer, size_t iterationCount)
- {OperateKeystream(WRITE_KEYSTREAM, buffer, NULL, iterationCount);}
bool CanOperateKeystream() const {return true;}
virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) =0;
-
- template <class B>
- struct KeystreamOutput
- {
- KeystreamOutput(KeystreamOperation operation, byte *output, const byte *input)
- : m_operation(operation), m_output(output), m_input(input) {}
-
- inline KeystreamOutput & operator()(WordType keystreamWord)
- {
- assert(IsAligned<WordType>(m_input));
- assert(IsAligned<WordType>(m_output));
-
- if (!NativeByteOrderIs(B::ToEnum()))
- keystreamWord = ByteReverse(keystreamWord);
-
- if (m_operation == WRITE_KEYSTREAM)
- *(WordType*)m_output = keystreamWord;
- else if (m_operation == XOR_KEYSTREAM)
- {
- *(WordType*)m_output = keystreamWord ^ *(WordType*)m_input;
- m_input += sizeof(WordType);
- }
- else if (m_operation == XOR_KEYSTREAM_INPLACE)
- *(WordType*)m_output ^= keystreamWord;
-
- m_output += sizeof(WordType);
-
- return *this;
- }
-
- KeystreamOperation m_operation;
- byte *m_output;
- const byte *m_input;
- };
};
+// use these to implement OperateKeystream
+#define CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, b, i, a) \
+ PutWord(bool(x & OUTPUT_ALIGNED), b, output+i*sizeof(WordType), (x & INPUT_NULL) ? a : a ^ GetWord<WordType>(bool(x & INPUT_ALIGNED), b, input+i*sizeof(WordType)));
+#define CRYPTOPP_KEYSTREAM_OUTPUT_XMM(x, i, a) {\
+ __m128i t = (x & INPUT_NULL) ? a : _mm_xor_si128(a, (x & INPUT_ALIGNED) ? _mm_load_si128((__m128i *)input+i) : _mm_loadu_si128((__m128i *)input+i));\
+ if (x & OUTPUT_ALIGNED) _mm_store_si128((__m128i *)output+i, t);\
+ else _mm_storeu_si128((__m128i *)output+i, t);}
+#define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y) \
+ switch (operation) \
+ { \
+ case WRITE_KEYSTREAM: \
+ x(WRITE_KEYSTREAM) \
+ break; \
+ case XOR_KEYSTREAM: \
+ x(XOR_KEYSTREAM) \
+ input += y; \
+ break; \
+ case XOR_KEYSTREAM_INPUT_ALIGNED: \
+ x(XOR_KEYSTREAM_INPUT_ALIGNED) \
+ input += y; \
+ break; \
+ case XOR_KEYSTREAM_OUTPUT_ALIGNED: \
+ x(XOR_KEYSTREAM_OUTPUT_ALIGNED) \
+ input += y; \
+ break; \
+ case WRITE_KEYSTREAM_ALIGNED: \
+ x(WRITE_KEYSTREAM_ALIGNED) \
+ break; \
+ case XOR_KEYSTREAM_BOTH_ALIGNED: \
+ x(XOR_KEYSTREAM_BOTH_ALIGNED) \
+ input += y; \
+ break; \
+ } \
+ output += y;
+
template <class BASE = AbstractPolicyHolder<AdditiveCipherAbstractPolicy, TwoBases<SymmetricCipher, RandomNumberGenerator> > >
class CRYPTOPP_NO_VTABLE AdditiveCipherTemplate : public BASE
{
public:
byte GenerateByte();
+ void GenerateBlock(byte *output, size_t size);
void ProcessData(byte *outString, const byte *inString, size_t length);
void GetNextIV(byte *iv) {this->AccessPolicy().CipherGetNextIV(iv);}
void Resynchronize(const byte *iv);
- unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();}
+ unsigned int OptimalBlockSize() const {return this->GetPolicy().GetOptimalBlockSize();}
unsigned int GetOptimalNextBlockSize() const {return (unsigned int)this->m_leftOver;}
unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
bool IsSelfInverting() const {return true;}