|
|
@@ -6,21 +6,23 @@ namespace shadowsocks_csharp |
|
|
|
{ |
|
|
|
public class RC4 |
|
|
|
{ |
|
|
|
class Context |
|
|
|
{ |
|
|
|
public int index1 = 0; |
|
|
|
public int index2 = 0; |
|
|
|
} |
|
|
|
|
|
|
|
int enc_index1 = 0; |
|
|
|
int enc_index2 = 0; |
|
|
|
|
|
|
|
int dec_index1 = 0; |
|
|
|
int dec_index2 = 0; |
|
|
|
private Context enc_ctx = new Context(); |
|
|
|
private Context dec_ctx = new Context(); |
|
|
|
|
|
|
|
public void Encrypt(byte[] table, byte[] data, int length) |
|
|
|
{ |
|
|
|
EncryptOutput(enc_index1, enc_index2, table, data, length); |
|
|
|
EncryptOutput(enc_ctx, table, data, length); |
|
|
|
} |
|
|
|
|
|
|
|
public void Decrypt(byte[] table, byte[] data, int length) |
|
|
|
{ |
|
|
|
EncryptOutput(dec_index1, dec_index2, table, data, length); |
|
|
|
EncryptOutput(dec_ctx, table, data, length); |
|
|
|
} |
|
|
|
|
|
|
|
public byte[] EncryptInitalize(byte[] key) |
|
|
@@ -42,18 +44,18 @@ namespace shadowsocks_csharp |
|
|
|
return s; |
|
|
|
} |
|
|
|
|
|
|
|
private void EncryptOutput(int index1, int index2, byte[] s, byte[] data, int length) |
|
|
|
private void EncryptOutput(Context ctx, byte[] s, byte[] data, int length) |
|
|
|
{ |
|
|
|
for (int n = 0; n < length; n++) |
|
|
|
{ |
|
|
|
byte b = data[n]; |
|
|
|
|
|
|
|
index1 = (index1 + 1) & 255; |
|
|
|
index2 = (index2 + s[index1]) & 255; |
|
|
|
ctx.index1 = (ctx.index1 + 1) & 255; |
|
|
|
ctx.index2 = (ctx.index2 + s[ctx.index1]) & 255; |
|
|
|
|
|
|
|
Swap(s, index1, index2); |
|
|
|
Swap(s, ctx.index1, ctx.index2); |
|
|
|
|
|
|
|
data[n] = (byte)(b ^ s[(s[index1] + s[index2]) & 255]); |
|
|
|
data[n] = (byte)(b ^ s[(s[ctx.index1] + s[ctx.index2]) & 255]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|