From d6e441fe6483d8dc76ffad62a7abec1420f83154 Mon Sep 17 00:00:00 2001 From: morkt Date: Tue, 15 Aug 2017 16:07:54 +0400 Subject: [PATCH] (KiriKiri): added variation of CX encryption scheme. --- ArcFormats/KiriKiri/CryptAlgorithms.cs | 16 +++++++++++++ ArcFormats/KiriKiri/KiriKiriCx.cs | 32 +++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/ArcFormats/KiriKiri/CryptAlgorithms.cs b/ArcFormats/KiriKiri/CryptAlgorithms.cs index b4269cf4..12d8d03d 100644 --- a/ArcFormats/KiriKiri/CryptAlgorithms.cs +++ b/ArcFormats/KiriKiri/CryptAlgorithms.cs @@ -967,6 +967,22 @@ namespace GameRes.Formats.KiriKiri Dictionary KnownNames = null; } + [Serializable] + public class NanaCxCrypt : SenrenCxCrypt + { + uint m_random_seed; + + public NanaCxCrypt (CxScheme scheme, uint seed) : base (scheme) + { + m_random_seed = seed; + } + + internal override CxProgram NewProgram (uint seed) + { + return new CxProgramNana (seed, m_random_seed, ControlBlock); + } + } + [Serializable] public class KissCrypt : ICrypt { diff --git a/ArcFormats/KiriKiri/KiriKiriCx.cs b/ArcFormats/KiriKiri/KiriKiriCx.cs index 2d02e899..55bcd9fa 100644 --- a/ArcFormats/KiriKiri/KiriKiriCx.cs +++ b/ArcFormats/KiriKiri/KiriKiriCx.cs @@ -217,7 +217,7 @@ namespace GameRes.Formats.KiriKiri CxProgram GenerateProgram (uint seed) { - var program = new CxProgram (seed, ControlBlock); + var program = NewProgram (seed); for (int stage = 5; stage > 0; --stage) { if (EmitCode (program, stage)) @@ -228,6 +228,11 @@ namespace GameRes.Formats.KiriKiri throw new CxProgramException ("Overly large CxEncryption bytecode"); } + internal virtual CxProgram NewProgram (uint seed) + { + return new CxProgram (seed, ControlBlock); + } + bool EmitCode (CxProgram program, int stage) { return program.EmitNop (5) // 0x57 0x56 0x53 0x51 0x52 @@ -437,7 +442,7 @@ namespace GameRes.Formats.KiriKiri private List m_code = new List (LengthLimit); private uint[] m_ControlBlock; private int m_length; - private uint m_seed; + protected uint m_seed; class Context { @@ -562,7 +567,7 @@ namespace GameRes.Formats.KiriKiri return EmitUInt32 (GetRandom()); } - public uint GetRandom () + public virtual uint GetRandom () { uint seed = m_seed; m_seed = 1103515245 * seed + 12345; @@ -570,6 +575,27 @@ namespace GameRes.Formats.KiriKiri } } + internal class CxProgramNana : CxProgram + { + protected uint m_random_seed; + + public CxProgramNana (uint seed, uint random_seed, uint[] control_block) : base (seed, control_block) + { + m_random_seed = random_seed; + } + + public override uint GetRandom () + { + uint s = m_seed ^ (m_seed << 17); + s ^= (s << 18) | (s >> 15); + m_seed = ~s; + uint r = m_random_seed ^ (m_random_seed << 13); + r ^= r >> 17; + m_random_seed = r ^ (r << 5); + return m_seed ^ m_random_seed; + } + } + /* CxEncryption base branch order OddBranchOrder {