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
	from_format
	to_format
	pack_compactsize
	unpack_compactsize
	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, which can be a string like "m/1/3'" or an object which implements get_derivation_path method (and does Bitcoin::Crypto::Role::WithDerivationPath). Returns undef if $path is not a valid path, otherwise returns the structure as an instance of Bitcoin::Crypto::DerivationPath:

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

You may also use "DerivationPath" in Bitcoin::Crypto::Types type and its coercions to achieve the same effect (but with an exception instead of undef on failure).

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)

  • base64, uses base64

from_format

$decoded = from_format [$format => $string];

Reverse of "to_format" - decodes $string into bytestring, treating it as $format.

Note: this is not usually needed to be called explicitly, as every bytestring parameter of the module will do this conversion implicitly.

pack_compactsize

$bytestr = pack_compactsize($integer);

Serializes $integer as Bitcoin's CompactSize format and returns it as a byte string.

unpack_compactsize

$integer = unpack_compactsize($bytestr, $pos = undef);

Deserializes CompactSize from $bytestr, returning an integer.

If $pos is passed, it must be a reference to a scalar containing the position at which to start the decoding. It will be modified to contain the next position after the CompactSize. If not, decoding will start at 0 and will raise an exception if $bytestr contains anything other than CompactSize.

hash160

$hash = hash160($data);

This is hash160 used by Bitcoin (RIPEMD160 of SHA256)

hash256

$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