Riflettendo ora risulta molto chiaro il funzionamento dei vanity gen che permettono di essere sicuri.
Basta dare chiave pubblica e il miner vanity somma G alla chiave k volte fino ad ottenere l'indirizzo desiderato, comunica k al proprietario della chiave privata "n" e genera un indirizzo privato n+k che magicamente diventa il vanity richiesto.
Dubbi residui:
- come critto un messaggio? Ossia poi, di fatto, come funziona?
Per quanto riguarda l'algoritmo ECDSA, sto preparando la spiegazione!
Non avevo mai pensato al funzionamento del vanity gen, in effetti dovrebbe essere proprio come lo hai descritto!
l'applicazione che porta da "private key" a E(Fp) è iniettiva? (in caso sarebbe anche suriettiva visto che hanno lo stesso numero di elementi).
Sì, una volta scelto il punto base G, detto per questo anche punto
generatore di E(FP), c'è una corrispondenza biunivoca tra l'insieme dei naturali compresi tra 1 e n-1 e i punti della curva
Si fissa G (è stato scelto "Standards for Efficient Cryptography" (SEC), vedi
http://www.secg.org/sec2-v2.pdf a pagina 9).
Fissato G, è univoco l'ordine con cui percorrere tutti i punti della curva:
1 --> G
2 --> 2*G
3 --> 3*G
..
..
n-1 --> (n-1)*G
la prima colonna è quella delle chiavi private (scalari)
la seconda colonna è quella delle chiavi pubbliche corrispondenti (punti di E(Fp)) (NB: lo scalare 0 non è considerato una chiave privata accettabile nel protocollo bitcoin, quindi 0*G ( o n*G, che è lo stesso) non lo ho inserito nelle possibilità.)
Per ogni chiave privata c'è un'unica chiave pubblica e viceversa.
Le 2 colonne hanno entrambe n-1 elementi (sono circa 2^256, un po' di meno di p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 che è l'ordine del campo delle coordinate). La corrispondenza biunivoca tra i due insiemi è garantita dalla matematica che ho spiegato nei post precedenti (E(Fp) è un gruppo ciclico, l'elemento G è un generatore che permette di riottenere tutti gli altri punti)
La corrispondenza però non è più biunivoca se aggiungiamo una terza "colonna", quella degli indirizzi, che non c'entrano però con le curve ellittiche.
insieme scalari (fissato G) <--> insieme di punti di E(Fp) --> indirizzi
L'insieme degli indirizzi ha circa 2^160 elementi distinti possibili. Per passare dall'insieme E(Fp) all'insieme degli indirizzi ci sono 2 operazioni, un hash256 e un ripemd160 che traducono una stringa di 256 bit in una di 160 bit (la quale viene poi rappresentata in base 58, ma questo è solo un problema appunto di rappresentazione del risultato finale).
Quindi ci sono tantissime chiavi private (con relative chiave pubbliche) che producono lo stesso indirizzo.***
***EDIT2: in realtà c'è anche un altro problema quando traduciamo un punto della curva in un indirizzo. Poichè la funzione hash lavora in modo stupido solo sulla rappresentazione del punto, se scriviamo un punto di E(Fp) nella sua forma compressa (cioè con solo la coordinata x e il "segno" della y, aggiungendo come prefisso 02 se y è pari e 03 se y è dispari), avremo che lo stesso punto può essere tradotto in due indirizzi completamente diversi (ma controllati sempre dalla stessa chiave privata)
Riporto qui il passo dedicato alla questione in "Mastering Bitcoin"
Compressed public keys
As we saw previously, the public key is a point on the elliptic curve consisting of a pair of coordinates (x,y). It is usually presented with the prefix 04 followed by two 256-bit numbers, one for the x coordinate of the point, the other for the y coordinate. The prefix 04 is used to distinguish uncompressed public keys from compressed public keys that begin with a 02 or a 03.
Here’s the public key generated by the private key we created earlier, shown as the coordinates x and y:
x = F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A
y = 07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB
Here’s the same public key shown as a 520-bit number (130 hex digits) with the prefix 04 followed by x and then y coordinates, as 04 x y:
K=04F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB
Compressed public keys were introduced to bitcoin to reduce the size of transactions and conserve disk space on nodes that store the bitcoin blockchain database. Most transactions include the public key, required to validate the owner’s credentials and spend the bitcoin. Each public key requires 520 bits (prefix \+ x \+ y), which when multiplied by several hundred transactions per block, or tens of thousands of transactions per day, adds a significant amount of data to the blockchain.
As we saw in the section “Public Keys”, a public key is a point (x,y) on an elliptic curve. Because the curve expresses a mathematical function, a point on the curve represents a solution to the equation and, therefore, if we know the x coordinate we can calculate the y coordinate by solving the equation y2 mod p = (x3 + 7) mod p. That allows us to store only the x coordinate of the public key point, omitting the y coordinate and reducing the size of the key and the space required to store it by 256 bits. An almost 50% reduction in size in every transaction adds up to a lot of data saved over time!
Whereas uncompressed public keys have a prefix of 04, compressed public keys start with either a 02 or a 03 prefix. Let’s look at why there are two possible prefixes: because the left side of the equation is y2, that means the solution for y is a square root, which can have a positive or negative value. Visually, this means that the resulting y coordinate can be above the x-axis or below the x-axis. As you can see from the graph of the elliptic curve in Figure 4-2, the curve is symmetric, meaning it is reflected like a mirror by the x-axis. So, while we can omit the y coordinate we have to store the sign of y (positive or negative), or in other words, we have to remember if it was above or below the x-axis because each of those options represents a different point and a different public key. When calculating the elliptic curve in binary arithmetic on the finite field of prime order p, the y coordinate is either even or odd, which corresponds to the positive/negative sign as explained earlier. Therefore, to distinguish between the two possible values of y, we store a compressed public key with the prefix 02 if the y is even, and 03 if it is odd, allowing the software to correctly deduce the y coordinate from the x coordinate and uncompress the public key to the full coordinates of the point.
Here’s the same public key generated previously, shown as a compressed public key stored in 264 bits (66 hex digits) with the prefix 03 indicating the y coordinate is odd:
K = 03F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A
This compressed public key corresponds to the same private key, meaning that it is generated from the same private key. However, it looks different from the uncompressed public key. More importantly, if we convert this compressed public key to a bitcoin address using the double-hash function (RIPEMD160(SHA256(K))) it will produce a different bitcoin address. This can be confusing, because it means that a single private key can produce a public key expressed in two different formats (compressed and uncompressed) that produce two different bitcoin addresses. However, the private key is identical for both bitcoin addresses.
EDIT: a voler essere pignoli, per ottenere un indirizzo è sufficiente sostituire nel meccanismo una qualsiasi stringa di 256 bit al posto dell'hash256 delle coordinate di un punto della curva ellittica. Non vorrei dire una stupidaggine ma penso che il sistema bitcoin - blockchain sia del tutto indipendente dalla teoria delle curve ellittiche e dall'algoritmo di firma digitale ECDSA.