XTEAEngine.cs 3.5 KB

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