Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

# 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(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;    // magic constant P for wordsize
    00019         static const RC6_WORD MAGIC_Q = 0x9e3779b9L;    // magic constant Q for wordsize
    00020         static const int U=sizeof(RC6_WORD);
    00021
    00022         const unsigned int c = STDMAX((keylen+U-1)/U, 1U);      // RC6 paper says c=1 if keylen==0
    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