I have developed a little program that outputs a PK (arnezami's) from the "central" seed (s0+1) and a DK (Atari Vampire's) previously stored at source code.
It is easy to modify it to output a DK from any DK. To do so, just modify seed (last byte is 0xd9 (to output left DK) or 0xdb (to output right DK)) and set inputkey to the parent DK.
To run:
javac devkey.java
java devkey
Code:
/*
* devkey - By xyz987. Released under GPL v2
*
* asHex() method is an example method from Sun Microsystems, Inc. website
* and Sun licensed it under BSD license
* http://developers.sun.com/license/berkeley_license.html
*
* Some routines are based on BackupHDDVD by muslix64
*/
import javax.crypto.Cipher;
import java.security.NoSuchAlgorithmException;
import java.lang.Exception;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.SecretKey;
import java.io.*;
public class devkey {
static Cipher AES = null;
static{
try{
AES =Cipher.getInstance("AES/ECB/NOPADDING");
}catch(Exception e){
e.printStackTrace();
}
}
public static byte[] decrypt(byte[] inputKey, byte[] seed){
try{
SecretKey AESKey = new SecretKeySpec(inputKey,0,16,"AES");
AES.init(Cipher.DECRYPT_MODE,AESKey);
return AES.doFinal(seed);
}catch(Exception e){
e.printStackTrace();
}
return null;
}
public static String asHex (byte buf[]) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10)
strbuf.append("0");
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
public static void main(String [] args) {
int i;
// testing values of seed, inputkey, and outputkey (in that order):
// 7B103C5D CB08C4E5 1A27B017 99053BDA
// AA856A1B A814AB99 FFDEBA6A EFBE1C04
// 09F91102 9D74E35B D84156C5 635688C0
byte[] seed = { (byte)0x7b, (byte)0x10, (byte)0x3c, (byte)0x5d,
(byte)0xcb, (byte)0x08, (byte)0xc4, (byte)0xe5,
(byte)0x1a, (byte)0x27, (byte)0xb0, (byte)0x17,
(byte)0x99, (byte)0x05, (byte)0x3b, (byte)0xda };
byte[] inputkey = { (byte)0xaa, (byte)0x85, (byte)0x6a, (byte)0x1b,
(byte)0xa8, (byte)0x14, (byte)0xab, (byte)0x99,
(byte)0xff, (byte)0xde, (byte)0xba, (byte)0x6a,
(byte)0xef, (byte)0xbe, (byte)0x1c, (byte)0x04 };
byte[] outputkey = { (byte)0x62, (byte)0x65, (byte)0x65, (byte)0x65,
(byte)0x65, (byte)0x65, (byte)0x65, (byte)0x65,
(byte)0x65, (byte)0x65, (byte)0x65, (byte)0x65,
(byte)0x65, (byte)0x65, (byte)0x65, (byte)0x65 };
outputkey= decrypt(inputkey, seed);
for (i=0; i<16; i++){
outputkey[i]= (byte) (outputkey[i] ^ seed[i]);
}
System.out.println("Output key is: " + asHex(outputkey));
}
}