arc4.cpp

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 &params)
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

Generated on Fri Jun 1 11:11:19 2007 for Crypto++ by  doxygen 1.5.2