Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

# 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 NameValuePairs &params, const byte *key, unsigned int keyLen, const byte *iv)
    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, unsigned int 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(unsigned int 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