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

Tausworthe.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002 ***    
00003 *** Copyright (c) 1995-2000 Regents of the University of California,
00004 ***               Andrew E. Caldwell, Andrew B. Kahng and Igor L. Markov
00005 *** Copyright (c) 2000-2004 Regents of the University of Michigan,
00006 ***               Saurabh N. Adya, Jarrod A. Roy and Igor L. Markov
00007 ***
00008 ***  Contact author(s): abk@cs.ucsd.edu, imarkov@umich.edu
00009 ***  Original Affiliation:   UCLA, Computer Science Department,
00010 ***                          Los Angeles, CA 90095-1596 USA
00011 ***
00012 ***  Permission is hereby granted, free of charge, to any person obtaining 
00013 ***  a copy of this software and associated documentation files (the
00014 ***  "Software"), to deal in the Software without restriction, including
00015 ***  without limitation 
00016 ***  the rights to use, copy, modify, merge, publish, distribute, sublicense, 
00017 ***  and/or sell copies of the Software, and to permit persons to whom the 
00018 ***  Software is furnished to do so, subject to the following conditions:
00019 ***
00020 ***  The above copyright notice and this permission notice shall be included
00021 ***  in all copies or substantial portions of the Software.
00022 ***
00023 *** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
00024 *** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
00025 *** OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
00026 *** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
00027 *** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
00028 *** OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
00029 *** THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00030 ***
00031 ***
00032 ***************************************************************************/
00033 
00034 
00035 
00036 
00037 //  Created : 10/09/97, Mike Oliver, VLSI CAD ABKGROUP UCLA 
00038 
00039 #include <string.h>
00040 
00041 #ifdef _MSC_VER
00042 #pragma warning(disable:4786)
00043 #endif
00044 
00045 #include "abkrand.h"
00046 #include "abkMD5.h"
00047 
00048 static const unsigned cryptMod    = 0xfffffffb; // greatest 32-bit prime
00049 static const unsigned initVector  = 0xa90acaf7;
00050 static const unsigned twoTo16     = 0x10000;
00051 static const unsigned twoTo31     = 0x80000000;
00052 
00053 static const char padding[]="I am I, Don Quixote, the Lord of La Mancha, my "
00054                       "destiny calls and I go.  And the wild winds of "
00055                       "fortune shall carry me onwards, o whithersoever "
00056                       "they blow";
00057 
00058 static void numToStr(char *str,unsigned num)
00059     {
00060     str[0] = (num & 0xf) +1;
00061     num >>= 4;
00062     str[1] = (num & 0xf) +1;
00063     num >>= 4;
00064     str[2] = (num & 0xf) +1;
00065     num >>= 4;
00066     str[3] = (num & 0xf) +1;
00067     num >>= 4;
00068     str[4] = (num & 0xf) +1;
00069     num >>= 4;
00070     str[5] = (num & 0xf) +1;
00071     num >>= 4;
00072     str[6] = (num & 0xf) +1;
00073     num >>= 4;
00074     str[7] = (num & 0xf) +1;
00075     }
00076 
00077 unsigned Tausworthe::_encryptWithSeed(unsigned clear)
00078     {
00079 //    cout << "clear: " << clear << endl;
00080     unsigned initval = clear^_seed;
00081 //    cout << "initval" << initval << endl;
00082     unsigned runval = initval;
00083     runval = _multmod(runval,runval);
00084 //    cout << "runval-I" << runval << endl;
00085     runval = _multmod(runval,runval);
00086     runval = _multmod(runval,runval);
00087     runval = _multmod(runval,runval);
00088     runval = _multmod(runval,initval);
00089     return runval;
00090 
00091     }
00092 
00093 inline unsigned trim(unsigned arg)
00094 { return (arg>=cryptMod)?(arg-cryptMod):arg;}
00095 
00096 
00097 unsigned addMod(unsigned x, unsigned y)
00098 {
00099     bool bigX=false,bigY=false;
00100     unsigned retval;
00101     if (x>=twoTo31) {x-=twoTo31;bigX=true;}
00102     if (y>=twoTo31) {y-=twoTo31;bigY=true;}
00103     if (bigX&&bigY)
00104     {
00105         retval = trim(trim(x+y)+5) ;//mod 2^32-5
00106     }
00107     else if (bigX||bigY)
00108     {
00109         if ((x+y)<twoTo31)
00110             retval = trim(x+y+twoTo31);
00111         else
00112             retval = trim(((x+y)-twoTo31)+5);
00113     }
00114     else
00115         retval = trim(x+y);
00116     return retval;
00117 }
00118 
00119 unsigned times5(unsigned x)
00120 {
00121     unsigned x2=addMod(x,x);
00122     unsigned x4=addMod(x2,x2);
00123     return addMod(x,x4);
00124     /*
00125     unsigned lowerX = x &  0x0000ffff;
00126     unsigned upperX = x >> 16;
00127     unsigned upTimes5=upperX*5; //can't overflow or exceed cryptMod
00128     unsigned upTerm;
00129     if (upTimes5>=twoTo16)
00130         upTerm=(upTimes5-twoTo16)*twoTo16+5; //can't overflow or exceed cryptMod
00131     else
00132         upTerm=upTimes5*twoTo16; // can't overflow or exceed cryptMod
00133     unsigned lowTerm=lowerX*5; //can't overflow or exceed cryptMod
00134     return addMod(upTerm,lowTerm);
00135     */
00136 }
00137 
00138 unsigned timesTwoTo16(unsigned x)
00139 {
00140     unsigned lowerX = x &  0x0000ffff;
00141     unsigned upperX = x >> 16;
00142     unsigned upTerm=upperX*5;
00143     unsigned lowTerm=lowerX*twoTo16;
00144 
00145     return addMod(upTerm,lowTerm);
00146 }
00147 
00148 unsigned Tausworthe::_multmod(unsigned x,unsigned y)
00149 {
00150     unsigned lowerY = y &  0x0000ffff;
00151     unsigned upperY = y >> 16;
00152     unsigned lowerX = x &  0x0000ffff;
00153     unsigned upperX = x >> 16;
00154 
00155     unsigned upperProd = trim(upperX*upperY);
00156     unsigned upperTerm = trim(times5(upperProd)); //contrib to sum mod 2^32-5
00157     unsigned midProd1 = trim(lowerY*upperX);
00158     unsigned midTerm1 = trim(timesTwoTo16(midProd1));
00159     unsigned midProd2 = trim(upperY*lowerX);
00160     unsigned midTerm2 = trim(timesTwoTo16(midProd2));
00161     unsigned lowerProd = trim(lowerY*lowerX);
00162 
00163     return addMod(upperTerm,addMod(midTerm1,addMod(midTerm2,lowerProd)));
00164 
00165 }
00166 
00167 void Tausworthe::_encryptBufWithSeed()
00168     {
00169     unsigned i;
00170     unsigned mask = 0xffffffff;
00171     unsigned setbit = 0x1;
00172     unsigned IVlocal = _encryptWithSeed(initVector);
00173 //  cout << "IVlocal" << IVlocal << endl;
00174     memcpy(_buffer,_preloads,_bufferSize*sizeof(unsigned));
00175 
00176     //Having preloaded the buffer with the noise above, we
00177     //now "encrypt" it in cipher-feedback mode.  "Encrypt" is
00178     //in quotes because it's not intended to be secure and isn't
00179     //*quite* a permutation (although there's a decryption method
00180     //that would work 99.999% of the time).
00181 
00182     //The purpose of this is so that related seeds will not
00183     //produce results that depend on each other in any obvious way.
00184 
00185     for (i=0;i<_bufferSize;i++)
00186         {
00187         _buffer[i] ^= IVlocal;
00188         IVlocal = _encryptWithSeed(_buffer[i]);
00189         }
00190 
00191     //Now we make sure the 32 columns of bits are linearly
00192     //independent.  This is kind of overkill as the chance
00193     //of linear dependence is only 1 in 2^218, but it doesn't
00194     //really cost anything and everybody does it, so why not.
00195 
00196     for (i=0;i<sizeof(unsigned)*8;i++)
00197         {
00198         _buffer[i] &= mask;
00199         _buffer[i] |= setbit;
00200         mask <<= 1;
00201         setbit <<= 1;
00202         }
00203 
00204     _cursor=0;
00205     }
00206 
00207 void Tausworthe::_encryptBufMultipartiteSeed()
00208     {
00209     unsigned i;
00210     unsigned mask = 0xffffffff;
00211     unsigned setbit = 0x1;
00212     MD5 hashPool;
00213     unsigned extSeed=getExternalSeed();
00214     unsigned counter=getCounter();
00215 
00216     char numstr[9];
00217     numstr[8]=0;
00218     const char *numstrPtr=reinterpret_cast<const char*>(numstr);
00219     const char *padPtr=reinterpret_cast<const char*>(padding);
00220 
00221     numToStr(numstr,extSeed);
00222     hashPool.update(numstrPtr,false);
00223     numToStr(numstr,counter);
00224     hashPool.update(numstrPtr,false);
00225 
00226     hashPool.update(getLocIdent(),false);
00227     hashPool.update(padPtr,false); //make sure we *do* MD5 transforms
00228 
00229     unsigned IVlocal = hashPool.getWord(0);
00230 
00231     memcpy(_buffer,_preloads,_bufferSize*sizeof(unsigned));
00232 
00233     //Having preloaded the buffer with the noise above, we
00234     //now "encrypt" it in cipher-feedback mode.
00235 
00236     //The purpose of this is so that related seeds will not
00237     //produce results that depend on each other in any obvious way.
00238 
00239     for (i=0;i<_bufferSize;i++)
00240         {
00241         _buffer[i] ^= IVlocal;
00242         numToStr(numstr,_buffer[i]);
00243         hashPool.update(numstrPtr,false);
00244         hashPool.update(padPtr,false);
00245         IVlocal = hashPool.getWord(0);
00246         }
00247 
00248     //Now we make sure the 32 columns of bits are linearly
00249     //independent.  This is kind of overkill as the chance
00250     //of linear dependence is only 1 in 2^218, but it doesn't
00251     //really cost anything and everybody does it, so why not.
00252 
00253     for (i=0;i<sizeof(unsigned)*8;i++)
00254         {
00255         _buffer[i] &= mask;
00256         _buffer[i] |= setbit;
00257         mask <<= 1;
00258         setbit <<= 1;
00259         }
00260 
00261     _cursor=0;
00262 
00263     }
00264 

Generated on Mon Apr 25 01:09:25 2005 for Parquete by doxygen 1.3.2