The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Bitcoin::Crypto::Util - General Bitcoin utilities

SYNOPSIS

        use Bitcoin::Crypto::Util qw(
                validate_wif
                validate_segwit
                get_address_type
                get_key_type
                get_public_key_compressed
                generate_mnemonic
                mnemonic_from_entropy
                mnemonic_to_seed
                get_path_info
                to_format
                hash160
                hash256
        );

DESCRIPTION

These are basic utilities for working with Bitcoin. They do not fit well as a part of other, more specialized packages.

FUNCTIONS

validate_wif

        $bool = validate_wif($str);

Ensures Base58 encoded string looks like encoded private key in WIF format. Throws an exception if $str is not valid base58.

validate_segwit

        $segwit_version = validate_segwit($program)

Performs a segwit program validation on $program, which is expected to be a byte string in which the first byte is a segwit version.

The function returns the detected segwit program version. Note that it does not perform any more checks than ensuring the byte string is in correct format.

The current implementation is in line with validations for segwit versions 0 and 1. Future segwit version addresses will work just fine, but no special validation will be performed until implemented.

Raises an exception (Bitcoin::Crypto::Exception::SegwitProgram) on error. Returns the detected segwit program version.

get_address_type

        $type = get_address_type($address, $network = Bitcoin::Crypto::Network->get)

Tries to guess the type of $address. Returns P2PKH, P2SH, P2WPKH, P2WSH or P2TR. May throw Base58, Bech32, SegwitProgram, Address or other exceptions if the string is not a valid address.

get_key_type

        $is_private = get_key_type($bytestr);

Checks if the $bytestr looks like a valid ASN X9.62 format (compressed / uncompressed / hybrid public key or private key entropy up to curve size bits).

Returns boolean which states whether the key is private. Returns undef if $bytestr does not look like a valid key entropy.

get_public_key_compressed

        $is_compressed = get_public_key_compressed($bytestr);

Checks if the $bytestr looks like a valid ASN X9.62 format (compressed / uncompressed / hybrid public key).

Returns boolean which states whether the key is compressed. Returns undef if $bytestr does not look like a valid public key.

generate_mnemonic

        $mnemonic = generate_mnemonic($len = 128, $lang = 'en')

Generates a new mnemonic code using Bytes::Random::Secure. Default entropy is 128 bits. This can be increased up to 256 bits (increasing by 32 bits each step) with $len argument.

Other languages than english require installation of additional modules language-specific for Bitcoin::BIP39.

Returns newly generated BIP39 mnemonic string. Dies when $len is invalid (less than 128, more than 256 or not divisible by 32).

In some environments a problem may be encountered that causes the secure random bytes generator to block the program execution (See "BLOCKING ENTROPY SOURCE" in Bytes::Random::Secure). In this case you can use "mnemonic_from_entropy" and pass in entropy generated by Bytes::Random::Secure in non-blocking mode (via the OO interface).

mnemonic_from_entropy

        $mnemonic = mnemonic_from_entropy($bytes, $lang = 'en')

Generates a new mnemonic code from custom entropy given in $bytes (a bytestring). This entropy should be of the same bit size as in "generate_mnemonic". Returns newly generated BIP39 mnemonic string.

This can be useful to avoid relying on the underlying PRNG implementation used by Bitcoin::BIP39.

Another use would be implementing one's own entropy source that can be truly random, not just cryptographically-secure. A popular example would be capturing user's mouse movements.

Be aware that the method you use to generate a mnemonic will be a very important factor in your key's security. If possible, use real sources of randomness (not pseudo-random) or a cryptographically secure pseduo-random number generator like the one used by Bytes::Random::Secure.

mnemonic_to_seed

        $seed = mnemonic_to_seed($mnemonic, $password);

Transforms the given BIP39 $mnemonic and $password into a valid BIP32 $seed, which can be fed into "from_seed" in Bitcoin::Crypto::Key::ExtPrivate.

$seed is a 512 bit bytestring (64 characters). $mnemonic should be a BIP39 mnemonic, but will not be checked against a dictionary.

This function is only useful if you need a seed instead of mnemonic (for example, you use a wallet implementation which does not implement BIP39). If you only want to create a private key from mnemonic, you should consider using "from_mnemonic" in Bitcoin::Crypto::Key::ExtPrivate instead.

Important note about unicode: this function only accepts UTF8-decoded strings (both $mnemonic and $password), but can't detect whether it got it or not. This will only become a problem if you use non-ascii mnemonic and/or password. If there's a possibility of non-ascii, always use utf8 and set binmodes to get decoded (wide) characters to avoid problems recovering your wallet.

get_path_info

        $path_data = get_path_info($path);

Tries to get derivation path data from $path (like "m/1/3'"). Returns undef if $path is not a valid path, otherwise returns the structure:

        {
                private => bool, # is path derivation private (lowercase m)
                path => [
                        # derivation path with 2^31 added to every hardened child number
                        int, int, ..
                ],
        }

to_format

        $encoded = to_format [$format => $bytes];

Unpacks bytestring $bytes into the given $format. Use this to avoid manual unpacking.

Supported $format values are:

bytes, does nothing

hex, encodes as a hexadecimal string (no 0x prefix)

base58, uses base58 and includes the checksum (base58check)

hash160

        my $hash = hash160($data);

This is hash160 used by Bitcoin (RIPEMD160 of SHA256)

hash256

        my $hash = hash256($data);

This is hash256 used by Bitcoin (SHA256 of SHA256)

SEE ALSO

https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki

https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki