Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

krc2.cpp

Go to the documentation of this file.
00001 /* C implementation of RC2 encryption algorithm, as described in RFC2268 */
00002 /* By Matthew Palmer <mjp16@uow.edu.au> */
00003 /* $Id: krc2.cpp,v 1.1.1.1 2003/07/22 19:23:17 zcarsten Exp $ */
00004 
00005 #include "krc2.h"
00006 
00007 unsigned char _rc2_pitable[] = { 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed,
00008                             0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,
00009                             0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
00010                             0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,
00011                             0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13,
00012                             0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
00013                             0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b,
00014                             0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,
00015                             0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
00016                             0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,
00017                             0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1,
00018                             0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
00019                             0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57,
00020                             0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,
00021                             0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
00022                             0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,
00023                             0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7,
00024                             0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
00025                             0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74,
00026                             0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,
00027                             0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
00028                             0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,
00029                             0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a,
00030                             0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
00031                             0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae,
00032                             0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,
00033                             0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
00034                             0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,
00035                             0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0,
00036                             0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
00037                             0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77,
00038                             0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad };
00039         
00040 unsigned char _rc2_expkey[128]; /* Expanded Key */
00041 int _rc2_counter;                               /* global integer variable used in mixing */
00042 int _rc2_s[] = {1, 2, 3, 5};
00043 
00044 Krc2::Krc2()
00045 {
00046 }
00047 
00048 Krc2::~Krc2()
00049 {
00050 }
00051 
00052 void Krc2::rc2_expandkey(char key[], int length, int ekl)
00053 {
00054         int ekl8, keymask, i;
00055         
00056         /* Put supplied key into first length - 1 bytes of the key buffer */
00057         for (i = 0; i < length; i++) {
00058                 _rc2_expkey[i] = key[i];
00059         }
00060         
00061         ekl8 = (ekl + 7) / 8;
00062         i = _rc2_pow(2, (8 + ekl - 8 * ekl8));
00063         keymask = 255 % i;
00064         
00065         /* First expansion step */
00066         for (i = length; i < 128; i++) {
00067                 _rc2_expkey[i] = _rc2_pitable[(_rc2_expkey[i - 1] + _rc2_expkey[i - length]) % 256];
00068         }
00069         
00070         /* Expansion intermediate step */
00071         _rc2_expkey[128 - ekl8] = _rc2_pitable[_rc2_expkey[128 - ekl8] & keymask];
00072         
00073         /* Third Expansion step */
00074         for (i = 127 - ekl8; i >= 0; i--) {
00075                 _rc2_expkey[i] = _rc2_pitable[_rc2_expkey[i + 1] ^ _rc2_expkey[i + ekl8]];
00076         }
00077 }
00078 
00079 void Krc2::rc2_encrypt(unsigned short input[4])
00080 {
00081         int i;
00082         
00083         _rc2_counter = 0;
00084         for (i = 0; i < 5; i++) {
00085                 _rc2_mix(input);
00086         }
00087         _rc2_mash(input);
00088         for (i = 0; i < 6; i++) {
00089                 _rc2_mix(input);
00090         }
00091         _rc2_mash(input);
00092         for (i = 0; i < 5; i++) {
00093                 _rc2_mix(input);
00094         }
00095 }
00096 
00097 void Krc2::_rc2_mix(unsigned short input[])
00098 {
00099         unsigned short K, i;
00100         
00101         for (i = 0; i < 4; i++) {
00102                 K = _rc2_expkey[_rc2_counter * 2] + 256 * _rc2_expkey[_rc2_counter * 2 + 1];
00103                 input[i] = input[i] + K + (input[(i + 3) % 4] & input[(i + 2) % 4]) + ((~input[(i + 3) % 4]) & input[(i + 1) % 4]);
00104                 _rc2_counter++;
00105                 input[i] = _rc2_rol(input[i], _rc2_s[i]);
00106         }
00107 }
00108 
00109 void Krc2::_rc2_mash(unsigned short input[])
00110 {
00111         unsigned short K, i, x;
00112         
00113         for (i = 0; i < 4; i++) {
00114                 x = input[(i + 3) % 4] & 63;
00115                 K = _rc2_expkey[2 * x] + 256 * _rc2_expkey[2 * x + 1];
00116                 input[i] = input[i] + K;
00117         }
00118 }
00119 
00120 void Krc2::rc2_decrypt(unsigned short input[4])
00121 {
00122         int i;
00123         
00124         _rc2_counter = 63;
00125         for (i = 0; i < 5; i++) {
00126                 _rc2_rmix(input);
00127         }
00128         _rc2_rmash(input);
00129         for (i = 0; i < 6; i++) {
00130                 _rc2_rmix(input);
00131         }
00132         _rc2_rmash(input);
00133         for (i = 0; i < 5; i++) {
00134                 _rc2_rmix(input);
00135         }
00136 }
00137 
00138 void Krc2::_rc2_rmix(unsigned short input[])
00139 {
00140         unsigned short K;
00141         int i;
00142 
00143         for (i = 3; i >= 0; i--) {
00144                 input[i] = _rc2_ror(input[i], _rc2_s[i]);
00145                 K = _rc2_expkey[_rc2_counter * 2] + 256 * _rc2_expkey[_rc2_counter * 2 + 1];
00146                 input[i] = input[i] - K - (input[(i + 3) % 4] & input[(i + 2) % 4]) - ((~input[(i + 3) % 4]) & input[(i + 1) % 4]);
00147                 _rc2_counter--;
00148         }
00149 }
00150 
00151 void Krc2::_rc2_rmash(unsigned short input[])
00152 {
00153         unsigned short K, x;
00154         int i;
00155         
00156         for (i = 3; i >= 0; i--) {
00157                 x = input[(i + 3) % 4] & 63;
00158                 K = _rc2_expkey[2 * x] + 256 * _rc2_expkey[2 * x + 1];
00159                 input[i] = input[i] - K;
00160         }
00161 }
00162 
00163 int Krc2::_rc2_pow(int base, int exponent)
00164 {
00165         int i, result;
00166 
00167         if (exponent == 0) {
00168                 return 1;
00169         }
00170         result = 1;
00171         for (i = 0; i < exponent; i++) {
00172                 result = result * base;
00173         }
00174         return result;
00175 }
00176 
00177 unsigned short Krc2::_rc2_rol(unsigned short input, int places)
00178 {
00179         unsigned short temp, i;
00180         
00181         for (i = 0; i < places; i++) {
00182                 temp = input & 0x8000;
00183                 input = input << 1;
00184                 if (temp) {
00185                         input++;
00186                 }
00187         }
00188         return input;
00189 }
00190 
00191 unsigned short Krc2::_rc2_ror(unsigned short input, int places)
00192 {
00193         unsigned short temp, i;
00194         for (i = 0; i < places; i++) {
00195                 temp = input & 0x1;
00196                 input = input >> 1;
00197                 if (temp) {
00198                         input = input + 0x8000;
00199                 }
00200         }
00201         return input;
00202 }
00203 

Generated on Sat Nov 5 16:17:14 2005 for OPIE by  doxygen 1.4.2