00001
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
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
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
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
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 Iterate(length / BLOCKSIZE, input);
00094
return length % BLOCKSIZE;
00095 }
00096
00097
template <
class B>
00098
void PanamaHash<B>::TruncatedFinal(byte *hash,
unsigned int size)
00099 {
00100 ThrowIfInvalidTruncatedSize(size);
00101
00102 PadLastBlock(BLOCKSIZE, 0x01);
00103
00104 vTransform(m_data);
00105
00106 Iterate(32);
00107
00108 ConditionalByteReverse(B::ToEnum(), m_state+9, m_state+9, DIGESTSIZE);
00109 memcpy(hash, m_state+9, size);
00110
00111 Restart();
00112 }
00113
00114
template <
class B>
00115
void PanamaCipherPolicy<B>::CipherSetKey(
const NameValuePairs ¶ms,
const byte *key,
unsigned int length)
00116 {
00117 FixedSizeSecBlock<word32, 8> buf;
00118
00119 Reset();
00120 memcpy(buf, key, 32);
00121 Iterate(1, buf);
00122
if (length == 64)
00123 memcpy(buf, key+32, 32);
00124
else
00125 memset(buf, 0, 32);
00126 Iterate(1, buf);
00127
00128 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 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