Addresses and Detection Keys

Rather than having a single address for each spending authority, Penumbra allows the creation of many different publicly unlinkable diversified addresses. An incoming viewing key can scan transactions to every diversified address simultaneously, so there is no per-address scanning cost. In addition, Penumbra attaches a detection key to each address, allowing a user to outsource probabilistic transaction detection to a relatively untrusted third-party scanning service.


Addresses are parameterized by diversifiers, 16-byte tags used to derive up to distinct addresses for each spending authority. The diversifier is included in the address, so it should be uniformly random. To ensure this, diversifiers are indexed by a address index ; the -th diversifier is the encryption of using AES with the diversifier key .1

Each diversifier is used to generate a diversified basepoint as where performs hash-to-group for decaf377 as follows: first, apply BLAKE2b-512 with personalization b"Penumbra_Divrsfy" to the input, then, interpret the 64-byte output as an integer in little-endian byte order and reduce it modulo , and finally, use the resulting element as input to the decaf377 CDH map-to-group method.

Detection Keys

Each address has an associated detection key, allowing the creator of the address to delegate a probabilistic detection capability to a third-party scanning service.

The detection key consists of one component,

  • , the detection key (component)2,

derived as follows. Define prf_expand(label, key, input) as BLAKE2b-512 with personalization label, key key, and input input. Define from_le_bytes(bytes) as the function that interprets its input bytes as an integer in little-endian order, and to_le_bytes as the function that encodes an integer to little-endian bytes. Then

dtk_d = from_le_bytes(prf_expand(b"PenumbraExpndFMD", to_le_bytes(ivk), d))


Each payment address has three components:

  • the diversifier ;
  • the transmission key , a decaf377 element;
  • the clue key , a decaf377 element.

The diversifier is derived from a address index as described above. The diversifier with index is the default diversifier, and corresponds to the default payment address.

The transmission key is derived as , where is the diversified basepoint.

The clue key is is derived as , where is the conventional decaf377 basepoint.

Address Encodings

The raw binary encoding of a payment address is the 80-byte string d || pk_d || ck_d. We then apply the F4Jumble algorithm to this string. This mitigates attacks where an attacker replaces a valid address with one derived from an attacker controlled key that encodes to an address with a subset of characters that collide with the target valid address. For example, an attacker may try to generate an address with the first characters matching the target address. See ZIP316 for more on this scenario as well as F4Jumble, which is a 4-round Feistel construction.

This jumbled string is then encoded with Bech32m with the following human-readable prefixes:

  • penumbra for mainnet, and
  • penumbra_tnXYZ_ for testnets, where XYZ is the current testnet number padded to three decimal places.

Short Address Form

Addresses can be displayed in a short form. A short form of length bits (excludes the human-readable prefix) is recommended to mitigate address replacement attacks. The attacker’s goal is to find a partially colliding prefix for any of addresses they have targeted.

Untargeted attack

In an untargeted attack, the attacker wants to find two different addresses that have a colliding short form of length bits.

A collision is found in steps due to the birthday bound, where is the number of bits of the prefix.

Thus we’d need to double the length to provide a desired security level of bits.

This is equivalent to characters of the Bech32m address, excluding the human-readable prefix. Thus for a targeted security level of 80 bits, we’d need a prefix length of 160 bits, which corresponds to 32 characters of the Bech32m address, excluding the human-readable prefix.

The short form is not intended to mitigate this attack.

Single-target attack

In a targeted attack, the attacker’s goal is to find one address that collides with a target prefix of length bits.

Here the birthday bound does not apply. To find a colliding prefix of the first M bits, they need to search addresses.

The short form is intended to mitigate this attack.

Multi-target attack

In a multi-target attack, the attacker’s goal is to be able to generate one address that collides with the short form of 1 of different addresses.

They are searching for a collision between the following two sets:

  • set of the short forms of the targeted addresses, which has size elements, and each element has length bits.
  • set of the short forms of all addresses, which has size elements.

If the attacker has a target set of addresses, she can find a collision after steps. Thus for a prefix length of bits, we get bits of security. For a targeted security level of 80 bits and a target set of size , we need a prefix length of 120 bits, which corresponds to 24 characters of the Bech32m address, excluding the human-readable prefix and separator.

The short form is intended to mitigate this attack.


This convention is not enforced by the protocol; client software could in principle construct diversifiers in another way, although deviating from this mechanism risks compromising privacy.


As in the previous section, we use the modifier “component” to distinguish between the internal key component and the external, opaque key.