obfuz/Editor/Encryption/RandomVirtualMachineCreator.cs

62 lines
2.4 KiB
C#

using Obfuz.Utils;
using UnityEngine.Assertions;
namespace Obfuz.Encryption
{
public class RandomVirtualMachineCreator : IVirtualMachineCreator
{
private readonly byte[] _byteSecretKey;
private readonly int[] _secretKey;
private readonly IRandom _random;
public RandomVirtualMachineCreator(byte[] secretKey)
{
_byteSecretKey = secretKey;
_secretKey = KeyGenerator.ConvertToIntKey(secretKey);
_random = new RandomWithKey(secretKey, 0);
}
private IEncryptInstruction CreateRandomInstruction(int secretKeyLength)
{
switch (_random.NextInt(3))
{
case 0:
return new AddInstruction(_random.NextInt(), _random.NextInt(secretKeyLength));
case 1:
return new XorInstruction(_random.NextInt(), _random.NextInt(secretKeyLength));
case 2:
return new BitRotateInstruction(_random.NextInt(32), _random.NextInt(secretKeyLength));
default:
throw new System.Exception("Invalid instruction type");
}
}
private EncryptOpCode CreateEncryptOpCode(ushort code, int opCodeCount)
{
Assert.IsTrue(code < opCodeCount);
var insts = new IEncryptInstruction[opCodeCount];
for (int i = 0; i < insts.Length; i++)
{
IEncryptInstruction inst = CreateRandomInstruction(VirtualMachine.SecretKeyLength);
Assert.AreEqual(1234, inst.Decrypt(inst.Encrypt(1234, _secretKey, i), _secretKey, i));
insts[i] = CreateRandomInstruction(opCodeCount);
}
var function = new EncryptFunction(insts);
Assert.AreEqual(1234, function.Decrypt(function.Encrypt(1234, _secretKey, code), _secretKey, code));
return new EncryptOpCode(code, function);
}
public VirtualMachine CreateVirtualMachine(int opCodeCount)
{
Assert.IsTrue(opCodeCount > 0);
Assert.AreEqual(0, opCodeCount ^ (opCodeCount - 1));
var opCodes = new EncryptOpCode[opCodeCount];
for (int i = 0; i < opCodes.Length; i++)
{
opCodes[i] = CreateEncryptOpCode((ushort)i, opCodeCount);
}
return new VirtualMachine(_byteSecretKey, opCodes);
}
}
}