/// <summary> /// Decrypt the data /// </summary> /// <param name="Data">The data to decrypt</param>l /// <param name="Offset">The index where the data starts</param> /// <param name="Length">The length to decrypt</param> public void Decrypt(byte[] Data, int Offset, int Length) { lock (DecState) { int OrgLen = Length; Length += Offset; for (int round = 0; round < Rounds; round++) { using (PayloadWriter pw = new PayloadWriter(new System.IO.MemoryStream(Data))) { ulong temp_Value = DecState.IV[EncMode == WopEncMode.Simple ? 0 : DecState.IV_Pos]; //is being used for CBC Mode (Block-Cipher-Chaining Mode) for (int i = Offset, k = 0; i < Length; k++) { pw.vStream.Position = i; int usedsize = 0; ulong value = 0; ulong OrgReadValue = 0; if (i + 8 < Length) { OrgReadValue = BitConverter.ToUInt64(Data, i); usedsize = 8; value = Decrypt_Core_Big(OrgReadValue ^ temp_Value, OrgLen, k); pw.WriteULong(value); } else { OrgReadValue = Data[i]; usedsize = 1; value = Decrypt_Core_Small((byte)OrgReadValue, OrgLen, k); pw.WriteByte((byte)value); } temp_Value += OrgReadValue; DecState.Seed += (int)value; i += usedsize; if (EncMode != WopEncMode.Simple) { DecState.Key_Pos += 1; DecState.Salt_Pos += 1; } } } } DecState.IV_Pos = (DecState.IV_Pos + 1) % DecState.IV.Length; switch (EncMode) { case WopEncMode.GenerateNewAlgorithm: { InstructionInfo tempEncCode = null; InstructionInfo tempDecCode = null; FastRandom fastRand = new FastRandom(DecState.Seed); for (int i = 0; i < DecState.Instructions.Length; i++) { GetNextRandomInstruction(fastRand, ref tempEncCode, ref tempDecCode); DecState.Instructions[i] = tempDecCode; } if (UseDynamicCompiler) { DecState.Compile(); } break; } case WopEncMode.ShuffleInstructions: { ShuffleInstructions(DecState.Instructions, DecState.Seed); if (UseDynamicCompiler) { DecState.Compile(); } break; } } } }