invisible domain attribution tags
ZeroName hides a website's domain inside a visible name using invisible Unicode codepoints. You enter your name and the site you are giving it to, and it returns a name that looks the same on screen but contains a hidden, passphrase-keyed payload. If that name later shows up in spam or a breach dump, paste it into the decoder to see which site leaked it. The domain is stored in the tag, so there is no database or lookup table to maintain.
The whole point: find out which website leaked your details.
Hide a keyed domain tag inside a name.
Looks the same as the plain name. Copy preserves the invisible characters.copied
Recover the hidden domain from a tagged name.
ZeroName is an attribution tool. It does not keep anything secret. It marks a name with a hidden tag so you can identify which recipient leaked your contact details. This section describes what the encoder and decoder do.
The payload is stored in two ranges of zero-width characters. They display nothing but survive copy and paste as normal text:
U+FE00 … U+FE0F, Variation Selectors 1–16 (VS1–VS16), hold byte values 0–15.U+E0100 … U+E01EF, Variation Selectors Supplement, hold byte values 16–255.Variation selectors normally select a glyph variant of the character before them. When there is no such variant, they display as nothing. They are also normalization-stable: they have no compatibility decomposition, so NFC and NFD leave them unchanged. NFKC does remove them, which is covered in the caveats.
SHA-256(passphrase) using crypto.subtle.digest, then repeat those 32 bytes as needed to cover the payload.0–15 to U+FE00 + b, and 16–255 to U+E0100 + (b − 16).This produces one invisible codepoint per payload byte. A 12-byte domain plus its checksum becomes 13 hidden characters.
The hidden characters are placed in the gaps between the visible letters, never before the
first letter and never after the last. They are spread evenly across those gaps, so hidden
character k is attached to the letter at floor(k × gaps ÷ payload).
Encoding the domain linkedin into the name Noah places three
invisible bytes in each gap, giving N•••o•••a•••h, where each • is
an invisible byte attached to the letter before it.
The placement is monotonic, so the hidden characters stay in payload order. Decoding does not depend on where they sit: it reads the string by codepoint, collects the characters in the two invisible ranges in order, and that sequence is the payload. There is a single copy of the payload, so if any hidden character is lost, the checksum fails.
A name needs at least two visible characters to have a gap. If it has only one, the payload is appended after it.
SHA-256 turns the passphrase into 32 bytes. Those bytes are cycled across the payload and XORed with it, and the same passphrase produces the same keystream to reverse the operation. Without the passphrase the bytes do not decode, and a tag made with a different passphrase will not decode against yours. This is obfuscation rather than encryption. A repeating-keystream XOR can be broken by anyone who knows the scheme and has enough samples. It stops the domain from being read directly, but it does not resist analysis.
The last payload byte is a checksum. On decode, the XOR of the recovered domain bytes is
compared against it. If a character was added, a byte was changed, or the passphrase is wrong,
the values differ and the decoder reports Invalid or stripped tag instead of
showing an incorrect domain. It is a one-byte check and does not correct errors.
maxlength that counts codepoints, or a validator that allows only letters or ASCII, will truncate or refuse the hidden bytes.ZeroName is open source and lives on GitHub. If you think it is neat or handy, a star helps other people find it.