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.

114 lines
2.8 KiB

  1. // wake.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #include "wake.h"
  4. #include "smartptr.h"
  5. NAMESPACE_BEGIN(CryptoPP)
  6. #if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
  7. void WAKE_TestInstantiations()
  8. {
  9. WAKE_OFB<>::Encryption x2;
  10. WAKE_OFB<>::Decryption x4;
  11. }
  12. #endif
  13. inline word32 WAKE_Base::M(word32 x, word32 y)
  14. {
  15. word32 w = x+y;
  16. return (w>>8) ^ t[w & 0xff];
  17. }
  18. void WAKE_Base::GenKey(word32 k0, word32 k1, word32 k2, word32 k3)
  19. {
  20. // this code is mostly copied from David Wheeler's paper "A Bulk Data Encryption Algorithm"
  21. signed int x, z, p;
  22. // x and z were declared as "long" in Wheeler's paper, which is a signed type. I don't know if that was intentional, but it's too late to change it now. -- Wei 7/4/2010
  23. CRYPTOPP_COMPILE_ASSERT(sizeof(x) == 4);
  24. static unsigned int tt[10]= {
  25. 0x726a8f3b, // table
  26. 0xe69a3b5c,
  27. 0xd3c71fe5,
  28. 0xab3c73d2,
  29. 0x4d3a8eb3,
  30. 0x0396d6e8,
  31. 0x3d4c2f7a,
  32. 0x9ee27cf3, } ;
  33. t[0] = k0;
  34. t[1] = k1;
  35. t[2] = k2;
  36. t[3] = k3;
  37. for (p=4 ; p<256 ; p++)
  38. {
  39. x=t[p-4]+t[p-1] ; // fill t
  40. t[p]= (x>>3) ^ tt[x&7] ;
  41. }
  42. for (p=0 ; p<23 ; p++)
  43. t[p]+=t[p+89] ; // mix first entries
  44. x=t[33] ; z=t[59] | 0x01000001 ;
  45. z=z&0xff7fffff ;
  46. for (p=0 ; p<256 ; p++) { //change top byte to
  47. x=(x&0xff7fffff)+z ; // a permutation etc
  48. t[p]=(t[p] & 0x00ffffff) ^ x ; }
  49. t[256]=t[0] ;
  50. byte y=byte(x);
  51. for (p=0 ; p<256 ; p++) { // further change perm.
  52. t[p]=t[y=byte(t[p^y]^y)] ; // and other digits
  53. t[y]=t[p+1] ; }
  54. }
  55. template <class B>
  56. void WAKE_Policy<B>::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
  57. {
  58. CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(key); CRYPTOPP_UNUSED(length);
  59. word32 k0, k1, k2, k3;
  60. BlockGetAndPut<word32, BigEndian>::Get(key)(r3)(r4)(r5)(r6)(k0)(k1)(k2)(k3);
  61. GenKey(k0, k1, k2, k3);
  62. }
  63. // OFB
  64. template <class B>
  65. void WAKE_Policy<B>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
  66. {
  67. #define WAKE_OUTPUT(x)\
  68. while (iterationCount--)\
  69. {\
  70. CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, r6);\
  71. r3 = M(r3, r6);\
  72. r4 = M(r4, r3);\
  73. r5 = M(r5, r4);\
  74. r6 = M(r6, r5);\
  75. output += 4;\
  76. if (!(x & INPUT_NULL))\
  77. input += 4;\
  78. }
  79. typedef word32 WordType;
  80. CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(WAKE_OUTPUT, 0);
  81. }
  82. /*
  83. template <class B>
  84. void WAKE_ROFB_Policy<B>::Iterate(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount)
  85. {
  86. KeystreamOutput<B> keystreamOperation(operation, output, input);
  87. while (iterationCount--)
  88. {
  89. keystreamOperation(r6);
  90. r3 = M(r3, r6);
  91. r4 = M(r4, r3);
  92. r5 = M(r5, r4);
  93. r6 = M(r6, r5);
  94. }
  95. }
  96. */
  97. template class WAKE_Policy<BigEndian>;
  98. template class WAKE_Policy<LittleEndian>;
  99. //template class WAKE_ROFB_Policy<BigEndian>;
  100. //template class WAKE_ROFB_Policy<LittleEndian>;
  101. NAMESPACE_END