From ad53c679c78ed95810f070ac2ed6438a25ee3066 Mon Sep 17 00:00:00 2001 From: morkt Date: Sun, 4 Nov 2018 15:47:31 +0400 Subject: [PATCH] (KiriKiri): another encryption scheme. --- ArcFormats/KiriKiri/CryptAlgorithms.cs | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/ArcFormats/KiriKiri/CryptAlgorithms.cs b/ArcFormats/KiriKiri/CryptAlgorithms.cs index 55990c4d..0b47d2a5 100644 --- a/ArcFormats/KiriKiri/CryptAlgorithms.cs +++ b/ArcFormats/KiriKiri/CryptAlgorithms.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using GameRes.Compression; using GameRes.Utility; @@ -1293,4 +1294,44 @@ namespace GameRes.Formats.KiriKiri Decrypt (entry, offset, data, pos, count); } } + + [Serializable] + public class PinPointCrypt : ICrypt + { + public override void Decrypt (Xp3Entry entry, long offset, byte[] data, int pos, int count) + { + for (int i = 0; i < count; ++i) + { + byte val = data[pos+i]; + int bit_count = CountSetBits (val); + if (bit_count > 0) + { + val = Binary.RotByteL (val, bit_count); + data[pos+i] = val; + } + } + } + + public override void Encrypt (Xp3Entry entry, long offset, byte[] data, int pos, int count) + { + for (int i = 0; i < count; ++i) + { + byte val = data[pos+i]; + int bit_count = CountSetBits (val); + if (bit_count > 0) + { + val = Binary.RotByteR (val, bit_count); + data[pos+i] = val; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static int CountSetBits (byte x) + { + int bit_count = (x & 0x55) + ((x >> 1) & 0x55); + bit_count = (bit_count & 0x33) + ((bit_count >> 2) & 0x33); + return ((bit_count & 0xF) + ((bit_count >> 4) & 0xF)) & 0xF; + } + } }