Skip to main content

diversified-and-stealth-keys

Deriving diversified public keys

A diversified public key can be derived from Alice's keys, to enhance Alice's transaction privacy. If Alice's counterparties' databases are compromised, it enables Alice to retain privacy from such leakages. Diversified public keys are used for generating diversified addresses.

Basically, Alice must personally derive and provide Bob and Charlie with random-looking addresses (for Alice). Because Alice is the one deriving these Diversified Addresses (they can only be derived by Alice), if Bob and Charlie chose to later collude, they would not be able to convince each-other that they'd interacted with Alice.

This is not to be confused with 'Stealth Addresses', which 'flip' who derives: Bob and Charlie would each derive a random-looking Stealth Address for Alice. Alice would then discover her new Stealth Addresses through decryption.

All of the key information below is Alice's

Alice derives a 'diversified' incoming viewing public key, and sends it to Bob:

ThingDerivationNameComments
d\drandF\stackrel{rand}{\leftarrow} \mathbb{F}diversifier
Gd\GddG\d \cdot Gdiversified generator
Ivpkm,d\IvpkmdivskmGd\ivskm \cdot \GdDiversified incoming viewing public key

Notice: when d=1\d = 1, Ivpkm,d=Ivpkm\Ivpkmd = \Ivpkm. Often, it will be unncessary to diversify the below data, but we keep d\d around for the most generality.

Deriving stealth public keys

All of the key information below is Alice's

Stealth Public Keys are used for generating Stealth Addresses. For Bob to derive a Stealth Address for Alice, Bob derives:

ThingDerivationNameComments
d\dGiven by Alice(Diversifier)Remember, in most cases, d=1\d=1 is sufficient.
Gd\GddG\d \cdot G(Diversified) generatorRemember, when d=1\d = 1, Gd=G\Gd = G.
eskstealth\esk_{stealth}randF\stackrel{rand}{\leftarrow} \mathbb{F}ephemeral secret, for deriving the stealth key shared secret
Epkd,stealth\Epkd,_{stealth}eskstealthGd\esk_{stealth} \cdot \Gd(Diversified) Ephemeral public key, for deriving the stealth key shared secret
Sm,stealth\sharedsecret_{m, stealth}eskstealthIvpkm,d\esk_{stealth} \cdot \IvpkmdStealth key shared secret
hstealth\hstealthpos2(“az_stealth_key”,Sm,stealth)\text{pos2}(\text{``az\_stealth\_key''}, \sharedsecret_{m, stealth})stealth key
Ivpkm,d,stealth\IvpkmdstealthhstealthGd+Ivpkm,d\hstealth \cdot \Gd + \Ivpkmd(Diversified) Stealth viewing public key

Having derived a Stealth Address for Alice, Bob can now share it with Alice as follows:

ThingDerivationNameComments
tagm,iBobAlice\tagg_{m, i}^{Bob \rightarrow Alice}See earlier in this doc.Derive the next tag in the BobAliceBob\rightarrow Alice sequence.
Note: we illustrate with a master tag sequence, but an app-specific tag sequence could also be used (in which case an encryption of the app_address in a ciphertext header wouldn't be required; it could just be inferred from the tag used).
eskheader\esk_{header}randF\stackrel{rand}{\leftarrow} \mathbb{F}ephemeral secret key, for deriving the ciphertext header shared secret
Epkd,header\Epkd,_{header}eskheaderGd\esk_{header} \cdot \Gd(Diversified) Ephemeral public key, for deriving the ciphertext header shared secret
Sm,header\sharedsecret_{m,header}eskheaderIvpkm\esk_{header} \cdot \IvpkmCiphertext header shared secretTODO: we might need to use a different ephemeral keypair from the one used to derive the stealth address.
hm,enc,header\hmencheaderpos2(“az_enc_key”,Sm,header)\text{pos2}(\text{``az\_enc\_key''}, \sharedsecret_{m,header})ciphertext header encryption key
ciphertext_header\ciphertextheaderencrypthm,enc,headerIvpkm\text{encrypt}^{\Ivpkm}_{\hmencheader}(app_address)TODO: diversify this?
payload\payload[ tagm,iBobAlice\tagg_{m, i}^{Bob \rightarrow Alice}, Epkd,header\Epkd,_{header}, ciphertext_header\ciphertextheader, Epkd,stealth\Epkd,_{stealth} ]

Alice can learn about her new Stealth Address as follows. First, she would identify the transaction has intended for her, either by observing tagm,iBobAlice\tagg_{m, i}^{Bob \rightarrow Alice} on-chain herself (and then downloading the rest of the payload which accompanies the tag), or by making a privacy-preserving request to a server, to retrieve the payload which accompanies the tag. Assuming the payload\payload has been identified as Alice's, we proceed:

ThingDerivationName
Sm,header\sharedsecret_{m,header}ivskmEpkd,header\ivskm \cdot \Epkd,_{header}Ciphertext header shared secret
hm,enc,header\hmencheaderpos2(“az_enc_key”,Sm,header)\text{pos2}(\text{``az\_enc\_key''}, \sharedsecret_{m,header})ciphertext header encryption key
app_addressdecrypthm,enc,headerivskm(ciphertext_header)\text{decrypt}_{\hmencheader}^{\ivskm}(\ciphertextheader)
ivskm\ivskmSee derivations above. Use the decrypted app_address in the derivation.app-specific incoming viewing secret key
Sm,stealth\sharedsecret_{m, stealth}ivskmEpkd,stealth\ivskm \cdot \Epkd,_{stealth}Stealth key shared secret
hstealth\hstealthpos2(“az_stealth_key”,Sm,stealth)\text{pos2}(\text{``az\_stealth\_key''}, \sharedsecret_{m, stealth})stealth key
ivskm,stealth\ivskmstealthhstealth+ivskm\hstealth + \ivskm
Ivpkm,d,stealth\Ivpkmdstealthivskm,stealthGd\ivskmstealth \cdot \Gd(Diversified) Stealth viewing public key