You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

CryptographyTest.cs 5.6 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. using Microsoft.VisualStudio.TestTools.UnitTesting;
  2. using Shadowsocks.Encryption;
  3. using Shadowsocks.Encryption.Stream;
  4. using Shadowsocks.Encryption.AEAD;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Threading;
  8. namespace Shadowsocks.Test
  9. {
  10. [TestClass]
  11. public class CryptographyTest
  12. {
  13. Random random = new Random();
  14. [TestMethod]
  15. public void TestMD5()
  16. {
  17. for (int len = 1; len < 64; len++)
  18. {
  19. System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
  20. byte[] bytes = new byte[len];
  21. random.NextBytes(bytes);
  22. string md5str = Convert.ToBase64String(md5.ComputeHash(bytes));
  23. string md5str2 = Convert.ToBase64String(CryptoUtils.MD5(bytes));
  24. Assert.IsTrue(md5str == md5str2);
  25. }
  26. }
  27. private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor)
  28. {
  29. RNG.Reload();
  30. byte[] plain = new byte[16384];
  31. byte[] cipher = new byte[plain.Length + 100];// AEAD with IPv4 address type needs +100
  32. byte[] plain2 = new byte[plain.Length + 16];
  33. //random = new Random();
  34. random.NextBytes(plain);
  35. encryptor.Encrypt(plain, plain.Length, cipher, out int outLen);
  36. decryptor.Decrypt(cipher, outLen, plain2, out int outLen2);
  37. Assert.AreEqual(plain.Length, outLen2);
  38. for (int j = 0; j < plain.Length; j++)
  39. {
  40. Assert.AreEqual(plain[j], plain2[j]);
  41. }
  42. encryptor.Encrypt(plain, 1000, cipher, out outLen);
  43. decryptor.Decrypt(cipher, outLen, plain2, out outLen2);
  44. Assert.AreEqual(1000, outLen2);
  45. for (int j = 0; j < outLen2; j++)
  46. {
  47. Assert.AreEqual(plain[j], plain2[j]);
  48. }
  49. encryptor.Encrypt(plain, 12333, cipher, out outLen);
  50. decryptor.Decrypt(cipher, outLen, plain2, out outLen2);
  51. Assert.AreEqual(12333, outLen2);
  52. for (int j = 0; j < outLen2; j++)
  53. {
  54. Assert.AreEqual(plain[j], plain2[j]);
  55. }
  56. }
  57. const string password = "barfoo!";
  58. private void RunSingleEncryptionThread(Type enc, Type dec, string method)
  59. {
  60. var ector = enc.GetConstructor(new Type[] { typeof(string), typeof(string) });
  61. var dctor = dec.GetConstructor(new Type[] { typeof(string), typeof(string) });
  62. try
  63. {
  64. IEncryptor encryptor = (IEncryptor)ector.Invoke(new object[] { method, password });
  65. IEncryptor decryptor = (IEncryptor)dctor.Invoke(new object[] { method, password });
  66. encryptor.AddressBufferLength = 1 + 4 + 2;// ADDR_ATYP_LEN + 4 + ADDR_PORT_LEN;
  67. decryptor.AddressBufferLength = 1 + 4 + 2;// ADDR_ATYP_LEN + 4 + ADDR_PORT_LEN;
  68. for (int i = 0; i < 16; i++)
  69. {
  70. RunEncryptionRound(encryptor, decryptor);
  71. }
  72. }
  73. catch
  74. {
  75. encryptionFailed = true;
  76. throw;
  77. }
  78. }
  79. private static bool encryptionFailed = false;
  80. private void TestEncryptionMethod(Type enc, string method)
  81. {
  82. TestEncryptionMethod(enc, enc, method);
  83. }
  84. private void TestEncryptionMethod(Type enc, Type dec, string method)
  85. {
  86. encryptionFailed = false;
  87. // run it once before the multi-threading test to initialize global tables
  88. RunSingleEncryptionThread(enc, dec, method);
  89. List<Thread> threads = new List<Thread>();
  90. for (int i = 0; i < 8; i++)
  91. {
  92. Thread t = new Thread(new ThreadStart(() => RunSingleEncryptionThread(enc, dec, method))); threads.Add(t);
  93. t.Start();
  94. }
  95. foreach (Thread t in threads)
  96. {
  97. t.Join();
  98. }
  99. Assert.IsFalse(encryptionFailed);
  100. }
  101. [TestMethod]
  102. public void TestAesGcmNativeAEADEncryption()
  103. {
  104. TestEncryptionMethod(typeof(AEADAesGcmNativeEncryptor), "aes-128-gcm");
  105. TestEncryptionMethod(typeof(AEADAesGcmNativeEncryptor), "aes-192-gcm");
  106. TestEncryptionMethod(typeof(AEADAesGcmNativeEncryptor), "aes-256-gcm");
  107. }
  108. [TestMethod]
  109. public void TestNaClAEADEncryption()
  110. {
  111. TestEncryptionMethod(typeof(AEADNaClEncryptor), "chacha20-ietf-poly1305");
  112. TestEncryptionMethod(typeof(AEADNaClEncryptor), "xchacha20-ietf-poly1305");
  113. }
  114. [TestMethod]
  115. public void TestNativeEncryption()
  116. {
  117. TestEncryptionMethod(typeof(StreamTableNativeEncryptor), "plain");
  118. TestEncryptionMethod(typeof(StreamRc4NativeEncryptor), "rc4");
  119. TestEncryptionMethod(typeof(StreamRc4NativeEncryptor), "rc4-md5");
  120. }
  121. [TestMethod]
  122. public void TestNativeTableEncryption()
  123. {
  124. // Too slow, run once to save CPU
  125. var enc = new StreamTableNativeEncryptor("table", "barfoo!");
  126. var dec = new StreamTableNativeEncryptor("table", "barfoo!");
  127. RunEncryptionRound(enc, dec);
  128. }
  129. }
  130. }