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