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

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

Generated on Sun Jul 3 00:20:21 2005 for Crypto++ by  doxygen 1.4.3-20050530