Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

wake.cpp

00001 // wake.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 #include "wake.h"
00005 
00006 NAMESPACE_BEGIN(CryptoPP)
00007 
00008 inline word32 WAKE::M(word32 x, word32 y)
00009 {
00010         word32 w = x+y;
00011         return (w>>8) ^ t[(byte)w];
00012 }
00013 
00014 inline word32 WAKE::enc(word32 V)
00015 {
00016         V = V^r6;
00017         r3 = M(r3, V);
00018         r4 = M(r4, r3);
00019         r5 = M(r5, r4);
00020         r6 = M(r6, r5);
00021         return V;
00022 }
00023 
00024 inline word32 WAKE::dec(word32 V)
00025 {
00026         r3 = M(r3, V);
00027         V = V^r6;
00028         r4 = M(r4, r3);
00029         r5 = M(r5, r4);
00030         r6 = M(r6, r5);
00031         return V;
00032 }
00033 
00034 void WAKE::genkey(word32 k0, word32 k1, word32 k2, word32 k3)
00035 {
00036         long x, z;
00037         int p ;
00038         static long tt[10]= {
00039                 0x726a8f3bL,                                                             // table
00040                 0xe69a3b5cL,
00041                 0xd3c71fe5L,
00042                 0xab3c73d2L,
00043                 0x4d3a8eb3L,
00044                 0x0396d6e8L,
00045                 0x3d4c2f7aL,
00046                 0x9ee27cf3L, } ;
00047         t[0] = k0;
00048         t[1] = k1;
00049         t[2] = k2;
00050         t[3] = k3;
00051         for (p=4 ; p<256 ; p++)
00052         {
00053           x=t[p-4]+t[p-1] ;                                        // fill t
00054           t[p]= (x>>3) ^ tt[byte(x&7)] ;
00055         }
00056 
00057         for (p=0 ; p<23 ; p++)
00058                 t[p]+=t[p+89] ;                   // mix first entries
00059         x=t[33] ; z=t[59] | 0x01000001L ;
00060         z=z&0xff7fffffL ;
00061         for (p=0 ; p<256 ; p++) {               //change top byte to
00062           x=(x&0xff7fffffL)+z ;                  // a permutation etc
00063           t[p]=(t[p] & 0x00ffffffL) ^ x ; }
00064 
00065         t[256]=t[0] ;
00066         byte y=byte(x);
00067         for (p=0 ; p<256 ; p++) {         // further change perm.
00068           t[p]=t[y=byte(t[p^y]^y)] ;  // and other digits
00069           t[y]=t[p+1] ;  }
00070 }
00071 
00072 WAKEEncryption::WAKEEncryption(const byte *key, BufferedTransformation *outQueue)
00073         : Filter(outQueue), inbuf(INBUFMAX), inbufSize(0)
00074 {
00075         r3 = ((word32)key[0] << 24) | ((word32)key[1] << 16) | ((word32)key[2] << 8) | (word32)key[3];
00076         r4 = ((word32)key[4] << 24) | ((word32)key[5] << 16) | ((word32)key[6] << 8) | (word32)key[7];
00077         r5 = ((word32)key[8] << 24) | ((word32)key[9] << 16) | ((word32)key[10] << 8) | (word32)key[11];
00078         r6 = ((word32)key[12] << 24) | ((word32)key[13] << 16) | ((word32)key[14] << 8) | (word32)key[15];
00079 
00080         word32 k0 = ((word32)key[16] << 24) | ((word32)key[17] << 16) | ((word32)key[18] << 8) | (word32)key[19];
00081         word32 k1 = ((word32)key[20] << 24) | ((word32)key[21] << 16) | ((word32)key[22] << 8) | (word32)key[23];
00082         word32 k2 = ((word32)key[24] << 24) | ((word32)key[25] << 16) | ((word32)key[26] << 8) | (word32)key[27];
00083         word32 k3 = ((word32)key[28] << 24) | ((word32)key[29] << 16) | ((word32)key[30] << 8) | (word32)key[31];
00084         genkey(k0, k1, k2, k3);
00085 }
00086 
00087 void WAKEEncryption::ProcessInbuf()
00088 {
00089         assert((inbufSize % 4) == 0);
00090 
00091         word32 *ptr = (word32 *)inbuf.ptr;
00092         byte *const end = (byte *)inbuf+inbufSize;
00093 
00094         while (ptr!=(word32 *)end)
00095         {
00096 #ifdef IS_LITTLE_ENDIAN
00097                 *ptr = byteReverse(enc(byteReverse(*ptr)));
00098 #else
00099                 *ptr = enc(*ptr);
00100 #endif
00101                 ptr++;
00102         }
00103 
00104         AttachedTransformation()->Put(inbuf, inbufSize);
00105         inbufSize=0;
00106 }
00107 
00108 void WAKEEncryption::Put(const byte *inString, unsigned int length)
00109 {
00110         while (length)
00111         {
00112                 if (inbufSize==INBUFMAX)
00113                         ProcessInbuf();
00114                 unsigned int l = STDMIN(length, INBUFMAX-inbufSize);
00115                 memcpy(inbuf+inbufSize, inString, l);
00116                 inString+=l;
00117                 length-=l;
00118                 inbufSize+=l;
00119         }
00120 }
00121 
00122 void WAKEEncryption::MessageEnd(int propagation)
00123 {
00124         if (inbufSize == INBUFMAX)
00125                 ProcessInbuf();
00126         // pad to next multiple of 4
00127         memset(inbuf+inbufSize, 4-(inbufSize%4), 4-(inbufSize%4));
00128         inbufSize += 4-(inbufSize%4);
00129         ProcessInbuf();
00130         Filter::MessageEnd(propagation);
00131 }
00132 
00133 void WAKEDecryption::ProcessInbuf()
00134 {
00135         assert((inbufSize % 4) == 0);
00136 
00137         word32 *ptr = (word32 *)inbuf.ptr;
00138         byte *const end = (byte *)inbuf+inbufSize;
00139 
00140         while (ptr!=(word32 *)end)
00141         {
00142 #ifdef IS_LITTLE_ENDIAN
00143                 *ptr = byteReverse(dec(byteReverse(*ptr)));
00144 #else
00145                 *ptr = dec(*ptr);
00146 #endif
00147                 ptr++;
00148         }
00149 
00150         if (lastBlock)
00151         {
00152                 if (inbuf[inbufSize-1] > 4) inbuf[inbufSize-1]=0;
00153                 AttachedTransformation()->Put(inbuf, inbufSize-inbuf[inbufSize-1]);
00154         }
00155         else
00156                 AttachedTransformation()->Put(inbuf, inbufSize);
00157 
00158         inbufSize=0;
00159 }
00160 
00161 void WAKEDecryption::MessageEnd(int propagation)
00162 {
00163         lastBlock = true;
00164         ProcessInbuf();
00165         Filter::MessageEnd(propagation);
00166 }
00167 
00168 NAMESPACE_END

Generated at Mon Jan 15 01:16:38 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000