Pre-UIP: Address-linked Attestations
This is a client-side only change, i.e. it requires no protocol changes / network upgrades.
Problem
We want to enable an entity with a Penumbra address to demonstrate approval of an arbitrary message. Currently we don’t have a way to sign messages with Penumbra addresses.
Proposed Solution
Since Penumbra addresses are ultimately associated with a spending key, we could:
- Provide a way to sign an arbitrary message using
decaf377-rdsa
and a user’s existing spend authorization key - Provide a ZKP that demonstrates that the address is derived from the spending key, and that the randomized verification key is a correct randomization of the spend verification key
- Define a way to bundle up the attestations which consist of a
decaf377-rdsa
signature, a randomized verification key, and a ZKP
1. Signing
Arbitrary byte messages $m$ will be signed using decaf377-rdsa
in the SpendAuth
signature domain [0]. The payload $p$ that will be signed is:
$p = \texttt{BLAKE2b-512}(\texttt{b"Penumbra_AddrAtt"} || m)$
We will demonstrate in the ZKP below that the randomized verification key is correctly derived.
2. ZKP
The Penumbra address consists of a diversifier $d$, a transmission key $pk_d$, and a clue key $ck_d$. We need to demonstrate in the proof statements that the transmission key $pk_d$ is derived via:
$pk_d = [ivk] B_d$
and:
$ivk = \texttt{poseidon_hash_2}(\texttt{from_le_bytes}(\texttt{b"penumbra.derive.ivk"}), nk, \texttt{decaf377_s}(ak)) \mod r$
where $nk$ is the nullifier-deriving key and $ak$ is the spend verification key.
We also need to demonstrate that the randomized verification key $rk$ is a correct randomization of the spend verification key $ak$ given a witnessed randomizer $\alpha$:
$rk = ak + [\alpha]B_{\texttt{SpendAuth}}$
Both of these checks are performed by the existing SpendProof
[1], so we can reuse that ZKP and fill in the following data for the other witness and public input fields:
- The witnessed note should have zero value, an
Rseed
consisting of zero bytes[0u8; 32]
, the fixed asset ID of the Penumbra staking token, and the address that is being attested to. - By using a zero value note, the note will be treated as a dummy note in the circuit. This means signers/verifiers don’t need to maintain state or provide a valid Merkle authentication path or anchor.
- The balance commitment can be filled in using a fixed zero blinding factor.
3. Attestation Format
The attestations $a$ will consist of:
- a 64 bytes
SpendAuth
signature $\sigma$ derived as described above, - a 32 byte randomized verification key $rk$,
- a 192 byte spend ZKP $\pi$.
These three components are concatenated into a 288 byte array and provided to verifiers:
$a = \sigma || rk || \pi$
Verifiers need the verification key for the spend ZKP (provided in the penumbra-proof-params
crate) and the address being attested to in order to verify this attestation.
[0] Randomizable Signatures - The Penumbra Protocol
[1] Spend - The Penumbra Protocol