You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
2.4 KiB
122 lines
2.4 KiB
// arc4.cpp - originally written and placed in the public domain by Wei Dai |
|
|
|
// The ARC4 algorithm was first revealed in an anonymous email to the |
|
// cypherpunks mailing list. This file originally contained some |
|
// code copied from this email. The code has since been rewritten in order |
|
// to clarify the copyright status of this file. It should now be |
|
// completely in the public domain. |
|
|
|
#include "pch.h" |
|
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 |
|
#include "arc4.h" |
|
|
|
NAMESPACE_BEGIN(CryptoPP) |
|
namespace Weak1 { |
|
|
|
#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) |
|
void ARC4_TestInstantiations() |
|
{ |
|
ARC4 x; |
|
} |
|
#endif |
|
|
|
ARC4_Base::~ARC4_Base() |
|
{ |
|
m_x = m_y = 0; |
|
} |
|
|
|
void ARC4_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) |
|
{ |
|
AssertValidKeyLength(length); |
|
|
|
m_x = 1; |
|
m_y = 0; |
|
|
|
unsigned int i; |
|
for (i=0; i<256; i++) |
|
m_state[i] = byte(i); |
|
|
|
unsigned int keyIndex = 0, stateIndex = 0; |
|
for (i=0; i<256; i++) |
|
{ |
|
unsigned int a = m_state[i]; |
|
stateIndex += key[keyIndex] + a; |
|
stateIndex &= 0xff; |
|
m_state[i] = m_state[stateIndex]; |
|
m_state[stateIndex] = byte(a); |
|
if (++keyIndex >= length) |
|
keyIndex = 0; |
|
} |
|
|
|
int discardBytes = params.GetIntValueWithDefault("DiscardBytes", GetDefaultDiscardBytes()); |
|
DiscardBytes(discardBytes); |
|
} |
|
|
|
template <class T> |
|
static inline unsigned int MakeByte(T &x, T &y, byte *s) |
|
{ |
|
unsigned int a = s[x]; |
|
y = byte((y+a) & 0xff); |
|
unsigned int b = s[y]; |
|
s[x] = byte(b); |
|
s[y] = byte(a); |
|
x = byte((x+1) & 0xff); |
|
return s[(a+b) & 0xff]; |
|
} |
|
|
|
void ARC4_Base::GenerateBlock(byte *output, size_t size) |
|
{ |
|
while (size--) |
|
*output++ = static_cast<byte>(MakeByte(m_x, m_y, m_state)); |
|
} |
|
|
|
void ARC4_Base::ProcessData(byte *outString, const byte *inString, size_t length) |
|
{ |
|
if (length == 0) |
|
return; |
|
|
|
byte *const s = m_state; |
|
unsigned int x = m_x; |
|
unsigned int y = m_y; |
|
|
|
if (inString == outString) |
|
{ |
|
do |
|
{ |
|
*outString++ ^= MakeByte(x, y, s); |
|
} while (--length); |
|
} |
|
else |
|
{ |
|
do |
|
{ |
|
*outString++ = *inString++ ^ byte(MakeByte(x, y, s)); |
|
} |
|
while(--length); |
|
} |
|
|
|
m_x = byte(x); |
|
m_y = byte(y); |
|
} |
|
|
|
void ARC4_Base::DiscardBytes(size_t n) |
|
{ |
|
if (n == 0) |
|
return; |
|
|
|
byte *const s = m_state; |
|
unsigned int x = m_x; |
|
unsigned int y = m_y; |
|
|
|
do |
|
{ |
|
MakeByte(x, y, s); |
|
} |
|
while(--n); |
|
|
|
m_x = byte(x); |
|
m_y = byte(y); |
|
} |
|
|
|
} |
|
NAMESPACE_END
|
|
|