Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class 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 #include "misc.h"
    00006
    00007 NAMESPACE_BEGIN(CryptoPP)
    00008
    00009 template <class B>
    00010 void Panama<B>::Reset()
    00011 {
    00012         m_bstart = 0;
    00013         memset(m_state, 0, m_state.size()*4);
    00014 }
    00015
    00016 template <class B>
    00017 void Panama<B>::Iterate(unsigned int count, const word32 *p, word32 *z, const word32 *y)
    00018 {
    00019         unsigned int bstart = m_bstart;
    00020         word32 *const a = m_state;
    00021 #define c (a+17)
    00022 #define b ((Stage *)(a+34))
    00023
    00024 // output
    00025 #define OA(i) z[i] = ConditionalByteReverse(B::ToEnum(), a[i+9])
    00026 #define OX(i) z[i] = y[i] ^ ConditionalByteReverse(B::ToEnum(), a[i+9])
    00027 // buffer update
    00028 #define US(i) {word32 t=b0[i]; b0[i]=ConditionalByteReverse(B::ToEnum(), p[i])^t; b25[(i+6)%8]^=t;}
    00029 #define UL(i) {word32 t=b0[i]; b0[i]=a[i+1]^t; b25[(i+6)%8]^=t;}
    00030 // gamma and pi
    00031 #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)
    00032 // theta and sigma
    00033 #define T(i,x) a[i] = c[i] ^ c[(i+1)%17] ^ c[(i+4)%17] ^ x
    00034 #define TS1S(i) T(i+1, ConditionalByteReverse(B::ToEnum(), p[i]))
    00035 #define TS1L(i) T(i+1, b4[i])
    00036 #define TS2(i) T(i+9, b16[i])
    00037
    00038         while (count--)
    00039         {
    00040                 if (z)
    00041                 {
    00042                         if (y)
    00043                         {
    00044                                 OX(0); OX(1); OX(2); OX(3); OX(4); OX(5); OX(6); OX(7);
    00045                                 y += 8;
    00046                         }
    00047                         else
    00048                         {
    00049                                 OA(0); OA(1); OA(2); OA(3); OA(4); OA(5); OA(6); OA(7);
    00050                         }
    00051                         z += 8;
    00052                 }
    00053
    00054                 word32 *const b16 = b[(bstart+16) % STAGES];
    00055                 word32 *const b4 = b[(bstart+4) % STAGES];
    00056         bstart = (bstart + STAGES - 1) % STAGES;
    00057                 word32 *const b0 = b[bstart];
    00058                 word32 *const b25 = b[(bstart+25) % STAGES];
    00059
    00060
    00061                 if (p)
    00062                 {
    00063                         US(0); US(1); US(2); US(3); US(4); US(5); US(6); US(7);
    00064                 }
    00065                 else
    00066                 {
    00067                         UL(0); UL(1); UL(2); UL(3); UL(4); UL(5); UL(6); UL(7);
    00068                 }
    00069
    00070                 GP(0); GP(1); GP(2); GP(3); GP(4); GP(5); GP(6); GP(7);
    00071                 GP(8); GP(9); GP(10); GP(11); GP(12); GP(13); GP(14); GP(15); GP(16);
    00072
    00073                 T(0,1);
    00074
    00075                 if (p)
    00076                 {
    00077                         TS1S(0); TS1S(1); TS1S(2); TS1S(3); TS1S(4); TS1S(5); TS1S(6); TS1S(7);
    00078                         p += 8;
    00079                 }
    00080                 else
    00081                 {
    00082                         TS1L(0); TS1L(1); TS1L(2); TS1L(3); TS1L(4); TS1L(5); TS1L(6); TS1L(7);
    00083                 }
    00084
    00085                 TS2(0); TS2(1); TS2(2); TS2(3); TS2(4); TS2(5); TS2(6); TS2(7);
    00086         }
    00087         m_bstart = bstart;
    00088 }
    00089
    00090 template <class B>
    00091 unsigned int PanamaHash<B>::HashMultipleBlocks(const word32 *input, unsigned int length)
    00092 {
    00093         this->Iterate(length / this->BLOCKSIZE, input);
    00094         return length % this->BLOCKSIZE;
    00095 }
    00096
    00097 template <class B>
    00098 void PanamaHash<B>::TruncatedFinal(byte *hash, unsigned int size)
    00099 {
    00100         this->ThrowIfInvalidTruncatedSize(size);
    00101
    00102         PadLastBlock(this->BLOCKSIZE, 0x01);
    00103
    00104         HashEndianCorrectedBlock(this->m_data);
    00105
    00106         this->Iterate(32);      // pull
    00107
    00108         ConditionalByteReverse(B::ToEnum(), this->m_state+9, this->m_state+9, DIGESTSIZE);
    00109         memcpy(hash, this->m_state+9, size);
    00110
    00111         this->Restart();                // reinit for next use
    00112 }
    00113
    00114 template <class B>
    00115 void PanamaCipherPolicy<B>::CipherSetKey(const NameValuePairs &params, const byte *key, unsigned int length)
    00116 {
    00117         FixedSizeSecBlock<word32, 8> buf;
    00118
    00119         this->Reset();
    00120         memcpy(buf, key, 32);
    00121         this->Iterate(1, buf);
    00122         if (length == 64)
    00123                 memcpy(buf, key+32, 32);
    00124         else
    00125                 memset(buf, 0, 32);
    00126         this->Iterate(1, buf);
    00127
    00128         this->Iterate(32);
    00129 }
    00130
    00131 template <class B>
    00132 void PanamaCipherPolicy<B>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount)
    00133 {
    00134         this->Iterate(iterationCount, NULL, (word32 *)output, (const word32 *)input);
    00135 }
    00136
    00137 template class Panama<BigEndian>;
    00138 template class Panama<LittleEndian>;
    00139
    00140 template class PanamaHash<BigEndian>;
    00141 template class PanamaHash<LittleEndian>;
    00142
    00143 template class PanamaCipherPolicy<BigEndian>;
    00144 template class PanamaCipherPolicy<LittleEndian>;
    00145
    00146 NAMESPACE_END