Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panama.cpp

00001 // panama.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 #include "panama.h"
00005 
00006 NAMESPACE_BEGIN(CryptoPP)
00007 
00008 static const unsigned int STAGES = 32;
00009 
00010 Panama::Panama()
00011         : m_state(17*2 + STAGES*sizeof(Stage))
00012 {
00013         Reset();
00014 }
00015 
00016 void Panama::Reset()
00017 {
00018         m_bstart = 0;
00019         memset(m_state, 0, m_state.size*4);
00020 }
00021 
00022 void Panama::Iterate(unsigned int count, const word32 *p, word32 *z, const word32 *y)
00023 {
00024         unsigned int bstart = m_bstart;
00025         word32 *const a = m_state;
00026 #define c (a+17)
00027 #define b ((Stage *)(a+34))
00028 
00029 // output
00030 #define OA(i) z[i] = a[i+9]
00031 #define OX(i) z[i] = y[i] ^ a[i+9]
00032 // buffer update
00033 #define US(i) {word32 t=b0[i]; b0[i]=p[i]^t; b25[(i+6)%8]^=t;}
00034 #define UL(i) {word32 t=b0[i]; b0[i]=a[i+1]^t; b25[(i+6)%8]^=t;}
00035 // gamma and pi
00036 #define GP(i) c[5*i%17] = rotlFixed(a[i] ^ (a[(i+1)%17] | ~a[(i+2)%17]), ((5*i%17)*((5*i%17)+1)/2)%32)
00037 // theta and sigma
00038 #define T(i,x) a[i] = c[i] ^ c[(i+1)%17] ^ c[(i+4)%17] ^ x
00039 #define TS1S(i) T(i+1, p[i])
00040 #define TS1L(i) T(i+1, b4[i])
00041 #define TS2(i) T(i+9, b16[i])
00042 
00043         while (count--)
00044         {
00045                 if (z)
00046                 {
00047                         if (y)
00048                         {
00049                                 OX(0); OX(1); OX(2); OX(3); OX(4); OX(5); OX(6); OX(7);
00050                                 y += 8;
00051                         }
00052                         else
00053                         {
00054                                 OA(0); OA(1); OA(2); OA(3); OA(4); OA(5); OA(6); OA(7);
00055                         }
00056                         z += 8;
00057                 }
00058 
00059                 word32 *const b16 = b[(bstart+16) % STAGES];
00060                 word32 *const b4 = b[(bstart+4) % STAGES];
00061                 bstart = (bstart + STAGES - 1) % STAGES;
00062                 word32 *const b0 = b[bstart];
00063                 word32 *const b25 = b[(bstart+25) % STAGES];
00064 
00065 
00066                 if (p)
00067                 {
00068                         US(0); US(1); US(2); US(3); US(4); US(5); US(6); US(7);
00069                 }
00070                 else
00071                 {
00072                         UL(0); UL(1); UL(2); UL(3); UL(4); UL(5); UL(6); UL(7);
00073                 }
00074 
00075                 GP(0); GP(1); GP(2); GP(3); GP(4); GP(5); GP(6); GP(7);
00076                 GP(8); GP(9); GP(10); GP(11); GP(12); GP(13); GP(14); GP(15); GP(16);
00077 
00078                 T(0,1);
00079 
00080                 if (p)
00081                 {
00082                         TS1S(0); TS1S(1); TS1S(2); TS1S(3); TS1S(4); TS1S(5); TS1S(6); TS1S(7);
00083                         p += 8;
00084                 }
00085                 else
00086                 {
00087                         TS1L(0); TS1L(1); TS1L(2); TS1L(3); TS1L(4); TS1L(5); TS1L(6); TS1L(7);
00088                 }
00089 
00090                 TS2(0); TS2(1); TS2(2); TS2(3); TS2(4); TS2(5); TS2(6); TS2(7);
00091         }
00092         m_bstart = bstart;
00093 }
00094 
00095 template <bool H>
00096 unsigned int PanamaHash<H>::HashMultipleBlocks(const word32 *input, unsigned int length)
00097 {
00098         if (CheckEndianess(HIGHFIRST))
00099         {
00100                 Iterate(length / BLOCKSIZE, input);
00101                 return length % BLOCKSIZE;
00102         }
00103         else
00104                 return IteratedHashBase<word32>::HashMultipleBlocks(input, length);
00105 }
00106 
00107 template <bool H>
00108 void PanamaHash<H>::Final(byte *hash)
00109 {
00110         PadLastBlock(BLOCKSIZE, 0x01);
00111         CorrectEndianess(data, data, BLOCKSIZE);
00112         
00113         vTransform(data);
00114 
00115         Iterate(32);    // pull
00116 
00117         CorrectEndianess(m_state+9, m_state+9, DigestSize());
00118         memcpy(hash, m_state+9, DigestSize());
00119 
00120         Reinit();               // reinit for next use
00121 }
00122 
00123 template <bool H>
00124 PanamaCipher<H>::PanamaCipher(const byte *key, const byte *iv)
00125         : m_buf(8), m_leftOver(0)
00126 {
00127         memcpy(m_buf, key, 32);
00128         CorrectEndianess(m_buf, m_buf, 32);
00129         Iterate(1, m_buf);
00130         if (iv)
00131         {
00132                 memcpy(m_buf, iv, 32);
00133                 CorrectEndianess(m_buf, m_buf, 32);
00134         }
00135         else
00136                 memset(m_buf, 0, 32);
00137         Iterate(1, m_buf);
00138 
00139         Iterate(32);
00140 }
00141 
00142 template <bool H>
00143 void PanamaCipher<H>::ProcessString(byte *outString, const byte *inString, unsigned int length)
00144 {
00145         if (m_leftOver > 0)
00146         {
00147                 unsigned int len = STDMIN(m_leftOver, length);
00148                 xorbuf(outString, inString, (byte *)(m_buf+m_buf.size)-m_leftOver, len);
00149                 length -= len;
00150                 m_leftOver -= len;
00151                 inString += len;
00152                 outString += len;
00153         }
00154 
00155         if (CheckEndianess(HIGHFIRST) && IsAligned<word32>(outString))
00156         {
00157                 if (!IsAligned<word32>(inString))
00158                 {
00159                         memcpy(outString, inString, length);
00160                         inString = outString;
00161                 }
00162                 Iterate(length / 32, NULL, (word32 *)outString, (const word32 *)inString);
00163                 inString += length - length % 32;
00164                 outString += length - length % 32;
00165                 length %= 32;
00166         }
00167 
00168         while (length)
00169         {
00170                 Iterate(1, NULL, m_buf);
00171                 CorrectEndianess(m_buf, m_buf, 32);
00172                 unsigned int len = STDMIN(32U, length);
00173                 xorbuf(outString, inString, (byte *)m_buf.ptr, len);
00174                 length -= len;
00175                 m_leftOver = 32 - len;
00176                 inString += len;
00177                 outString += len;
00178         }
00179 }
00180 
00181 template class PanamaHash<true>;
00182 template class PanamaHash<false>;
00183 
00184 template class PanamaCipher<true>;
00185 template class PanamaCipher<false>;
00186 
00187 NAMESPACE_END

Generated at Mon Jan 15 01:16:34 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000