Crypto++
|
00001 // safer.cpp - modified by by Wei Dai from Richard De Moliner's safer.c 00002 00003 #include "pch.h" 00004 #include "safer.h" 00005 #include "misc.h" 00006 #include "argnames.h" 00007 00008 NAMESPACE_BEGIN(CryptoPP) 00009 00010 const byte SAFER::Base::exp_tab[256] = 00011 {1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, 00012 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, 00013 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 00014 255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 00015 241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 00016 129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 00017 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 00018 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217, 00019 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194, 00020 249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10, 00021 193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, 00022 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, 00023 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237, 00024 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97, 00025 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5, 00026 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40}; 00027 00028 const byte SAFER::Base::log_tab[256] = 00029 {128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248, 00030 192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130, 00031 112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37, 00032 201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15, 00033 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198, 00034 175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84, 00035 121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188, 00036 189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217, 00037 208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158, 00038 210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42, 00039 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219, 00040 164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29, 00041 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14, 00042 122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104, 00043 109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66, 00044 184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48}; 00045 00046 #define EXP(x) exp_tab[(x)] 00047 #define LOG(x) log_tab[(x)] 00048 #define PHT(x, y) { y += x; x += y; } 00049 #define IPHT(x, y) { x -= y; y -= x; } 00050 00051 static const unsigned int BLOCKSIZE = 8; 00052 static const unsigned int MAX_ROUNDS = 13; 00053 00054 void SAFER::Base::UncheckedSetKey(const byte *userkey_1, unsigned int length, const NameValuePairs ¶ms) 00055 { 00056 bool strengthened = Strengthened(); 00057 unsigned int nof_rounds = params.GetIntValueWithDefault(Name::Rounds(), length == 8 ? (strengthened ? 8 : 6) : 10); 00058 00059 const byte *userkey_2 = length == 8 ? userkey_1 : userkey_1 + 8; 00060 keySchedule.New(1 + BLOCKSIZE * (1 + 2 * nof_rounds)); 00061 00062 unsigned int i, j; 00063 byte *key = keySchedule; 00064 SecByteBlock ka(BLOCKSIZE + 1), kb(BLOCKSIZE + 1); 00065 00066 if (MAX_ROUNDS < nof_rounds) 00067 nof_rounds = MAX_ROUNDS; 00068 *key++ = (unsigned char)nof_rounds; 00069 ka[BLOCKSIZE] = 0; 00070 kb[BLOCKSIZE] = 0; 00071 for (j = 0; j < BLOCKSIZE; j++) 00072 { 00073 ka[BLOCKSIZE] ^= ka[j] = rotlFixed(userkey_1[j], 5U); 00074 kb[BLOCKSIZE] ^= kb[j] = *key++ = userkey_2[j]; 00075 } 00076 00077 for (i = 1; i <= nof_rounds; i++) 00078 { 00079 for (j = 0; j < BLOCKSIZE + 1; j++) 00080 { 00081 ka[j] = rotlFixed(ka[j], 6U); 00082 kb[j] = rotlFixed(kb[j], 6U); 00083 } 00084 for (j = 0; j < BLOCKSIZE; j++) 00085 if (strengthened) 00086 *key++ = (ka[(j + 2 * i - 1) % (BLOCKSIZE + 1)] 00087 + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF; 00088 else 00089 *key++ = (ka[j] + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF; 00090 for (j = 0; j < BLOCKSIZE; j++) 00091 if (strengthened) 00092 *key++ = (kb[(j + 2 * i) % (BLOCKSIZE + 1)] 00093 + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF; 00094 else 00095 *key++ = (kb[j] + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF; 00096 } 00097 } 00098 00099 typedef BlockGetAndPut<byte, BigEndian> Block; 00100 00101 void SAFER::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 00102 { 00103 byte a, b, c, d, e, f, g, h, t; 00104 const byte *key = keySchedule+1; 00105 unsigned int round = keySchedule[0]; 00106 00107 Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); 00108 while(round--) 00109 { 00110 a ^= key[0]; b += key[1]; c += key[2]; d ^= key[3]; 00111 e ^= key[4]; f += key[5]; g += key[6]; h ^= key[7]; 00112 a = EXP(a) + key[ 8]; b = LOG(b) ^ key[ 9]; 00113 c = LOG(c) ^ key[10]; d = EXP(d) + key[11]; 00114 e = EXP(e) + key[12]; f = LOG(f) ^ key[13]; 00115 g = LOG(g) ^ key[14]; h = EXP(h) + key[15]; 00116 key += 16; 00117 PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h); 00118 PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h); 00119 PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h); 00120 t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t; 00121 } 00122 a ^= key[0]; b += key[1]; c += key[2]; d ^= key[3]; 00123 e ^= key[4]; f += key[5]; g += key[6]; h ^= key[7]; 00124 Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h); 00125 } 00126 00127 void SAFER::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 00128 { 00129 byte a, b, c, d, e, f, g, h, t; 00130 unsigned int round = keySchedule[0]; 00131 const byte *key = keySchedule + BLOCKSIZE * (1 + 2 * round) - 7; 00132 00133 Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); 00134 h ^= key[7]; g -= key[6]; f -= key[5]; e ^= key[4]; 00135 d ^= key[3]; c -= key[2]; b -= key[1]; a ^= key[0]; 00136 while (round--) 00137 { 00138 key -= 16; 00139 t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t; 00140 IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h); 00141 IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h); 00142 IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h); 00143 h -= key[15]; g ^= key[14]; f ^= key[13]; e -= key[12]; 00144 d -= key[11]; c ^= key[10]; b ^= key[9]; a -= key[8]; 00145 h = LOG(h) ^ key[7]; g = EXP(g) - key[6]; 00146 f = EXP(f) - key[5]; e = LOG(e) ^ key[4]; 00147 d = LOG(d) ^ key[3]; c = EXP(c) - key[2]; 00148 b = EXP(b) - key[1]; a = LOG(a) ^ key[0]; 00149 } 00150 Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h); 00151 } 00152 00153 NAMESPACE_END