static void Main(string[] args) { var RNG = new Random(); int seed = RNG.Next(); int diff = 2; var hashcash = HashCashWorker.Create(seed, diff); var whatever = new byte[128]; RNG.NextBytes(whatever); var xor = new EmulateMe.HashCash.EncryptionAlgorithms.EncryptionAlgorithmXOR(); var buffer_to_gen = whatever; var controlFlowSwitches = GetRandomValuesDistinct(buffer_to_gen.Length); var switchTerminater = NextUInt32(); int lengthCounter = 0; if (controlFlowSwitches.Contains(switchTerminater)) { throw new Exception("Restart the program. Unlucky."); } Stopwatch sw = new Stopwatch(); sw.Start(); var rdr = new StateReader(controlFlowSwitches); var codeGen = new StringBuilder(); var listOfBlocks = new List <StringBuilder>(); codeGen.AppendLine("public static byte[] GenBuffer()"); codeGen.AppendLine("{"); codeGen.AppendLine("List<byte> buffer = new List<byte>();"); // <!-- Change this constructor accordingly ---!> // Encryption Default: XOR // Hash Default: SHA256 codeGen.AppendLine($"var HashCash = HashCashWorker.Create({seed},{diff});"); codeGen.AppendLine($"uint state = 0x{rdr.First:X4};"); codeGen.AppendLine(); codeGen.AppendLine($"while(state != 0x{switchTerminater:X4})"); codeGen.AppendLine("{"); codeGen.AppendLine("switch(state)"); codeGen.AppendLine("{"); using (var progress = new ProgressBar()) { // Base Case { var initBlock = new StringBuilder(); initBlock.AppendLine($"case 0x{rdr.First:X4}:"); // This is the solution to the proof-of-work challenge // It will begin with whatever bitstring chosen // In this case difficulty = 1 and bitstring is simply 0s var solution = hashcash.Solve(GetBytes(rdr.CurrentValue)); // Here, we are encrypting the next state with the hashed solution // Thus, we can only decrypt by solving the proof-of-work problem again // Or by bruteforcing var encryptedNextState = hashcash.EncryptWithSolution(GetBytes(rdr.NextValue)); // Build our buffer at runtime, byte by byte // You may also choose to encrypt this value in the same way // We are encrypting the state variables initBlock.AppendLine($"buffer.Add(0x{buffer_to_gen[lengthCounter++]:X2});"); // Let's repeat this same process (for finding the decryption/encryption key) in the source code initBlock.AppendLine($"HashCash.Solve({BytesToSourceString(GetBytes(rdr.CurrentValue))});"); initBlock.AppendLine($"state = BitConverter.ToUInt32(HashCash.DecryptWithSolution({BytesToSourceString(encryptedNextState)}), 0);"); initBlock.AppendLine("break;"); listOfBlocks.Add(initBlock); rdr.NextState(); progress.Report((double)lengthCounter / buffer_to_gen.Length); } // N-1 Case { while (!rdr.IsAtEnd) { var nState = new StringBuilder(); var solution = hashcash.Solve(GetBytes(rdr.CurrentValue)); var encryptedNextState = hashcash.EncryptWithSolution(GetBytes(rdr.NextValue)); nState.AppendLine($"case 0x{rdr.CurrentValue:X4}:"); nState.AppendLine($"buffer.Add(0x{buffer_to_gen[lengthCounter++]:X2});"); nState.AppendLine($"HashCash.Solve({BytesToSourceString(GetBytes(rdr.CurrentValue))});"); nState.AppendLine($"state = BitConverter.ToUInt32(HashCash.DecryptWithSolution({BytesToSourceString(encryptedNextState)}), 0);"); nState.AppendLine("break;"); listOfBlocks.Add(nState); rdr.NextState(); progress.Report((double)lengthCounter / buffer_to_gen.Length); } } // Nth Case { var finalCase = new StringBuilder(); if (rdr.CurrentValue != rdr.Last) { throw new Exception("Not last state."); } var solution = hashcash.Solve(GetBytes(rdr.CurrentValue)); var encryptedNextState = hashcash.EncryptWithSolution(GetBytes(switchTerminater)); finalCase.AppendLine($"case 0x{rdr.CurrentValue:X4}:"); finalCase.AppendLine($"buffer.Add(0x{buffer_to_gen[lengthCounter++]:X2});"); finalCase.AppendLine($"HashCash.Solve({BytesToSourceString(GetBytes(rdr.CurrentValue))});"); finalCase.AppendLine($"state = BitConverter.ToUInt32(HashCash.DecryptWithSolution({BytesToSourceString(encryptedNextState)}), 0);"); finalCase.AppendLine("break;"); listOfBlocks.Add(finalCase); progress.Report((double)lengthCounter / buffer_to_gen.Length); } } // Shuffle the ordering listOfBlocks = listOfBlocks.OrderBy(R => RNG.Next()).ToList(); foreach (var block in listOfBlocks) { codeGen.Append(block.ToString()); } codeGen.AppendLine("}"); codeGen.AppendLine("}"); codeGen.AppendLine("return buffer.ToArray();"); codeGen.AppendLine("}"); string resultantCode = codeGen.ToString(); File.WriteAllText("out.cs1", resultantCode); sw.Stop(); long sec = sw.ElapsedMilliseconds / 1000; Console.WriteLine($"Generating the buffer at runtime will take approximately {(Math.Max(sec, 1) == 1 ? (sw.ElapsedMilliseconds + " milliseconds.") : (sec + " seconds."))}"); Console.ReadLine(); }