00001
00002
00003
00004
#include "pch.h"
00005
#include "seal.h"
00006
#include "sha.h"
00007
#include "misc.h"
00008
00009
#include "strciphr.cpp"
00010
00011 NAMESPACE_BEGIN(CryptoPP)
00012
00013 void SEAL_TestInstantiations()
00014 {
00015
SEAL<>::Encryption x;
00016 }
00017
00018
struct SEAL_Gamma
00019 {
00020 SEAL_Gamma(
const byte *key)
00021 : H(5), Z(5), D(16), lastIndex(0xffffffff)
00022 {
00023 GetUserKey(BIG_ENDIAN_ORDER, H.begin(), 5, key, 20);
00024 memset(D, 0, 64);
00025 }
00026
00027 word32 Apply(word32 i);
00028
00029
SecBlock<word32> H, Z, D;
00030 word32 lastIndex;
00031 };
00032
00033 word32 SEAL_Gamma::Apply(word32 i)
00034 {
00035 word32 shaIndex = i/5;
00036
if (shaIndex != lastIndex)
00037 {
00038 memcpy(Z, H, 20);
00039 D[0] = shaIndex;
00040 SHA::Transform(Z, D);
00041 lastIndex = shaIndex;
00042 }
00043
return Z[i%5];
00044 }
00045
00046
template <
class B>
00047
void SEAL_Policy<B>::CipherSetKey(
const NameValuePairs ¶ms,
const byte *key,
unsigned int length)
00048 {
00049 m_insideCounter = m_outsideCounter = m_startCount = 0;
00050
00051
unsigned int L = params.
GetIntValueWithDefault(
"NumberOfOutputBitsPerPositionIndex", 32*1024);
00052 m_iterationsPerCount = L / 8192;
00053
00054 SEAL_Gamma gamma(key);
00055
unsigned int i;
00056
00057
for (i=0; i<512; i++)
00058 m_T[i] = gamma.Apply(i);
00059
00060
for (i=0; i<256; i++)
00061 m_S[i] = gamma.Apply(0x1000+i);
00062
00063 m_R.New(4*(L/8192));
00064
00065
for (i=0; i<m_R.size(); i++)
00066 m_R[i] = gamma.Apply(0x2000+i);
00067 }
00068
00069
template <
class B>
00070
void SEAL_Policy<B>::CipherResynchronize(byte *keystreamBuffer,
const byte *IV)
00071 {
00072 m_outsideCounter = UnalignedGetWord<word32>(BIG_ENDIAN_ORDER,
IV);
00073 m_startCount = m_outsideCounter;
00074 m_insideCounter = 0;
00075 }
00076
00077
template <
class B>
00078
void SEAL_Policy<B>::SeekToIteration(dword iterationCount)
00079 {
00080 m_outsideCounter = m_startCount + (
unsigned int)(iterationCount / m_iterationsPerCount);
00081 m_insideCounter = (
unsigned int)(iterationCount % m_iterationsPerCount);
00082 }
00083
00084
template <
class B>
00085
void SEAL_Policy<B>::OperateKeystream(KeystreamOperation operation, byte *output,
const byte *input,
unsigned int iterationCount)
00086 {
00087 KeystreamOutput<B> keystreamOutput(operation, output, input);
00088 word32 a, b, c, d, n1, n2, n3, n4;
00089
unsigned int p, q;
00090
00091
for (
unsigned int iteration = 0; iteration < iterationCount; ++iteration)
00092 {
00093
#define Ttab(x) *(word32 *)((byte *)m_T.begin()+x)
00094
00095 a = m_outsideCounter ^ m_R[4*m_insideCounter];
00096 b = rotrFixed(m_outsideCounter, 8U) ^ m_R[4*m_insideCounter+1];
00097 c = rotrFixed(m_outsideCounter, 16U) ^ m_R[4*m_insideCounter+2];
00098 d = rotrFixed(m_outsideCounter, 24U) ^ m_R[4*m_insideCounter+3];
00099
00100
for (
unsigned int j=0; j<2; j++)
00101 {
00102 p = a & 0x7fc;
00103 b += Ttab(p);
00104 a = rotrFixed(a, 9U);
00105
00106 p = b & 0x7fc;
00107 c += Ttab(p);
00108 b = rotrFixed(b, 9U);
00109
00110 p = c & 0x7fc;
00111 d += Ttab(p);
00112 c = rotrFixed(c, 9U);
00113
00114 p = d & 0x7fc;
00115 a += Ttab(p);
00116 d = rotrFixed(d, 9U);
00117 }
00118
00119 n1 = d, n2 = b, n3 = a, n4 = c;
00120
00121 p = a & 0x7fc;
00122 b += Ttab(p);
00123 a = rotrFixed(a, 9U);
00124
00125 p = b & 0x7fc;
00126 c += Ttab(p);
00127 b = rotrFixed(b, 9U);
00128
00129 p = c & 0x7fc;
00130 d += Ttab(p);
00131 c = rotrFixed(c, 9U);
00132
00133 p = d & 0x7fc;
00134 a += Ttab(p);
00135 d = rotrFixed(d, 9U);
00136
00137
00138
for (
unsigned int i=0; i<64; i++)
00139 {
00140 p = a & 0x7fc;
00141 a = rotrFixed(a, 9U);
00142 b += Ttab(p);
00143 b ^= a;
00144
00145 q = b & 0x7fc;
00146 b = rotrFixed(b, 9U);
00147 c ^= Ttab(q);
00148 c += b;
00149
00150 p = (p+c) & 0x7fc;
00151 c = rotrFixed(c, 9U);
00152 d += Ttab(p);
00153 d ^= c;
00154
00155 q = (q+d) & 0x7fc;
00156 d = rotrFixed(d, 9U);
00157 a ^= Ttab(q);
00158 a += d;
00159
00160 p = (p+a) & 0x7fc;
00161 b ^= Ttab(p);
00162 a = rotrFixed(a, 9U);
00163
00164 q = (q+b) & 0x7fc;
00165 c += Ttab(q);
00166 b = rotrFixed(b, 9U);
00167
00168 p = (p+c) & 0x7fc;
00169 d ^= Ttab(p);
00170 c = rotrFixed(c, 9U);
00171
00172 q = (q+d) & 0x7fc;
00173 d = rotrFixed(d, 9U);
00174 a += Ttab(q);
00175
00176 keystreamOutput (b + m_S[4*i+0])
00177 (c ^ m_S[4*i+1])
00178 (d + m_S[4*i+2])
00179 (a ^ m_S[4*i+3]);
00180
00181
if (i & 1)
00182 {
00183 a += n3;
00184 b += n4;
00185 c ^= n3;
00186 d ^= n4;
00187 }
00188
else
00189 {
00190 a += n1;
00191 b += n2;
00192 c ^= n1;
00193 d ^= n2;
00194 }
00195 }
00196
00197
if (++m_insideCounter == m_iterationsPerCount)
00198 {
00199 ++m_outsideCounter;
00200 m_insideCounter = 0;
00201 }
00202 }
00203
00204 a = b = c = d = n1 = n2 = n3 = n4 = 0;
00205 p = q = 0;
00206 }
00207
00208
template class SEAL_Policy<BigEndian>;
00209
template class SEAL_Policy<LittleEndian>;
00210
00211 NAMESPACE_END