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 #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 &params)
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

Generated on Sat Dec 23 02:07:10 2006 for Crypto++ by  doxygen 1.5.1-p1