Bitcoinolog - Reason about Bitcoin addresses with Prolog
Elliptic Curves
An elliptic
curve over the finite field Fp is a set
of points (x,y) that satisfy the equation:
y2 = x3 + ax + b mod p
Such a curve is defined by the
parameters a, b, p. In addition,
a generator point G is given.
An elliptic curve is
an Abelian variety:
There is an operation called addition of points, which
forms
a group,
and multiplication of points by a scalar. The maximum
number of different points that can be obtained by multiplying the
generator by a scalar is called the order of
the curve.
Elliptic curves can be used for encryption
and signing. The signature algorithm based on elliptic
curves is called ECDSA.
A Prolog library for rudimentary reasoning about elliptic curves
is available: ecclog.pl
Note the use of declarative integer
arithmetic to
allow declarative debugging.
Bitcoin is
a cryptocurrency that uses ECDSA for signing
transactions.
Bitcoinolog
Bitcoinolog is a Prolog program for
reasoning about Bitcoin addresses:
bitcoinolog.pl
The source code is also available from a public git
repository: https://github.com/triska/bitcoinolog
You need Scryer Prolog to run it.
Bitcoinolog
uses library(crypto)
to compute various hashes, and to reason about
the named curve secp256k1,
which is used by Bitcoin.
Alternatively, you can also
use ecclog.pl for the required
operations over elliptic curves.
Video: |
|
Related: Cryptography with Prolog
Use cases of Bitcoinolog
Here are a few use cases Bitcoinolog:
- Offline Bitcoin wallet creation
To generate a public/private key pair, you can use
the Prolog predicates new_private_key/1
and private_key_to_public_key/2:
?- new_private_key(PrivateKey),
private_key_to_public_key(PrivateKey, PublicKey).
PrivateKey = 87443244391001342896527975361878627920717378785443876955045552084285386647786,
PublicKey = "020766fd4ffbbfa2086a96b335ba6eff24b58e4819936f8dc9d4002dabc9b11405".
Note that in ECDSA, a private key is an integer, and
the corresponding public key is a point on the curve.
In the above, the so-called compressed encoding of the
public key is used, which is recommended for Bitcoin as
of version 0.6.
- Convert public keys to Bitcoin addresses
As transaction targets, Bitcoin uses addresses
that are derived from public keys. You can use the
Prolog predicate public_key_to_address/2 to
convert a public key as shown above to its
corresponding address:
?- public_key_to_address("020766fd4ffbbfa2086a96b335ba6eff24b58e4819936f8dc9d4002dabc9b11405", Address).
Address = "1FVRX63gUDxkQ25C7ivMa27C9nT1DUafmD".
- Export private keys to Wallet Import Format (WIF)
To use those keys that you generate with Bitcoinolog
also with other programs, you can export
private keys to Wallet Import Format (WIF)
via the Prolog predicate private_key_to_wif/2.
For example:
?- private_key_to_wif(87443244391001342896527975361878627920717378785443876955045552084285386647786, WIF).
WIF = "L3hWTxRVjB9qzgdWQwcgWtSJZMzNnNvnWvajHstPuSPwzx2H4sbp".
Here is a Prolog query that indefinitely generates
private keys and corresponding Bitcoin addresses:
?- repeat,
new_private_key(PrivateKey),
private_key_to_wif(PrivateKey, WIF),
private_key_to_public_key(PrivateKey, PublicKey),
public_key_to_address(PublicKey, Address),
format:portray_clause((address_key(A, K) :- A=Address, K=WIF)),
false.
It yields output like:
address_key(A, B) :-
A="1Fo9WojzYwhfjqQKQDWQyehxWyMJVhySBA",
B="Ky91qbBbHnrozFkJRFBA6KQG8hzctWPRKGWd3kRxX1ajVKEzmrSp".
address_key(A, B) :-
A="1HQXkmyUPnhXdzk1gacXzCLx3mV6843ncN",
B="L3yC2Bf2Ko3nLW61vkhqJia18QkTJb3KGxQJ6fWSNa4o7x71JNXU".
address_key(A, B) :-
A="1FMuyjrVi7DUDFrThZNcNkBG8bq1YNfqiG",
B="Kxmburb4FiNQHnaWf6e8mTDJUnCaUzuXaHM5TeeKiTjpT2bPCNBR".
address_key(A, B) :-
A="1FeQG4oBfWA3HCaiEKyeaGWQRLazwzmaUy",
B="L4EresJ9xiC7JzbXV3gU7SpUsenqq12ZxonYFYHr6c9GSt3RKyVA".
etc.
More about Prolog: The Power of Prolog
Main page