~zooko/cryptopp/trunk

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 &params)
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