From 851f567904d2e6ef236fede79b02d638c71e4e2f Mon Sep 17 00:00:00 2001 From: weidai Date: Sun, 15 Apr 2007 22:54:31 +0000 Subject: SSE2 optimizations git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@282 57ff6487-cd31-0410-9ec3-f628ee90f5f0 --- strciphr.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 16 deletions(-) (limited to 'strciphr.cpp') diff --git a/strciphr.cpp b/strciphr.cpp index b25017e..6294785 100644 --- a/strciphr.cpp +++ b/strciphr.cpp @@ -37,6 +37,57 @@ byte AdditiveCipherTemplate::GenerateByte() return *(KeystreamBufferEnd()-m_leftOver--); } +template +void AdditiveCipherTemplate::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 void AdditiveCipherTemplate::ProcessData(byte *outString, const byte *inString, size_t length) { @@ -48,29 +99,26 @@ void AdditiveCipherTemplate::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; -- cgit v1.2.1