summaryrefslogtreecommitdiff
path: root/strciphr.cpp
diff options
context:
space:
mode:
authorweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2002-10-04 17:31:41 +0000
committerweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2002-10-04 17:31:41 +0000
commitb21162cf8e06f40baa1f58be6a8c17435cebc34d (patch)
tree8b045309c238226c32a563b1df6b9c30a2f0e0b3 /strciphr.cpp
downloadcryptopp-b21162cf8e06f40baa1f58be6a8c17435cebc34d.tar.gz
Initial revision
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@2 57ff6487-cd31-0410-9ec3-f628ee90f5f0
Diffstat (limited to 'strciphr.cpp')
-rw-r--r--strciphr.cpp188
1 files changed, 188 insertions, 0 deletions
diff --git a/strciphr.cpp b/strciphr.cpp
new file mode 100644
index 0000000..694d158
--- /dev/null
+++ b/strciphr.cpp
@@ -0,0 +1,188 @@
+// strciphr.cpp - written and placed in the public domain by Wei Dai
+
+#include "pch.h"
+#include "strciphr.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+template <class S>
+byte AdditiveCipherTemplate<S>::GenerateByte()
+{
+ PolicyInterface &policy = AccessPolicy();
+
+ if (m_leftOver == 0)
+ {
+ policy.WriteKeystream(m_buffer, policy.GetIterationsToBuffer());
+ m_leftOver = policy.GetBytesPerIteration();
+ }
+
+ return KeystreamBufferEnd()[-m_leftOver--];
+}
+
+template <class S>
+inline void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, unsigned int length)
+{
+ if (m_leftOver > 0)
+ {
+ unsigned int len = STDMIN(m_leftOver, length);
+ xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len);
+ length -= len;
+ m_leftOver -= len;
+ inString += len;
+ outString += len;
+ }
+
+ if (!length)
+ return;
+
+ assert(m_leftOver == 0);
+
+ PolicyInterface &policy = AccessPolicy();
+ unsigned int bytesPerIteration = policy.GetBytesPerIteration();
+ unsigned int alignment = policy.GetAlignment();
+
+ if (policy.CanOperateKeystream() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
+ {
+ 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;
+
+ if (!length)
+ return;
+ }
+
+ unsigned int bufferByteSize = GetBufferByteSize(policy);
+ unsigned int bufferIterations = policy.GetIterationsToBuffer();
+
+ while (length >= bufferByteSize)
+ {
+ policy.WriteKeystream(m_buffer, bufferIterations);
+ xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize);
+ length -= bufferByteSize;
+ inString += bufferByteSize;
+ outString += bufferByteSize;
+ }
+
+ if (length > 0)
+ {
+ policy.WriteKeystream(m_buffer, bufferIterations);
+ xorbuf(outString, inString, KeystreamBufferBegin(), length);
+ m_leftOver = bytesPerIteration - length;
+ }
+}
+
+template <class S>
+void AdditiveCipherTemplate<S>::Resynchronize(const byte *iv)
+{
+ PolicyInterface &policy = AccessPolicy();
+ m_leftOver = 0;
+ m_buffer.New(GetBufferByteSize(policy));
+ policy.CipherResynchronize(m_buffer, iv);
+}
+
+template <class BASE>
+void AdditiveCipherTemplate<BASE>::Seek(dword position)
+{
+ PolicyInterface &policy = AccessPolicy();
+ unsigned int bytesPerIteration = policy.GetBytesPerIteration();
+
+ policy.SeekToIteration(position / bytesPerIteration);
+ position %= bytesPerIteration;
+
+ if (position > 0)
+ {
+ policy.WriteKeystream(m_buffer, 1);
+ m_leftOver = bytesPerIteration - position;
+ }
+ else
+ m_leftOver = 0;
+}
+
+template <class BASE>
+void CFB_CipherTemplate<BASE>::Resynchronize(const byte *iv)
+{
+ PolicyInterface &policy = AccessPolicy();
+ policy.CipherResynchronize(iv);
+ m_leftOver = policy.GetBytesPerIteration();
+}
+
+template <class BASE>
+void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, unsigned int length)
+{
+ PolicyInterface &policy = AccessPolicy();
+ unsigned int bytesPerIteration = policy.GetBytesPerIteration();
+ unsigned int alignment = policy.GetAlignment();
+ byte *reg = policy.GetRegisterBegin();
+
+ if (m_leftOver)
+ {
+ unsigned int len = STDMIN(m_leftOver, length);
+ CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len);
+ m_leftOver -= len;
+ length -= len;
+ inString += len;
+ outString += len;
+ }
+
+ if (!length)
+ return;
+
+ assert(m_leftOver == 0);
+
+ if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
+ {
+ if (IsAlignedOn(inString, alignment))
+ policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration);
+ else
+ {
+ memcpy(outString, inString, length);
+ policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration);
+ }
+ inString += length - length % bytesPerIteration;
+ outString += length - length % bytesPerIteration;
+ length %= bytesPerIteration;
+ }
+
+ while (length >= bytesPerIteration)
+ {
+ policy.TransformRegister();
+ CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
+ length -= bytesPerIteration;
+ inString += bytesPerIteration;
+ outString += bytesPerIteration;
+ }
+
+ if (length > 0)
+ {
+ policy.TransformRegister();
+ CombineMessageAndShiftRegister(outString, reg, inString, length);
+ m_leftOver = bytesPerIteration - length;
+ }
+}
+
+template <class BASE>
+void CFB_EncryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length)
+{
+ xorbuf(reg, message, length);
+ memcpy(output, reg, length);
+}
+
+template <class BASE>
+void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length)
+{
+ for (unsigned int i=0; i<length; i++)
+ {
+ byte b = message[i];
+ output[i] = reg[i] ^ b;
+ reg[i] = b;
+ }
+}
+
+NAMESPACE_END