Browse Source

Merge branch 'nacl-core-chacha20' into net-core-build

pull/2865/head
Student Main 5 years ago
parent
commit
019b6656c5
4 changed files with 154 additions and 19 deletions
  1. +85
    -0
      shadowsocks-csharp/Encryption/AEAD/AEADNaClEncryptor.cs
  2. +5
    -0
      shadowsocks-csharp/packages.config
  3. +2
    -0
      shadowsocks-csharp/shadowsocks-csharp.csproj
  4. +62
    -19
      test/CryptographyTest.cs

+ 85
- 0
shadowsocks-csharp/Encryption/AEAD/AEADNaClEncryptor.cs View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NaCl.Core;
using NaCl.Core.Base;

namespace Shadowsocks.Encryption.AEAD
{
public class AEADNaClEncryptor : AEADEncryptor
{

SnufflePoly1305 enc;
SnufflePoly1305 dec;
public AEADNaClEncryptor(string method, string password) : base(method, password)
{

}

public override void InitCipher(byte[] salt, bool isEncrypt, bool isUdp)
{
base.InitCipher(salt, isEncrypt, isUdp);
DeriveSessionKey(isEncrypt ? encryptSalt : decryptSalt,
_Masterkey, sessionKey);

SnufflePoly1305 tmp;
switch (_cipher)
{
default:
case CipherChaCha20Poly1305:
tmp = new ChaCha20Poly1305(sessionKey);
break;
case CipherXChaCha20Poly1305:
tmp = new XChaCha20Poly1305(sessionKey);
break;
}
if (isEncrypt) enc = tmp;
else dec = tmp;
}

public override void cipherDecrypt(byte[] ciphertext, uint clen, byte[] plaintext, ref uint plen)
{
var pt = dec.Decrypt(ciphertext, null, decNonce);
pt.CopyTo(plaintext, 0);
plen = (uint)pt.Length;
}

public override void cipherEncrypt(byte[] plaintext, uint plen, byte[] ciphertext, ref uint clen)
{
var ct = enc.Encrypt(plaintext, null, encNonce);
ct.CopyTo(ciphertext, 0);
clen = (uint)ct.Length;
}

public override void Dispose()
{
}

const int CipherChaCha20Poly1305 = 1;
const int CipherXChaCha20Poly1305 = 2;

private static readonly Dictionary<string, EncryptorInfo> _ciphers = new Dictionary<string, EncryptorInfo>
{
{"chacha20-ietf-poly1305", new EncryptorInfo(32, 32, 12, 16, 1)},
{"xchacha20-ietf-poly1305", new EncryptorInfo(32, 32, 24, 16, 2)},
//{"aes-256-gcm", new EncryptorInfo(32, 32, 12, 16, CIPHER_AES256GCM)},
};

protected override Dictionary<string, EncryptorInfo> getCiphers()
{
return _ciphers;
}

public override byte[] CipherEncrypt2(byte[] plain)
{
return enc.Encrypt(plain, null, encNonce);
}

public override byte[] CipherDecrypt2(byte[] cipher)
{
return dec.Decrypt(cipher, null, decNonce);
}
}
}

+ 5
- 0
shadowsocks-csharp/packages.config View File

@@ -5,8 +5,13 @@
<package id="Costura.Fody" version="3.3.3" targetFramework="net472" />
<package id="Fody" version="4.2.1" targetFramework="net472" developmentDependency="true" />
<package id="GlobalHotKey" version="1.1.0" targetFramework="net472" />
<package id="NaCl.Core" version="1.2.0" targetFramework="net472" />
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net472" />
<package id="NLog" version="4.6.8" targetFramework="net472" />
<package id="StringEx.CS" version="0.3.1" targetFramework="net472" developmentDependency="true" />
<package id="System.Buffers" version="4.4.0" targetFramework="net472" />
<package id="System.Memory" version="4.5.2" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net472" />
<package id="ZXing.Net" version="0.16.5" targetFramework="net472" />
</packages>

+ 2
- 0
shadowsocks-csharp/shadowsocks-csharp.csproj View File

@@ -66,6 +66,8 @@
</PackageReference>
<PackageReference Include="Microsoft.VisualBasic" Version="10.3.0" />
<PackageReference Include="NaCl.Core" Version="1.2.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NLog" Version="4.6.8" />
<PackageReference Include="StringEx.CS" Version="0.3.1">


+ 62
- 19
test/CryptographyTest.cs View File

@@ -82,17 +82,39 @@ namespace Shadowsocks.Test
Assert.IsFalse(encryptionFailed);
}
private void RunSingleBouncyCastleAEADEncryptionThread()
{
try
{
for (int i = 0; i < 100; i++)
{
var random = new Random();
IEncryptor encryptor;
IEncryptor decryptor;
encryptor = new Encryption.AEAD.AEADBouncyCastleEncryptor("aes-256-gcm", "barfoo!");
encryptor.AddrBufLength = 1 + 4 + 2;// ADDR_ATYP_LEN + 4 + ADDR_PORT_LEN;
decryptor = new Encryption.AEAD.AEADBouncyCastleEncryptor("aes-256-gcm", "barfoo!");
decryptor.AddrBufLength = 1 + 4 + 2;// ADDR_ATYP_LEN + 4 + ADDR_PORT_LEN;
RunEncryptionRound(encryptor, decryptor);
}
}
catch
{
encryptionFailed = true;
throw;
}
}
[TestMethod]
public void TestNativeEncryption()
public void TesNaClAEADEncryption()
{
encryptionFailed = false;
// run it once before the multi-threading test to initialize global tables
RunSingleNativeEncryptionThread();
RunSingleNaClAEADEncryptionThread();
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(new ThreadStart(RunSingleNativeEncryptionThread));
threads.Add(t);
Thread t = new Thread(new ThreadStart(RunSingleNaClAEADEncryptionThread)); threads.Add(t);
t.Start();
}
foreach (Thread t in threads)
@@ -103,17 +125,20 @@ namespace Shadowsocks.Test
Assert.IsFalse(encryptionFailed);
}
private void RunSingleNativeEncryptionThread()
private void RunSingleNaClAEADEncryptionThread()
{
try
{
for (int i = 0; i < 100; i++)
{
IEncryptor encryptorN;
IEncryptor decryptorN;
encryptorN = new StreamRc4NativeEncryptor("rc4-md5", "barfoo!");
decryptorN = new StreamRc4NativeEncryptor("rc4-md5", "barfoo!");
RunEncryptionRound(encryptorN, decryptorN);
var random = new Random();
IEncryptor encryptor;
IEncryptor decryptor;
encryptor = new Encryption.AEAD.AEADNaClEncryptor("chacha20-ietf-poly1305", "barfoo!");
encryptor.AddrBufLength = 1 + 4 + 2;// ADDR_ATYP_LEN + 4 + ADDR_PORT_LEN;
decryptor = new Encryption.AEAD.AEADNaClEncryptor("chacha20-ietf-poly1305", "barfoo!");
decryptor.AddrBufLength = 1 + 4 + 2;// ADDR_ATYP_LEN + 4 + ADDR_PORT_LEN;
RunEncryptionRound(encryptor, decryptor);
}
}
catch
@@ -123,20 +148,38 @@ namespace Shadowsocks.Test
}
}
private void RunSingleBouncyCastleAEADEncryptionThread()
[TestMethod]
public void TestNativeEncryption()
{
encryptionFailed = false;
// run it once before the multi-threading test to initialize global tables
RunSingleNativeEncryptionThread();
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(new ThreadStart(RunSingleNativeEncryptionThread));
threads.Add(t);
t.Start();
}
foreach (Thread t in threads)
{
t.Join();
}
RNG.Close();
Assert.IsFalse(encryptionFailed);
}
private void RunSingleNativeEncryptionThread()
{
try
{
for (int i = 0; i < 100; i++)
{
var random = new Random();
IEncryptor encryptor;
IEncryptor decryptor;
encryptor = new Encryption.AEAD.AEADBouncyCastleEncryptor("aes-256-gcm", "barfoo!");
encryptor.AddrBufLength = 1 + 4 + 2;// ADDR_ATYP_LEN + 4 + ADDR_PORT_LEN;
decryptor = new Encryption.AEAD.AEADAesGcmNativeEncryptor("aes-256-gcm", "barfoo!");
decryptor.AddrBufLength = 1 + 4 + 2;// ADDR_ATYP_LEN + 4 + ADDR_PORT_LEN;
RunEncryptionRound(encryptor, decryptor);
IEncryptor encryptorN;
IEncryptor decryptorN;
encryptorN = new StreamRc4NativeEncryptor("rc4-md5", "barfoo!");
decryptorN = new StreamRc4NativeEncryptor("rc4-md5", "barfoo!");
RunEncryptionRound(encryptorN, decryptorN);
}
}
catch


Loading…
Cancel
Save