summaryrefslogtreecommitdiff
path: root/modes.cpp
diff options
context:
space:
mode:
authorweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2002-10-06 03:58:13 +0000
committerweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2002-10-06 03:58:13 +0000
commita2f7dfe3afb5c056fdbb2a7e3f2e20753771fa95 (patch)
tree0c0531b9afb27bb170a0ec1f6ec4d56e35368e90 /modes.cpp
parent54aac9c52276331c818cebd420354c5e281d363a (diff)
downloadcryptopp-a2f7dfe3afb5c056fdbb2a7e3f2e20753771fa95.tar.gz
bug fix and optimization
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@8 57ff6487-cd31-0410-9ec3-f628ee90f5f0
Diffstat (limited to 'modes.cpp')
-rw-r--r--modes.cpp53
1 files changed, 45 insertions, 8 deletions
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; i<n; i++, j+=s)
+ IncrementCounterByOne(m_counterArray + j + s, m_counterArray + j, s);
+ m_cipher->ProcessAndXorMultipleBlocks(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();