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.

122 lines
2.3 KiB

  1. // arc4.cpp - written and placed in the public domain by Wei Dai
  2. // The ARC4 algorithm was first revealed in an anonymous email to the
  3. // cypherpunks mailing list. This file originally contained some
  4. // code copied from this email. The code has since been rewritten in order
  5. // to clarify the copyright status of this file. It should now be
  6. // completely in the public domain.
  7. #include "pch.h"
  8. #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
  9. #include "arc4.h"
  10. NAMESPACE_BEGIN(CryptoPP)
  11. namespace Weak1 {
  12. #if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
  13. void ARC4_TestInstantiations()
  14. {
  15. ARC4 x;
  16. }
  17. #endif
  18. ARC4_Base::~ARC4_Base()
  19. {
  20. m_x = m_y = 0;
  21. }
  22. void ARC4_Base::UncheckedSetKey(const byte *key, unsigned int keyLen, const NameValuePairs &params)
  23. {
  24. AssertValidKeyLength(keyLen);
  25. m_x = 1;
  26. m_y = 0;
  27. unsigned int i;
  28. for (i=0; i<256; i++)
  29. m_state[i] = byte(i);
  30. unsigned int keyIndex = 0, stateIndex = 0;
  31. for (i=0; i<256; i++)
  32. {
  33. unsigned int a = m_state[i];
  34. stateIndex += key[keyIndex] + a;
  35. stateIndex &= 0xff;
  36. m_state[i] = m_state[stateIndex];
  37. m_state[stateIndex] = byte(a);
  38. if (++keyIndex >= keyLen)
  39. keyIndex = 0;
  40. }
  41. int discardBytes = params.GetIntValueWithDefault("DiscardBytes", GetDefaultDiscardBytes());
  42. DiscardBytes(discardBytes);
  43. }
  44. template <class T>
  45. static inline unsigned int MakeByte(T &x, T &y, byte *s)
  46. {
  47. unsigned int a = s[x];
  48. y = byte((y+a) & 0xff);
  49. unsigned int b = s[y];
  50. s[x] = byte(b);
  51. s[y] = byte(a);
  52. x = byte((x+1) & 0xff);
  53. return s[(a+b) & 0xff];
  54. }
  55. void ARC4_Base::GenerateBlock(byte *output, size_t size)
  56. {
  57. while (size--)
  58. *output++ = static_cast<byte>(MakeByte(m_x, m_y, m_state));
  59. }
  60. void ARC4_Base::ProcessData(byte *outString, const byte *inString, size_t length)
  61. {
  62. if (length == 0)
  63. return;
  64. byte *const s = m_state;
  65. unsigned int x = m_x;
  66. unsigned int y = m_y;
  67. if (inString == outString)
  68. {
  69. do
  70. {
  71. *outString++ ^= MakeByte(x, y, s);
  72. } while (--length);
  73. }
  74. else
  75. {
  76. do
  77. {
  78. *outString++ = *inString++ ^ byte(MakeByte(x, y, s));
  79. }
  80. while(--length);
  81. }
  82. m_x = byte(x);
  83. m_y = byte(y);
  84. }
  85. void ARC4_Base::DiscardBytes(size_t length)
  86. {
  87. if (length == 0)
  88. return;
  89. byte *const s = m_state;
  90. unsigned int x = m_x;
  91. unsigned int y = m_y;
  92. do
  93. {
  94. MakeByte(x, y, s);
  95. }
  96. while(--length);
  97. m_x = byte(x);
  98. m_y = byte(y);
  99. }
  100. }
  101. NAMESPACE_END