📄 idea.cpp
字号:
// idea.cpp - written and placed in the public domain by Wei Dai#include "pch.h"#include "idea.h"#include "misc.h"NAMESPACE_BEGIN(CryptoPP)static const int IDEA_KEYLEN=(6*IDEA::ROUNDS+4); // key schedule length in # of word16s#define low16(x) ((x)&0xffff) // compiler should be able to optimize this away if word is 16 bits#define high16(x) ((x)>>16)CRYPTOPP_COMPILE_ASSERT(sizeof(IDEA::Word) >= 2);// should use an inline function but macros are still faster in MSVC 4.0#define DirectMUL(a,b) \{ \ assert(b <= 0xffff); \ \ word32 p=(word32)low16(a)*b; \ \ if (p) \ { \ p = low16(p) - high16(p); \ a = (IDEA::Word)p - (IDEA::Word)high16(p); \ } \ else \ a = 1-a-b; \}#ifdef IDEA_LARGECACHEbool IDEA::Base::tablesBuilt = false;word16 IDEA::Base::log[0x10000];word16 IDEA::Base::antilog[0x10000];void IDEA::Base::BuildLogTables(){ if (tablesBuilt) return; else { tablesBuilt = true; IDEA::Word x=1; word32 i; for (i=0; i<0x10000; i++) { antilog[i] = (word16)x; DirectMUL(x, 3); } for (i=0; i<0x10000; i++) log[antilog[i]] = (word16)i; }}void IDEA::Base::LookupKeyLogs(){ IDEA::Word* Z=key; int r=ROUNDS; do { Z[0] = log[Z[0]]; Z[3] = log[Z[3]]; Z[4] = log[Z[4]]; Z[5] = log[Z[5]]; Z+=6; } while (--r); Z[0] = log[Z[0]]; Z[3] = log[Z[3]];}inline void IDEA::Base::LookupMUL(IDEA::Word &a, IDEA::Word b){ a = antilog[low16(log[low16(a)]+b)];}#endif // IDEA_LARGECACHEvoid IDEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &){ AssertValidKeyLength(length); #ifdef IDEA_LARGECACHE BuildLogTables();#endif EnKey(userKey); if (!IsForwardTransformation()) DeKey(); #ifdef IDEA_LARGECACHE LookupKeyLogs();#endif}void IDEA::Base::EnKey (const byte *userKey){ unsigned int i; for (i=0; i<8; i++) m_key[i] = ((IDEA::Word)userKey[2*i]<<8) | userKey[2*i+1]; for (; i<IDEA_KEYLEN; i++) { unsigned int j = RoundDownToMultipleOf(i,8U)-8; m_key[i] = low16((m_key[j+(i+1)%8] << 9) | (m_key[j+(i+2)%8] >> 7)); }}static IDEA::Word MulInv(IDEA::Word x){ IDEA::Word y=x; for (unsigned i=0; i<15; i++) { DirectMUL(y,low16(y)); DirectMUL(y,x); } return low16(y);}static inline IDEA::Word AddInv(IDEA::Word x){ return low16(0-x);}void IDEA::Base::DeKey(){ FixedSizeSecBlock<IDEA::Word, 6*ROUNDS+4> tempkey; unsigned int i; for (i=0; i<ROUNDS; i++) { tempkey[i*6+0] = MulInv(m_key[(ROUNDS-i)*6+0]); tempkey[i*6+1] = AddInv(m_key[(ROUNDS-i)*6+1+(i>0)]); tempkey[i*6+2] = AddInv(m_key[(ROUNDS-i)*6+2-(i>0)]); tempkey[i*6+3] = MulInv(m_key[(ROUNDS-i)*6+3]); tempkey[i*6+4] = m_key[(ROUNDS-1-i)*6+4]; tempkey[i*6+5] = m_key[(ROUNDS-1-i)*6+5]; } tempkey[i*6+0] = MulInv(m_key[(ROUNDS-i)*6+0]); tempkey[i*6+1] = AddInv(m_key[(ROUNDS-i)*6+1]); tempkey[i*6+2] = AddInv(m_key[(ROUNDS-i)*6+2]); tempkey[i*6+3] = MulInv(m_key[(ROUNDS-i)*6+3]); m_key = tempkey;}#ifdef IDEA_LARGECACHE#define MUL(a,b) LookupMUL(a,b)#else#define MUL(a,b) DirectMUL(a,b)#endifvoid IDEA::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const{ typedef BlockGetAndPut<word16, BigEndian> Block; const IDEA::Word *key = m_key; IDEA::Word x0,x1,x2,x3,t0,t1; Block::Get(inBlock)(x0)(x1)(x2)(x3); for (unsigned int i=0; i<ROUNDS; i++) { MUL(x0, key[i*6+0]); x1 += key[i*6+1]; x2 += key[i*6+2]; MUL(x3, key[i*6+3]); t0 = x0^x2; MUL(t0, key[i*6+4]); t1 = t0 + (x1^x3); MUL(t1, key[i*6+5]); t0 += t1; x0 ^= t1; x3 ^= t0; t0 ^= x1; x1 = x2^t1; x2 = t0; } MUL(x0, key[ROUNDS*6+0]); x2 += key[ROUNDS*6+1]; x1 += key[ROUNDS*6+2]; MUL(x3, key[ROUNDS*6+3]); Block::Put(xorBlock, outBlock)(x0)(x2)(x1)(x3);}NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -