|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.CompilerServices;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace Shadowsocks.Encryption.Stream
- {
- public class StreamTableNativeEncryptor : StreamEncryptor
- {
- // table mode use special way to generate key
- readonly string _password;
-
- public StreamTableNativeEncryptor(string method, string password) : base(method, password)
- {
- _password = password;
- }
-
- protected override void initCipher(byte[] iv, bool isEncrypt)
- {
- // another cipher is plain, needn't a table
- if (cipherFamily != CipherFamily.Table) return;
- ulong a = BitConverter.ToUInt64(CryptoUtils.MD5(Encoding.UTF8.GetBytes(_password)), 0);
- for (int i = 0; i < 256; i++)
- {
- _encryptTable[i] = (byte)i;
- }
- Span<byte> t = _encryptTable;
- // copy array 1024 times? excuse me?
- for (int i = 1; i < 1024; i++)
- {
- t = MergeSort(t, a, i);
- }
- _encryptTable = t.ToArray();
- for (int i = 0; i < 256; i++)
- {
- _decryptTable[_encryptTable[i]] = (byte)i;
- }
- }
-
- protected override void cipherUpdate(bool isEncrypt, int length, byte[] buf, byte[] outbuf)
- {
- if (cipherFamily == CipherFamily.Table)
- {
- var table = isEncrypt ? _encryptTable : _decryptTable;
- for (int i = 0; i < length; i++)
- {
- outbuf[i] = table[buf[i]];
- }
- }
- else if (cipherFamily == CipherFamily.Plain)
- {
- Array.Copy(buf, outbuf, length);
- }
- }
-
- protected override int CipherDecrypt(Span<byte> plain, Span<byte> cipher)
- {
- if (cipherFamily == CipherFamily.Plain)
- {
- cipher.CopyTo(plain);
- return cipher.Length;
- }
-
- for (int i = 0; i < cipher.Length; i++)
- {
- plain[i] = _decryptTable[cipher[i]];
- }
- return cipher.Length;
- }
-
- protected override int CipherEncrypt(Span<byte> plain, Span<byte> cipher)
- {
- if (cipherFamily == CipherFamily.Plain)
- {
- plain.CopyTo(cipher);
- return plain.Length;
- }
-
- for (int i = 0; i < plain.Length; i++)
- {
- cipher[i] = _decryptTable[plain[i]];
- }
- return plain.Length;
- }
-
- #region Cipher Info
- private static readonly Dictionary<string, CipherInfo> _ciphers = new Dictionary<string, CipherInfo>
- {
- {"plain", new CipherInfo("plain", 0, 0, CipherFamily.Plain) },
- {"table", new CipherInfo("table", 0, 0, CipherFamily.Table) },
- };
-
- public static Dictionary<string, CipherInfo> SupportedCiphers()
- {
- return _ciphers;
- }
-
- protected override Dictionary<string, CipherInfo> getCiphers()
- {
- return _ciphers;
- }
- #endregion
-
- #region Table
- private byte[] _encryptTable = new byte[256];
- private byte[] _decryptTable = new byte[256];
- private byte[] _tmp = new byte[256];
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static long Compare(byte x, byte y, ulong a, int i)
- {
- return (long)(a % (ulong)(x + i)) - (long)(a % (ulong)(y + i));
- }
-
- byte[] buf = new byte[1024];
- private Span<byte> MergeSort(Span<byte> array, ulong a, int j)
- {
- if (array.Length == 1)
- {
- return array;
- }
- int middle = array.Length / 2;
-
- Span<byte> left = MergeSort(array.Slice(0, middle), a, j);;
- Span<byte> right = MergeSort(array.Slice(middle), a, j);
-
- int leftptr = 0;
- int rightptr = 0;
-
- // why a new array?
- Span<byte> sorted = new byte[array.Length];// buf.AsSpan().Slice(0,array.Length); // // _tmp;
-
- for (int k = 0; k < array.Length; k++)
- {
- if (rightptr == right.Length || ((leftptr < left.Length) && (Compare(left[leftptr], right[rightptr], a, j) <= 0)))
- {
- sorted[k] = left[leftptr];
- leftptr++;
- }
- else if (leftptr == left.Length || ((rightptr < right.Length) && (Compare(right[rightptr], left[leftptr], a, j)) <= 0))
- {
- sorted[k] = right[rightptr];
- rightptr++;
- }
- }
- return sorted;
- }
- #endregion
- }
- }
|