You can talk about almost anything that you want to on this board.

Moderator: Moderators

Posts: 7892
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Hello guys,
I've spend the last few days reverse-engineering the password system in Dragon Quest (J) but I need some help in order to fully understand the system.

The two routines involved are, obviously, the routine encoding a password when you talk to the king and display it on screen. And the routine decoding a password from the password entry screen.

The password is made of 20 hiragana character, arranged in a 5/7/5/3 haiku fashion (this is purely cosmetic, it doesn't play a role for the computer). The game technically supports entering shorter passwords but they'll always be rejected. There is at least 8 known passwords which are known to be made of meaningful japanese words.

Each hiragana character represent 6-bit worth of data (range \$00-\$3f). The password length is then 20*6=120 bits of data.

The password encoding does the following :
• Store relevant data such as HP, EXP, equip list, etc... in a RAM array of 15 bytes (120 bits of data)
• 3 bits are also taken from the random number generator and store in the password, so there is actually groups of 8 randomly-selected passwords for each game state (why ?)
• Compute a 8-bit checksum and insert it in the first 8-bits
• Re-arrange the password from 15x8-bit words into 20x6-bit words
• Scramble the symbol so that each symbol is added with the previous symbol, and added with the constant #4 (overflow within 6-bit range)
• Convert 6-bit symbols to actual hiragana characters and prints them
The password decoding is the opposite :
• Password is rejected if length <20
• Symbols are de-scrambled by subracting from the previos symbol and subtracting a constant #4 (overflow within 6-bit range)
• The 20x6-bit words are re-arranged as 15x8-bit words
• The checksum is computed in the 14 last words, and should match the first word, if there's no match the password is rejected
• The relevant data from the password is stored into game state, with some sanity checks, which might also get the password rejected if something is inconsistant
Now what I need help for is :
1) How is the ckecksum computed. I have the code, but I wonder if that's a CRC checksum or something else, or just something random the programmers came up with
2) How in the world is it possible to have (at least) 8 meaningful pre-defined passwords with such a system ? I'd though with the 8-bit checksum defined in a clever way, at most one meaningful password could naturally come out of this. It cannot be a pure coincidence, but I checked and I didn't see any specific code to detect meaningful passwords like I'd have expected to !! I'm puzzled !

Now the disassembled code, for password decoding. It is stored in CHR-ROM bank #3 and loaded in RAM at runtime, which is why the automatically generated disassembler's labels are wrong adresses.

Code: Select all

``````lbl_e376:	ldx #\$0
stx \$42
and #\$c0
beq +
inc \$42			; \$42 counts invalid characters in password
+		inx
cpx #\$14
bne -
lda \$42
beq +
jmp invalid_password	; I suppose the branch distance was too large ?

+		dex
-		lda \$1a,x
sec
sbc \$19,x
sec
sbc #\$4
and #\$3f
sta \$61,x	; De-scramble password symbols to \$61-\$71 zp buffer
dex
bne -
lda \$1a		; I suppose the programmers weren't very skilled with 6502...
sec
sbc #\$4
and #\$3f
sta \$61

lda #\$0
sta \$3c
tay
---		lda #\$8
sta \$40
--		ldx #\$14
-		ror \$60,x	; rotate a password bit into carry
dex
bne -

php
lda \$3c
lbl_e3ba:	inc \$3c
and #\$7
cmp #\$6		; continue rotating until 6 bits are done
bcc lbl_e3c6	; (the last 2 bits are ignored because always '0')
plp
jmp --
;--------------------
lbl_e3c6:	plp
ror \$3e		; the 6 meaningful bits are stored in the high 6 bits of \$3e
dec \$40
bne --

lda \$3e
sta \$51,y	; Store the password in 8-bits words to \$51-\$5f
lbl_e3d2:	iny		; Player's password : 20 symbols x 6 bits = 120 bits
cpy #\$f		; Computer's password : 15 bytes x 8 bits = 120 bits
bne ---

ldx #\$0
stx \$3c
stx \$3d		; Clear the check sum
inx

--		ldy #\$8
lda \$51
sta \$3e
-		lda \$3d
eor \$3e
asl \$3c
rol \$3d		; Mysterious checksum algorithm
asl \$3e
asl a
bcc +

lda \$3c
eor #\$21
sta \$3c
lda \$3d
eor #\$10
sta \$3d
+		dey
bne -

inx
cpx #\$f
bne --

lda \$3c			; Compare computer checksum
cmp \$51			; With the first 8-bit of password
beq Valid_password:	; Only valid if the same value !

lda #\$66		; This routine displays the dialogue box
sta \$99			; to tell the player the password is invalid
lda #\$7
sta \$9a
jsr lbl_544
jsr lbl_ab9b
jsr lbl_b8c3
lda \$47
bne lbl_e416
jsr lbl_ab9b
jsr lbl_b8c3
lda \$47
lsr a
bcc lbl_e420
jsr lbl_ab9b
jsr lbl_b8c3
lda \$47
bne lbl_e42b
lda #\$8c
sta \$99
lda #\$7
sta \$9a
jsr lbl_544
jmp lbl_369
;--------------------
lbl_544:
lda #\$a
lbl_e445:	sta \$97
sta \$9d
lda #\$f
sta \$98
lda #\$1
sta \$9
jsr lbl_bd09
inc \$99
bne lbl_e45a
inc \$9a
lbl_e45a:	dec \$98
lda \$98
cmp #\$14
bne lbl_e451
rts
;--------------------
valid_password:	lda \$56		; copies values from password buffer \$51-\$5f to real game values
lsr a
lsr a
jsr lbl_704
sta \$b5		; \$B5 first name letter
lbl_e46c:	lda \$5e
lsr a
and #\$3f
jsr lbl_704
sta \$b6		; \$B6 2nd name letter
lda \$53
and #\$3f
jsr lbl_704
sta \$b7		; \$B7 3rd name letter
lda \$58
and #\$3f
jsr lbl_704
sta \$b8		; \$B8 4th name letter

lda \$52
sta \$ba
lda \$5d
sta \$bb		; \$ba-\$bb = experience

lda \$55
sta \$bc		; \$bc-\$bd = money
lda \$5a
sta \$bd

lda \$59
sta \$be		; equipment

lda \$5f
sta \$c1
lda \$54
sta \$c2
lda \$5c
sta \$c3
lda \$57
sta \$c4		; \$c1-\$c4 = inventory

lda \$5b
and #\$f
sta \$c0		; \$c0 = amount of herbs
lda \$5b
lsr a
lsr a
lsr a
lsr a
sta \$bf		; \$bf = amount of keys

lda #\$0
sta \$df
lbl_e4be:	sta \$e4
sta \$cf		; Quest progress, a huge mess
bit \$53
bvc lbl_e4ca
lda #\$4
sta \$df
lbl_e4ca:	lda \$56
and #\$2
sta \$e4
lda \$58
and #\$c0
lbl_e4d4:	ora \$e4
sta \$e4
lda \$5e
bpl lbl_e4e0
lda #\$10
sta \$cf
lbl_e4e0:	lda \$5e
lsr a
bcc lbl_e4eb
lda \$cf
ora #\$20
sta \$cf
lbl_e4eb:	lda \$df
ora #\$8
sta \$df
lda #\$8
jsr lbl_de40
cmp #\$ff
beq lbl_e500
lda \$df
ora #\$2
sta \$df

lbl_e500:	lda \$c0
cmp #\$7
bcs lbl_e516
lda \$bf
cmp #\$7
lbl_e50a:	bcs lbl_e516	; Whether >7 keys or herbs refuse password
lda #\$f
jsr lbl_de40
cmp #\$ff
bne lbl_e516
rts
;--------------------
lbl_e516:	jmp lbl_50c
;--------------------
cmp #\$1
bne lbl_e552
lda \$c7
cmp #\$13
bne lbl_e526
jmp lbl_413
;--------------------
lbl_e526:	jsr lbl_6f1
inc \$c7
lbl_e52b:	inc \$90
lda \$c7
cmp #\$5
beq lbl_e537
cmp #\$11
bne lbl_e53c
lbl_e537:	inc \$90
jmp lbl_649
;--------------------
lbl_e53c:	cmp #\$c
bne lbl_e548
lda #\$8
sta \$90
lda #\$a
lbl_e546:	sta \$92
lbl_e548:	jsr lbl_6de
lda #\$0
sta \$4f
lbl_e54f:	jmp lbl_413
;--------------------
lbl_e552:	bcs lbl_e587
lda \$c7
bne lbl_e55b
jmp lbl_413
;--------------------
lbl_e55b:	jsr lbl_6f1
dec \$c7
lbl_e560:	dec \$90
lda \$c7
cmp #\$10
beq lbl_e56c
cmp #\$4
bne lbl_e571
lbl_e56c:	dec \$90
jmp lbl_67e
;--------------------
lbl_e571:	cmp #\$b
bne lbl_e57d
lda #\$14
sta \$90
lda #\$7
lbl_e57b:	sta \$92
lbl_e57d:	jsr lbl_6de
lda #\$0
sta \$4f
jmp lbl_413
;--------------------
lbl_e587:	sec
sbc #\$a
cmp #\$cd
bcc lbl_e591
sec
sbc #\$a1
lbl_e591:	ldx \$c7
sta \$1a,x		; Store password character in buffer
lda \$90
sta \$3c
ldx \$92
dex
dex
stx \$3e
jsr lbl_ac9f
lda #\$5f
sta \$8
jsr lbl_aba4
lda \$90
sta \$97
lda \$92
sta \$98
dec \$98
lda #\$1
sta \$9
lbl_e5b7:	jsr lbl_bd18
lda \$c7
cmp #\$13
bne lbl_e5c3
jmp lbl_471
;--------------------
lbl_e5c3:	jmp lbl_627
;--------------------
lda \$8e
sta \$3c
lda \$8f
sta \$3e
jsr lbl_ac9f
lda #\$5f
sta \$8
jsr lbl_aba4
lda #\$0
sta \$4f
rts
;--------------------
lda \$90
sta \$3c
lda \$92
sta \$3e
jsr lbl_ac9f
lda #\$3d
sta \$8
jsr lbl_aba4
rts
;--------------------
lda \$90
sta \$3c
lda \$92
sta \$3e
jsr lbl_ac9f
lda #\$5f
sta \$8
jsr lbl_aba4
rts
;--------------------		; Retrives name's letter in \$3c-\$3f range which are special characters
cmp #\$3c	; (why on earch didn't they just change CHR-ROM order to match this ?!)
lbl_e605:	bne lbl_e60a
lda #\$53	; \$3c becomes dakuten
rts
;--------------------
lbl_e60a:	cmp #\$3d
lbl_e60c:	bne lbl_e611
lda #\$54	; \$3d becomes handakuten
rts
;--------------------
lbl_e611:	cmp #\$3e
bne lbl_e618
lda #\$4e	; \$3e becomes dash
rts
;--------------------
lbl_e618:	cmp #\$3f
bne lbl_e61e	; \$3f becomes space
lda #\$5f
lbl_e61e:	rts
;--------------------``````
And for password encoding (a bit simpler hopefully, and stored in normal PRG-ROIM) :

Code: Select all

``````				; This routine generates a password
lbl_ef69:	lda \$4
bne lbl_ef69	; Wait for Vsync
lda \$b7
jsr lbl_f0c6
sta \$302
lda \$b5
jsr lbl_f0c6
asl a		; Store name (\$b5-\$b8) in a strange scrambled way
asl a
sta \$305
lda \$b8
jsr lbl_f0c6
sta \$307
lda \$b6
jsr lbl_f0c6
asl a
sta \$30d

lda \$bb
sta \$30c
lda \$ba
sta \$301	; Store experience

lda \$bc
sta \$304
lda \$bd
sta \$309	; Gold

lda \$c2
sta \$303
lda \$c4
sta \$306
lda \$c3
sta \$30b
lda \$c1
sta \$30e	; Items

lda \$be
sta \$308	; Equipment

lda \$bf
asl a
asl a
asl a
asl a
ora \$c0
sta \$30a	; Amount of herbs and keys

lda \$df		; Quest progress, a huge mess
and #\$4
beq lbl_efd6
lda #\$40
ora \$302
sta \$302
lbl_efd6:	lda \$cf
and #\$10
beq lbl_efe4
lda #\$80
ora \$30d
sta \$30d
lbl_efe4:	lda \$cf
and #\$20
beq lbl_eff2
lda #\$1
ora \$30d
sta \$30d
lbl_eff2:	lda \$e4
and #\$2
ora \$305
sta \$305
lda \$e4
and #\$40
ora \$307
sta \$307

jsr lbl_b0bf	; Trigger RNG
lda \$95		; Store 2 bits
and #\$80
ora \$302
sta \$302
lda \$95
and #\$1
ora \$305
sta \$305
jsr lbl_b0bf	; Trigger RNG agian dnd store a 3rd bit
lda \$95		; I guess this is so that the king gives a semi-random
and #\$80	; password form 8 possible at a given game state
ora \$307

lda #\$0
sta \$3c
sta \$3d		; Clear checksum

ldx #\$1
--		ldy #\$8
lda \$300,x
sta \$3e

-		lda \$3d
eor \$3e
asl \$3c
rol \$3d
asl \$3e
asl a
bcc +

lda \$3c
eor #\$21
sta \$3c
lda \$3d
eor #\$10
sta \$3d
+		dey
bne -

inx
cpx #\$f
bne --
lda \$3c		; check stored in the first 8-bits of password
sta \$300

lda #\$5f
ldx #\$0
lbl_f063:	sta \$400,x	; clear the password (why ?)
inx
cpx #\$1c
bne lbl_f063
lda #\$fe
sta \$40f
lda #\$fc
sta \$41b	; ??

lda #\$0
sta \$3c
sta \$3e
lbl_f07b:	lda \$300	; Take a password letter
and #\$3f
clc
clc
and #\$3f	; Add 4 and keep result within 6 bits
sta \$3e
jsr lbl_f0e2	; Convert password symbol \$00-\$3f to actual letter
ldx \$3c
sta \$402,x	; Store next letter bits in the line buffer

inc \$3c
lda \$3c
cmp #\$5		; create spaces between words where necessary
beq lbl_f0c2
cmp #\$15
beq lbl_f0c2
cmp #\$d
beq lbl_f0be
cmp #\$19
bne lbl_f07b
lda #\$0
sta \$99
lda #\$4
sta \$9a
jsr lbl_c45f	; Actually display the password in the text box.
lda #\$ff
ldx #\$0
lbl_f0b5:	sta \$400,x
inx
cpx #\$20
bne lbl_f0b5
rts
;--------------------
lbl_f0be:	inc \$3c
inc \$3c
lbl_f0c2:	inc \$3c
bne lbl_f07b	; always taken
;--------------------
lbl_f0c6:	cmp #\$53	; Decode special caracters in name
bne lbl_f0cd	; dakuten, handakuten, dash and space
lda #\$3c	; to be in \$00-\$3f range
rts
;--------------------
lbl_f0cd:	cmp #\$54
bne lbl_f0d4
lda #\$3d
rts
;--------------------
lbl_f0d4:	cmp #\$4e
bne lbl_f0db
lda #\$3e
rts
;--------------------
lbl_f0db:	cmp #\$5f
bne lbl_f0e1
lda #\$3f
lbl_f0e1:	rts
;--------------------
lbl_f0e2:	ldy #\$6
lbl_f0e4:	ldx #\$f
lbl_f0e6:	ror \$2ff,x	; rotate 6 bits out of the buffer
dex
bne lbl_f0e6
dey
bne lbl_f0e4
clc
cmp #\$36	; convert password symbol (in A) into a letter
bcc lbl_f0f9
clc
lbl_f0f9:	rts
``````
I also attack 8 FCEUX save states with the 8 meaningful passwords almost entered (just press 'A' to enter the final symbol and start the game) to help understanding this mystery.
Attachments
Last edited by Bregalad on Sun Apr 26, 2020 6:12 am, edited 1 time in total.

Pokun
Posts: 1492
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Dragon Quest (J) passwords reverse-engineering

Good job so far!
I don't want to spoil everything but since the password system has been cracked by Japanese hackers you may want to take a look at their work as well.

It looks like he has solved both DQ1 and DQ2 password systems and there are links for password generators for both games (requires Applocale or something to view text). There is also web version of the generators.

Here are some of my notes when analysing this earlier (everything might not be correct):

Code: Select all

``````Passwords for DQ1 and DQ2 both works with the MSX versions of both games.
The only exception is that MSX version of DQ2 has the Abunai Mizugi (Revealing Swimsuit)
item, and if it's in the inventory, DQ2 will refuse the password on Famicom.

Each password is 20 characters long and each character uses 6 bit meaning the
saved data is 6 * 20 = 120 bit in total size.

Data:

name              - 4 characters (24 bit)
experience points - 0 ~ 65535 (16-bit)
gold              - 0 ~ 65535 (16-bit)
item              - 8 item slots, 14 item types (4 bit * 8)
herb              - 0 ~ 6 (4 bit)
key               - 0 ~ 6 (4 bit)
weapon            - 7 weapon types (3 bit)
armor             - 7 armor types (3 bit)
shield            - 3 shield types (2 bit)
flags             - 5 flags (5 bit)
check code        - (11 bit)

item types:
nothing
torch
holy water
chimera wing
dragon scale
fairy flute
warrior's ring
emblem of Roto
princess' love
cursed belt
silver harp
death necklace
sun stone
staff of rainclouds
rainbow drop

weapon types:
nothing
bamboo pole
club
copper sword
iron axe
steel sword
flame sword
sword of Roto

armor types:
nothing
linen cloth
leather cloth
chainmail
iron armor
steel armor
magic armor
armor of Roto

shield types:
nothing
leather shield
iron shield
mikagami shield

Weapon, armor and shield data are combined into one byte (8-bit).
Herbs and keys uses 4 byte each meaning they can be between 0 and 15. But
the game only allows a maximum of 6 herbs and 6 keys so values above 6 are
invalid.

flags:
dragon scale equiped
warrior's ring equiped
swamp cave dragon defeated
golem defeated
death necklace obtained

Things like HP and strength are not stored in the password. They are
calculated by level (experience points) and by growth rate which is decided by
the hero's name.

byte content
1    item 2 (4 bit), item 1 ( 4 bit)
2    dragon scale flag (1 bit), name 2 (6 bit), warrior's ring flag (1 bit)
3    experience points high byte (8 bit)
4    item 6 (4 bit), item 5 (4 bit)
5    key (4 bit), herb (4 bit)
6    gold high byte (8 bit)
7    weapon (3 bit), armor (3 bit), shield (2 bit)
8    check code (1 bit), dragon defeat flag (1 bit), name 4 (6 bit)
9    item 8 (4 bit), item 7 (4 bit)
10   name 1 (6 bit), golem defeat flag (1 bit), check code (1 bit)
11   gold low byte (8 bit)
12   item 4 (4 bit), item 3 (4 bit)
13   check code (1 bit), death necklace obtained flag (1 bit), name 3 (6 bit)
14   experience points low byte (8 bit)
15   check code (8 bit)

(5 characters, 7 characters, 5 characters, 3 characters)

chara content
1     check code low (6 bit)
2     exp 4 (4 bit), check code high (2 bit)
3     name 3 low (2 bit), exp 3 (4 bit)
4     check code (1 bit), death necklace obtained flag (1 bit),
name 3 high (4 bit)
5     item 4 low (2 bit), item 3 (4 bit)

6     gold 4 (4 bit), item 4 high (2 bit)
7     golem defeat flag (1 bit), check code (1 bit), gold 3 (4 bit)
8     name 1 (6 bit)
9     item 8 low (2 bit), item 7 (4 bit)
10    name 4 low (4 bit), item 8 high (2 bit)
11    shield (2 bit), check code (1 bit), dragon flag (1 bit),
name 4 high (2 bit)
12    weapon (3 bit), armor (3 bit)

13    gold 2 (6 bit)
14    herb (4 bit), gold 1 (2 bit)
15    item 5 low (2 bit), key (4 bit)
16    item 6 (4 bit), item 5 high (2 bit)
17    exp 2 (6 bit)

18    name 2 low (3 bit), warrior's ring flag (1 bit), exp 1 (2 bit)
19    item 1 low (2 bit), dragon scale flag (1 bit), name 2 high (3 bit)
20    item 2 (4 bit). item 1 high (2 bit)

あ=0
い=1
う=2
え=3
お=4

か=5
き=6
く=7
け=8
こ=9

さ=10
し=11
す=12
せ=13
そ=14

た=15
ち=16
つ=17
て=18
と=19

な=20
に=21
ぬ=22
ね=23
の=24

は=25
ひ=26
ふ=27
へ=28
ほ=29

ま=30
み=31
む=32
め=33
も=34

や=35
ゆ=36
よ=37

ら=38
り=39
る=40
れ=41
ろ=42

わ=43

が=44
ぎ=45
ぐ=46
げ=47
ご=48

ざ=49
じ=50
ず=51
ぜ=52
ぞ=53

だ=54
ぢ=55
づ=56
で=57
ど=58

ば=59
び=60
ぶ=61
べ=62
ぼ=63

Magic numbers used by the check code:

0x88 0xc4 0x62 0x31 0x08 0x84 0x42 0x21
0x98 0xcc 0xe6 0x73 0xa9 0xc4 0x62 0x31
0x5a 0xad 0xc6 0x63 0xa1 0xc0 0x60 0x30
0x38 0x9c 0x4e 0xa7 0xc3 0xf1 0x68 0xb4
0xd0 0x68 0xb4 0x5a 0x2d 0x06 0x83 0x51
0x20 0x10 0x08 0x84 0x42 0xa1 0x40 0xa0
0xf9 0xec 0xf6 0x7b 0xad 0xc6 0xe3 0x61
0x81 0xd0 0x68 0xb4 0xda 0x6d 0xa6 0xd3
0xb2 0xd9 0xfc 0xfe 0xff 0xef 0x67 0x23
0x34 0x1a 0x0d 0x96 0x4b 0x35 0x8a 0x45
0xaa 0xd5 0x7a 0x3d 0x8e 0x47 0xb3 0x49
0xa1 0x40 0xa0 0x50 0xa8 0xd4 0xea 0x75
0xa0 0xd0 0x68 0xb4 0x5a 0xad 0xc6 0x63
0x7e 0xbf 0xcf 0xf7 0x6b 0xa5 0xc2 0x61

``````
Then there's also 4 different growth tables that's based on the hero's name. It can be found on Gamefaq but for DW, not DQ, and they have been shifted around I think, and some numbers may have changed.

As for why there are 8 variants of each password (10 variants in DQ2 IIRCC), it's probably just to make the passwords magical and higher chance to be unique. Even if two players uses the exact same name and has the same amount of EXP, gold and items they could still have different passwords (unless speaking to the king enough times, he generates a new password each time).

Posts: 7892
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Re: Dragon Quest (J) passwords reverse-engineering

Pokun wrote:
Sun Apr 26, 2020 2:41 am
Good job so far!
I don't want to spoil everything but since the password system has been cracked by Japanese hackers you may want to take a look at their work as well.

It looks like he has solved both DQ1 and DQ2 password systems and there are links for password generators for both games (requires Applocale or something to view text).
OK that's good an all, but since everything is in japanese (and not just the password), it's just as obscure and obfuscated to me than dealing directly with the ROM disassembly...

I'm not surprised japanese people cracked the password system but as far as I know nobody in the international community did.

But, I still don't understand how multiple meaningful passwords can exist with such a system. It's rather simple to do one meaningful password. I mean, enter it and design the checksum algorithm so that it is happy with that meaningful password.
But then it would mean the 7 other meaningful password would be pure coincidence, something I can't believe.

Needlessness to say, in the approximately 2^112 valid passwords (a bit less actually), some have to be meaningful by pure chance... but good luck figuring them out before quantum tunnel effect computers are a thing. But in this case, a list of japanese cities, and the list of developer's names being meaninful passwords by pure chance, I just can't believe it.

Also, you're right that HP is not stored in the password, but that means if you're wounded, you can see the king and note the password, then use it and you're healed for free, and spare the inn cost. Am I correct in this ? Same if you're poisoned.

You're wrong, the ckeck sum is clearly 8-bit and not 11 as you claim in your notes.

Pokun
Posts: 1492
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Dragon Quest (J) passwords reverse-engineering

I thought google translate or something would take care of the Japanese. But I should at least direct you to the password analysis page in case you find anything there helpful. It's here. If you see something there in particular that you want translated (as in not the whole page) just ask.

Code: Select all

``````DQ1:
ほりい　ゆうじ　えにつく
すどら　ごくえ　すとだよ
Hero: おっﾟて, Lv 15

DQ2:
ゆうて いみや おうきむ
こうほ りいゆ うじとり
やまあ きらぺ ぺぺぺぺ
ぺぺぺ ぺぺぺ ぺぺぺぺ
ぺぺぺ ぺぺぺ ぺぺぺぺ ぺぺ
Hero: もょもと, Lv 18
``````
I believe they are just purely coincidental passwords accidentally discovered by someone and spread in the Japanese DQ community just because they have names of the developers and because you get fairly far into the game with them, just like the famous Justin Baily password for NES version of Metroid. Biggest reason I believe that is because the hero name in both cases are invalid combinations of kana characters and are unpronounceable. There are a few others that almost makes sense, but they usually have something weird like two copies of the unique death necklace or such which makes me think it's just another case where someone got lucky entering random words.
But if you do find out any hardcoded passwords like Narpassword in NES Metroid that would be great.

Sorry about my notes. They are gathered from looking at various sources of information, mostly by googling Japanese internet for the subject. I forgot what everything is, so it's not complete or anything. Yes the checksum is indeed 8-bit, as can be seen on the page I linked above. I've no idea where I got 11-bit from (might be from the DW SRAM save which saves more stuff).

Bregalad wrote: Also, you're right that HP is not stored in the password, but that means if you're wounded, you can see the king and note the password, then use it and you're healed for free, and spare the inn cost. Am I correct in this ? Same if you're poisoned.
Yep that's right. But the trouble of writing down the password and then entering it again isn't worth it just to save a few gold (unless maybe if you do a "new game minus" after the bad ending and is forced to fight slimes naked with no gold at level 1 and you really don't want to die). They probably thought it was more important to keep the password as short as possible than to prevent tricks like this.
The exception would be curse, since you can't get into Ladutorm castle and save while cursed. But that also means there is no need to save equip flags in the password for the two cursed items, the death necklace and the cursed belt.
Last edited by Pokun on Sun Jul 26, 2020 3:49 pm, edited 1 time in total.

Posts: 7892
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Re: Dragon Quest (J) passwords reverse-engineering

I thought google translate or something would take care of the Japanese.
I thought machines translations were doing a terrible job at asian languages such as jap.
Exactly.
I believe they are just purely coincidental passwords accidentally discovered by someone and spread in the Japanese DQ community just because they have names of the developers and because you get fairly far into the game with them
You mean those would be pure coincidences ?!? And how on earth were they discovered - you can't get them legimately, and by entering random data in password area you have less than 1/256 chance of the password being accepted. If there was one or two letters of garbage somewhere in the password this changes everything - those would be needed for the checksum to be correct. But an entiere password being meaningful by coincidence, that can only happen for one password in the game, if the checksum algorithm was designed for that password specifically to work.

You can check my FECUX savestates posted above to see the 8 known meaningful passwords (there could be more). I didn't find any code checking specifically for them as I'd have expected.
Biggest reason I believe that is because the hero name in both cases are invalid combinations of kana characters and are unpronounceable.
Indeed there is sanity check for the # of herbs and torches, so that even a correct password with more than 6 of those will be rejected. But for the name, characters that actually can't be picked when starting a new game, such as 0-9, are allowed in passwords !

But even admitting the name can be garbage, it doesn't make a sentence more of a valid password ! You need a correct checksum within the sentence for the password to be accepted.

Dwedit
Posts: 4333
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Dragon Quest (J) passwords reverse-engineering

"JUSTIN BAILEY" and "ENGAGE RIDLEY MOTHER FUCKER" are two passwords for Metroid that just happen to pass the checksum test, and are meaningful.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!

Pokun
Posts: 1492
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Dragon Quest (J) passwords reverse-engineering

Yes, so is "ICARUS FIGHTS MEDUSA ANGELS" in Kid Icarus (I think). There's even a Swedish one in Kid Icarus: "DUVANS MAMMOR KOMMER BORTOT" (the dove's mamas are coming towards). Although "bortot" is misspelled and should really be spelled "bortåt" normally, it's still a fully comprehensible and meaningful password. It was a famous password in Sweden but I really doubt it would be hardcoded by Nintendo. It's just that the checksum part of the password just happened to be correct when someone randomly entered meaningful words. A lot of players tries making up a password themselves. I did as well when I was a kid (but I never got lucky).
Only "NARPAS SWORD0 000000 000000" in Metroid is said to be hardcoded.

1/256 chance sounds fair. Japan has a high population and DQ was a popular game, and considering a Swede (Sweden has quite a low population) could find the dove one in Kid Icarus it sounds very plausible to me.
The entire password isn't entirely meaningful though since it's missing the "n" in "doragon kuesuto".

Bregalad wrote:for the name, characters that actually can't be picked when starting a new game, such as 0-9, are allowed in passwords !

But even admitting the name can be garbage, it doesn't make a sentence more of a valid password ! You need a correct checksum within the sentence for the password to be accepted.
I'm not talking about the password system allowing hero names with characters that normally can't be entered by the player. I'm saying that hero names like おっﾟて and もょもと sounds like they are randomly generated. Handakuten can only be on は, ひ, ふ, へ or ほ and absolutely not on っ. Similarly the ょ without an i-row character before it is totally illegal. The pronunciation is undefined in both cases (some weird combinations do exists when writing sounds that doesn't exist in Japanese, such as the Ainu language though). If it really was a hardcoded password, the password system would probably make an exception for it and allow it, despite not having a valid checksum. And also the hero would probably have a meaningful name and have some meaningful progress. Like level 30 for a debug cheatcode password for example.

Bregalad wrote:I thought machines translations were doing a terrible job at asian languages.
Yeah they are. But I think google translate is not as bad as it used to be. I left you the link anyway and you can do what you want with it.

Memblers
Posts: 3864
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: Dragon Quest (J) passwords reverse-engineering

The EOR constants in the checksum are familiar to me, it's the polynomial used in XMODEM CRC16. Googling "0x1021" will turn up some info on that. Being 8-bits it already has a 1/256 chance of being false positive, if the sanity checking is only on herbs and torches, that's barely 2 bits. I would guesstimate that maybe 1 in 4000 random passwords would work? I'm thinking it becomes higher than 1/256 because those two sanity-checked ranges.

Pretty awesome that there is a Yuji Horii password. Does the rest of the password have a meaningful translation? It does seem to be a coincidence. Cognitive biases would make it easier to ignore all the uninteresting combinations that would work.

Pokun
Posts: 1492
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Dragon Quest (J) passwords reverse-engineering

Code: Select all

``````ほりい　ゆうじ　えにつく
すどら　ごくえ　すとだよ
``````
Horii Yuuji Enikkusu Dorago Kuesuto da yo
Translation: This is Horii Yuuji Enix Drago Quest!

Code: Select all

``````ゆうて いみや おうきむ
こうほ りいゆ うじとり
やまあ きらぺ ぺぺぺぺ
ぺぺぺ ぺぺぺ ぺぺぺぺ
ぺぺぺ ぺぺぺ ぺぺぺぺ ぺぺ
``````
Yuutei Miyaou Kimu-kou Horii Yuuji Toriyama Akira pe pe pe pe pe pe pe pe pe pe pe pe pe pe pe pe pe pe pe pe pe pe pe pe pe pe pe

These are all names of some of the developers of the game. Enix was really a publishing company without any programmers, so they enlisted people that could program by holding competitions (that's how Kooichi "Chun" Nakamura and Yuuji "Yuutei" Horii got into it). These guys were amateur programmers and were working on the Jump magazine. The nicknames like Kimu-kou (Lord Kim) and Miyaou (King Miya) are their aliases they used in the magazine as they where working on the Famicom corner of Jump. Toriyama was of course a manga artist in Jump. Most of these guys also actually appears in DQ1 as NPCs, but in English their names were changed to Nester and other things. I'm explaining it in a bit more detail in my DQ1 - DW1 comparison (scroll down to "Some name differences") which I posted earlier.
This is relevant to the discussion, because understanding this you can tell that the passwords are not very consistent (Horii appears twice, once by his nickname Yuutei and once by his full name).

I have yet to check the passwords that Bregalad made save states of, but at least these two are most likely not hardcoded. They are Japanese Justin Bailies though, and interesting from a gaming historical perspective.

Posts: 7892
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Re: Dragon Quest (J) passwords reverse-engineering

Memblers wrote:
Sun Apr 26, 2020 5:08 pm
The EOR constants in the checksum are familiar to me, it's the polynomial used in XMODEM CRC16. Googling "0x1021" will turn up some info on that.
I knww this constant reminded me of something ! Thanks Memblers !
The problem is : Why use CRC16 but check only 8-bits ? They'd have to either use CRC-8 or use CRC-16 but check 16-bits. Also, why does they initialize the checksum to \$0000 ? Normally CRC16 should be inifialized to \$FFFF; as opposed to CRC-8 and CRC-32, if I remember well. And is the loop actually calculating a CRC ?
Memblers wrote:
Sun Apr 26, 2020 5:08 pm
Being 8-bits it already has a 1/256 chance of being false positive, if the sanity checking is only on herbs and torches, that's barely 2 bits. I would guesstimate that maybe 1 in 4000 random passwords would work? I'm thinking it becomes higher than 1/256 because those two sanity-checked ranges.
Definitely, but I suck too much at probability math to compute the likelyhood of a random password to be accepted. It's in all cases very low. There's 1/256 chance to get the checksum right, and after that there is 7/16 chances to have a valid # of herbs and 7/16 chances to have a valid # of torches (because 0-6 makes the password valid and 7-15 makes it invalid). That would make the final answer (1/256) * (7/16) * (7/16) ~= 1/1337 chance of having a valid password. My calculation could very well be wrong, though.

It's crazy to think those meaningul passwords are due to pure chance, but actually the calculation is so complex it would need further investigation. At least for DQ, looking at the source code makes it appear it's pure chance. It's an infinity/infinity problem : There's a very large amount of valid passwords but also an even larger amount of invalid passwords, and both of those sets will have meaningful phrases by pure chance. Due to the calculation above, a meaninful phrase has a 1/1337 chance of being a valid password, and since there's almost an infinity of 20-letter long meaningful phrases, some of them happens to be valid passwords. Now the problem is how they're discovered, without resorting to brute force, I fail to see how they're discovered. Random people having less than 1/1000 chance of getting something will mean discovery rate is low, but when a lot of dudes does this exercice in parallel.... this gets interesting. Maybe something to ask on some StackExchange channel.
Horii Yuuji Enikkusu Dorago Kuesuto da yo
Translation: This is Horii Yuuji Enix Drago Quest!
This is crazy that by pure chance this is a valid password, but considering it's "Drago Quest" and "Enitsux" instead of "Enix"; by tolerating small errors the likelyhood of anything with small errors being a valid password is much hier than the same without the small errors.

The most impressive is the "well-known haiku", this one had to have zero modifications tolerances to work ! There aren't that many well-known haikus I guess, so it's impressive - but the hero's name is garbage so I guess it's pure coincidence.

This password who list japanese cities has the meaningful hero's name of よまもよ but has 2 cursed belts, so it's probably a coincidence as well ? The last password of the list has the meaningful name まるかつ and a meaningful inventory, HOWEVER I'm unsure if the password itself is a real japanese sentence. If so, it would be be *the* candidate for intentional hardcoded password ?

Pokun
Posts: 1492
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Dragon Quest (J) passwords reverse-engineering

Any of those passwords containing insults like bakayarou are about equally unplausible that "ENGAGE RIDLEY MOTHER FUCKER" would be a hardcoded password in Metroid. It's simply bad taste and very rude words, not something you would normally see in any licensed game for a respectable console (Erika to Satoru no Yumebouken is a notable exception but the message was made by a very upset programmer without his superiors' knowledge).

That one of Enitsuku is actually not incorrect. In the absence of a small tsu (っ) in a system (especially some electronic devices with a small number of characters) it's common to use a normal tsu (つ) instead, and treat it like a small tsu (doubling the length of the next consonant sound) when reading it. In other words, both えにっくす and えにつくす are technically correct for writing Enikkusu in the right context, and since the password system is lacking the small tsu character it can be considered correct. It is also the historical way to write it, since there was no small tsu in the Japanese writing system for a long time, and it was actually pronounced [tsu] in classic Japanese instead of a consonant quantity increment notation.

Another example in that Gamefaq link:
まるかつは　やつはりせかい
いちだつた　のだよ
With small tsu it would be written as:
まるかつは　やっぱりせかい
いちだった　のだよ
Translation (roughly): Marukatsu was the best in the world after all.
The author of that FAQ probably couldn't read it because he treated all tsu like large ones. This document also has several mistakes in the translation of the game script, so the author was probably still not fully fluent in Japanese when he made this FAQ (but he got most of it right).

Dorago is weird though. I think if it was hardcoded you would probably skip the final yo (よ) or da (だ) instead to make room for the n (ん) while still correct. This wouldn't change the meaning at all, but it would change the tone of the whole phrase.

I don't know what kind of name よまもよ (Yomamoyo) is, but at least it's fully readable with no invalid character combinations.
The only password that seems to have a meaningful name though is the last password in the FAQ. It also appears to have meaningful progress (level 1 with all the best items) but not a meaningful password. Since it's probably impossible to be level 1 and get the best equipment and items, I believe people on that magazine must either have figured the password system out and created a custom password, or have hacked the RAM somehow to get all that stuff and then generated the password by speaking to the king.

The haiku is pretty amazing that it works, but after googling it I can see there's a problem with it:
ふるいけや かわずとびこむ
みずのおと ばしや
Translation (bear with me):
An old pond, frogs jumping in,
the sound of water, horse-wagon

ばしや, the horse-wagon (I'm not sure it's even supposed to be horse-wagon) feels totally random and it appears it was not part of the original haiku.

Posts: 7892
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Re: Dragon Quest (J) passwords reverse-engineering

Any of those passwords containing insults like bakayarou are about equally unplausible that "ENGAGE RIDLEY MOTHER FUCKER" would be a hardcoded password in Metroid. It's simply bad taste and very rude words, not something you would normally see in any licensed game for a respectable console
Not necessairly, if some immature programmer inserted it for his own pleasure but no supperior knowns, this could have easily slipped in the game without anyone knowing. (and who's that Ridley anyway ?)

And even worse, a game could give an offensive password just by pure coincidence
Pokun wrote:
Mon Apr 27, 2020 6:15 am
Dorago is weird though. I think if it was hardcoded you would probably skip the final yo (よ) or da (だ) instead to make room for the n (ん) while still correct. This wouldn't change the meaning at all, but it would change the tone of the whole phrase.
I don't know, there's also no particle between "horii" and "enix", normally shouldn't there be a "to" for "and" ?

It seems almost incredible a password with the autor's names and the game's name is a valid password by pure chance. But if we start to allow missing letters, changing the order of words, etc... there's quickly a lot of possibilities, and when we reach a thousand possibilities there's a good chance one of those is a valid password I guess. That's why small details matter.
Pokun wrote:
Mon Apr 27, 2020 6:15 am
It is also the historical way to write it, since there was no small tsu in the Japanese writing system for a long time, and it was actually pronounced [tsu] in classic Japanese instead of a consonant quantity increment notation.
Wow this is new info for me, thanks. I was always puzzled by those small tsus, I wonder why doesn't they give them up entierely, since in my native language doubled consonant letters makes no difference for pronunciation, and are just an orthographical annoyance.
Pokun wrote:
Mon Apr 27, 2020 6:15 am
The only password that seems to have a meaningful name though is the last password in the FAQ. It also appears to have meaningful progress (level 1 with all the best items) but not a meaningful password. Since it's probably impossible to be level 1 and get the best equipment and items, I believe people on that magazine must either have figured the password system out and created a custom password, or have hacked the RAM somehow to get all that stuff and then generated the password by speaking to the king.
Oh OK, I thought this was a meaningful password because it was after the other meaningful passwords. It's not like I can be of much help to know if the password is meaningful or not ^^
So the FAQ is like
* 7 meaningful passwords but with non-meaningful progress

That's where my misinterpretation came from. So the last password with a meaningful name is the list of japanese cities, but even then the item inventory is not meaningful. Sucks. So I guess all those passwords, however surprising it is, are pure coincidence.

Dwedit
Posts: 4333
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Dragon Quest (J) passwords reverse-engineering

Double consonants are a real thing. It's the difference between the leaning tower of Pisa, and the leaning tower of pizza.
For example, "Bokken" (wooden sword) sounds kinda like "bok-ken" rather than bo-ken.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!

Memblers
Posts: 3864
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: Dragon Quest (J) passwords reverse-engineering

Mon Apr 27, 2020 2:21 am
Memblers wrote:
Sun Apr 26, 2020 5:08 pm
The EOR constants in the checksum are familiar to me, it's the polynomial used in XMODEM CRC16. Googling "0x1021" will turn up some info on that.
I knww this constant reminded me of something ! Thanks Memblers !
The problem is : Why use CRC16 but check only 8-bits ? They'd have to either use CRC-8 or use CRC-16 but check 16-bits. Also, why does they initialize the checksum to \$0000 ? Normally CRC16 should be inifialized to \$FFFF; as opposed to CRC-8 and CRC-32, if I remember well. And is the loop actually calculating a CRC ?
I took another look, and I think it actually is the same algorithm, interestingly. I see it checking that upper bit, and branching over the EORs. Here's the C version I use for XMODEM (I have 2 different 6502 CRC routines, but I didn't write either of those and they're both optimized beyond my own comprehension)

Code: Select all

``````int CALC_CHECKSUM(const unsigned char *ptr, int count)
{
int  crc;
char i;

crc = 0;
while (--count >= 0)
{
crc = crc ^ (int) *ptr++ << 8;
i = 8;
do
{
if (crc & 0x8000)
crc = crc << 1 ^ 0x1021;
else
crc = crc << 1;
} while(--i);
}
return (crc);
}
``````
I'm sure using only 8 bits of it makes it less effective to some degree, I remember looking into it before and there was information about CRC-8 having an optimal polynomial. But it's not as critical as it would be for communication, for password use I suppose it's decent enough of a sanity check. As a kid I might have better off if passwords had error-correcting codes, I remember having bad luck transcribing them sometimes.
Definitely, but I suck too much at probability math to compute the likelyhood of a random password to be accepted. It's in all cases very low. There's 1/256 chance to get the checksum right, and after that there is 7/16 chances to have a valid # of herbs and 7/16 chances to have a valid # of torches (because 0-6 makes the password valid and 7-15 makes it invalid). That would make the final answer (1/256) * (7/16) * (7/16) ~= 1/1337 chance of having a valid password. My calculation could very well be wrong, though.
It's calculable, but I think the odds go down a rabbit hole, once the herbs and torches have to be in that range AND at the same time not break the checksum. 1337 would be an appropriate number for cultural reasons though, haha.

I've had a similar moment in a game, when a friend and I were playing Talking Super Jeopardy, and buzzed in on a question we didn't know. We took the time to put in a fairly long string of expletives, which turned out to be the correct answer. We were stunned.

And another time where I used a Game Genie on SMB3. I randomly entered an 8-letter code, which I already knew even then was like 1/256 chance of it not even activating. Played for a while with nothing, but then was amazed when getting a 1-up played an expanded 10-second long version of the 1-up jingle. I've heard it again in one of the later NSF rips more recently (in Mr Norbert's archive, surely), so I know I didn't hallucinate it, haha. I wasn't able to remember the code, it was just something I put in randomly on a whim.

I always thought it was funny to imagine some at Konami sneaking the FUCKM E1111 code into the game somehow, but I'm sure that one would turn out to be a coincidence as well. That one was famous enough that I knew about it as a kid, before I had the internet. Makes me wonder where that "viral" info came from anyways, I sure didn't get it from Nintendo Power magazine.

Pokun
Posts: 1492
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Dragon Quest (J) passwords reverse-engineering

The chance to enter a valid password by random is 1337. Sounds good for me.

You probably learned it from a friend who in turn learned it from another friend or a magazine. There are a lot things like that, that I thought was just known in the neighbourhood, but when internet came you learn that it had been a worldwide phenomenon all along. Whether it was famous passwords or the infamous "house rules" of Monopoly among other things.

Bregalad wrote:Not necessairly, if some immature programmer inserted it for his own pleasure but no supperior knowns, this could have easily slipped in the game without anyone knowing. (and who's that Ridley anyway ?)
Yeah it's always a possibility.
Ridley is one of the main villains in the Metroid series. I think he shows up in pretty much every Metroid game in some form or another, he is in the very first boss fight in Super Metroid (dragon-like space pirate leader with wings). He is named after Ridley Scott who directed Alien which Metroid is inspirerd by.

Bregalad wrote:I don't know, there's also no particle between "horii" and "enix", normally shouldn't there be a "to" for "and" ?
Yeah you are right. Sometimes the genitive particle no (の) can be omitted but here it just sounds wrong.

Bregalad wrote: I wonder why doesn't they give them up entierely, since in my native language doubled consonant letters makes no difference for pronunciation, and are just an orthographical annoyance.
As Dwedit said, double consonants is a real thing in both spoken and written languages, and in some languages like Japanese, it affects the meaning of the word just like long and short vowels affects the meaning of words in many languages. If you get it wrong Japanese people will either misunderstand the meaning or possibly not understand at all what you are trying to say, so omitting it in the written language would just make things harder (since you would have to memorize which words has double consonants or not).

Some long consonants are probably easy to imagine even if it isn't meaning-changing in your native language. For example S (as in stick) can easily be said continuously like sssssssssss... (like Golum when he hisses "my precioussss"). Consonants like K (as in take) on the other hand relies on the sudden release of air in the mouth so it can't be said continuously the same way. They way it works in Japanese (and probably most other languages) is that you "hold" it in your mouth for a brief moment before you release it. This small pause is what indicates a long consonant to the listener.

English would be a bad example because spelling and modern English pronunciation is just too far apart (double consonants are often written where the consonant is still pronounced as a single one).

Bregalad wrote: Oh OK, I thought this was a meaningful password because it was after the other meaningful passwords. It's not like I can be of much help to know if the password is meaningful or not ^^
So the FAQ is like