1 // rc6.cpp - written and placed in the public domain by Sean Woods
2 // based on Wei Dai's RC5 code.
3 
4 #include "pch.h"
5 #include "rc6.h"
6 #include "misc.h"
7 #include "secblock.h"
8 
NAMESPACE_BEGIN(CryptoPP)9 NAMESPACE_BEGIN(CryptoPP)
10 
11 void RC6::Base::UncheckedSetKey(const byte *k, unsigned int keylen, const NameValuePairs &params)
12 {
13 	AssertValidKeyLength(keylen);
14 
15 	r = GetRoundsAndThrowIfInvalid(params, this);
16 	sTable.New(2*(r+2));
17 
18 	static const RC6_WORD MAGIC_P = 0xb7e15163L;    // magic constant P for wordsize
19 	static const RC6_WORD MAGIC_Q = 0x9e3779b9L;    // magic constant Q for wordsize
20 	static const int U=sizeof(RC6_WORD);
21 
22 	const unsigned int c = STDMAX((keylen+U-1)/U, 1U);	// RC6 paper says c=1 if keylen==0
23 	SecBlock<RC6_WORD> l(c);
24 
25 	GetUserKey(LITTLE_ENDIAN_ORDER, l.begin(), c, k, keylen);
26 
27 	sTable[0] = MAGIC_P;
28 	for (unsigned j=1; j<sTable.size();j++)
29 		sTable[j] = sTable[j-1] + MAGIC_Q;
30 
31 	RC6_WORD a=0, b=0;
32 	const unsigned n = 3*STDMAX((unsigned int)sTable.size(), c);
33 
34 	for (unsigned h=0; h < n; h++)
35 	{
36 		a = sTable[h % sTable.size()] = rotlFixed((sTable[h % sTable.size()] + a + b), 3);
37 		b = l[h % c] = rotlMod((l[h % c] + a + b), (a+b));
38 	}
39 }
40 
41 typedef BlockGetAndPut<RC6::RC6_WORD, LittleEndian> Block;
42 
ProcessAndXorBlock(const byte * inBlock,const byte * xorBlock,byte * outBlock) const43 void RC6::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
44 {
45 	const RC6_WORD *sptr = sTable;
46 	RC6_WORD a, b, c, d, t, u;
47 
48 	Block::Get(inBlock)(a)(b)(c)(d);
49 	b += sptr[0];
50 	d += sptr[1];
51 	sptr += 2;
52 
53 	for(unsigned i=0; i<r; i++)
54 	{
55 		t = rotlFixed(b*(2*b+1), 5);
56 		u = rotlFixed(d*(2*d+1), 5);
57 		a = rotlMod(a^t,u) + sptr[0];
58 		c = rotlMod(c^u,t) + sptr[1];
59 		t = a; a = b; b = c; c = d; d = t;
60 		sptr += 2;
61 	}
62 
63 	a += sptr[0];
64 	c += sptr[1];
65 
66 	Block::Put(xorBlock, outBlock)(a)(b)(c)(d);
67 }
68 
ProcessAndXorBlock(const byte * inBlock,const byte * xorBlock,byte * outBlock) const69 void RC6::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
70 {
71 	const RC6_WORD *sptr = sTable.end();
72 	RC6_WORD a, b, c, d, t, u;
73 
74 	Block::Get(inBlock)(a)(b)(c)(d);
75 
76 	sptr -= 2;
77 	c -= sptr[1];
78 	a -= sptr[0];
79 
80 	for (unsigned i=0; i < r; i++)
81 	{
82 		sptr -= 2;
83 		t = a; a = d; d = c; c = b; b = t;
84 		u = rotlFixed(d*(2*d+1), 5);
85 		t = rotlFixed(b*(2*b+1), 5);
86 		c = rotrMod(c-sptr[1], t) ^ u;
87 		a = rotrMod(a-sptr[0], u) ^ t;
88 	}
89 
90 	sptr -= 2;
91 	d -= sTable[1];
92 	b -= sTable[0];
93 
94 	Block::Put(xorBlock, outBlock)(a)(b)(c)(d);
95 }
96 
97 NAMESPACE_END
98