[Back] With Bitcoins, we generate a 256-bit random private key \((n\)) and use a point on the elliptic curve \((G\)). The public key is then \(n \times G\), and the hash of this is used to generate the Bitcoin address. If we have the processing power we can search for private keys which would generate an output address which would have a required character sequence in it. In the following we generate private key and then the public one, until it matches the required one or two sequence characters in the Bitcoin address:
Vanity Bitcoin Address Generation
With Bitcoins, we generate a 256-bit private key (\(n\)) and use a point on the elliptic curve (\(G\)). The public key \(P\) is then \(n \times G\), and the signature of this is used to generate the Bitcoin address. If we have the processing power we can search for private keys which would generate an output address which would have a required character sequence in it. In the program on this page we generate private key and then the public one, and see if the required sequence is contained in the Bitcoin address. If it is not, then we increment the private key by one, and then try again.
A sample run shows the searching for a sequence of "aa". It can be see that "aa" exists in the generated public Bitcoin address (spaces have been added around the sequence):
Addresses tried ... (just showing first six characters of address) 1MqVCg 18L1Sy 1BLUEh 1MQVFZ 1nA3d6 1AT81f 1DJ9kQ 12RYEK 1CWUtx 1AcDgP 12bxD3 1KNdgg 19xxHn 1885zi 1JzbWn 19ui1w 1J9RVM 1CoaMd 1FxD87 1DGSKJ 1QHeQr 16kRHz 16eNtm 1Avfbd 1DmiAA 1GCPdQ 12ANbh 1C3RWL 14TzuR 14aBU5 1Mzfpm 127kZq 1C1uGu 17G8C1 1H1W2V 14kJku 1HRazj 1NhUEJ 1PL5c9 1PktPP 16Tdks 14XbXN 1FjnPf 1GhHqE 18P4PJ 15MsvM 1DtRJ5 1H2DVm 1Lh2xC 18RCxL 124C2k 17updw 1FVA5n 1CLjQb 15JUkZ 1J9g8a 13Y1Lv 1tJkk6 Public Bitcoin address is 1tJkk66uYRRy aa Eyr6Yz9XB1NwrgxN9Mv Private Bitcoin address is: 1291049162141473901904148853179377639061071336882801200545944876355160619226
It should be noted that Bitcoin addresses always start with a "1" and are created with Base 58 characters. If you are interested in how Bitcoin addresses are created click [here].
If I use a program which does not have limits on the number of keys search, and search for "b1L", the result is:
Public Bitcoin address is: 1HpuY2st1bUDq9pxE4d8ajzJR1 b1L NBdF and the associated private key is: 4939905350059000420219188404344301855642743657175451 6193252594725833234851243
As we are using Base-58, we replace an 'i' for '1', and an 'o' for a '0'.
The following is an outline (and based on [code]:
import random import ecdsa import hashlib from ecdsa.util import string_to_number, number_to_string from bitcoin import * # secp256k1, http://www.oid-info.com/get/184.108.40.206.10 _p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL _r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L _b = 0x0000000000000000000000000000000000000000000000000000000000000007L _a = 0x0000000000000000000000000000000000000000000000000000000000000000L _Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L _Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L 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 def get_key(privkey,search_for): count = 0 address = '' print "Addresses tried ... (just showing first six characters of address)" while not search_for.lower() in address.lower(): privkey += 1 pubkey_point =fast_multiply(G, privkey) address = pubkey_to_address(pubkey_point) print address[:6], count += 1 if (count>99): return 0,0 return address,privkey seq="aa" privkey = random.randrange(2**256) address,privkey=get_key(privkey,seq) if (address==0): print "Could not find sequence. Need a cluster!" else: print "\n\nPublic Bitcoin address is",address print "Private Bitcoin address is:",privkey
Split vanity address generation
So we are unlikely to be able to have the computing power to generate complex character sequences, but the Bitcoin mining network has excellent resources which we can use to mine our address. But how can we get a miner to create our address, without the miner actually knowing what our private key is? Well we use split vanity address generation, and where we can use a miner to create the required address sequence, without them knowing our private key.
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 [proof]
The following is a presentation on the topic [slides]: