00001
00002
00003
00004 #include "pch.h"
00005 #include "rc6.h"
00006 #include "misc.h"
00007
00008 NAMESPACE_BEGIN(CryptoPP)
00009
00010 void RC6::Base::UncheckedSetKey(const byte *k, unsigned int keylen, const NameValuePairs ¶ms)
00011 {
00012 AssertValidKeyLength(keylen);
00013
00014 r = GetRoundsAndThrowIfInvalid(params, this);
00015 sTable.New(2*(r+2));
00016
00017 static const RC6_WORD MAGIC_P = 0xb7e15163L;
00018 static const RC6_WORD MAGIC_Q = 0x9e3779b9L;
00019 static const int U=sizeof(RC6_WORD);
00020
00021 const unsigned int c = STDMAX((keylen+U-1)/U, 1U);
00022 SecBlock<RC6_WORD> l(c);
00023
00024 GetUserKey(LITTLE_ENDIAN_ORDER, l.begin(), c, k, keylen);
00025
00026 sTable[0] = MAGIC_P;
00027 for (unsigned j=1; j<sTable.size();j++)
00028 sTable[j] = sTable[j-1] + MAGIC_Q;
00029
00030 RC6_WORD a=0, b=0;
00031 const unsigned n = 3*STDMAX((unsigned int)sTable.size(), c);
00032
00033 for (unsigned h=0; h < n; h++)
00034 {
00035 a = sTable[h % sTable.size()] = rotlFixed((sTable[h % sTable.size()] + a + b), 3);
00036 b = l[h % c] = rotlMod((l[h % c] + a + b), (a+b));
00037 }
00038 }
00039
00040 typedef BlockGetAndPut<RC6::RC6_WORD, LittleEndian> Block;
00041
00042 void RC6::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00043 {
00044 const RC6_WORD *sptr = sTable;
00045 RC6_WORD a, b, c, d, t, u;
00046
00047 Block::Get(inBlock)(a)(b)(c)(d);
00048 b += sptr[0];
00049 d += sptr[1];
00050 sptr += 2;
00051
00052 for(unsigned i=0; i<r; i++)
00053 {
00054 t = rotlFixed(b*(2*b+1), 5);
00055 u = rotlFixed(d*(2*d+1), 5);
00056 a = rotlMod(a^t,u) + sptr[0];
00057 c = rotlMod(c^u,t) + sptr[1];
00058 t = a; a = b; b = c; c = d; d = t;
00059 sptr += 2;
00060 }
00061
00062 a += sptr[0];
00063 c += sptr[1];
00064
00065 Block::Put(xorBlock, outBlock)(a)(b)(c)(d);
00066 }
00067
00068 void RC6::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00069 {
00070 const RC6_WORD *sptr = sTable.end();
00071 RC6_WORD a, b, c, d, t, u;
00072
00073 Block::Get(inBlock)(a)(b)(c)(d);
00074
00075 sptr -= 2;
00076 c -= sptr[1];
00077 a -= sptr[0];
00078
00079 for (unsigned i=0; i < r; i++)
00080 {
00081 sptr -= 2;
00082 t = a; a = d; d = c; c = b; b = t;
00083 u = rotlFixed(d*(2*d+1), 5);
00084 t = rotlFixed(b*(2*b+1), 5);
00085 c = rotrMod(c-sptr[1], t) ^ u;
00086 a = rotrMod(a-sptr[0], u) ^ t;
00087 }
00088
00089 sptr -= 2;
00090 d -= sTable[1];
00091 b -= sTable[0];
00092
00093 Block::Put(xorBlock, outBlock)(a)(b)(c)(d);
00094 }
00095
00096 NAMESPACE_END