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 Sat Apr 2 21:53:53 2005 for Crypto++ by  doxygen 1.3.9.1