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

safer.cpp

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

Generated on Fri Aug 27 13:36:37 2004 for Crypto++ by doxygen 1.3.8