XTEAEngine.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  7. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
  8. {
  9. /**
  10. * An XTEA engine.
  11. */
  12. public class XteaEngine
  13. : IBlockCipher
  14. {
  15. private const int
  16. rounds = 32,
  17. block_size = 8,
  18. // key_size = 16,
  19. delta = unchecked((int) 0x9E3779B9);
  20. /*
  21. * the expanded key array of 4 subkeys
  22. */
  23. private uint[] _S = new uint[4],
  24. _sum0 = new uint[32],
  25. _sum1 = new uint[32];
  26. private bool _initialised, _forEncryption;
  27. /**
  28. * Create an instance of the TEA encryption algorithm
  29. * and set some defaults
  30. */
  31. public XteaEngine()
  32. {
  33. _initialised = false;
  34. }
  35. public virtual string AlgorithmName
  36. {
  37. get { return "XTEA"; }
  38. }
  39. public virtual bool IsPartialBlockOkay
  40. {
  41. get { return false; }
  42. }
  43. public virtual int GetBlockSize()
  44. {
  45. return block_size;
  46. }
  47. /**
  48. * initialise
  49. *
  50. * @param forEncryption whether or not we are for encryption.
  51. * @param params the parameters required to set up the cipher.
  52. * @exception ArgumentException if the params argument is
  53. * inappropriate.
  54. */
  55. public virtual void Init(
  56. bool forEncryption,
  57. ICipherParameters parameters)
  58. {
  59. if (!(parameters is KeyParameter))
  60. {
  61. throw new ArgumentException("invalid parameter passed to TEA init - "
  62. + BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
  63. }
  64. _forEncryption = forEncryption;
  65. _initialised = true;
  66. KeyParameter p = (KeyParameter) parameters;
  67. setKey(p.GetKey());
  68. }
  69. public virtual int ProcessBlock(
  70. byte[] inBytes,
  71. int inOff,
  72. byte[] outBytes,
  73. int outOff)
  74. {
  75. if (!_initialised)
  76. throw new InvalidOperationException(AlgorithmName + " not initialised");
  77. Check.DataLength(inBytes, inOff, block_size, "input buffer too short");
  78. Check.OutputLength(outBytes, outOff, block_size, "output buffer too short");
  79. return _forEncryption
  80. ? encryptBlock(inBytes, inOff, outBytes, outOff)
  81. : decryptBlock(inBytes, inOff, outBytes, outOff);
  82. }
  83. public virtual void Reset()
  84. {
  85. }
  86. /**
  87. * Re-key the cipher.
  88. *
  89. * @param key the key to be used
  90. */
  91. private void setKey(
  92. byte[] key)
  93. {
  94. int i, j;
  95. for (i = j = 0; i < 4; i++,j+=4)
  96. {
  97. _S[i] = Pack.BE_To_UInt32(key, j);
  98. }
  99. for (i = j = 0; i < rounds; i++)
  100. {
  101. _sum0[i] = ((uint)j + _S[j & 3]);
  102. j += delta;
  103. _sum1[i] = ((uint)j + _S[j >> 11 & 3]);
  104. }
  105. }
  106. private int encryptBlock(
  107. byte[] inBytes,
  108. int inOff,
  109. byte[] outBytes,
  110. int outOff)
  111. {
  112. // Pack bytes into integers
  113. uint v0 = Pack.BE_To_UInt32(inBytes, inOff);
  114. uint v1 = Pack.BE_To_UInt32(inBytes, inOff + 4);
  115. for (int i = 0; i < rounds; i++)
  116. {
  117. v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ _sum0[i];
  118. v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ _sum1[i];
  119. }
  120. Pack.UInt32_To_BE(v0, outBytes, outOff);
  121. Pack.UInt32_To_BE(v1, outBytes, outOff + 4);
  122. return block_size;
  123. }
  124. private int decryptBlock(
  125. byte[] inBytes,
  126. int inOff,
  127. byte[] outBytes,
  128. int outOff)
  129. {
  130. // Pack bytes into integers
  131. uint v0 = Pack.BE_To_UInt32(inBytes, inOff);
  132. uint v1 = Pack.BE_To_UInt32(inBytes, inOff + 4);
  133. for (int i = rounds-1; i >= 0; i--)
  134. {
  135. v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ _sum1[i];
  136. v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ _sum0[i];
  137. }
  138. Pack.UInt32_To_BE(v0, outBytes, outOff);
  139. Pack.UInt32_To_BE(v1, outBytes, outOff + 4);
  140. return block_size;
  141. }
  142. }
  143. }
  144. #pragma warning restore
  145. #endif