Técnico › Claves y direcciones

Subdirecciones

Cualquier número de direcciones no vinculables a partir de un solo par de claves

En resumen

La subdirección con índice (i, j) es el par de puntos D = B + m·G y C = a·D, donde m = Hs("SubAddr\0" ‖ a ‖ i ‖ j). Sin la clave de visualización a no se puede saber que varias subdirecciones pertenecen al mismo monedero.

Para qué

Si das la misma dirección a dos personas distintas, pueden comparar datos y darse cuenta de que pagaron al mismo destinatario. Las subdirecciones lo resuelven: una dirección por cada pagador, mientras el monedero sigue siendo uno solo y el escaneo no se vuelve más lento.

Las subdirecciones forman una jerarquía de dos niveles: la cuenta i (major) y el índice dentro de la cuenta j (minor). La subdirección (0, 0) es la dirección principal.

¿Por qué la dirección (1,0) no empieza por 4?

Un monedero tiene exactamente una dirección principal: (0,0), que es simplemente B y A con el prefijo 18. Cualquier otro índice, incluida la «primera» dirección de la segunda cuenta, (1,0), es una subdirección: sus claves se derivan mediante m = Hs("SubAddr\0" ‖ a ‖ 1 ‖ 0) y se codifica con el prefijo 42, de ahí el 8…. Una cuenta es solo una forma de agrupar subdirecciones; no tiene una dirección «principal» propia.

Cómo se calcula

m = Hs( "SubAddr\0" ‖ a ‖ i ‖ j )
D = B + m·G     C = a·D i y j son números de 32 bits little-endian; "SubAddr\0" son 8 bytes con un byte cero al final

Una subdirección se codifica como una dirección normal pero con el prefijo 42 (en mainnet empieza por 8): Base58(42 ‖ D ‖ C ‖ checksum).

Fíjate en que la «clave de visualización» pública de la subdirección, C, no es a·G sino a·D. Este truco es necesario para poder enviar.

Enviar a una subdirección

Al enviar a una dirección normal, la clave de transacción es R = r·G. Al enviar a una subdirección, el remitente usa R = r·D. Así el destinatario calcula el secreto compartido como siempre:

a·R = a·r·D = r·(a·D) = r·C

El remitente conoce r y C, el destinatario conoce a y R, y ambos obtienen el mismo punto.

Cómo reconoce el monedero sus subdirecciones

El monedero precalcula D para unos cientos de índices y guarda una tabla D → (i, j). Para cada salida calcula un candidato

D' = P − Hs(8·a·R ‖ n)·G

y busca D' en la tabla. Si lo encuentra, la salida es nuestra, y además sabemos a qué subdirección llegó. Por eso las subdirecciones no ralentizan el escaneo: una resta y una búsqueda en una tabla hash.

Un detalle: subdirecciones y varias salidas

Si una transacción tiene una salida hacia una subdirección, el monedero que envía usa una clave de transacción distinta para cada salida (claves adicionales en tx_extra). De lo contrario, el destinatario podría comprobar si el cambio del remitente pertenece a alguna dirección.