<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>Crypto++: safer.cpp Source File</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.3.7 --> <div class="qindex"><a class="qindex" href="index.html">Main Page</a> | <a class="qindex" href="namespaces.html">Namespace List</a> | <a class="qindex" href="hierarchy.html">Class Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical List</a> | <a class="qindex" href="annotated.html">Class List</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="namespacemembers.html">Namespace Members</a> | <a class="qindex" href="functions.html">Class Members</a> | <a class="qindex" href="globals.html">File Members</a></div> <h1>safer.cpp</h1><pre class="fragment"><div>00001 <span class="comment">// safer.cpp - modified by by Wei Dai from Richard De Moliner's safer.c</span> 00002 00003 <span class="preprocessor">#include "pch.h"</span> 00004 <span class="preprocessor">#include "<a class="code" href="safer_8h.html">safer.h</a>"</span> 00005 <span class="preprocessor">#include "misc.h"</span> 00006 00007 NAMESPACE_BEGIN(CryptoPP) 00008 00009 const byte <a class="code" href="class_s_a_f_e_r.html">SAFER</a>::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 <span class="keyword">const</span> 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 <span class="preprocessor">#define EXP(x) exp_tab[(x)]</span> 00046 <span class="preprocessor"></span><span class="preprocessor">#define LOG(x) log_tab[(x)]</span> 00047 <span class="preprocessor"></span><span class="preprocessor">#define PHT(x, y) { y += x; x += y; }</span> 00048 <span class="preprocessor"></span><span class="preprocessor">#define IPHT(x, y) { x -= y; y -= x; }</span> 00049 <span class="preprocessor"></span> 00050 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> BLOCKSIZE = 8; 00051 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MAX_ROUNDS = 13; 00052 00053 <span class="keywordtype">void</span> SAFER::Base::UncheckedSetKey(CipherDir dir, <span class="keyword">const</span> byte *userkey_1, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> nof_rounds) 00054 { 00055 <span class="keyword">const</span> byte *userkey_2 = length == 8 ? userkey_1 : userkey_1 + 8; 00056 keySchedule.New(1 + BLOCKSIZE * (1 + 2 * nof_rounds)); 00057 00058 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, j; 00059 byte *key = keySchedule; 00060 <a class="code" href="class_sec_block.html">SecByteBlock</a> ka(BLOCKSIZE + 1), kb(BLOCKSIZE + 1); 00061 00062 <span class="keywordflow">if</span> (MAX_ROUNDS < nof_rounds) 00063 nof_rounds = MAX_ROUNDS; 00064 *key++ = (<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>)nof_rounds; 00065 ka[BLOCKSIZE] = 0; 00066 kb[BLOCKSIZE] = 0; 00067 <span class="keywordflow">for</span> (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 <span class="keywordflow">for</span> (i = 1; i <= nof_rounds; i++) 00073 { 00074 <span class="keywordflow">for</span> (j = 0; j < BLOCKSIZE + 1; j++) 00075 { 00076 ka[j] = rotlFixed(ka[j], 6U); 00077 kb[j] = rotlFixed(kb[j], 6U); 00078 } 00079 <span class="keywordflow">for</span> (j = 0; j < BLOCKSIZE; j++) 00080 <span class="keywordflow">if</span> (strengthened) 00081 *key++ = (ka[(j + 2 * i - 1) % (BLOCKSIZE + 1)] 00082 + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF; 00083 <span class="keywordflow">else</span> 00084 *key++ = (ka[j] + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF; 00085 <span class="keywordflow">for</span> (j = 0; j < BLOCKSIZE; j++) 00086 <span class="keywordflow">if</span> (strengthened) 00087 *key++ = (kb[(j + 2 * i) % (BLOCKSIZE + 1)] 00088 + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF; 00089 <span class="keywordflow">else</span> 00090 *key++ = (kb[j] + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF; 00091 } 00092 } 00093 00094 <span class="keyword">typedef</span> BlockGetAndPut<byte, BigEndian> Block; 00095 00096 <span class="keywordtype">void</span> SAFER::Enc::ProcessAndXorBlock(<span class="keyword">const</span> byte *inBlock, <span class="keyword">const</span> byte *xorBlock, byte *outBlock)<span class="keyword"> const</span> 00097 <span class="keyword"></span>{ 00098 byte a, b, c, d, e, f, g, h, t; 00099 <span class="keyword">const</span> byte *key = keySchedule+1; 00100 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> round = keySchedule[0]; 00101 00102 Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); 00103 <span class="keywordflow">while</span>(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 <span class="keywordtype">void</span> SAFER::Dec::ProcessAndXorBlock(<span class="keyword">const</span> byte *inBlock, <span class="keyword">const</span> byte *xorBlock, byte *outBlock)<span class="keyword"> const</span> 00123 <span class="keyword"></span>{ 00124 byte a, b, c, d, e, f, g, h, t; 00125 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> round = keySchedule[0]; 00126 <span class="keyword">const</span> 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 <span class="keywordflow">while</span> (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 </div></pre><hr size="1"><address style="align: right;"><small>Generated on Sun Nov 7 08:23:59 2004 for Crypto++ by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border=0 ></a> 1.3.7 </small></address> </body> </html>