Skip to content
/ bip38 Public

Partial BIP 0038 implementation and cracker written in Go

License

Notifications You must be signed in to change notification settings

chigley/bip38

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bip38

Partial 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:

I'm writing this primarily as an exercise to learn Go, and also to learn more about the inner workings of Bitcoin. In the future, I may extend this to be a full implementation of BIP 0038 (including encryption). It'd also be quite fun to experiment with making a distributed brute forcer.

TODO

  • Support for brute forcing over a given character set, rather than a hardcoded charset value
  • Support for variable-length passphrases, rather than a hardcoded length value of 3
  • 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

import (
	"fmt"
	"github.com/chigley/bip38"
)

func main() {
	privKey := bip38.DecryptWithPassphrase("6PfQu77ygVyJLZjfvMLyhLMQbYnu5uguoJJ4kMCLqWwPEdfpwANVS76gTX", "TestingOneTwoThree")
	fmt.Printf("%s", privKey)
	// a43a940577f4e97f5c4d39eb14ff083a98187c64ea7c99ef7ce460833959a519

	result := bip38.Brute(4, "6PfYWMgNPboK3PQ1D5mNqaKxRmD9j7Wooi2wLmjVM2Ze776Qx3tyMR26pq")
	fmt.Printf("%s", result)
	// 6d0507ca41e06bd1a9297e82d1a1f6ee9a824b14bb5170873ef7ca8296701f7f (  !)
}

See also

About

Partial BIP 0038 implementation and cracker written in Go

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages