[Back] With a Split Vanity Bitcoin Address, Bob generates \(a\) for his private key, and \(A\) for his public key. He then gives \(A\) to Trent, and who generates a new private key of \(b\), and a public key of \(B\). He publishes Bob's public key as Hash(\(A+B\)), and returns \(b\) to Bob. Bob computes the associated private key as \(a+b\). This page proves this approach [background]:

## Vanity Bitcoin Address Proof |

## Split vanity address generation

In split vanity address generation, Bob wants a vanity Bitcoin address with a defined sequence, and so generates a key pair (a,A), and publishes A (his public key) to the Trent. Bob then asks for Trent to generate a key pair (b,B) and which will produce a given hash which has defined letters. Trent then searches for the best solution. If found, Trent gives Bob the solution of (b,B) and Bob's private key becomes (a+b). The address will then be the hash of (A+B) ... this is the public Bitcoin address. This works because of the way the elliptic curve works, where we can add private key:

\(A = a \times G\)

\(B = b \times G\)

\(A+B = a \times G + b \times G = (a+b) \times G\)

The operation we have is an addition of the keys, and where Bob simply adds \(a\) and \(b\) to find the private key for the published Bitcoin address (Hash(A+B)).

The following outlines the process:

The code in this page proves this. Here is a sample run:

Private Key (a) 86061879872531449951982497796959448028218381820041432789293827894874333168061 Private Key (B) 67049838517580778648042191759706328871467476377487957098163453293050470005128 Public Key (A) (52281756525516179214864400768152603516588884663484649962958165358048515611229L, 3506106637400073941700097757900439597340138321945710007917595359770824320067L) Public Key (B) (92274947923957043323674480256700292927552770224860750077123722920663254277413L, 111720110584941718181062835691990151475626279782674278759154810677066455066531L) Public key (Hash(A+B)): 1PkuH4XSqSrgnb7Uegxfh8ebRXYjP9CA49 Public key (Pub(a+b)): 1PkuH4XSqSrgnb7Uegxfh8ebRXYjP9CA49

## Code

The following is an outline (and based on [code] and we are using the Bitcoin Python library for to add and multiply points [link]:

import random import ecdsa from bitcoin import * # secp256k1, http://www.oid-info.com/get/1.3.132.0.10 _p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F _r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 _b = 0x0000000000000000000000000000000000000000000000000000000000000007 _a = 0x0000000000000000000000000000000000000000000000000000000000000000 _Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 _Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 curve_secp256k1 = ecdsa.ellipticcurve.CurveFp(_p, _a, _b) generator_secp256k1 = ecdsa.ellipticcurve.Point(curve_secp256k1, _Gx, _Gy, _r) oid_secp256k1 = (1, 3, 132, 0, 10) SECP256k1 = ecdsa.curves.Curve("SECP256k1", curve_secp256k1, generator_secp256k1, oid_secp256k1) ec_order = _r curve = curve_secp256k1 generator = generator_secp256k1 a = random.randrange(2**256) b = random.randrange(2**256) A =fast_multiply(G, a) B =fast_multiply(G, b) print("Bob Private Key (a)",a) print("Bob Public Key (A)",A) print("\nTrent Private Key (b)",b) print("Trent Public Key (B)",B) address = pubkey_to_address(fast_add(A,B)) print("\nTrent shows public key (Hash(A+B)):",address) a_b = a+b % _p A_B =fast_multiply(G, a_b) address = pubkey_to_address(A_B) print("Bob calculates public key (Hash(Pub(a+b))):",address) print("\nBob calculates private key (a+b):",a_b)

## Presentation

The following is a presentation on the topic [slides]: