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.

125 lines
2.8 KiB

  1. // serpent.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #include "serpent.h"
  4. #include "secblock.h"
  5. #include "misc.h"
  6. #include "serpentp.h"
  7. NAMESPACE_BEGIN(CryptoPP)
  8. void Serpent_KeySchedule(word32 *k, unsigned int rounds, const byte *userKey, size_t keylen)
  9. {
  10. FixedSizeSecBlock<word32, 8> k0;
  11. GetUserKey(LITTLE_ENDIAN_ORDER, k0.begin(), 8, userKey, keylen);
  12. if (keylen < 32)
  13. k0[keylen/4] |= word32(1) << ((keylen%4)*8);
  14. word32 t = k0[7];
  15. unsigned int i;
  16. for (i = 0; i < 8; ++i)
  17. k[i] = k0[i] = t = rotlFixed(k0[i] ^ k0[(i+3)%8] ^ k0[(i+5)%8] ^ t ^ 0x9e3779b9 ^ i, 11);
  18. for (i = 8; i < 4*(rounds+1); ++i)
  19. k[i] = t = rotlFixed(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i, 11);
  20. k -= 20;
  21. word32 a,b,c,d,e;
  22. for (i=0; i<rounds/8; i++)
  23. {
  24. afterS2(LK); afterS2(S3); afterS3(SK);
  25. afterS1(LK); afterS1(S2); afterS2(SK);
  26. afterS0(LK); afterS0(S1); afterS1(SK);
  27. beforeS0(LK); beforeS0(S0); afterS0(SK);
  28. k += 8*4;
  29. afterS6(LK); afterS6(S7); afterS7(SK);
  30. afterS5(LK); afterS5(S6); afterS6(SK);
  31. afterS4(LK); afterS4(S5); afterS5(SK);
  32. afterS3(LK); afterS3(S4); afterS4(SK);
  33. }
  34. afterS2(LK); afterS2(S3); afterS3(SK);
  35. }
  36. void Serpent::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, const NameValuePairs &)
  37. {
  38. AssertValidKeyLength(keylen);
  39. Serpent_KeySchedule(m_key, 32, userKey, keylen);
  40. }
  41. typedef BlockGetAndPut<word32, LittleEndian> Block;
  42. void Serpent::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
  43. {
  44. word32 a, b, c, d, e;
  45. Block::Get(inBlock)(a)(b)(c)(d);
  46. const word32 *k = m_key;
  47. unsigned int i=1;
  48. do
  49. {
  50. beforeS0(KX); beforeS0(S0); afterS0(LT);
  51. afterS0(KX); afterS0(S1); afterS1(LT);
  52. afterS1(KX); afterS1(S2); afterS2(LT);
  53. afterS2(KX); afterS2(S3); afterS3(LT);
  54. afterS3(KX); afterS3(S4); afterS4(LT);
  55. afterS4(KX); afterS4(S5); afterS5(LT);
  56. afterS5(KX); afterS5(S6); afterS6(LT);
  57. afterS6(KX); afterS6(S7);
  58. if (i == 4)
  59. break;
  60. ++i;
  61. c = b;
  62. b = e;
  63. e = d;
  64. d = a;
  65. a = e;
  66. k += 32;
  67. beforeS0(LT);
  68. }
  69. while (true);
  70. afterS7(KX);
  71. Block::Put(xorBlock, outBlock)(d)(e)(b)(a);
  72. }
  73. void Serpent::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
  74. {
  75. word32 a, b, c, d, e;
  76. Block::Get(inBlock)(a)(b)(c)(d);
  77. const word32 *k = m_key + 96;
  78. unsigned int i=4;
  79. beforeI7(KX);
  80. goto start;
  81. do
  82. {
  83. c = b;
  84. b = d;
  85. d = e;
  86. k -= 32;
  87. beforeI7(ILT);
  88. start:
  89. beforeI7(I7); afterI7(KX);
  90. afterI7(ILT); afterI7(I6); afterI6(KX);
  91. afterI6(ILT); afterI6(I5); afterI5(KX);
  92. afterI5(ILT); afterI5(I4); afterI4(KX);
  93. afterI4(ILT); afterI4(I3); afterI3(KX);
  94. afterI3(ILT); afterI3(I2); afterI2(KX);
  95. afterI2(ILT); afterI2(I1); afterI1(KX);
  96. afterI1(ILT); afterI1(I0); afterI0(KX);
  97. }
  98. while (--i != 0);
  99. Block::Put(xorBlock, outBlock)(a)(d)(b)(e);
  100. }
  101. NAMESPACE_END