Spending Keys

A BIP39 24-word seed phrase can be used to derive one or more spend authorities. From this mnemonic seed phrase, spend seeds can be derived using PBKDF2 with:

  • HMAC-SHA512 as the PRF and an iteration count of 2048 (following BIP39)
  • the seed phrase used as the password
  • mnemonic concatenated with an index used as the salt, i.e. the default spend authority is derived using the salt mnemonic0

TODO: describe new BIP44 derivation and change raw BIP39 derivation to be described as “legacy”.

The root key material for a particular spend authority is the 32-byte spend_key_bytes derived as above from the seed phrase. The spend_key_bytes value is used to derive

  • , the spend authorization key, and
  • , the nullifier key,

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. Then

ask = from_le_bytes(prf_expand("Penumbra_ExpndSd", spend_key_bytes, 0)) mod r
nk  = from_le_bytes(prf_expand("Penumbra_ExpndSd", spend_key_bytes, 0)) mod q

The spending key consists of spend_key_bytes and ask. (Since ask is derived from spend_key_bytes, only the spend_key_bytes need to be stored, but the ask is considered part of the spending key). When using a hardware wallet or similar custody mechanism, the spending key remains on the device.

The spend authorization key is used as a decaf377-rdsa signing key.1 The corresponding verification key is the spend verification key . The spend verification key and the nullifier key are used to create the full viewing key described in the next section.

1

Note that it is technically possible for the derived or to be , but this happens with probability approximately , so we ignore this case, as, borrowing phrasing from Adam Langley, it happens significantly less often than malfunctions in the CPU instructions we’d use to check it.