(KiriKiri): added variation of CX encryption scheme.

This commit is contained in:
morkt 2017-08-15 16:07:54 +04:00
parent 651aad92a2
commit d6e441fe64
2 changed files with 45 additions and 3 deletions

View File

@ -967,6 +967,22 @@ namespace GameRes.Formats.KiriKiri
Dictionary<string, string> KnownNames = null; Dictionary<string, string> 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] [Serializable]
public class KissCrypt : ICrypt public class KissCrypt : ICrypt
{ {

View File

@ -217,7 +217,7 @@ namespace GameRes.Formats.KiriKiri
CxProgram GenerateProgram (uint seed) CxProgram GenerateProgram (uint seed)
{ {
var program = new CxProgram (seed, ControlBlock); var program = NewProgram (seed);
for (int stage = 5; stage > 0; --stage) for (int stage = 5; stage > 0; --stage)
{ {
if (EmitCode (program, stage)) if (EmitCode (program, stage))
@ -228,6 +228,11 @@ namespace GameRes.Formats.KiriKiri
throw new CxProgramException ("Overly large CxEncryption bytecode"); throw new CxProgramException ("Overly large CxEncryption bytecode");
} }
internal virtual CxProgram NewProgram (uint seed)
{
return new CxProgram (seed, ControlBlock);
}
bool EmitCode (CxProgram program, int stage) bool EmitCode (CxProgram program, int stage)
{ {
return program.EmitNop (5) // 0x57 0x56 0x53 0x51 0x52 return program.EmitNop (5) // 0x57 0x56 0x53 0x51 0x52
@ -437,7 +442,7 @@ namespace GameRes.Formats.KiriKiri
private List<uint> m_code = new List<uint> (LengthLimit); private List<uint> m_code = new List<uint> (LengthLimit);
private uint[] m_ControlBlock; private uint[] m_ControlBlock;
private int m_length; private int m_length;
private uint m_seed; protected uint m_seed;
class Context class Context
{ {
@ -562,7 +567,7 @@ namespace GameRes.Formats.KiriKiri
return EmitUInt32 (GetRandom()); return EmitUInt32 (GetRandom());
} }
public uint GetRandom () public virtual uint GetRandom ()
{ {
uint seed = m_seed; uint seed = m_seed;
m_seed = 1103515245 * seed + 12345; 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 /* CxEncryption base branch order
OddBranchOrder OddBranchOrder
{ {