Subaddress
Un numero qualsiasi di indirizzi non collegabili da un'unica coppia di chiavi
Il subaddress con indice (i, j) è la coppia di punti D = B + m·G e C = a·D, dove m = Hs("SubAddr\0" ‖ a ‖ i ‖ j). Senza la view key a non si può capire che dei subaddress appartengono allo stesso wallet.
Perché
Se hai dato lo stesso indirizzo a due persone diverse, queste possono confrontarsi e accorgersi di aver pagato lo stesso destinatario. I subaddress risolvono il problema: un indirizzo per ogni pagatore, mentre il wallet resta uno solo e la scansione non rallenta.
I subaddress formano una gerarchia a due livelli: l'account i (indice principale) e l'indice all'interno dell'account j (indice secondario). Il subaddress (0, 0) è l'indirizzo principale.
Un wallet ha esattamente un indirizzo principale, (0,0), che è semplicemente B e A con prefisso 18. Qualsiasi altro indice, compreso il "primo" indirizzo del secondo account (1,0), è un subaddress: le sue chiavi sono derivate tramite m = Hs("SubAddr\0" ‖ a ‖ 1 ‖ 0) ed è codificato con prefisso 42, da cui 8…. Un account è solo un modo per raggruppare i subaddress; non ha un proprio indirizzo "principale".
Come si calcola
D = B + m·G C = a·D i e j sono numeri little-endian a 32 bit; "SubAddr\0" sono 8 byte con un byte zero finale
Un subaddress è codificato come un normale indirizzo ma con prefisso 42 (inizia con 8 sulla mainnet): Base58(42 ‖ D ‖ C ‖ checksum).
Nota che la "view key" pubblica del subaddress, C, non è a·G ma a·D. Questo trucco serve per l'invio.
Inviare a un subaddress
Quando si invia a un indirizzo normale la chiave della transazione è R = r·G. Quando si invia a un subaddress, il mittente usa R = r·D. Il destinatario calcola poi il segreto condiviso come al solito:
Il mittente conosce r e C, il destinatario conosce a e R, ed entrambi ottengono lo stesso punto.
Come il wallet riconosce i propri subaddress
Il wallet precalcola D per qualche centinaio di indici e tiene una tabella D → (i, j). Per ogni output calcola un candidato
e cerca D' nella tabella. Se lo trova, l'output è nostro, e sappiamo anche a quale subaddress è arrivato. Ecco perché i subaddress non rallentano la scansione: una sottrazione e una ricerca in una tabella hash.
Se una transazione ha un output verso un subaddress, il wallet mittente usa una chiave di transazione separata per ogni output (chiavi aggiuntive in tx_extra). Altrimenti il destinatario potrebbe verificare se il resto del mittente appartiene a un certo indirizzo.