diff --git a/Editor/Encryption/AddInstruction.cs b/Editor/Encryption/AddInstruction.cs new file mode 100644 index 0000000..598cc5b --- /dev/null +++ b/Editor/Encryption/AddInstruction.cs @@ -0,0 +1,23 @@ +namespace Obfuz.Encryption +{ + public class AddInstruction : EncryptInstructionBase + { + private readonly int _addValue; + private readonly int _opKeyIndex; + + public AddInstruction(int addValue, int opKeyIndex) + { + _addValue = addValue; + _opKeyIndex = opKeyIndex; + } + public override int Encrypt(int value, int[] secretKey, int salt) + { + return value + secretKey[_opKeyIndex] + salt + _addValue; + } + + public override int Decrypt(int value, int[] secretKey, int salt) + { + return value - secretKey[_opKeyIndex] - salt - _addValue; + } + } +} diff --git a/Editor/Encryption/BitRotateInstruction.cs b/Editor/Encryption/BitRotateInstruction.cs new file mode 100644 index 0000000..14f41a3 --- /dev/null +++ b/Editor/Encryption/BitRotateInstruction.cs @@ -0,0 +1,29 @@ +namespace Obfuz.Encryption +{ + public class BitRotateInstruction : EncryptInstructionBase + { + private readonly int _rotateBitNum; + private readonly int _opKeyIndex; + + public BitRotateInstruction(int rotateBitNum, int opKeyIndex) + { + _rotateBitNum = rotateBitNum; + _opKeyIndex = opKeyIndex; + } + + public override int Encrypt(int value, int[] secretKey, int salt) + { + uint part1 = (uint)value << _rotateBitNum; + uint part2 = (uint)value >> (32 - _rotateBitNum); + return ((int)(part1 | part2) ^ secretKey[_opKeyIndex]) + salt; + } + + public override int Decrypt(int value, int[] secretKey, int salt) + { + uint value2 = (uint)((value - salt) ^ secretKey[_opKeyIndex]); + uint part1 = value2 >> _rotateBitNum; + uint part2 = value2 << (32 - _rotateBitNum); + return (int)(part1 | part2); + } + } +} diff --git a/Editor/Encryption/EncryptFunction.cs b/Editor/Encryption/EncryptFunction.cs index ac7408e..8e6e398 100644 --- a/Editor/Encryption/EncryptFunction.cs +++ b/Editor/Encryption/EncryptFunction.cs @@ -5,88 +5,6 @@ using System.Threading.Tasks; namespace Obfuz.Encryption { - public interface IEncryptInstruction - { - int Encrypt(int value, int[] secretKey, int salt); - - int Decrypt(int value, int[] secretKey, int salt); - } - - public abstract class EncryptInstructionBase : IEncryptInstruction - { - public abstract int Encrypt(int value, int[] secretKey, int salt); - public abstract int Decrypt(int value, int[] secretKey, int salt); - } - - public class AddInstruction : EncryptInstructionBase - { - private readonly int _addValue; - private readonly int _opKeyIndex; - - public AddInstruction(int addValue, int opKeyIndex) - { - _addValue = addValue; - _opKeyIndex = opKeyIndex; - } - public override int Encrypt(int value, int[] secretKey, int salt) - { - return value + secretKey[_opKeyIndex] + salt + _addValue; - } - - public override int Decrypt(int value, int[] secretKey, int salt) - { - return value - secretKey[_opKeyIndex] - salt - _addValue; - } - } - - public class XorInstruction : EncryptInstructionBase - { - private readonly int _xorValue; - private readonly int _opKeyIndex; - - public XorInstruction(int xorValue, int opKeyIndex) - { - _xorValue = xorValue; - _opKeyIndex = opKeyIndex; - } - - public override int Encrypt(int value, int[] secretKey, int salt) - { - return value ^ secretKey[_opKeyIndex] ^ salt ^ _xorValue; - } - - public override int Decrypt(int value, int[] secretKey, int salt) - { - return value ^ secretKey[_opKeyIndex] ^ salt ^ _xorValue; - } - } - - public class BitRotateInstruction : EncryptInstructionBase - { - private readonly int _rotateBitNum; - private readonly int _opKeyIndex; - - public BitRotateInstruction(int rotateBitNum, int opKeyIndex) - { - _rotateBitNum = rotateBitNum; - _opKeyIndex = opKeyIndex; - } - - public override int Encrypt(int value, int[] secretKey, int salt) - { - uint part1 = (uint)value << _rotateBitNum; - uint part2 = (uint)value >> (32 - _rotateBitNum); - return ((int)(part1 | part2) ^ secretKey[_opKeyIndex]) + salt; - } - - public override int Decrypt(int value, int[] secretKey, int salt) - { - uint value2 = (uint)((value - salt) ^ secretKey[_opKeyIndex]); - uint part1 = value2 >> _rotateBitNum; - uint part2 = value2 << (32 - _rotateBitNum); - return (int)(part1 | part2); - } - } public class EncryptFunction : EncryptInstructionBase { diff --git a/Editor/Encryption/EncryptInstructionBase.cs b/Editor/Encryption/EncryptInstructionBase.cs new file mode 100644 index 0000000..be52283 --- /dev/null +++ b/Editor/Encryption/EncryptInstructionBase.cs @@ -0,0 +1,8 @@ +namespace Obfuz.Encryption +{ + public abstract class EncryptInstructionBase : IEncryptInstruction + { + public abstract int Encrypt(int value, int[] secretKey, int salt); + public abstract int Decrypt(int value, int[] secretKey, int salt); + } +} diff --git a/Editor/Encryption/EncryptVirtualMachineSimulator.cs b/Editor/Encryption/EncryptVirtualMachineSimulator.cs index e645567..f02018a 100644 --- a/Editor/Encryption/EncryptVirtualMachineSimulator.cs +++ b/Editor/Encryption/EncryptVirtualMachineSimulator.cs @@ -10,6 +10,8 @@ namespace Obfuz.Encryption { public class VirtualMachine { + public const int SecretKeyLength = 1024; + public readonly int vmSeed; public readonly EncryptOpCode[] opCodes; @@ -27,22 +29,27 @@ namespace Obfuz.Encryption public class RandomVirtualMachineCreator : IVirtualMachineCreator { + private readonly int[] _debugSecretKey; public RandomVirtualMachineCreator() { - + _debugSecretKey = new int[VirtualMachine.SecretKeyLength]; + for (int i = 0; i < _debugSecretKey.Length; i++) + { + _debugSecretKey[i] = i; + } } - private IEncryptInstruction CreateRandomInstruction(IRandom random, int opCodeCount) + private IEncryptInstruction CreateRandomInstruction(IRandom random, int secretKeyLength) { switch (random.NextInt(3)) { case 0: - return new AddInstruction(random.NextInt(), random.NextInt(opCodeCount)); + return new AddInstruction(random.NextInt(), random.NextInt(secretKeyLength)); case 1: - return new XorInstruction(random.NextInt(), random.NextInt(opCodeCount)); + return new XorInstruction(random.NextInt(), random.NextInt(secretKeyLength)); case 2: - return new BitRotateInstruction(random.NextInt(32), random.NextInt(opCodeCount)); + return new BitRotateInstruction(random.NextInt(32), random.NextInt(secretKeyLength)); default: throw new System.Exception("Invalid instruction type"); } @@ -54,9 +61,12 @@ namespace Obfuz.Encryption var insts = new IEncryptInstruction[opCodeCount]; for (int i = 0; i < insts.Length; i++) { + IEncryptInstruction inst = CreateRandomInstruction(r, VirtualMachine.SecretKeyLength); + Assert.AreEqual(1234, inst.Decrypt(inst.Encrypt(1234, _debugSecretKey, i), _debugSecretKey, i)); insts[i] = CreateRandomInstruction(r, opCodeCount); } var function = new EncryptFunction(insts); + Assert.AreEqual(1234, function.Decrypt(function.Encrypt(1234, _debugSecretKey, code), _debugSecretKey, code)); return new EncryptOpCode(code, function); } @@ -191,6 +201,11 @@ namespace Obfuz.Encryption return encInts; } + public int[] Encrypt(byte[] bytes, int ops, int salt) + { + return Encrypt(bytes, 0, bytes.Length, ops, salt); + } + public byte[] Decrypt(int[] value, int offset, int byteLength, int ops, int salt) { if (byteLength == 0) @@ -209,6 +224,11 @@ namespace Obfuz.Encryption return bytes; } + public byte[] Decrypt(int[] value, int byteLength, int ops, int salt) + { + return Decrypt(value, 0, byteLength, ops, salt); + } + public int[] Encrypt(string value, int ops, int salt) { if (value.Length == 0) diff --git a/Editor/Encryption/IEncryptInstruction.cs b/Editor/Encryption/IEncryptInstruction.cs new file mode 100644 index 0000000..e2fd265 --- /dev/null +++ b/Editor/Encryption/IEncryptInstruction.cs @@ -0,0 +1,9 @@ +namespace Obfuz.Encryption +{ + public interface IEncryptInstruction + { + int Encrypt(int value, int[] secretKey, int salt); + + int Decrypt(int value, int[] secretKey, int salt); + } +} diff --git a/Editor/Encryption/XorInstruction.cs b/Editor/Encryption/XorInstruction.cs new file mode 100644 index 0000000..2df5a6e --- /dev/null +++ b/Editor/Encryption/XorInstruction.cs @@ -0,0 +1,24 @@ +namespace Obfuz.Encryption +{ + public class XorInstruction : EncryptInstructionBase + { + private readonly int _xorValue; + private readonly int _opKeyIndex; + + public XorInstruction(int xorValue, int opKeyIndex) + { + _xorValue = xorValue; + _opKeyIndex = opKeyIndex; + } + + public override int Encrypt(int value, int[] secretKey, int salt) + { + return value ^ secretKey[_opKeyIndex] ^ salt ^ _xorValue; + } + + public override int Decrypt(int value, int[] secretKey, int salt) + { + return value ^ secretKey[_opKeyIndex] ^ salt ^ _xorValue; + } + } +} diff --git a/Runtime/DefaultEncryptor.cs b/Runtime/DefaultEncryptor.cs index c28cf6e..2e2056d 100644 --- a/Runtime/DefaultEncryptor.cs +++ b/Runtime/DefaultEncryptor.cs @@ -15,19 +15,19 @@ namespace Obfuz _key = key; } - public void EncryptBytes(byte[] data, int minorSecret) + public void EncryptBlock(byte[] data, long ops, int salt) { for (int i = 0; i < data.Length; i++) { - data[i] ^= (byte)(_key[i % _key.Length] ^ minorSecret); + data[i] ^= (byte)(_key[i % _key.Length] ^ salt); } } - public void DecryptBytes(byte[] data, int minorSecret) + public void DecryptBlock(byte[] data, long ops, int salt) { for (int i = 0; i < data.Length; i++) { - data[i] ^= (byte)(_key[i % _key.Length] ^ minorSecret); + data[i] ^= (byte)(_key[i % _key.Length] ^ salt); } } } diff --git a/Runtime/EncryptionService.cs b/Runtime/EncryptionService.cs index 4d4e4e5..088cccc 100644 --- a/Runtime/EncryptionService.cs +++ b/Runtime/EncryptionService.cs @@ -10,9 +10,14 @@ namespace Obfuz { private static readonly IEncryptor _encryptor = new DefaultEncryptor(new byte[] { 0x1A, 0x2B, 0x3C, 0x4D }); - public static void DecryptBytes(byte[] data, int minorSecret) + public static void EncryptBlock(byte[] data, int salt) { - _encryptor.EncryptBytes(data, minorSecret); + _encryptor.EncryptBlock(data, salt); + } + + public static void DecryptBlock(byte[] data, int salt) + { + _encryptor.DecryptBlock(data, salt); } } } diff --git a/Runtime/IEncryptor.cs b/Runtime/IEncryptor.cs index 648a846..8ede0b1 100644 --- a/Runtime/IEncryptor.cs +++ b/Runtime/IEncryptor.cs @@ -8,7 +8,7 @@ namespace Obfuz { public interface IEncryptor { - void EncryptBytes(byte[] data, int minorSecret); - void DecryptBytes(byte[] data, int minorSecret); + void EncryptBlock(byte[] data, long ops, int salt); + void DecryptBlock(byte[] data, long ops, int salt); } }