Bitcoin Private/Public Key and Address Example

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
>>> len('115792089237316195423570985008687907853269984665640564039457584007913129639936')
Max value of bitcoin private key 1.1578 * 1077 in decimal
>>> 10**73 * 11578
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

>>> bits_hex = hex(bits)
>>> bits_hex

>>> private_key

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

>>> bits_hex = hex(bits)
>>> bits_hex

>>> private_key = bits_hex[2:]
>>> private_key

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()

> privateKey.toWIF()

> 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()

> publicKey.toJSON()
x: '1727d63e7f8032d9e0a7f2ec452199435500bfa23ad2bbf9a36f046390cbfa2a',
y: '012252fc198a93a394383c463383959a635a7bebd168f685603d450056b0b5b2',
compressed: true
Generate bitcoin address from private key and public key
> privateKey.toAddress().toString()

> publicKey.toAddress().toString()

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.




Leave a Comment

Your email address will not be published. Required fields are marked *