From a2f7dfe3afb5c056fdbb2a7e3f2e20753771fa95 Mon Sep 17 00:00:00 2001 From: weidai Date: Sun, 6 Oct 2002 03:58:13 +0000 Subject: bug fix and optimization git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@8 57ff6487-cd31-0410-9ec3-f628ee90f5f0 --- modes.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 8 deletions(-) (limited to 'modes.cpp') diff --git a/modes.cpp b/modes.cpp index 0222260..1b5f853 100644 --- a/modes.cpp +++ b/modes.cpp @@ -72,20 +72,57 @@ void CTR_ModePolicy::SeekToIteration(dword iterationCount) } } +static inline void IncrementCounterByOne(byte *inout, unsigned int s) +{ + for (int i=s-1, carry=1; i>=0 && carry; i--) + carry = !++inout[i]; +} + +static inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s) +{ + for (int i=s-1, carry=1; i>=0; i--) + carry = !(output[i] = input[i]+carry) && carry; +} + +inline void CTR_ModePolicy::ProcessMultipleBlocks(byte *output, const byte *input, unsigned int n) +{ + unsigned int s = BlockSize(), j = 0; + for (unsigned int i=1; iProcessAndXorMultipleBlocks(m_counterArray, input, output, n); + IncrementCounterByOne(m_counterArray, m_counterArray + s*(n-1), s); +} + void CTR_ModePolicy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount) { unsigned int maxBlocks = m_cipher->OptimalNumberOfParallelBlocks(); - unsigned int sizeIncrement = maxBlocks * m_cipher->BlockSize(); - while (iterationCount >= maxBlocks) + if (maxBlocks == 1) { - ProcessMultipleBlocks(output, input, maxBlocks); - output += sizeIncrement; - input += sizeIncrement; - iterationCount -= maxBlocks; + unsigned int sizeIncrement = BlockSize(); + while (iterationCount) + { + m_cipher->ProcessAndXorBlock(m_counterArray, input, output); + IncrementCounterByOne(m_counterArray, sizeIncrement); + output += sizeIncrement; + input += sizeIncrement; + iterationCount -= 1; + } + } + else + { + unsigned int sizeIncrement = maxBlocks * BlockSize(); + while (iterationCount >= maxBlocks) + { + ProcessMultipleBlocks(output, input, maxBlocks); + output += sizeIncrement; + input += sizeIncrement; + iterationCount -= maxBlocks; + } + if (iterationCount > 0) + ProcessMultipleBlocks(output, input, iterationCount); } - if (iterationCount > 0) - ProcessMultipleBlocks(output, input, iterationCount); } + void CTR_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv) { unsigned int s = BlockSize(); -- cgit v1.2.1