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

shark.cpp

00001 // shark.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 
00005 #ifdef WORD64_AVAILABLE
00006 
00007 #include "shark.h"
00008 #include "misc.h"
00009 #include "modes.h"
00010 #include "gf256.h"
00011 
00012 NAMESPACE_BEGIN(CryptoPP)
00013 
00014 static word64 SHARKTransform(word64 a)
00015 {
00016         static const byte iG[8][8] = {
00017                 0xe7, 0x30, 0x90, 0x85, 0xd0, 0x4b, 0x91, 0x41, 
00018                 0x53, 0x95, 0x9b, 0xa5, 0x96, 0xbc, 0xa1, 0x68, 
00019                 0x02, 0x45, 0xf7, 0x65, 0x5c, 0x1f, 0xb6, 0x52, 
00020                 0xa2, 0xca, 0x22, 0x94, 0x44, 0x63, 0x2a, 0xa2, 
00021                 0xfc, 0x67, 0x8e, 0x10, 0x29, 0x75, 0x85, 0x71, 
00022                 0x24, 0x45, 0xa2, 0xcf, 0x2f, 0x22, 0xc1, 0x0e, 
00023                 0xa1, 0xf1, 0x71, 0x40, 0x91, 0x27, 0x18, 0xa5, 
00024                 0x56, 0xf4, 0xaf, 0x32, 0xd2, 0xa4, 0xdc, 0x71, 
00025         };
00026 
00027         word64 result=0;
00028         GF256 gf256(0xf5);
00029         for (unsigned int i=0; i<8; i++)
00030                 for(unsigned int j=0; j<8; j++) 
00031                         result ^= word64(gf256.Multiply(iG[i][j], GF256::Element(a>>(56-8*j)))) << (56-8*i);
00032         return result;
00033 }
00034 
00035 void SHARK::Base::UncheckedSetKey(CipherDir dir, const byte *key, unsigned int keyLen, unsigned int rounds)
00036 {
00037         AssertValidKeyLength(keyLen);
00038         AssertValidRounds(rounds);
00039 
00040         m_rounds = rounds;
00041         m_roundKeys.New(m_rounds+1);
00042 
00043         // concatenate key enought times to fill a
00044         for (unsigned int i=0; i<(m_rounds+1)*8; i++)
00045                 ((byte *)m_roundKeys.begin())[i] = key[i%keyLen];
00046 
00047         SHARK::Encryption e;
00048         e.InitForKeySetup();
00049         byte IV[8] = {0,0,0,0,0,0,0,0};
00050         CFB_Mode_ExternalCipher::Encryption cfb(e, IV);
00051 
00052         cfb.ProcessString((byte *)m_roundKeys.begin(), (m_rounds+1)*8);
00053 
00054         ConditionalByteReverse(BIG_ENDIAN_ORDER, m_roundKeys.begin(), m_roundKeys.begin(), (m_rounds+1)*8);
00055 
00056         m_roundKeys[m_rounds] = SHARKTransform(m_roundKeys[m_rounds]);
00057 
00058         if (dir == DECRYPTION)
00059         {
00060                 unsigned int i;
00061 
00062                 // transform encryption round keys into decryption round keys
00063                 for (i=0; i<m_rounds/2; i++)
00064                         std::swap(m_roundKeys[i], m_roundKeys[m_rounds-i]);
00065 
00066                 for (i=1; i<m_rounds; i++)
00067                         m_roundKeys[i] = SHARKTransform(m_roundKeys[i]);
00068         }
00069 
00070 #ifdef IS_LITTLE_ENDIAN
00071         m_roundKeys[0] = ByteReverse(m_roundKeys[0]);
00072         m_roundKeys[m_rounds] = ByteReverse(m_roundKeys[m_rounds]);
00073 #endif
00074 }
00075 
00076 // construct an SHARK_Enc object with fixed round keys, to be used to initialize actual round keys
00077 void SHARK::Enc::InitForKeySetup()
00078 {
00079         m_rounds = DEFAULT_ROUNDS;
00080         m_roundKeys.New(DEFAULT_ROUNDS+1);
00081 
00082         for (unsigned int i=0; i<DEFAULT_ROUNDS; i++)
00083                 m_roundKeys[i] = cbox[0][i];
00084 
00085         m_roundKeys[DEFAULT_ROUNDS] = SHARKTransform(cbox[0][DEFAULT_ROUNDS]);
00086 
00087 #ifdef IS_LITTLE_ENDIAN
00088         m_roundKeys[0] = ByteReverse(m_roundKeys[0]);
00089         m_roundKeys[m_rounds] = ByteReverse(m_roundKeys[m_rounds]);
00090 #endif
00091 }
00092 
00093 typedef word64 ArrayOf256Word64s[256];
00094 
00095 template <const byte *sbox, const ArrayOf256Word64s *cbox>
00096 struct SharkProcessAndXorBlock{         // VC60 workaround: problem with template functions
00097 inline SharkProcessAndXorBlock(const word64 *roundKeys, unsigned int rounds, const byte *inBlock, const byte *xorBlock, byte *outBlock)
00098 {
00099         word64 tmp = *(word64 *)inBlock ^ roundKeys[0];
00100 
00101         ByteOrder order = GetNativeByteOrder();
00102         tmp = cbox[0][GetByte(order, tmp, 0)] ^ cbox[1][GetByte(order, tmp, 1)] 
00103                 ^ cbox[2][GetByte(order, tmp, 2)] ^ cbox[3][GetByte(order, tmp, 3)] 
00104                 ^ cbox[4][GetByte(order, tmp, 4)] ^ cbox[5][GetByte(order, tmp, 5)] 
00105                 ^ cbox[6][GetByte(order, tmp, 6)] ^ cbox[7][GetByte(order, tmp, 7)]
00106                 ^ roundKeys[1];
00107 
00108         for(unsigned int i=2; i<rounds; i++) 
00109         {
00110                 tmp = cbox[0][GETBYTE(tmp, 7)] ^ cbox[1][GETBYTE(tmp, 6)] 
00111                         ^ cbox[2][GETBYTE(tmp, 5)] ^ cbox[3][GETBYTE(tmp, 4)] 
00112                         ^ cbox[4][GETBYTE(tmp, 3)] ^ cbox[5][GETBYTE(tmp, 2)] 
00113                         ^ cbox[6][GETBYTE(tmp, 1)] ^ cbox[7][GETBYTE(tmp, 0)]
00114                         ^ roundKeys[i];
00115         }
00116 
00117         PutBlock<byte, BigEndian>(xorBlock, outBlock)
00118                 (sbox[GETBYTE(tmp, 7)])
00119                 (sbox[GETBYTE(tmp, 6)])
00120                 (sbox[GETBYTE(tmp, 5)])
00121                 (sbox[GETBYTE(tmp, 4)])
00122                 (sbox[GETBYTE(tmp, 3)])
00123                 (sbox[GETBYTE(tmp, 2)])
00124                 (sbox[GETBYTE(tmp, 1)])
00125                 (sbox[GETBYTE(tmp, 0)]);
00126 
00127         *(word64 *)outBlock ^= roundKeys[rounds];
00128 }};
00129 
00130 void SHARK::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00131 {
00132         SharkProcessAndXorBlock<sbox, cbox>(m_roundKeys, m_rounds, inBlock, xorBlock, outBlock);
00133 }
00134 
00135 void SHARK::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00136 {
00137         SharkProcessAndXorBlock<sbox, cbox>(m_roundKeys, m_rounds, inBlock, xorBlock, outBlock);
00138 }
00139 
00140 NAMESPACE_END
00141 
00142 #endif // WORD64_AVAILABLE

Generated on Sun Mar 14 20:44:28 2004 for Crypto++ by doxygen 1.3.6-20040222