# PINs

Back to the [README](../README.md).

Every card has a 4-digit ATM PIN from the start, since the spec says PINs
are generated with the card's data. It's derived from the card number, like
the CVV, so it's stable but not guessable from the docs; read it with 4.23
PIN Retrieval and change it with 4.25. A restart or `/_sim/reset` restores
the default PINs, and a replacement card (4.6) gets its own.

ATM PINs travel as an `epinBlock`, as the spec describes: an ISO 9564
format-0 PIN block, triple-DES encrypted under a Zone PIN Key and sent as 16
hex digits. The key is `:zone_pin_key` in config, by default the well-known
test key `0123456789ABCDEFFEDCBA9876543210`. To build an `epinBlock` for PIN
1234 on card `4111111111111111`:

```bash
# PIN field 041234FFFFFFFFFF XOR PAN field 0000111111111111 (the 12 digits
# before the check digit)
printf '041225EEEEEEEEEE' | xxd -r -p |
  openssl enc -des-ede3 -nopad \
    -K 0123456789ABCDEFFEDCBA98765432100123456789ABCDEF | xxd -p
# → 2a3d408a1977dde9
```

In Elixir, `YspSimulator.PinBlock.encrypt("1234", card_number)` and
`decrypt(epin_block, card_number)` do the same. An `epinBlock` that doesn't
decrypt to a format-0 block with a 4-digit PIN for that card returns `104`
("Invalid EPinBlock").
