FUGUSEED-QR(1) General Commands Manual FUGUSEED-QR(1)

fuguseed-qrturn 12 seed words into a Standard SeedQR

fuguseed-qr

fuguseed-qr reads 12 seed words from the first line of standard input. It prints a Standard SeedQR as text, zone by zone, so that a person can draw the code on paper. The program takes no option and no argument.

The words enter on standard input only. No argument, no file name, and no environment variable carries a word. The program opens no file, it starts no other program, and it reads no environment variable. The three standard streams are its one contact with the computer.

fuguseed-qr sees the seed words. Run it on an air-gapped computer only.

The first line of standard input holds the 12 words, with one space between two words. Each word must be a word of the English word list of BIP39.

With a valid checksum, fuguseed-qr prints the SeedQR. Standard output holds the digit string on the first line: the 12 word indexes, 0-based, each as 4 decimal digits. The grid view of the 25 rows follows, and then the 25 zone views, from “A-1” to “E-5”. A dark module prints as a number sign, and a light module prints as a period. A zone view holds the zone name, the 5 rows of the zone, and the count of the dark modules of the zone.

After each zone view, the program reads one line from standard input. Press the return key to get the next zone. At the end of the input, the remaining zones print without a pause.

With a wrong checksum, fuguseed-qr prints the check word. Standard output holds that one word, and the program prints no SeedQR in that run. The dice give the YELLOW block and the BLUE row of word 12, and the program finds the one word of that row that makes the checksum valid. Write the check word in place of word 12, and start the program again.

The output is a Standard SeedQR of 25 x 25 modules. It is not a Compact SeedQR: fuguseed-qr prints no Compact SeedQR. A Standard SeedQR decodes to the digit string, so a person can map the digits back to the 12 words. A consumer such as FuguPass reads the SeedQR with a camera, and it reads no typed word.

The release publishes fuguseed-qr as one file, beside the tarballs. The signed SHA256 manifest of the release names that file. Compare the digest of the file with the manifest on the air-gapped computer, before the first run:

$ sha256 fuguseed-qr

The two digests must agree. Do not run a file with a different digest.

: The SeedQR is the 12 words in another form. A person who scans the code gets the seed. Keep the paper as you keep the words. Do not photograph the code, and do not put it on a computer. A loss of the words is irreversible.

The procedure needs an air-gapped computer, a printed 25 x 25 template, and a marker. The template is the printable 25 x 25 template of the SeedQR specification, or a grid with the same zones. The template must hold a quiet zone of 4 light modules around the code. Each module must be 5 mm or more, because the drawing must scan under a camera.

Do these steps:

  1. Start fuguseed-qr on the air-gapped computer, and type the 12 words.
  2. Find the zone of the template with the name of the zone view.
  3. Fill one square of that zone for each dark module of the zone view.
  4. Count the filled squares of the zone. The count must agree with the count of the zone view.
  5. Press the return key, and do the same for each of the other 24 zones.
  6. Compare the grid view with the template, row by row.
  7. Scan the drawing with the camera of the device. The device must show the 12 words, in the same order.

The scan proves the drawing. Do the scan before you keep the paper, and before you erase the words from the air-gapped computer.

0
fuguseed-qr printed the SeedQR, or it printed the check word.
1
The input did not hold 12 words of the list. fuguseed-qr printed one line to standard error. That line names the word position or the word count, never a word.
2
The command line held an argument. fuguseed-qr printed one usage line to standard error.

Start the program on the air-gapped computer:

$ fuguseed-qr

The program waits for the 12 words on standard input.

The word list and the checksum come from BIP39, the mnemonic code for the generation of a deterministic key. The form of the code comes from the SeedQR specification of the SeedSigner project. The QR code follows ISO/IEC 18004: version 2, error correction level L, numeric mode, and mask pattern 0.

Dick Olsson <hi@senzilla.io>

The program prints no penalty score and it selects no mask. The mask is pattern 0, always. Every reader decodes the code, because the format information names the mask.

September 19, 2026 OpenBSD