Crypto++  5.6.3
Free C++ class library of cryptographic schemes
arc4.cpp
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 
13 NAMESPACE_BEGIN(CryptoPP)
14 namespace Weak1 {
15 
16 #if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
17 void ARC4_TestInstantiations()
18 {
19  ARC4 x;
20 }
21 #endif
22 
23 ARC4_Base::~ARC4_Base()
24 {
25  m_x = m_y = 0;
26 }
27 
28 void ARC4_Base::UncheckedSetKey(const byte *key, unsigned int keyLen, const NameValuePairs &params)
29 {
30  AssertValidKeyLength(keyLen);
31 
32  m_x = 1;
33  m_y = 0;
34 
35  unsigned int i;
36  for (i=0; i<256; i++)
37  m_state[i] = byte(i);
38 
39  unsigned int keyIndex = 0, stateIndex = 0;
40  for (i=0; i<256; i++)
41  {
42  unsigned int a = m_state[i];
43  stateIndex += key[keyIndex] + a;
44  stateIndex &= 0xff;
45  m_state[i] = m_state[stateIndex];
46  m_state[stateIndex] = byte(a);
47  if (++keyIndex >= keyLen)
48  keyIndex = 0;
49  }
50 
51  int discardBytes = params.GetIntValueWithDefault("DiscardBytes", GetDefaultDiscardBytes());
52  DiscardBytes(discardBytes);
53 }
54 
55 template <class T>
56 static inline unsigned int MakeByte(T &x, T &y, byte *s)
57 {
58  unsigned int a = s[x];
59  y = byte((y+a) & 0xff);
60  unsigned int b = s[y];
61  s[x] = byte(b);
62  s[y] = byte(a);
63  x = byte((x+1) & 0xff);
64  return s[(a+b) & 0xff];
65 }
66 
67 void ARC4_Base::GenerateBlock(byte *output, size_t size)
68 {
69  while (size--)
70  *output++ = static_cast<byte>(MakeByte(m_x, m_y, m_state));
71 }
72 
73 void ARC4_Base::ProcessData(byte *outString, const byte *inString, size_t length)
74 {
75  if (length == 0)
76  return;
77 
78  byte *const s = m_state;
79  unsigned int x = m_x;
80  unsigned int y = m_y;
81 
82  if (inString == outString)
83  {
84  do
85  {
86  *outString++ ^= MakeByte(x, y, s);
87  } while (--length);
88  }
89  else
90  {
91  do
92  {
93  *outString++ = *inString++ ^ byte(MakeByte(x, y, s));
94  }
95  while(--length);
96  }
97 
98  m_x = byte(x);
99  m_y = byte(y);
100 }
101 
102 void ARC4_Base::DiscardBytes(size_t length)
103 {
104  if (length == 0)
105  return;
106 
107  byte *const s = m_state;
108  unsigned int x = m_x;
109  unsigned int y = m_y;
110 
111  do
112  {
113  MakeByte(x, y, s);
114  }
115  while(--length);
116 
117  m_x = byte(x);
118  m_y = byte(y);
119 }
120 
121 }
122 NAMESPACE_END
Alleged RC4
Definition: arc4.h:49
int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
Definition: cryptlib.h:380
Crypto++ library namespace.
Classes for ARC4 cipher.
Interface for retrieving values given their names.
Definition: cryptlib.h:277