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.
Diversifiers
Addresses are parameterized by diversifiers, 11-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 diversifier index ; the -th diversifier is the encryption of using AES-FF1 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))
Addresses
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 diversifier 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 75-byte string d || pk_d || ck_d
. We pad this string to 80 bytes, then apply the F4Jumble algorithm to
this padded 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, andpenumbra_tnXYZ_
for testnets, where XYZ is the current testnet number padded to three decimal places.
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.