Crypto++
|
00001 // arc4.cpp - written and placed in the public domain by Wei Dai 00002 00003 // The ARC4 algorithm was first revealed in an anonymous email to the 00004 // cypherpunks mailing list. This file originally contained some 00005 // code copied from this email. The code has since been rewritten in order 00006 // to clarify the copyright status of this file. It should now be 00007 // completely in the public domain. 00008 00009 #include "pch.h" 00010 #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 00011 #include "arc4.h" 00012 00013 NAMESPACE_BEGIN(CryptoPP) 00014 namespace Weak1 { 00015 00016 void ARC4_TestInstantiations() 00017 { 00018 ARC4 x; 00019 } 00020 00021 ARC4_Base::~ARC4_Base() 00022 { 00023 m_x = m_y = 0; 00024 } 00025 00026 void ARC4_Base::UncheckedSetKey(const byte *key, unsigned int keyLen, const NameValuePairs ¶ms) 00027 { 00028 AssertValidKeyLength(keyLen); 00029 00030 m_x = 1; 00031 m_y = 0; 00032 00033 unsigned int i; 00034 for (i=0; i<256; i++) 00035 m_state[i] = i; 00036 00037 unsigned int keyIndex = 0, stateIndex = 0; 00038 for (i=0; i<256; i++) 00039 { 00040 unsigned int a = m_state[i]; 00041 stateIndex += key[keyIndex] + a; 00042 stateIndex &= 0xff; 00043 m_state[i] = m_state[stateIndex]; 00044 m_state[stateIndex] = a; 00045 if (++keyIndex >= keyLen) 00046 keyIndex = 0; 00047 } 00048 00049 int discardBytes = params.GetIntValueWithDefault("DiscardBytes", GetDefaultDiscardBytes()); 00050 DiscardBytes(discardBytes); 00051 } 00052 00053 template <class T> 00054 static inline unsigned int MakeByte(T &x, T &y, byte *s) 00055 { 00056 unsigned int a = s[x]; 00057 y = (y+a) & 0xff; 00058 unsigned int b = s[y]; 00059 s[x] = b; 00060 s[y] = a; 00061 x = (x+1) & 0xff; 00062 return s[(a+b) & 0xff]; 00063 } 00064 00065 void ARC4_Base::GenerateBlock(byte *output, size_t size) 00066 { 00067 while (size--) 00068 *output++ = MakeByte(m_x, m_y, m_state); 00069 } 00070 00071 void ARC4_Base::ProcessData(byte *outString, const byte *inString, size_t length) 00072 { 00073 if (length == 0) 00074 return; 00075 00076 byte *const s = m_state; 00077 unsigned int x = m_x; 00078 unsigned int y = m_y; 00079 00080 if (inString == outString) 00081 { 00082 do 00083 { 00084 *outString++ ^= MakeByte(x, y, s); 00085 } while (--length); 00086 } 00087 else 00088 { 00089 do 00090 { 00091 *outString++ = *inString++ ^ MakeByte(x, y, s); 00092 } 00093 while(--length); 00094 } 00095 00096 m_x = x; 00097 m_y = y; 00098 } 00099 00100 void ARC4_Base::DiscardBytes(size_t length) 00101 { 00102 if (length == 0) 00103 return; 00104 00105 byte *const s = m_state; 00106 unsigned int x = m_x; 00107 unsigned int y = m_y; 00108 00109 do 00110 { 00111 MakeByte(x, y, s); 00112 } 00113 while(--length); 00114 00115 m_x = x; 00116 m_y = y; 00117 } 00118 00119 } 00120 NAMESPACE_END