Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

219 lines
4.4 KiB

  1. // seal.cpp - written and placed in the public domain by Wei Dai
  2. // updated to SEAL 3.0 by Leonard Janke
  3. #include "pch.h"
  4. #include "seal.h"
  5. #include "sha.h"
  6. #include "misc.h"
  7. #include "secblock.h"
  8. NAMESPACE_BEGIN(CryptoPP)
  9. #if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
  10. void SEAL_TestInstantiations()
  11. {
  12. SEAL<>::Encryption x;
  13. }
  14. #endif
  15. struct SEAL_Gamma
  16. {
  17. SEAL_Gamma(const byte *key)
  18. : H(5), Z(5), D(16), lastIndex(0xffffffff)
  19. {
  20. GetUserKey(BIG_ENDIAN_ORDER, H.begin(), 5, key, 20);
  21. memset(D, 0, 64);
  22. }
  23. word32 Apply(word32 i);
  24. SecBlock<word32> H, Z, D;
  25. word32 lastIndex;
  26. };
  27. word32 SEAL_Gamma::Apply(word32 i)
  28. {
  29. word32 shaIndex = i/5;
  30. if (shaIndex != lastIndex)
  31. {
  32. memcpy(Z, H, 20);
  33. D[0] = shaIndex;
  34. SHA::Transform(Z, D);
  35. lastIndex = shaIndex;
  36. }
  37. return Z[i%5];
  38. }
  39. template <class B>
  40. void SEAL_Policy<B>::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
  41. {
  42. CRYPTOPP_UNUSED(length);
  43. m_insideCounter = m_outsideCounter = m_startCount = 0;
  44. unsigned int L = params.GetIntValueWithDefault("NumberOfOutputBitsPerPositionIndex", 32*1024);
  45. m_iterationsPerCount = L / 8192;
  46. SEAL_Gamma gamma(key);
  47. unsigned int i;
  48. for (i=0; i<512; i++)
  49. m_T[i] = gamma.Apply(i);
  50. for (i=0; i<256; i++)
  51. m_S[i] = gamma.Apply(0x1000+i);
  52. m_R.New(4*(L/8192));
  53. for (i=0; i<m_R.size(); i++)
  54. m_R[i] = gamma.Apply(0x2000+i);
  55. }
  56. template <class B>
  57. void SEAL_Policy<B>::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length)
  58. {
  59. CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(IV), CRYPTOPP_UNUSED(length);
  60. assert(length==4);
  61. m_outsideCounter = IV ? GetWord<word32>(false, BIG_ENDIAN_ORDER, IV) : 0;
  62. m_startCount = m_outsideCounter;
  63. m_insideCounter = 0;
  64. }
  65. template <class B>
  66. void SEAL_Policy<B>::SeekToIteration(lword iterationCount)
  67. {
  68. m_outsideCounter = m_startCount + (unsigned int)(iterationCount / m_iterationsPerCount);
  69. m_insideCounter = (unsigned int)(iterationCount % m_iterationsPerCount);
  70. }
  71. template <class B>
  72. void SEAL_Policy<B>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
  73. {
  74. word32 a, b, c, d, n1, n2, n3, n4;
  75. unsigned int p, q;
  76. for (size_t iteration = 0; iteration < iterationCount; ++iteration)
  77. {
  78. #define Ttab(x) *(word32 *)((byte *)m_T.begin()+x)
  79. a = m_outsideCounter ^ m_R[4*m_insideCounter];
  80. b = rotrFixed(m_outsideCounter, 8U) ^ m_R[4*m_insideCounter+1];
  81. c = rotrFixed(m_outsideCounter, 16U) ^ m_R[4*m_insideCounter+2];
  82. d = rotrFixed(m_outsideCounter, 24U) ^ m_R[4*m_insideCounter+3];
  83. for (unsigned int j=0; j<2; j++)
  84. {
  85. p = a & 0x7fc;
  86. b += Ttab(p);
  87. a = rotrFixed(a, 9U);
  88. p = b & 0x7fc;
  89. c += Ttab(p);
  90. b = rotrFixed(b, 9U);
  91. p = c & 0x7fc;
  92. d += Ttab(p);
  93. c = rotrFixed(c, 9U);
  94. p = d & 0x7fc;
  95. a += Ttab(p);
  96. d = rotrFixed(d, 9U);
  97. }
  98. n1 = d, n2 = b, n3 = a, n4 = c;
  99. p = a & 0x7fc;
  100. b += Ttab(p);
  101. a = rotrFixed(a, 9U);
  102. p = b & 0x7fc;
  103. c += Ttab(p);
  104. b = rotrFixed(b, 9U);
  105. p = c & 0x7fc;
  106. d += Ttab(p);
  107. c = rotrFixed(c, 9U);
  108. p = d & 0x7fc;
  109. a += Ttab(p);
  110. d = rotrFixed(d, 9U);
  111. // generate 8192 bits
  112. for (unsigned int i=0; i<64; i++)
  113. {
  114. p = a & 0x7fc;
  115. a = rotrFixed(a, 9U);
  116. b += Ttab(p);
  117. b ^= a;
  118. q = b & 0x7fc;
  119. b = rotrFixed(b, 9U);
  120. c ^= Ttab(q);
  121. c += b;
  122. p = (p+c) & 0x7fc;
  123. c = rotrFixed(c, 9U);
  124. d += Ttab(p);
  125. d ^= c;
  126. q = (q+d) & 0x7fc;
  127. d = rotrFixed(d, 9U);
  128. a ^= Ttab(q);
  129. a += d;
  130. p = (p+a) & 0x7fc;
  131. b ^= Ttab(p);
  132. a = rotrFixed(a, 9U);
  133. q = (q+b) & 0x7fc;
  134. c += Ttab(q);
  135. b = rotrFixed(b, 9U);
  136. p = (p+c) & 0x7fc;
  137. d ^= Ttab(p);
  138. c = rotrFixed(c, 9U);
  139. q = (q+d) & 0x7fc;
  140. d = rotrFixed(d, 9U);
  141. a += Ttab(q);
  142. #define SEAL_OUTPUT(x) \
  143. CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, b + m_S[4*i+0]);\
  144. CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 1, c ^ m_S[4*i+1]);\
  145. CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 2, d + m_S[4*i+2]);\
  146. CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 3, a ^ m_S[4*i+3]);
  147. CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(SEAL_OUTPUT, 4*4);
  148. if (i & 1)
  149. {
  150. a += n3;
  151. b += n4;
  152. c ^= n3;
  153. d ^= n4;
  154. }
  155. else
  156. {
  157. a += n1;
  158. b += n2;
  159. c ^= n1;
  160. d ^= n2;
  161. }
  162. }
  163. if (++m_insideCounter == m_iterationsPerCount)
  164. {
  165. ++m_outsideCounter;
  166. m_insideCounter = 0;
  167. }
  168. }
  169. a = b = c = d = n1 = n2 = n3 = n4 = 0;
  170. p = q = 0;
  171. }
  172. template class SEAL_Policy<BigEndian>;
  173. template class SEAL_Policy<LittleEndian>;
  174. NAMESPACE_END