📄 diamond_8cpp-source.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"><title>Crypto++: diamond.cpp Source File</title><link href="doxygen.css" rel="stylesheet" type="text/css"></head><body><!-- Generated by Doxygen 1.3.2 --><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">Compound 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">Compound Members</a> | <a class="qindex" href="globals.html">File Members</a></div><h1>diamond.cpp</h1><div class="fragment"><pre>00001 <span class="comment">// diamond.cpp - modified by Wei Dai from:</span>00002 00003 <span class="comment">/* diamond2.c - Encryption designed to exceed DES in security.</span>00004 <span class="comment"> This file and the Diamond2 and Diamond2 Lite Block Ciphers</span>00005 <span class="comment"> described herein are hereby dedicated to the Public Domain by the</span>00006 <span class="comment"> author and inventor, Michael Paul Johnson. Feel free to use these</span>00007 <span class="comment"> for any purpose that is legally and morally right. The names</span>00008 <span class="comment"> "Diamond2 Block Cipher" and "Diamond2 Lite Block Cipher" should only</span>00009 <span class="comment"> be used to describe the algorithms described in this file, to avoid</span>00010 <span class="comment"> confusion.</span>00011 <span class="comment"></span>00012 <span class="comment"> Disclaimers: the following comes with no warranty, expressed or</span>00013 <span class="comment"> implied. You, the user, must determine the suitability of this</span>00014 <span class="comment"> information to your own uses. You must also find out what legal</span>00015 <span class="comment"> requirements exist with respect to this data and programs using</span>00016 <span class="comment"> it, and comply with whatever valid requirements exist.</span>00017 <span class="comment">*/</span>00018 00019 <span class="preprocessor">#include "pch.h"</span>00020 <span class="preprocessor">#include "<a class="code" href="diamond_8h.html">diamond.h</a>"</span>00021 <span class="preprocessor">#include "crc.h"</span>00022 00023 NAMESPACE_BEGIN(CryptoPP)00024 00025 <span class="keyword">class </span>Diamond2SboxMaker00026 {00027 <span class="keyword">public</span>:00028 Diamond2SboxMaker(<span class="keyword">const</span> byte *external_key, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> key_size,00029 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> rounds, <span class="keywordtype">bool</span> lite);00030 00031 <span class="keywordtype">void</span> MakeSbox(byte *sbox, CipherDir direction);00032 00033 <span class="keyword">private</span>:00034 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> keyrand(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> max_value, <span class="keyword">const</span> byte *prevSbox);00035 <span class="keywordtype">void</span> makeonebox(byte *s, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> j);00036 00037 <a class="code" href="class_c_r_c32.html">CRC32</a> crc;00038 <span class="keyword">const</span> byte *<span class="keyword">const</span> key;00039 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> keysize;00040 <span class="keywordtype">unsigned</span> keyindex;00041 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> numrounds;00042 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> roundsize; <span class="comment">// Number of bytes in one round of substitution boxes</span>00043 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> blocksize;00044 };00045 00046 Diamond2SboxMaker::Diamond2SboxMaker(<span class="keyword">const</span> byte *external_key, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> key_size, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> rounds,00047 <span class="keywordtype">bool</span> lite)00048 : key(external_key),00049 keysize(key_size),00050 keyindex(0),00051 numrounds(rounds),00052 roundsize(lite ? 2048 : 4096),00053 blocksize(lite ? 8 : 16)00054 {00055 assert((rounds * blocksize) <= 255);00056 }00057 00058 <span class="comment">// Returns uniformly distributed pseudorandom value based on key[], sized keysize</span>00059 <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Diamond2SboxMaker::keyrand(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> max_value, <span class="keyword">const</span> byte *prevSbox)00060 {00061 assert(max_value <= 255);00062 00063 <span class="keywordflow">if</span> (!max_value) <span class="keywordflow">return</span> 0;00064 00065 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> mask, prandvalue, i;00066 00067 <span class="comment">// Create a mask to get the minimum number of </span>00068 <span class="comment">// bits to cover the range 0 to max_value.</span>00069 <span class="keywordflow">for</span> (i=max_value, mask=0; i > 0; i = i >> 1)00070 mask = (mask << 1) | 1;00071 00072 assert(i==0);00073 <span class="keywordflow">do</span>00074 {00075 <span class="keywordflow">if</span> (prevSbox)00076 crc.UpdateByte(prevSbox[key[keyindex++]]);00077 <span class="keywordflow">else</span>00078 crc.UpdateByte(key[keyindex++]);00079 00080 <span class="keywordflow">if</span> (keyindex >= keysize)00081 {00082 keyindex = 0; <span class="comment">/* Recycle thru the key */</span>00083 crc.UpdateByte(byte(keysize));00084 crc.UpdateByte(byte(keysize >> 8));00085 }00086 prandvalue = crc.GetCrcByte(0) & mask;00087 <span class="keywordflow">if</span> ((++i>97) && (prandvalue > max_value)) <span class="comment">/* Don't loop forever. */</span>00088 prandvalue -= max_value; <span class="comment">/* Introduce negligible bias. */</span>00089 }00090 <span class="keywordflow">while</span> (prandvalue > max_value); <span class="comment">/* Discard out of range values. */</span>00091 <span class="keywordflow">return</span> prandvalue;00092 }00093 00094 <span class="keywordtype">void</span> Diamond2SboxMaker::makeonebox(byte *s, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> j)00095 {00096 <span class="keywordtype">bool</span> filled[256];00097 byte *sbox = s + (roundsize*i) + (256*j);00098 byte *prevSbox = (i||j) ? sbox-256 : 0;00099 00100 <span class="keywordtype">unsigned</span> m;00101 <span class="keywordflow">for</span> (m = 0; m < 256; m++) <span class="comment">/* The filled array is used to make sure that */</span>00102 filled[m] = <span class="keyword">false</span>; <span class="comment">/* each byte of the array is filled only once. */</span>00103 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> n = 255; n >= 0 ; n--) <span class="comment">/* n counts the number of bytes left to fill */</span>00104 {00105 <span class="comment">// pos is the position among the UNFILLED</span>00106 <span class="comment">// components of the s array that the number n should be placed.</span>00107 <span class="keywordtype">unsigned</span> pos = keyrand(n, prevSbox); 00108 <span class="keywordtype">unsigned</span> p=0;00109 <span class="keywordflow">while</span> (filled[p]) p++;00110 <span class="keywordflow">for</span> (m=0; m<pos; m++)00111 {00112 p++;00113 <span class="keywordflow">while</span> (filled[p]) p++;00114 }00115 assert(p<256);00116 sbox[p] = n;00117 filled[p] = <span class="keyword">true</span>;00118 }00119 }00120 00121 <span class="keywordtype">void</span> Diamond2SboxMaker::MakeSbox(byte *s, CipherDir direction)00122 {00123 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, j, k;00124 00125 <span class="keywordflow">for</span> (i = 0; i < numrounds; i++)00126 <span class="keywordflow">for</span> (j = 0; j < blocksize; j++)00127 makeonebox(s, i, j);00128 00129 <span class="keywordflow">if</span> (direction==DECRYPTION)00130 {00131 <a class="code" href="class_sec_block.html">SecByteBlock</a> si(numrounds * roundsize);00132 <span class="keywordflow">for</span> (i = 0; i < numrounds; i++)00133 <span class="keywordflow">for</span> (j = 0; j < blocksize; j++)00134 <span class="keywordflow">for</span> (k = 0; k < 256; k++)00135 *(si + (roundsize * i) + (256 * j) + *(s + (roundsize * i) + (256 * j) + k)) = k;00136 memcpy(s, si, numrounds * roundsize);00137 }00138 }00139 00140 <span class="keywordtype">void</span> Diamond2::Base::UncheckedSetKey(CipherDir direction, <span class="keyword">const</span> byte *userKey, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> rounds)00141 {00142 AssertValidKeyLength(length);00143 00144 numrounds = rounds;00145 s.New(numrounds * ROUNDSIZE);00146 00147 Diamond2SboxMaker m(userKey, length, rounds, <span class="keyword">false</span>);00148 m.MakeSbox(s, direction);00149 }00150 00151 <span class="keyword">inline</span> <span class="keywordtype">void</span> Diamond2::Base::substitute(<span class="keywordtype">int</span> round, byte *x, <span class="keyword">const</span> byte *y)<span class="keyword"> const</span>00152 <span class="keyword"></span>{00153 <span class="keyword">const</span> byte *sbox = s + (ROUNDSIZE*round);00154 x[0] = sbox[0*256+y[0]];00155 x[1] = sbox[1*256+y[1]];00156 x[2] = sbox[2*256+y[2]];00157 x[3] = sbox[3*256+y[3]];00158 x[4] = sbox[4*256+y[4]];00159 x[5] = sbox[5*256+y[5]];00160 x[6] = sbox[6*256+y[6]];00161 x[7] = sbox[7*256+y[7]];00162 x[8] = sbox[8*256+y[8]];00163 x[9] = sbox[9*256+y[9]];00164 x[10] = sbox[10*256+y[10]];00165 x[11] = sbox[11*256+y[11]];00166 x[12] = sbox[12*256+y[12]];00167 x[13] = sbox[13*256+y[13]];00168 x[14] = sbox[14*256+y[14]];00169 x[15] = sbox[15*256+y[15]];00170 }00171 00172 <span class="preprocessor">#ifdef DIAMOND_USE_PERMTABLE</span>00173 <span class="preprocessor"></span>00174 <span class="keyword">inline</span> <span class="keywordtype">void</span> Diamond2::Base::permute(byte *a)00175 {00176 <span class="preprocessor">#ifdef IS_LITTLE_ENDIAN</span>00177 <span class="preprocessor"></span> word32 temp0 = (a[0] | (word32(a[10])<<24)) & 0x80000001;00178 <span class="preprocessor">#else</span>00179 <span class="preprocessor"></span> word32 temp0 = ((word32(a[0])<<24) | a[10]) & 0x01000080;00180 <span class="preprocessor">#endif</span>00181 <span class="preprocessor"></span> temp0 |= permtable[0][a[1]] |00182 permtable[1][a[2]] | permtable[2][a[3]] |00183 permtable[3][a[4]] | permtable[4][a[5]] |00184 permtable[5][a[6]] | permtable[6][a[7]] |00185 permtable[7][a[8]] | permtable[8][a[9]];00186 00187 <span class="preprocessor">#ifdef IS_LITTLE_ENDIAN</span>00188 <span class="preprocessor"></span> word32 temp1 = (a[4] | (word32(a[14])<<24)) & 0x80000001;00189 <span class="preprocessor">#else</span>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -