OpenPGP key paper slips with SVG

"There was a girl. No idea who she was. Don't even know her name. I was too drunk to care."

"And what, you slept with her?"

"No. I signed her public key."

From XKCD 364: Responsible Behavior

Some key-signing parties require you to come with paper slips of your key. It's just a piece of paper with your name and your key fingerprint. You give it out to people who are to sign your key, usually after they verified your identity using some form of government-issued ID.

There's also hundreds of tools, both online and offline, to generate such slips for you. So, of course, I decided to reinvent the wheel again. I also wanted to use the standard "credit card" size (also known as ISO/IEC 7810 ID-1), ie 85.6×53.98 millimeters.

I considered using XETƎX, but setting up the fonts, the page layout, etc is tedious. So I settled on writing a simple SVG document. The final result looks like this (including marks for cutting):

John Doe 786A 02F7 4201 5903 C6C6 FD85 2552 D272 912F 4740 —

To generate the DataMatrix code, I used Zint and forced the output size to 16×48 (a square image wouldn't be as good a fit on the card). I saved the code as SVG then copied the <rect> elements. I prefer DataMatrix over QR codes, as they pack more error-correction and remain scannable at very small sizes. (I also think they look less stupid, but that's my opinion.)

The <use> element of SVG is extremely useful here, as you can avoid repeating yourself if you want to fill a page full of such cards. Here's a template for filling 8 cards on an A4 piece of paper. The margins are generous enough that any printer should be able to print it without issues. Convert that to PDF (for example using Inkscape) and print at 1:1 size.

<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<svg width="210mm" height="297mm" viewBox="0 0 210 297" xmlns="" xmlns:xlink="">
    <g id="card"><!-- 85.6x53.98 -->
      <text font-family="Vollkorn" font-weight="900" font-size="9" x="42.8" y="10" text-anchor="middle">John Doe</text>
      <text font-family="Inconsolata" font-size="5.5" x="42.8" y="18" text-anchor="middle">786A 02F7 4201 5903 C6C6</text>
      <text font-family="Inconsolata" font-size="5.5" x="42.8" y="24" text-anchor="middle">FD85 2552 D272 912F 4740</text>
      <text font-family="Vollkorn" font-style="italic" font-size="3.7" x="42.8" y="30" text-anchor="middle"> —</text>
      <use transform="translate(15.3 33) scale(1.1)" xlink:href="#barcode" />
      <use xlink:href="#corner" />
      <use transform="translate(85.6 0) rotate(90)" xlink:href="#corner" />
      <use transform="translate(85.6 53.98) rotate(180)" xlink:href="#corner" />
      <use transform="translate(0 53.98) rotate(270)" xlink:href="#corner" />
    <g id="corner">
      <line x1="-2" y1="0" x2="2" y2="0" stroke-width=".25" stroke="#000" />
      <line x1="0" y1="-2" x2="0" y2="2" stroke-width=".25" stroke="#000" />
    <g id="barcode"><!-- 50x18 -->
       <!-- Paste here DataMatrix code: $(grep rect zint-output.svg | xclip) -->
    <g id="col">
      <use xlink:href="#card" />
      <use y="63.98" xlink:href="#card" />
      <use y="127.96" xlink:href="#card" />
      <use y="191.94" xlink:href="#card" />

  <use transform="translate(14.4 25.54)" xlink:href="#col" />
  <use transform="translate(110.0 25.54)" xlink:href="#col" />

Everything remains easily tweakable (paper size, fonts, positioning, etc.), adapt according to your taste. Now all you have to do it to find a key-signing party near you.