diff --git a/shadowsocks-csharp/Controller/LoggerExtension.cs b/shadowsocks-csharp/Controller/LoggerExtension.cs index eb6ee840..b3fc6e4c 100644 --- a/shadowsocks-csharp/Controller/LoggerExtension.cs +++ b/shadowsocks-csharp/Controller/LoggerExtension.cs @@ -17,7 +17,7 @@ namespace NLog if (length == -1) length = arr.Length; if (!logger.IsTraceEnabled) return; - string hex = BitConverter.ToString(arr.AsSpan().Slice(0, length).ToArray()).Replace("-", ""); + string hex = BitConverter.ToString(arr.AsSpan(0, length).ToArray()).Replace("-", ""); string content = $@" {tag}: {hex} @@ -31,7 +31,7 @@ namespace NLog if (length == -1) length = arr.Length; if (!logger.IsTraceEnabled) return; - string hex =Convert.ToBase64String(arr.AsSpan().Slice(0, length).ToArray()); + string hex =Convert.ToBase64String(arr.AsSpan(0, length).ToArray()); string content = $@" {tag}: {hex} diff --git a/shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs b/shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs index bafe5c5f..3c3f4ab0 100644 --- a/shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs +++ b/shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs @@ -328,13 +328,13 @@ namespace Shadowsocks.Encryption.AEAD { // Generate salt //RNG.GetBytes(outbuf, saltLen); - RNG.GetSpan(outbuf.AsSpan().Slice(0, saltLen)); + RNG.GetSpan(outbuf.AsSpan(0, saltLen)); InitCipher(outbuf, true, true); //uint olen = 0; lock (_udpTmpBuf) { //cipherEncrypt(buf, (uint)length, _udpTmpBuf, ref olen); - var plain = buf.AsSpan().Slice(0, length).ToArray(); // mmp + var plain = buf.AsSpan(0, length).ToArray(); // mmp var cipher = CipherEncrypt2(plain); //Debug.Assert(olen == length + tagLen); Buffer.BlockCopy(cipher, 0, outbuf, saltLen, length + tagLen); @@ -351,7 +351,7 @@ namespace Shadowsocks.Encryption.AEAD { // copy remaining data to first pos Buffer.BlockCopy(buf, saltLen, buf, 0, length - saltLen); - byte[] b = buf.AsSpan().Slice(0, length - saltLen).ToArray(); + byte[] b = buf.AsSpan(0, length - saltLen).ToArray(); byte[] o = CipherDecrypt2(b); //cipherDecrypt(buf, (uint)(length - saltLen), _udpTmpBuf, ref olen); Buffer.BlockCopy(o, 0, outbuf, 0, o.Length); diff --git a/shadowsocks-csharp/Encryption/Stream/StreamAesBouncyCastleEncryptor.cs b/shadowsocks-csharp/Encryption/Stream/StreamAesBouncyCastleEncryptor.cs index a247f548..8d111c3a 100644 --- a/shadowsocks-csharp/Encryption/Stream/StreamAesBouncyCastleEncryptor.cs +++ b/shadowsocks-csharp/Encryption/Stream/StreamAesBouncyCastleEncryptor.cs @@ -25,7 +25,7 @@ namespace Shadowsocks.Encryption.Stream protected override void cipherUpdate(bool isEncrypt, int length, byte[] buf, byte[] outbuf) { - var i = buf.AsSpan().Slice(0, length); + var i = buf.AsSpan(0, length); if (isEncrypt) CipherEncrypt(i, outbuf); else CipherDecrypt(outbuf, i); } diff --git a/shadowsocks-csharp/Encryption/Stream/StreamChachaNaClEncryptor.cs b/shadowsocks-csharp/Encryption/Stream/StreamChachaNaClEncryptor.cs index 4833b621..da6969b7 100644 --- a/shadowsocks-csharp/Encryption/Stream/StreamChachaNaClEncryptor.cs +++ b/shadowsocks-csharp/Encryption/Stream/StreamChachaNaClEncryptor.cs @@ -6,29 +6,36 @@ namespace Shadowsocks.Encryption.Stream { public class StreamChachaNaClEncryptor : StreamEncryptor { - readonly ChaCha20 c; + // yes, they update over all saved data everytime... + byte[] chachaBuf = new byte[65536]; + int ptr = 0; public StreamChachaNaClEncryptor(string method, string password) : base(method, password) { - c = new ChaCha20(key, 0); } protected override int CipherDecrypt(Span plain, Span cipher) { - var p = c.Decrypt(cipher, iv); - p.CopyTo(plain); - return p.Length; + int len = cipher.Length; + cipher.CopyTo(chachaBuf.AsSpan(ptr)); + var p = new ChaCha20(key, 0).Decrypt(chachaBuf, iv); + p.AsSpan(ptr, len).CopyTo(plain); + ptr += len; + return len; } protected override int CipherEncrypt(Span plain, Span cipher) { - var e = c.Encrypt(plain, iv); - e.CopyTo(cipher); - return e.Length; + int len = plain.Length; + plain.CopyTo(chachaBuf.AsSpan(ptr)); + var p = new ChaCha20(key, 0).Encrypt(chachaBuf, iv); + p.AsSpan(ptr, len).CopyTo(cipher); + ptr += len; + return len; } protected override void cipherUpdate(bool isEncrypt, int length, byte[] buf, byte[] outbuf) { - var i = buf.AsSpan().Slice(0, length); + var i = buf.AsSpan(0, length); if (isEncrypt) { CipherEncrypt(i, outbuf); diff --git a/test/CryptographyTest.cs b/test/CryptographyTest.cs index bfd2abda..10eda453 100644 --- a/test/CryptographyTest.cs +++ b/test/CryptographyTest.cs @@ -67,7 +67,7 @@ namespace Shadowsocks.Test encryptor.Encrypt(plain, length, cipher, out int outLen); decryptor.Decrypt(cipher, outLen, plain2, out int outLen2); Assert.AreEqual(length, outLen2); - ArrayEqual(plain.AsSpan().Slice(0, length).ToArray(), plain2.AsSpan().Slice(0, length).ToArray()); + ArrayEqual(plain.AsSpan(0, length).ToArray(), plain2.AsSpan(0, length).ToArray()); } private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor)