2002-10-04 17:31:41 +00:00
// wake.cpp - written and placed in the public domain by Wei Dai
# include "pch.h"
# include "wake.h"
NAMESPACE_BEGIN ( CryptoPP )
void WAKE_TestInstantiations ( )
{
WAKE_OFB < > : : Encryption x2 ;
WAKE_OFB < > : : Decryption x4 ;
}
inline word32 WAKE_Base : : M ( word32 x , word32 y )
{
word32 w = x + y ;
2010-07-05 01:15:14 +00:00
return ( w > > 8 ) ^ t [ w & 0xff ] ;
2002-10-04 17:31:41 +00:00
}
void WAKE_Base : : GenKey ( word32 k0 , word32 k1 , word32 k2 , word32 k3 )
{
2010-07-05 01:15:14 +00:00
// this code is mostly copied from David Wheeler's paper "A Bulk Data Encryption Algorithm"
signed int x , z , p ;
// 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
CRYPTOPP_COMPILE_ASSERT ( sizeof ( x ) = = 4 ) ;
2015-06-09 13:49:02 +00:00
static unsigned int tt [ 10 ] = {
2010-07-05 01:15:14 +00:00
0x726a8f3b , // table
0xe69a3b5c ,
0xd3c71fe5 ,
0xab3c73d2 ,
0x4d3a8eb3 ,
0x0396d6e8 ,
0x3d4c2f7a ,
0x9ee27cf3 , } ;
2002-10-04 17:31:41 +00:00
t [ 0 ] = k0 ;
t [ 1 ] = k1 ;
t [ 2 ] = k2 ;
t [ 3 ] = k3 ;
for ( p = 4 ; p < 256 ; p + + )
{
x = t [ p - 4 ] + t [ p - 1 ] ; // fill t
2010-07-05 01:15:14 +00:00
t [ p ] = ( x > > 3 ) ^ tt [ x & 7 ] ;
2002-10-04 17:31:41 +00:00
}
for ( p = 0 ; p < 23 ; p + + )
t [ p ] + = t [ p + 89 ] ; // mix first entries
2010-07-05 01:15:14 +00:00
x = t [ 33 ] ; z = t [ 59 ] | 0x01000001 ;
z = z & 0xff7fffff ;
2002-10-04 17:31:41 +00:00
for ( p = 0 ; p < 256 ; p + + ) { //change top byte to
2010-07-05 01:15:14 +00:00
x = ( x & 0xff7fffff ) + z ; // a permutation etc
t [ p ] = ( t [ p ] & 0x00ffffff ) ^ x ; }
2002-10-04 17:31:41 +00:00
t [ 256 ] = t [ 0 ] ;
byte y = byte ( x ) ;
for ( p = 0 ; p < 256 ; p + + ) { // further change perm.
t [ p ] = t [ y = byte ( t [ p ^ y ] ^ y ) ] ; // and other digits
t [ y ] = t [ p + 1 ] ; }
}
template < class B >
2005-07-12 04:23:32 +00:00
void WAKE_Policy < B > : : CipherSetKey ( const NameValuePairs & params , const byte * key , size_t length )
2002-10-04 17:31:41 +00:00
{
word32 k0 , k1 , k2 , k3 ;
2009-03-02 02:39:17 +00:00
BlockGetAndPut < word32 , BigEndian > : : Get ( key ) ( r3 ) ( r4 ) ( r5 ) ( r6 ) ( k0 ) ( k1 ) ( k2 ) ( k3 ) ;
2002-10-04 17:31:41 +00:00
GenKey ( k0 , k1 , k2 , k3 ) ;
}
// OFB
template < class B >
2005-07-12 04:23:32 +00:00
void WAKE_Policy < B > : : OperateKeystream ( KeystreamOperation operation , byte * output , const byte * input , size_t iterationCount )
2002-10-04 17:31:41 +00:00
{
2007-04-15 22:59:12 +00:00
# define WAKE_OUTPUT(x)\
while ( iterationCount - - ) \
{ \
CRYPTOPP_KEYSTREAM_OUTPUT_WORD ( x , B : : ToEnum ( ) , 0 , r6 ) ; \
r3 = M ( r3 , r6 ) ; \
r4 = M ( r4 , r3 ) ; \
r5 = M ( r5 , r4 ) ; \
r6 = M ( r6 , r5 ) ; \
output + = 4 ; \
2009-10-31 21:18:37 +00:00
if ( ! ( x & INPUT_NULL ) ) \
2007-04-15 22:59:12 +00:00
input + = 4 ; \
2002-10-04 17:31:41 +00:00
}
2007-04-15 22:59:12 +00:00
typedef word32 WordType ;
CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH ( WAKE_OUTPUT , 0 ) ;
2002-10-04 17:31:41 +00:00
}
/*
template < class B >
void WAKE_ROFB_Policy < B > : : Iterate ( KeystreamOperation operation , byte * output , const byte * input , unsigned int iterationCount )
{
KeystreamOutput < B > keystreamOperation ( operation , output , input ) ;
while ( iterationCount - - )
{
keystreamOperation ( r6 ) ;
r3 = M ( r3 , r6 ) ;
r4 = M ( r4 , r3 ) ;
r5 = M ( r5 , r4 ) ;
r6 = M ( r6 , r5 ) ;
}
}
*/
template class WAKE_Policy < BigEndian > ;
template class WAKE_Policy < LittleEndian > ;
//template class WAKE_ROFB_Policy<BigEndian>;
//template class WAKE_ROFB_Policy<LittleEndian>;
NAMESPACE_END