rc6.cpp

00001 // rc6.cpp - written and placed in the public domain by Sean Woods
00002 // based on Wei Dai's RC5 code.
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 &params)
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;    // magic constant P for wordsize
00018         static const RC6_WORD MAGIC_Q = 0x9e3779b9L;    // magic constant Q for wordsize
00019         static const int U=sizeof(RC6_WORD);
00020 
00021         const unsigned int c = STDMAX((keylen+U-1)/U, 1U);      // RC6 paper says c=1 if keylen==0
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

Generated on Sat Dec 23 02:07:09 2006 for Crypto++ by  doxygen 1.5.1-p1