1
by weidai
Initial revision |
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" |
|
313
by weidai
use Weak1 namespace |
10 |
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
|
1
by weidai
Initial revision |
11 |
#include "arc4.h" |
12 |
||
13 |
NAMESPACE_BEGIN(CryptoPP) |
|
313
by weidai
use Weak1 namespace |
14 |
namespace Weak1 { |
1
by weidai
Initial revision |
15 |
|
16 |
void ARC4_TestInstantiations() |
|
17 |
{
|
|
18 |
ARC4 x; |
|
19 |
}
|
|
20 |
||
21 |
ARC4_Base::~ARC4_Base() |
|
22 |
{
|
|
23 |
m_x = m_y = 0; |
|
24 |
}
|
|
25 |
||
232
by weidai
port to GCC 4, reorganize implementations of SetKey |
26 |
void ARC4_Base::UncheckedSetKey(const byte *key, unsigned int keyLen, const NameValuePairs ¶ms) |
1
by weidai
Initial revision |
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 |
||
53 |
template <class T> |
|
54 |
static 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 |
||
313
by weidai
use Weak1 namespace |
65 |
void ARC4_Base::GenerateBlock(byte *output, size_t size) |
1
by weidai
Initial revision |
66 |
{
|
313
by weidai
use Weak1 namespace |
67 |
while (size--) |
68 |
*output++ = MakeByte(m_x, m_y, m_state); |
|
1
by weidai
Initial revision |
69 |
}
|
70 |
||
184
by weidai
port to MSVC .NET 2005 beta 2 |
71 |
void ARC4_Base::ProcessData(byte *outString, const byte *inString, size_t length) |
1
by weidai
Initial revision |
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 |
||
184
by weidai
port to MSVC .NET 2005 beta 2 |
100 |
void ARC4_Base::DiscardBytes(size_t length) |
1
by weidai
Initial revision |
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 |
||
309
by weidai
move ARC4 into Weak namespace |
119 |
}
|
1
by weidai
Initial revision |
120 |
NAMESPACE_END
|