@@ -17,7 +17,7 @@ namespace NLog | |||||
if (length == -1) length = arr.Length; | if (length == -1) length = arr.Length; | ||||
if (!logger.IsTraceEnabled) return; | 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 = $@" | string content = $@" | ||||
{tag}: | {tag}: | ||||
{hex} | {hex} | ||||
@@ -31,7 +31,7 @@ namespace NLog | |||||
if (length == -1) length = arr.Length; | if (length == -1) length = arr.Length; | ||||
if (!logger.IsTraceEnabled) return; | 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 = $@" | string content = $@" | ||||
{tag}: | {tag}: | ||||
{hex} | {hex} | ||||
@@ -328,13 +328,13 @@ namespace Shadowsocks.Encryption.AEAD | |||||
{ | { | ||||
// Generate salt | // Generate salt | ||||
//RNG.GetBytes(outbuf, saltLen); | //RNG.GetBytes(outbuf, saltLen); | ||||
RNG.GetSpan(outbuf.AsSpan().Slice(0, saltLen)); | |||||
RNG.GetSpan(outbuf.AsSpan(0, saltLen)); | |||||
InitCipher(outbuf, true, true); | InitCipher(outbuf, true, true); | ||||
//uint olen = 0; | //uint olen = 0; | ||||
lock (_udpTmpBuf) | lock (_udpTmpBuf) | ||||
{ | { | ||||
//cipherEncrypt(buf, (uint)length, _udpTmpBuf, ref olen); | //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); | var cipher = CipherEncrypt2(plain); | ||||
//Debug.Assert(olen == length + tagLen); | //Debug.Assert(olen == length + tagLen); | ||||
Buffer.BlockCopy(cipher, 0, outbuf, saltLen, length + tagLen); | Buffer.BlockCopy(cipher, 0, outbuf, saltLen, length + tagLen); | ||||
@@ -351,7 +351,7 @@ namespace Shadowsocks.Encryption.AEAD | |||||
{ | { | ||||
// copy remaining data to first pos | // copy remaining data to first pos | ||||
Buffer.BlockCopy(buf, saltLen, buf, 0, length - saltLen); | 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); | byte[] o = CipherDecrypt2(b); | ||||
//cipherDecrypt(buf, (uint)(length - saltLen), _udpTmpBuf, ref olen); | //cipherDecrypt(buf, (uint)(length - saltLen), _udpTmpBuf, ref olen); | ||||
Buffer.BlockCopy(o, 0, outbuf, 0, o.Length); | Buffer.BlockCopy(o, 0, outbuf, 0, o.Length); | ||||
@@ -25,7 +25,7 @@ namespace Shadowsocks.Encryption.Stream | |||||
protected override void cipherUpdate(bool isEncrypt, int length, byte[] buf, byte[] outbuf) | 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); | if (isEncrypt) CipherEncrypt(i, outbuf); | ||||
else CipherDecrypt(outbuf, i); | else CipherDecrypt(outbuf, i); | ||||
} | } | ||||
@@ -6,29 +6,36 @@ namespace Shadowsocks.Encryption.Stream | |||||
{ | { | ||||
public class StreamChachaNaClEncryptor : StreamEncryptor | 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) | public StreamChachaNaClEncryptor(string method, string password) : base(method, password) | ||||
{ | { | ||||
c = new ChaCha20(key, 0); | |||||
} | } | ||||
protected override int CipherDecrypt(Span<byte> plain, Span<byte> cipher) | protected override int CipherDecrypt(Span<byte> plain, Span<byte> 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<byte> plain, Span<byte> cipher) | protected override int CipherEncrypt(Span<byte> plain, Span<byte> 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) | 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) | if (isEncrypt) | ||||
{ | { | ||||
CipherEncrypt(i, outbuf); | CipherEncrypt(i, outbuf); | ||||
@@ -67,7 +67,7 @@ namespace Shadowsocks.Test | |||||
encryptor.Encrypt(plain, length, cipher, out int outLen); | encryptor.Encrypt(plain, length, cipher, out int outLen); | ||||
decryptor.Decrypt(cipher, outLen, plain2, out int outLen2); | decryptor.Decrypt(cipher, outLen, plain2, out int outLen2); | ||||
Assert.AreEqual(length, outLen2); | Assert.AreEqual(length, outLen2); | ||||
ArrayEqual<byte>(plain.AsSpan().Slice(0, length).ToArray(), plain2.AsSpan().Slice(0, length).ToArray()); | |||||
ArrayEqual<byte>(plain.AsSpan(0, length).ToArray(), plain2.AsSpan(0, length).ToArray()); | |||||
} | } | ||||
private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor) | private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor) | ||||