- Main Page
- Namespaces
- Classes
- Files

- File List
- 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(const byte *key, unsigned int keyLen, const NameValuePairs &params)
    00036 {
    00037         AssertValidKeyLength(keyLen);
    00038
    00039         m_rounds = GetRoundsAndThrowIfInvalid(params, this);
    00040         m_roundKeys.New(m_rounds+1);
    00041
    00042         // concatenate key enought times to fill a
    00043         for (unsigned int i=0; i<(m_rounds+1)*8; i++)
    00044                 ((byte *)m_roundKeys.begin())[i] = key[i%keyLen];
    00045
    00046         SHARK::Encryption e;
    00047         e.InitForKeySetup();
    00048         byte IV[8] = {0,0,0,0,0,0,0,0};
    00049         CFB_Mode_ExternalCipher::Encryption cfb(e, IV);
    00050
    00051         cfb.ProcessString((byte *)m_roundKeys.begin(), (m_rounds+1)*8);
    00052
    00053         ConditionalByteReverse(BIG_ENDIAN_ORDER, m_roundKeys.begin(), m_roundKeys.begin(), (m_rounds+1)*8);
    00054
    00055         m_roundKeys[m_rounds] = SHARKTransform(m_roundKeys[m_rounds]);
    00056
    00057         if (!IsForwardTransformation())
    00058         {
    00059                 unsigned int i;
    00060
    00061                 // transform encryption round keys into decryption round keys
    00062                 for (i=0; i<m_rounds/2; i++)
    00063                         std::swap(m_roundKeys[i], m_roundKeys[m_rounds-i]);
    00064
    00065                 for (i=1; i<m_rounds; i++)
    00066                         m_roundKeys[i] = SHARKTransform(m_roundKeys[i]);
    00067         }
    00068
    00069 #ifdef IS_LITTLE_ENDIAN
    00070         m_roundKeys[0] = ByteReverse(m_roundKeys[0]);
    00071         m_roundKeys[m_rounds] = ByteReverse(m_roundKeys[m_rounds]);
    00072 #endif
    00073 }
    00074
    00075 // construct an SHARK_Enc object with fixed round keys, to be used to initialize actual round keys
    00076 void SHARK::Enc::InitForKeySetup()
    00077 {
    00078         m_rounds = DEFAULT_ROUNDS;
    00079         m_roundKeys.New(DEFAULT_ROUNDS+1);
    00080
    00081         for (unsigned int i=0; i<DEFAULT_ROUNDS; i++)
    00082                 m_roundKeys[i] = cbox[0][i];
    00083
    00084         m_roundKeys[DEFAULT_ROUNDS] = SHARKTransform(cbox[0][DEFAULT_ROUNDS]);
    00085
    00086 #ifdef IS_LITTLE_ENDIAN
    00087         m_roundKeys[0] = ByteReverse(m_roundKeys[0]);
    00088         m_roundKeys[m_rounds] = ByteReverse(m_roundKeys[m_rounds]);
    00089 #endif
    00090 }
    00091
    00092 typedef word64 ArrayOf256Word64s[256];
    00093
    00094 template <const byte *sbox, const ArrayOf256Word64s *cbox>
    00095 struct SharkProcessAndXorBlock{         // VC60 workaround: problem with template functions
    00096 inline SharkProcessAndXorBlock(const word64 *roundKeys, unsigned int rounds, const byte *inBlock, const byte *xorBlock, byte *outBlock)
    00097 {
    00098         word64 tmp = *(word64 *)inBlock ^ roundKeys[0];
    00099
    00100         ByteOrder order = GetNativeByteOrder();
    00101         tmp = cbox[0][GetByte(order, tmp, 0)] ^ cbox[1][GetByte(order, tmp, 1)]
    00102                 ^ cbox[2][GetByte(order, tmp, 2)] ^ cbox[3][GetByte(order, tmp, 3)]
    00103                 ^ cbox[4][GetByte(order, tmp, 4)] ^ cbox[5][GetByte(order, tmp, 5)]
    00104                 ^ cbox[6][GetByte(order, tmp, 6)] ^ cbox[7][GetByte(order, tmp, 7)]
    00105                 ^ roundKeys[1];
    00106
    00107         for(unsigned int i=2; i<rounds; i++)
    00108         {
    00109                 tmp = cbox[0][GETBYTE(tmp, 7)] ^ cbox[1][GETBYTE(tmp, 6)]
    00110                         ^ cbox[2][GETBYTE(tmp, 5)] ^ cbox[3][GETBYTE(tmp, 4)]
    00111                         ^ cbox[4][GETBYTE(tmp, 3)] ^ cbox[5][GETBYTE(tmp, 2)]
    00112                         ^ cbox[6][GETBYTE(tmp, 1)] ^ cbox[7][GETBYTE(tmp, 0)]
    00113                         ^ roundKeys[i];
    00114         }
    00115
    00116         PutBlock<byte, BigEndian>(xorBlock, outBlock)
    00117                 (sbox[GETBYTE(tmp, 7)])
    00118                 (sbox[GETBYTE(tmp, 6)])
    00119                 (sbox[GETBYTE(tmp, 5)])
    00120                 (sbox[GETBYTE(tmp, 4)])
    00121                 (sbox[GETBYTE(tmp, 3)])
    00122                 (sbox[GETBYTE(tmp, 2)])
    00123                 (sbox[GETBYTE(tmp, 1)])
    00124                 (sbox[GETBYTE(tmp, 0)]);
    00125
    00126         *(word64 *)outBlock ^= roundKeys[rounds];
    00127 }};
    00128
    00129 void SHARK::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
    00130 {
    00131         SharkProcessAndXorBlock<sbox, cbox>(m_roundKeys, m_rounds, inBlock, xorBlock, outBlock);
    00132 }
    00133
    00134 void SHARK::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
    00135 {
    00136         SharkProcessAndXorBlock<sbox, cbox>(m_roundKeys, m_rounds, inBlock, xorBlock, outBlock);
    00137 }
    00138
    00139 NAMESPACE_END
    00140
    00141 #endif // WORD64_AVAILABLE