Generating a private key from a random number
Creating a bitcoin key is essentially the same as “Pick a number between 1 and 2256.” The exact method you use to pick that number does not matter as long as it is not predictable or repeatable.
More precisely, the private key can be any number between 0 and n – 1 inclusive, where n is a constant (n = 1.1578 * 1077, slightly less than 2256) defined as the order of the elliptic curve used in bitcoin
Value of 2256 in decimal
$ python3 >>> 2 ** 256 115792089237316195423570985008687907853269984665640564039457584007913129639936 >>> len('115792089237316195423570985008687907853269984665640564039457584007913129639936') 78
Max value of bitcoin private key 1.1578 * 1077 in decimal
>>> 10**73 * 11578 115780000000000000000000000000000000000000000000000000000000000000000000000000
Bitcoin private key range in decimal:
0 to 115780000000000000000000000000000000000000000000000000000000000000000000000000
This 256-bit number can be represented in several formats: in hexadecimal – 256 bits, in hexadecimal is 32 bytes, or 64 characters in the range 0-9 or A-F, Base64 string, a WIF key, or a mnemonic phrase.
Generating with standard RNG
$ python3 >>> import random >>> bits = random.getrandbits(256) >>> bits 18637599346649113490923573892016445555865372454431646970278647587660986165059 >>> bits_hex = hex(bits) >>> bits_hex '0x293481e54e6f6a9cf3e3eced7a2067858fec3bf38beb2f96a80d17159cd9a743' >>> private_key '293481e54e6f6a9cf3e3eced7a2067858fec3bf38beb2f96a80d17159cd9a743'
The generated string is based on a seed, the seed represents the current time so several brute-force attacks can be applied to it
Cryptographically strong RNG
The entropy is generated directly from the operating system to make it more difficult to reproduce.
$ python3 >>> import secrets >>> bits = secrets.randbits(256) >>> bits 44021681257556267495323874456560941351085360348283269924856348981472949690647 >>> bits_hex = hex(bits) >>> bits_hex '0x6153637cd75eb501891a85b16bdf791e0b07e90903c6edf6c51efb09dd3be117' >>> private_key = bits_hex[2:] >>> private_key '6153637cd75eb501891a85b16bdf791e0b07e90903c6edf6c51efb09dd3be117'
Using bitcore-lib
$ node > const bitcore = require('bitcore-lib') > randNum = bitcore.crypto.BN.fromBuffer(bitcore.crypto.Random.getRandomBuffer(32)) > const privateKey = new bitcore.PrivateKey(randNum) > privateKey.toString() 'fc41827b5b37da605124c82646cfca78af05018e33a8c3bb59cb3100e3d3c71d' > privateKey.toWIF() 'L5g4dUGyE6XukN5WHnkMq2pCPNBiZMXVHVdfLEXxfsukGystL4Fc' > privateKey.toJSON() { bn: 'fc41827b5b37da605124c82646cfca78af05018e33a8c3bb59cb3100e3d3c71d', compressed: true, network: 'livenet' }
Create PrivateKey object form WIF format string and generate public key
> const privateKey = bitcore.PrivateKey.fromWIF('L5g4dUGyE6XukN5WHnkMq2pCPNBiZMXVHVdfLEXxfsukGystL4Fc') > const publicKey = privateKey.toPublicKey() > publicKey.toString() '021727d63e7f8032d9e0a7f2ec452199435500bfa23ad2bbf9a36f046390cbfa2a' > publicKey.toJSON() { x: '1727d63e7f8032d9e0a7f2ec452199435500bfa23ad2bbf9a36f046390cbfa2a', y: '012252fc198a93a394383c463383959a635a7bebd168f685603d450056b0b5b2', compressed: true }
Generate bitcoin address from private key and public key
> privateKey.toAddress().toString() '1FdM5HRNSgc5wCTKdFLPTGh27uNcTgyXN1' > publicKey.toAddress().toString() '1FdM5HRNSgc5wCTKdFLPTGh27uNcTgyXN1'
Generating a Public Key
Starting with a private key in the form of a randomly generated numberk, we multiply it by a predetermined point on the curve called thegenerator pointGto produce another point somewhere else on the curve, which is the corresponding public keyK. The generator point is specified as part of the secp256k1 standard and is always the same for all keys in bitcoin: {K = k * G}
where k is the private key, G is the generator point, and K is the resulting public key, a point on the curve.
PublicKey = PrivateKey * Generator/PredeterminedPoint => AnotherPointInTheCurve K = kG = (x, y)
In elliptic curves, adding a point to itself is the equivalent of drawing a tangent line on the point and finding where it intersects the curve again, then reflecting that point on the x-axis. Most bitcoin implementations use theOpenSSL cryptographic libraryto do the elliptic curve math.