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 Fri Aug 27 16:09:33 2004 for Crypto++ by doxygen 1.3.8