Bitcoin

From Leo's Notes
Revision as of 07:54, 24 September 2015 by Leo (talk | contribs) (→Brain Wallets)
This page was last edited on 24 September 2015, at 07:54.

Bitcoin is a proof of work cryptocurrency.

This article covers some specific aspects of the Bitcoin protocol.

My Bitcoin Address is: 1HDp1gU3rgrRNKqrKorz8uWCpHUNdyGqXm

Overview

Bitcoin is a decentralized protocol that operates in an untrusted peer to peer environment while still being a reliable method to exchange credits (bitcoins) between people.

For detailed information, read the Bitcoin paper or one of the many sites out there.

Hashes & Encoding

You will see hashes as part of the Bitcoin protocol everywhere.

Types of Hashes

Here are a few common hashes you will encounter.

40 character long / 160-bit value

37f332f68db77bd9d7edd4969571ad671cf9dd3b

Generated using RIPEMD-160

64 character long / 256-bit value

600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408

Generated using SHA256 of any number of rounds. This is typically seen as a transaction ID. The private key of an address also uses a 256-bit value.

130 character long

0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6

The private key of an address

Hash160 (Transactions)

Transaction numbers are represented using Hash160 of the public key. That is:

TransactionID = Hash160 = RIPEMD160(SHA256(PubKey))

It is outputted as a 160-bit value in hex (64 characters long). For example:

49123c475ef78814414f1318eff0a349bcbafd182d8b3e110684152ee0e44081

Hash

Hashes in Bitcoin are done using two rounds of SHA256.

Hash = SHA256(SHA256(X))

Base58Check

Base58Check is used to generate Bitcoin addresses.

Address / Keys

A Bitcoin address is a 160-bit hash of the ECDSA public/private keypair.

Generating An Address

  1. Take a random 160-bit value as the private key.
  2. Generate a public key with it
  3. Hash = SHA256(PublicKey)
  4. Hash160 = RIPEMD160(Hash)
  5. Address = Base58Check(Hash160)

Where Base58Check takes a Hash160 hash value:

  1. BaseAddress = 00 + RIPEMD160(Hash160)
  2. Check = SHA256(SHA256(BaseAddress))
  3. FinalAddress = BaseAddress + (first 4 bytes of Check)
  4. Address = Base58CheckEncode(FinalAddress)

See Also: https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses

Brain Wallets

A brain wallet allows for the generation of the public/private key pair using a passphrase. It is accomplished by:

  1. Converting a pass phrase into a private key
    • PrivateKey = SHA256(PassPhrase)
  2. Generate a public key using the private key
    • PublicKey = privateToPublic(PrivateKey)
  3. Generate the bitcoin address
    • Hash = SHA256(PublicKey)
    • Hash160 = RIPEMD160(Hash) (used by transactions)
    • Address = Base58Check(Hash160)

The publickey can either be uncompressed or compressed. A compressed public key is simply a truncated key where the missing parts can be recomputed.

Attack

Ryan Castellucci did a talk on Defcon 23 on cracking brain wallets using his program called Brainflayer, available at https://github.com/ryancdotorg/brainflayer.

The basic idea is to extract all unique addresses in the bitcoin system. Dump the addresses into a bloom filter for almost constant time search, then use Brainflayer to bruteforce check on a word list that matches a specific address hash.

That is:

  1. get all Bitcoin Addresses as Hash160 > hashes.hex
  2. hex2blf hashes.hex hashes.blf
  3. brainflayer -b hashes.blf -i phraselist.txt
  4. or cat password.txt | brainflayer -b hashes.blf
  5. or john --incremental --stdout | brainflayer -b hashes.blf

Key Stretching

To make brain wallets stronger, the key generation can be made to be more expensive and thereby limiting the number of tries an attacker can made per second.