Skip to content

Fix XP3 creation with RiddleCxCrypt#186

Merged
crskycode merged 1 commit into
crskycode:masterfrom
CBerJun:rj-crypt-encrypt-fix
Apr 18, 2026
Merged

Fix XP3 creation with RiddleCxCrypt#186
crskycode merged 1 commit into
crskycode:masterfrom
CBerJun:rj-crypt-encrypt-fix

Conversation

@CBerJun
Copy link
Copy Markdown

@CBerJun CBerJun commented Apr 13, 2026

Issue

The current XP3 RiddleCxCrypt encryption is broken.

To reproduce, just create any XP3 pack that uses RiddleCxCrypt ("Riddle Joker" or "Café Stella to Shinigami no Chou"). Then you decrypt it and see that the file extracted is not the same as the original file.

For example, I created a pack with one file test.txt containing the following bytes:

30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46

Creating a XP3 with "Café Stella to Shinigami no Chou" crypt and then extracting it, the extracted test.txt has the following bytes:

83 a6 b6 8a 33 1b 35 9a 38 39 41 42 43 44 45 46

Cause

Look at GameRes.Formats.KiriKiri.RiddleCxCrypt.Encrypt:

public override void Encrypt (Xp3Entry entry, long offset, byte[] buffer, int pos, int count)
{
base.Encrypt (entry, offset, buffer, pos, count);
ProcessFirstBytes (entry, offset, buffer, pos, count);
}

base.Encrypt would call GameRes.Formats.KiriKiri.CxEncryption.Encrypt:

public override void Encrypt (Xp3Entry entry, long offset, byte[] values, int pos, int count)
{
Decrypt (entry, offset, values, pos, count);
}

which would call Decrypt again as the algorithm is symmetric, but Decrypt is virtual and this would call GameRes.Formats.KiriKiri.RiddleCxCrypt.Decrypt:

public override void Decrypt (Xp3Entry entry, long offset, byte[] buffer, int pos, int count)
{
ProcessFirstBytes (entry, offset, buffer, pos, count);
base.Decrypt (entry, offset, buffer, pos, count);
}

As you can tell from the process, ProcessFirstBytes gets invoked twice (once before the Cx crypt and once after) when it should have only been invoked once after the Cx crypt.

Fix

Let CxEncryption.Encrypt call CxEncryption's own implementation of Decrypt only. This fix should not break other crypts derived from CxEncryption as they don't call base.Encrypt or rely on the fact that base.Encrypt calls their Decrypt.

@crskycode crskycode merged commit 01fd4e9 into crskycode:master Apr 18, 2026
@crskycode
Copy link
Copy Markdown
Owner

Thank you

@CBerJun CBerJun deleted the rj-crypt-encrypt-fix branch April 18, 2026 20:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants