summaryrefslogtreecommitdiff
path: root/strciphr.cpp
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.cpp
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.cpp')
-rw-r--r--strciphr.cpp80
1 files changed, 64 insertions, 16 deletions
diff --git a/strciphr.cpp b/strciphr.cpp
index b25017e..6294785 100644
--- a/strciphr.cpp
+++ b/strciphr.cpp
@@ -38,6 +38,57 @@ byte AdditiveCipherTemplate<S>::GenerateByte()
}
template <class S>
+void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length)
+{
+ if (m_leftOver > 0)
+ {
+ size_t len = STDMIN(m_leftOver, length);
+ memcpy(outString, KeystreamBufferEnd()-m_leftOver, len);
+ length -= len;
+ m_leftOver -= len;
+ outString += len;
+
+ if (!length)
+ return;
+ }
+ assert(m_leftOver == 0);
+
+ PolicyInterface &policy = this->AccessPolicy();
+ unsigned int bytesPerIteration = policy.GetBytesPerIteration();
+
+ if (length >= bytesPerIteration)
+ {
+ size_t iterations = length / bytesPerIteration;
+
+ policy.WriteKeystream(outString, iterations);
+
+ outString += iterations * bytesPerIteration;
+ length -= iterations * bytesPerIteration;
+
+ if (!length)
+ return;
+ }
+
+ unsigned int bufferByteSize = GetBufferByteSize(policy);
+ unsigned int bufferIterations = policy.GetIterationsToBuffer();
+
+ while (length >= bufferByteSize)
+ {
+ policy.WriteKeystream(m_buffer, bufferIterations);
+ memcpy(outString, KeystreamBufferBegin(), bufferByteSize);
+ length -= bufferByteSize;
+ outString += bufferByteSize;
+ }
+
+ if (length > 0)
+ {
+ policy.WriteKeystream(m_buffer, bufferIterations);
+ memcpy(outString, KeystreamBufferBegin(), length);
+ m_leftOver = bytesPerIteration - length;
+ }
+}
+
+template <class S>
void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, size_t length)
{
if (m_leftOver > 0)
@@ -48,29 +99,26 @@ void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inStrin
m_leftOver -= len;
inString += len;
outString += len;
- }
-
- if (!length)
- return;
+ if (!length)
+ return;
+ }
assert(m_leftOver == 0);
PolicyInterface &policy = this->AccessPolicy();
unsigned int bytesPerIteration = policy.GetBytesPerIteration();
- unsigned int alignment = policy.GetAlignment();
- if (policy.CanOperateKeystream() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
+ if (policy.CanOperateKeystream() && length >= bytesPerIteration)
{
- if (IsAlignedOn(inString, alignment))
- policy.OperateKeystream(XOR_KEYSTREAM, outString, inString, length / bytesPerIteration);
- else
- {
- memcpy(outString, inString, length);
- policy.OperateKeystream(XOR_KEYSTREAM_INPLACE, outString, outString, length / bytesPerIteration);
- }
- inString += length - length % bytesPerIteration;
- outString += length - length % bytesPerIteration;
- length %= bytesPerIteration;
+ size_t iterations = length / bytesPerIteration;
+ unsigned int alignment = policy.GetAlignment();
+ KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment));
+
+ policy.OperateKeystream(operation, outString, inString, iterations);
+
+ inString += iterations * bytesPerIteration;
+ outString += iterations * bytesPerIteration;
+ length -= iterations * bytesPerIteration;
if (!length)
return;