1// arc4.cpp - written and placed in the public domain by Wei Dai 2 3// The ARC4 algorithm was first revealed in an anonymous email to the 4// cypherpunks mailing list. This file originally contained some 5// code copied from this email. The code has since been rewritten in order 6// to clarify the copyright status of this file. It should now be 7// completely in the public domain. 8 9#include "pch.h" 10#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 11#include "arc4.h" 12 13NAMESPACE_BEGIN(CryptoPP) 14namespace Weak1 { 15 16void ARC4_TestInstantiations() 17{ 18 ARC4 x; 19} 20 21ARC4_Base::~ARC4_Base() 22{ 23 m_x = m_y = 0; 24} 25 26void ARC4_Base::UncheckedSetKey(const byte *key, unsigned int keyLen, const NameValuePairs ¶ms) 27{ 28 AssertValidKeyLength(keyLen); 29 30 m_x = 1; 31 m_y = 0; 32 33 unsigned int i; 34 for (i=0; i<256; i++) 35 m_state[i] = i; 36 37 unsigned int keyIndex = 0, stateIndex = 0; 38 for (i=0; i<256; i++) 39 { 40 unsigned int a = m_state[i]; 41 stateIndex += key[keyIndex] + a; 42 stateIndex &= 0xff; 43 m_state[i] = m_state[stateIndex]; 44 m_state[stateIndex] = a; 45 if (++keyIndex >= keyLen) 46 keyIndex = 0; 47 } 48 49 int discardBytes = params.GetIntValueWithDefault("DiscardBytes", GetDefaultDiscardBytes()); 50 DiscardBytes(discardBytes); 51} 52 53template <class T> 54static inline unsigned int MakeByte(T &x, T &y, byte *s) 55{ 56 unsigned int a = s[x]; 57 y = (y+a) & 0xff; 58 unsigned int b = s[y]; 59 s[x] = b; 60 s[y] = a; 61 x = (x+1) & 0xff; 62 return s[(a+b) & 0xff]; 63} 64 65void ARC4_Base::GenerateBlock(byte *output, size_t size) 66{ 67 while (size--) 68 *output++ = MakeByte(m_x, m_y, m_state); 69} 70 71void ARC4_Base::ProcessData(byte *outString, const byte *inString, size_t length) 72{ 73 if (length == 0) 74 return; 75 76 byte *const s = m_state; 77 unsigned int x = m_x; 78 unsigned int y = m_y; 79 80 if (inString == outString) 81 { 82 do 83 { 84 *outString++ ^= MakeByte(x, y, s); 85 } while (--length); 86 } 87 else 88 { 89 do 90 { 91 *outString++ = *inString++ ^ MakeByte(x, y, s); 92 } 93 while(--length); 94 } 95 96 m_x = x; 97 m_y = y; 98} 99 100void ARC4_Base::DiscardBytes(size_t length) 101{ 102 if (length == 0) 103 return; 104 105 byte *const s = m_state; 106 unsigned int x = m_x; 107 unsigned int y = m_y; 108 109 do 110 { 111 MakeByte(x, y, s); 112 } 113 while(--length); 114 115 m_x = x; 116 m_y = y; 117} 118 119} 120NAMESPACE_END 121