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