rc2.cpp

00001 // rc2.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 #include "rc2.h"
00005 #include "misc.h"
00006 #include "argnames.h"
00007 
00008 NAMESPACE_BEGIN(CryptoPP)
00009 
00010 void RC2::Base::UncheckedSetKey(const byte *key, unsigned int keyLen, const NameValuePairs &params)
00011 {
00012         AssertValidKeyLength(keyLen);
00013 
00014         int effectiveLen = params.GetIntValueWithDefault(Name::EffectiveKeyLength(), DEFAULT_EFFECTIVE_KEYLENGTH);
00015         if (effectiveLen > MAX_EFFECTIVE_KEYLENGTH)
00016                 throw InvalidArgument("RC2: effective key length parameter exceeds maximum");
00017 
00018         static const unsigned char PITABLE[256] = {
00019                 217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157,
00020                 198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162,
00021                  23,154, 89,245,135,179, 79, 19, 97, 69,109,141,  9,129,125, 50,
00022                 189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130,
00023                  84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220,
00024                  18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38,
00025                 111,191, 14,218, 70,105,  7, 87, 39,242, 29,155,188,148, 67,  3,
00026                 248, 17,199,246,144,239, 62,231,  6,195,213, 47,200,102, 30,215,
00027                   8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42,
00028                 150, 26,210,113, 90, 21, 73,116, 75,159,208, 94,  4, 24,164,236,
00029                 194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57,
00030                 153,124, 58,133, 35,184,180,122,252,  2, 54, 91, 37, 85,151, 49,
00031                  45, 93,250,152,227,138,146,174,  5,223, 41, 16,103,108,186,201,
00032                 211,  0,230,207,225,158,168, 44, 99, 22,  1, 63, 88,226,137,169,
00033                  13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46,
00034                 197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173};
00035 
00036         SecByteBlock L(128);
00037         memcpy(L, key, keyLen);
00038 
00039         int i;
00040         for (i=keyLen; i<128; i++)
00041                 L[i] = PITABLE[(L[i-1] + L[i-keyLen]) & 255];
00042 
00043         unsigned int T8 = (effectiveLen+7) / 8;
00044         byte TM = 255 >> ((8-(effectiveLen%8))%8);
00045         L[128-T8] = PITABLE[L[128-T8] & TM];
00046 
00047         for (i=127-T8; i>=0; i--)
00048                 L[i] = PITABLE[L[i+1] ^ L[i+T8]];
00049 
00050         for (i=0; i<64; i++)
00051                 K[i] = L[2*i] + (L[2*i+1] << 8);
00052 }
00053 
00054 typedef BlockGetAndPut<word16, LittleEndian> Block;
00055 
00056 void RC2::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00057 {
00058         word16 R0, R1, R2, R3;
00059         Block::Get(inBlock)(R0)(R1)(R2)(R3);
00060 
00061         for (int i = 0; i < 16; i++)
00062         {
00063                 R0 += (R1 & ~R3) + (R2 & R3) + K[4*i+0];
00064                 R0 = rotlFixed(R0, 1);
00065 
00066                 R1 += (R2 & ~R0) + (R3 & R0) + K[4*i+1];
00067                 R1 = rotlFixed(R1, 2);
00068 
00069                 R2 += (R3 & ~R1) + (R0 & R1) + K[4*i+2];
00070                 R2 = rotlFixed(R2, 3);
00071 
00072                 R3 += (R0 & ~R2) + (R1 & R2) + K[4*i+3];
00073                 R3 = rotlFixed(R3, 5);
00074 
00075                 if (i == 4 || i == 10)
00076                 {
00077                         R0 += K[R3 & 63];
00078                         R1 += K[R0 & 63];
00079                         R2 += K[R1 & 63];
00080                         R3 += K[R2 & 63];
00081                 }
00082         }
00083 
00084         Block::Put(xorBlock, outBlock)(R0)(R1)(R2)(R3);
00085 }
00086 
00087 void RC2::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00088 {
00089         word16 R0, R1, R2, R3;
00090         Block::Get(inBlock)(R0)(R1)(R2)(R3);
00091 
00092         for (int i = 15; i >= 0; i--)
00093         {
00094                 if (i == 4 || i == 10)
00095                 {
00096                         R3 -= K[R2 & 63];
00097                         R2 -= K[R1 & 63];
00098                         R1 -= K[R0 & 63];
00099                         R0 -= K[R3 & 63];
00100                 }
00101 
00102                 R3 = rotrFixed(R3, 5);
00103                 R3 -= (R0 & ~R2) + (R1 & R2) + K[4*i+3];
00104 
00105                 R2 = rotrFixed(R2, 3);
00106                 R2 -= (R3 & ~R1) + (R0 & R1) + K[4*i+2];
00107 
00108                 R1 = rotrFixed(R1, 2);
00109                 R1 -= (R2 & ~R0) + (R3 & R0) + K[4*i+1];
00110 
00111                 R0 = rotrFixed(R0, 1);
00112                 R0 -= (R1 & ~R3) + (R2 & R3) + K[4*i+0];
00113         }
00114 
00115         Block::Put(xorBlock, outBlock)(R0)(R1)(R2)(R3);
00116 }
00117 
00118 NAMESPACE_END

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