diff options
author | weidai <weidai11@users.noreply.github.com> | 2002-10-04 17:31:41 +0000 |
---|---|---|
committer | weidai <weidai11@users.noreply.github.com> | 2002-10-04 17:31:41 +0000 |
commit | a3b6ece7ab341b5b14135baeccea7d5e4c086771 (patch) | |
tree | 8b045309c238226c32a563b1df6b9c30a2f0e0b3 /strciphr.cpp | |
download | cryptopp-git-a3b6ece7ab341b5b14135baeccea7d5e4c086771.tar.gz |
Initial revision
Diffstat (limited to 'strciphr.cpp')
-rw-r--r-- | strciphr.cpp | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/strciphr.cpp b/strciphr.cpp new file mode 100644 index 00000000..694d1587 --- /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 |