diff --git a/ArcFormats/KiriKiri/CryptAlgorithms.cs b/ArcFormats/KiriKiri/CryptAlgorithms.cs index 8e1149ad..a94e8262 100644 --- a/ArcFormats/KiriKiri/CryptAlgorithms.cs +++ b/ArcFormats/KiriKiri/CryptAlgorithms.cs @@ -1406,4 +1406,91 @@ namespace GameRes.Formats.KiriKiri return key; } } + + [Serializable] + public class NinkiSeiyuuCrypt : ICrypt + { + ulong m_key1; + ulong m_key2; + ulong m_key3; + + byte[] m_tbl2; + byte[] m_tbl3; + + public NinkiSeiyuuCrypt(ulong key1, ulong key2, ulong key3) + { + m_key1 = key1; + m_key2 = key2; + m_key3 = key3; + + m_tbl2 = GetTable2(3080); + m_tbl3 = GetTable3(3080, m_key1, m_key2, m_key3); + } + + static byte[] GetTable1(uint seed) + { + var key = new byte[32]; + + uint v48 = seed & 0x7FFFFFFF; + + for (var i = 0; i < 31; i++) + { + key[i] = (byte)v48; + v48 = (v48 >> 8) | (uint)((byte)v48 << 23); + } + + return key; + } + + static byte[] GetTable2(uint seed) + { + var key = new byte[64]; + + uint v51 = seed & 0xFFF; + ulong v52 = (ulong)(v51 | (v51 << 13)) | ((ulong)(v51 >> 19) << 32); + uint v53 = v51 | ((uint)v52 << 13); + uint v54 = (uint)((ulong)(((uint)v52 << 7) & 0x1FFFFFFF) | (v52 >> 19)); + + for (int i = 0; i < 61; i++) + { + var v56 = (byte)v53; + key[i] = (byte)v53; + v53 = (uint)((((ulong)v54 << 32) | v53) >> 8); + v54 = (v54 >> 8) | (uint)(v56 << 21); + } + + return key; + } + + static byte[] GetTable3(uint seed, ulong key1, ulong key2, ulong key3) + { + var key = new byte[64]; + + uint v88 = seed & 0xFFF; + ulong v89 = (ulong)(v88 | (v88 << 13)) | ((ulong)(v88 >> 19) << 32); + uint v90 = (uint)((key1 + key2) ^ (ulong)(v88 | ((uint)v89 << 13))); + uint v91 = (uint)((ulong)(((key1 + ((key3 & 0xFFFFFFFF00000000) | (key2 & 0xFFFFFFFF))) >> 32) & 0x1FFFFFFF) ^ ((ulong)(((uint)v89 << 7) & 0x1FFFFFFF) | (v89 >> 19))); + + for (int i = 0; i < 61; i++) + { + var v93 = (byte)v90; + key[i] = (byte)v90; + v90 = (uint)((((ulong)v91 << 32) | v90) >> 8); + v91 = (v91 >> 8) | (uint)(v93 << 21); + } + + return key; + } + + public override void Decrypt(Xp3Entry entry, long offset, byte[] buffer, int pos, int count) + { + var tbl1 = GetTable1(entry.Hash); + + for (var i = 0; i < count; i++) + { + buffer[pos + i] ^= tbl1[(offset + i) % 0x1F]; + buffer[pos + i] += (byte)(m_tbl2[(offset + i) % 0x3D] ^ m_tbl3[(offset + i) % 0x3D]); + } + } + } } diff --git a/ArcFormats/Resources/Formats.dat b/ArcFormats/Resources/Formats.dat index b8cd78b3..64830f2f 100644 Binary files a/ArcFormats/Resources/Formats.dat and b/ArcFormats/Resources/Formats.dat differ