00001
00002
00003
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];
00041 int _rc2_counter;
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
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
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
00071 _rc2_expkey[128 - ekl8] = _rc2_pitable[_rc2_expkey[128 - ekl8] & keymask];
00072
00073
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