- Main Page
- Namespaces
- Classes
- Files

# 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