Secret Agent encryption
Most Secret Agent data files are encrypted, but not compressed: an encrypted file has exactly the same size as its corresponding unencrypted file.
Encrypting and decrypting files for Secret Agent depend on a key. The key consists of the string "Copyright 1991 Peder Jungck" followed by a null-character. So the length of the key is 28 characters.
The first time the key is used (the first byte to decode), it is the ASCII code of the first character in the string. So, it will be 67 (because the 67th entry in the ASCII table is 'C'). The second time (for the second byte to decode) it is 111 ('o'), and so on. When all 28 characters are used, including the null-character, the key loops back to the beginning with 67 ('C').
The game appears to perform the decryption after reading in a particular amount of data, which means the key appears to reset (start again from 67/'C') at the boundaries of these data chunks. Thus when encrypting or decrypting a whole file in one go, the key must be reset after a particular number of bytes:
- Level files (SAM?03.GFX) - reset every 42 bytes. If the value 0 is used to decrypt the 42nd byte in a chunk (instead of the expected character '1') the last two bytes of the chunk will form a newline (0x0D0A), making the resulting file easier to read in a text editor. While this won't produce the exact original file, it is harmless as the game only uses the first 40 bytes of each chunk in a level file.
- 8×8 sprite files (SAM?01.GFX) - reset every 8064 bytes
- 16×16 sprite files (SAM?02.GFX) - reset every 2048 bytes
For all bytes in a file, do:
- Read a byte.
- Swap the order of the bits in the byte. For example, 00000001 becomes 10000000, and 10110000 becomes 00001101.
- XOR this turned-around-byte with the next key-value.
- Return the result
Encryption is the reverse of decryption. So, after reading a byte, XOR it with the next key-value and then turn the bits around.
This encryption was reverse engineered by Frenkel. If you find this information helpful in a project you're working on, please give credit where credit is due. (A link back to this wiki would be nice too!)