Crypto++
|
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 void WAKE_TestInstantiations() 00009 { 00010 WAKE_OFB<>::Encryption x2; 00011 WAKE_OFB<>::Decryption x4; 00012 } 00013 00014 inline word32 WAKE_Base::M(word32 x, word32 y) 00015 { 00016 word32 w = x+y; 00017 return (w>>8) ^ t[w & 0xff]; 00018 } 00019 00020 void WAKE_Base::GenKey(word32 k0, word32 k1, word32 k2, word32 k3) 00021 { 00022 // this code is mostly copied from David Wheeler's paper "A Bulk Data Encryption Algorithm" 00023 signed int x, z, p; 00024 // x and z were declared as "long" in Wheeler's paper, which is a signed type. I don't know if that was intentional, but it's too late to change it now. -- Wei 7/4/2010 00025 CRYPTOPP_COMPILE_ASSERT(sizeof(x) == 4); 00026 static int tt[10]= { 00027 0x726a8f3b, // table 00028 0xe69a3b5c, 00029 0xd3c71fe5, 00030 0xab3c73d2, 00031 0x4d3a8eb3, 00032 0x0396d6e8, 00033 0x3d4c2f7a, 00034 0x9ee27cf3, } ; 00035 t[0] = k0; 00036 t[1] = k1; 00037 t[2] = k2; 00038 t[3] = k3; 00039 for (p=4 ; p<256 ; p++) 00040 { 00041 x=t[p-4]+t[p-1] ; // fill t 00042 t[p]= (x>>3) ^ tt[x&7] ; 00043 } 00044 00045 for (p=0 ; p<23 ; p++) 00046 t[p]+=t[p+89] ; // mix first entries 00047 x=t[33] ; z=t[59] | 0x01000001 ; 00048 z=z&0xff7fffff ; 00049 for (p=0 ; p<256 ; p++) { //change top byte to 00050 x=(x&0xff7fffff)+z ; // a permutation etc 00051 t[p]=(t[p] & 0x00ffffff) ^ x ; } 00052 00053 t[256]=t[0] ; 00054 byte y=byte(x); 00055 for (p=0 ; p<256 ; p++) { // further change perm. 00056 t[p]=t[y=byte(t[p^y]^y)] ; // and other digits 00057 t[y]=t[p+1] ; } 00058 } 00059 00060 template <class B> 00061 void WAKE_Policy<B>::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) 00062 { 00063 word32 k0, k1, k2, k3; 00064 BlockGetAndPut<word32, BigEndian>::Get(key)(r3)(r4)(r5)(r6)(k0)(k1)(k2)(k3); 00065 GenKey(k0, k1, k2, k3); 00066 } 00067 00068 // OFB 00069 template <class B> 00070 void WAKE_Policy<B>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) 00071 { 00072 #define WAKE_OUTPUT(x)\ 00073 while (iterationCount--)\ 00074 {\ 00075 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, r6);\ 00076 r3 = M(r3, r6);\ 00077 r4 = M(r4, r3);\ 00078 r5 = M(r5, r4);\ 00079 r6 = M(r6, r5);\ 00080 output += 4;\ 00081 if (!(x & INPUT_NULL))\ 00082 input += 4;\ 00083 } 00084 00085 typedef word32 WordType; 00086 CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(WAKE_OUTPUT, 0); 00087 } 00088 /* 00089 template <class B> 00090 void WAKE_ROFB_Policy<B>::Iterate(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount) 00091 { 00092 KeystreamOutput<B> keystreamOperation(operation, output, input); 00093 00094 while (iterationCount--) 00095 { 00096 keystreamOperation(r6); 00097 r3 = M(r3, r6); 00098 r4 = M(r4, r3); 00099 r5 = M(r5, r4); 00100 r6 = M(r6, r5); 00101 } 00102 } 00103 */ 00104 template class WAKE_Policy<BigEndian>; 00105 template class WAKE_Policy<LittleEndian>; 00106 //template class WAKE_ROFB_Policy<BigEndian>; 00107 //template class WAKE_ROFB_Policy<LittleEndian>; 00108 00109 NAMESPACE_END