Closed kabili207 closed 9 years ago
I didn't think all Game IDs were valid.
Edit by kabili: Publishing someone's personal contact info probably isn't a good idea.
Sorry. Did you at least get it down somewhere? I would have emailed it to you if I knew your email address. :/
Valid games IDs range from 1 to 32767. In 39ster's attempt at deciphering the code, which I've linked above (post #4), he identified the following formula for calculating the cipher byte: ID bit 0 XOR ID bit 8 = Cipher start byte bit 0 ID bit 1 XOR ID bit 9 = Cipher start byte bit 1 ID bit 2 XOR ID bit 10 = Cipher start byte bit 2
Unfortunately, this only works for a very limited subset of game IDs. For example, all odd Game IDs will fail to generate a matching cipher.
On the second page of 39ster's post he decodes someone's game ID that is odd, so how is the cipher formula wrong for all odd game ID's?
Decoding the secrets will work for any valid code. The first three bits, the cipher key, is all that's needed. You don't need the XOR formula, or even the game ID, to decode the secret. The game ID plays no part in the actual decoding process, it's just part of the message.
The problem is trying to encode the secrets. The formula above does not work when trying to create the cipher key. The cipher key is only 3 bits, whereas the game ID is 15 bits. For a single game ID there are a huge number of XOR formulas that will create a working cipher key. But not all of those formulas will work for other games IDs. 39ster was lucky enough to find a formula that worked for his original test cases.
Thanks for the explanation, I'll see what I can do to work out a formula. One thing that I don't understand is what decimal value the {space} stands for. There are 65 characters on the input screen including the space. I've never seen a code with a space; so is the space just not considered a character? If so, it must be only there to fill in for the lack of lowercase 'l', which may be confused with the number 1.
The space is indeed not considered a character. It's only used for alignment purposes.
There are some notes in doc folder of the source code that I've gathered from the gamefaqs posts and my own findings, if you think it would be helpful.
I've noticed a pattern with the memory secrets (first three bits are the RAW values, everything else is decoded). The second bit in the cipher always seems to be 1 for Ages, and 0 for Seasons. There's also a noticeable pattern in the checksum at the end (assuming you decode it). I get the impression that the cipher byte also plays a role in determining what kind of secret is being used.
If the cipher byte plays a role in determining secret type, that would imply each secret type can only start with a few types of characters and seasons and ages have different characters that can start the code. I'll keep working on the checksum, I've been playing my linked ages game trying to get a new set of all 8 secrets, I'll post those to my git repo.
It's possible that a value indicating the secret type is used in an AND, OR, or XOR operation against the Game ID, rather than being used directly. Or perhaps the Game IDs I used for my memory secrets just happened to generate ciphers with the same pattern by coincidence.
We also still have to identify what the unknown value at the beginning of the secrets are used for.
On another note, bit two in the first byte may not be the RingOrGame bit as 39ster originally thought. Someone sent me some test data that causes this bit to be the inverse of the expected value (0 instead of 1 for game secrets).
Hero: Link ID: 20839 Child: Garen Behavior: BouncyE Friend: Dimitri
I am thinking the manual way of discovering the checksum and cipher byte generation algorithms is becoming tedious. I have restarted school again and time is limited, I'll see if I can write a script to test multiple variations of algorithms automatically with a given data set.
So my next goal before the script would be to collect data (all secrets) from the Internet to get a large enough and varied enough sample set. I don't want to use Paulygon's program since it might not be 100% accurate.
I've been in a similar situation since I started working on this. The vast majority of what I've worked on has been done over my vacation time from work.
I'll see about gathering up my secrets and sending them your way.
I just noticed the following text on Paulygon's website: "the password engine for both games is nearly identical, which simplified things quite a bit."
I'm very curious what's different about the two algorithms.
What would be cool is if the former dev team would be willing/allowed to discuss the password system, if only it was easy to contact developers from behind the corporate barrier.
Created a google form in order to collect secrets from various forums:
https://docs.google.com/forms/d/1HsF1bFkzCEEPn6QDyQ82FG1O2Qkip2QvILrCkbi9G1k/viewform
Let me know what you think and I'll start posting it around to get responses.
That looks good to me, though you'll want to add the Hero's Secret as well. Do we want to add the other half of the memory secrets? Paulygon's program never generated them, but they would still be useful to know how to encode/decode them.
Also, can you provide a link to the responses spreadsheet?
https://docs.google.com/spreadsheets/d/1nql5s9nSazISf4UUls8hL3r9S1pmNFGuIVJ7jAgnVQY Can you verify you can copy/paste the spreadsheet? Also, the hero secrets are in the form now. And yes, I would like to collect all the secrets in order to have varied data in order to help crack the code completely.
I can copy text from it, but I can't edit it. That's not really an issue as far as I'm concerned. I only care about reading the data. We'll want to change the Hero's Secrets to read "from" instead of "to" since they can be entered in either game.
Alright, form should be good now.
Cipher key generation for game and ring secrets works as follows:
id = (MSB) XXXXXXX YYYYYYYY (LSB)
ZZZZZghi = XXXXXXXX + YYYYYYYY
key = ihg
Basically you add the two bytes that conform the id, then pick the three LSB of that sum result byte and reverse their order, that's the key.
For memory secrets the key generation is a bit more convoluted.
I'm working on rewriting the logic that encodes and decodes the secrets. I'll update the key generation and validation once I'm finished with my cleanup.
Cipher key generation for memory secrets:
id = (MSB) XXXXXXXX YYYYYYYY (LSB)
memoryID = (MSB) WWWt (LSB)
gm = 0x01 //For AGES NEW
gm = 0x02 //For AGES LINKED
gm = 0x03 //For SEASONS NEW
gm = 0x00 //For SEASONS LINKED
ZZZZZghi = XXXXXXX + YYYYYYYY + 00000tgm
key = ihg
This generation is almost the same, you only have to add a third byte to the sum. This byte depends on the memoryID, the game and the mode.
Your cipher logic seems to work as far as I can tell. I'd consider this issue resolved.
The XOR logic for cipher generation as described by 39ster only works for about 25% of game IDs. I suspect there is a simpler formula used that I am currently overlooking.