Crypto++
|
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 ¶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; // 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