<commit_before>bip38
=====

Partial [BIP 0038](https://en.bitcoin.it/wiki/BIP_0038) implementation and cracker written in Go. Exported functions are `DecryptWithPassphrase` and `Brute`. The former decrypts a BIP 0038-encrypted private key given the passphrase, returning the private key in a hex string, or the empty string on failure. `Brute` attempts to brute force a Bitcoin private key that has been passphrase-protected with BIP 0038 (currently hardcoded for a passphrase length of 3 characters - see TODO below). Designed to attempt puzzles such as:

* http://www.reddit.com/r/Bitcoin/comments/1q5wu7/this_paper_wallet_contains_01125_btc_and_is_bip/
* https://bitcointalk.org/index.php?topic=128699.0

I'm writing this primarily as an exercise to learn Go, and also to learn more about the inner workings of Bitcoin.

TODO
----

* Remove gocoin dependency (currently only used for base58 decoding, and passpoint & address calculation)
* Catch panic case when all goroutines return without finding the passphrase (i.e. brute force failure)
* Optimise searchRange when not starting at 0, and add in support for variable-length passphrases
* Proper support for brute forcing over a given character set, rather than a hardcoded value
* Implement decryption when EC multiply mode not used (and write tests)
* Add proper doc comments to code

Note about cracking
-------------------

The first argument to `Brute` is an integer number of goroutines to call while attempting the brute force search. For best results, set this to the number of cores you have available on your machine. Also make sure you set the `GOMAXPROCS` environment variable to this value before compiling! Otherwise your program will only run on a single core (by default), regardless of what you set `routines` to.

On my quad-core Intel i5-2500K, I get speeds of about 10 keys/second when brute forcing a 3 character passphrase over the printable ASCII characters.

Example
-------

    package main
    <commit_msg>Reorder TODO list and other README tweaks<commit_after>bip38
=====

Partial [BIP 0038](https://en.bitcoin.it/wiki/BIP_0038) implementation and cracker written in Go. Exported functions are `DecryptWithPassphrase` and `Brute`. The former decrypts a BIP 0038-encrypted private key given the passphrase, returning the private key in a hex string, or the empty string on failure. `Brute` attempts to brute force a Bitcoin private key that has been passphrase-protected with BIP 0038 (currently hardcoded for a passphrase length of 3 characters - see TODO below). Designed to attempt puzzles such as:

* http://www.reddit.com/r/Bitcoin/comments/1q5wu7/this_paper_wallet_contains_01125_btc_and_is_bip/
* https://bitcointalk.org/index.php?topic=128699.0

I'm writing this primarily as an exercise to learn Go, and also to learn more about the inner workings of Bitcoin.

TODO
----

* Proper support for brute forcing over a given character set, rather than a hardcoded value
* Support for variable-length passphrases, or to search a given length range
* Catch panic case when all goroutines return without finding the passphrase (i.e. brute force failure)
* Implement decryption when EC multiply mode not used (and write tests)
* Add proper doc comments to code
* Optimise searchRange when not starting at 0
* Remove gocoin dependency (currently only used for base58 decoding, and passpoint & address calculation)

Note about cracking
-------------------

The first argument to `Brute` is an `int` number of goroutines to call while attempting the brute force search. For best results, set this to the number of cores you have available on your machine. Also make sure you set the `GOMAXPROCS` environment variable to this value before compiling! Otherwise your program will only run on a single core (by default), regardless of what you set `routines` to.

On my quad-core Intel i5-2500K, I get speeds of about 10 keys/second when brute forcing a 3 character passphrase over the printable ASCII characters.

Example
-------

    package main
    
{'fraction_non_alphanumeric': 0.06527674360883594, 'fraction_numerical': 0.022338049143708117, 'mean_word_length': 4.316622691292876, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5226439', 'n_tokens_mistral': 1146, 'n_tokens_neox': 1047, 'n_words': 552}