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 #include "arc4.h"
00011 
00012 NAMESPACE_BEGIN(CryptoPP)
00013 
00014 void ARC4_TestInstantiations()
00015 {
00016         ARC4 x;
00017 }
00018 
00019 ARC4_Base::~ARC4_Base()
00020 {
00021         m_x = m_y = 0;
00022 }
00023 
00024 void ARC4_Base::UncheckedSetKey(const byte *key, unsigned int keyLen, const NameValuePairs &params)
00025 {
00026         AssertValidKeyLength(keyLen);
00027 
00028         m_x = 1;
00029         m_y = 0;
00030 
00031         unsigned int i;
00032         for (i=0; i<256; i++)
00033                 m_state[i] = i;
00034 
00035         unsigned int keyIndex = 0, stateIndex = 0;
00036         for (i=0; i<256; i++)
00037         {
00038                 unsigned int a = m_state[i];
00039                 stateIndex += key[keyIndex] + a;
00040                 stateIndex &= 0xff;
00041                 m_state[i] = m_state[stateIndex];
00042                 m_state[stateIndex] = a;
00043                 if (++keyIndex >= keyLen)
00044                         keyIndex = 0;
00045         }
00046 
00047         int discardBytes = params.GetIntValueWithDefault("DiscardBytes", GetDefaultDiscardBytes());
00048         DiscardBytes(discardBytes);
00049 }
00050 
00051 template <class T>
00052 static inline unsigned int MakeByte(T &x, T &y, byte *s)
00053 {
00054         unsigned int a = s[x];
00055         y = (y+a) & 0xff;
00056         unsigned int b = s[y];
00057         s[x] = b;
00058         s[y] = a;
00059         x = (x+1) & 0xff;
00060         return s[(a+b) & 0xff];
00061 }
00062 
00063 byte ARC4_Base::GenerateByte()
00064 {
00065         return MakeByte(m_x, m_y, m_state);
00066 }
00067 
00068 void ARC4_Base::ProcessData(byte *outString, const byte *inString, size_t length)
00069 {
00070         if (length == 0)
00071                 return;
00072 
00073         byte *const s = m_state;
00074         unsigned int x = m_x;
00075         unsigned int y = m_y;
00076 
00077         if (inString == outString)
00078         {
00079                 do
00080                 {
00081                         *outString++ ^= MakeByte(x, y, s);
00082                 } while (--length);
00083         }
00084         else
00085         {
00086                 do
00087                 {
00088                         *outString++ = *inString++ ^ MakeByte(x, y, s);
00089                 }
00090                 while(--length);
00091         }
00092 
00093         m_x = x;
00094         m_y = y;
00095 }
00096 
00097 void ARC4_Base::DiscardBytes(size_t length)
00098 {
00099         if (length == 0)
00100                 return;
00101 
00102         byte *const s = m_state;
00103         unsigned int x = m_x;
00104         unsigned int y = m_y;
00105 
00106         do
00107         {
00108                 MakeByte(x, y, s);
00109         }
00110         while(--length);
00111 
00112         m_x = x;
00113         m_y = y;
00114 }
00115 
00116 NAMESPACE_END

Generated on Sat Dec 23 02:07:05 2006 for Crypto++ by  doxygen 1.5.1-p1