Source code for helium_py.crypto.utils

"""Utility methods for cryptography."""
import binascii
from typing import Tuple

import nacl.bindings
import nacl.encoding
from base58 import b58decode, b58encode
from nacl.hash import sha256

EMPTY_SIGNATURE = bytes([0]*64)


[docs]def random_bytes(n: int) -> bytes: """Return random bytes of size n.""" return nacl.bindings.randombytes(n)
[docs]def bytes_to_binary(byte_array: bytes) -> str: """Return binary from provided bytes.""" return ''.join([format(byte_data, '08b') for byte_data in byte_array])
[docs]def derive_checksum_bits(entropy: bytes): """Return checksum bits from entropy bytes.""" ent = len(entropy) * 8 cs = int(ent / 32) hash_val = sha256(entropy) return bytes_to_binary(binascii.unhexlify(hash_val))[:cs]
[docs]def bs58_check_encode(version: int, binary: bytes) -> bytes: """Return endoed Base58 address from version and bytes.""" versioned_payload = bytes([version]) + binary checksum = sha256(binascii.unhexlify(sha256(versioned_payload))) checksum_bytes = bytes(binascii.unhexlify(checksum[:8])) result = versioned_payload + checksum_bytes return b58encode(result)
[docs]def bs58_to_bin(bs58_address: bytes) -> bytes: """Return decoded bytes from Base58 address bytes.""" bs58_bin = b58decode(bs58_address) versioned_payload = bs58_bin[0:-4] payload = bs58_bin[1:-4] checksum = binascii.hexlify(bs58_bin[-4:]) checksum_verify = sha256(binascii.unhexlify(sha256(versioned_payload)))[:8] if checksum_verify != checksum: raise ValueError('Invalid checksum') return payload
[docs]def byte_to_net_type_and_key_type(byte_val: int) -> Tuple[int, int]: """Return network type and key type in a tuple from byte value.""" return byte_to_net_type(byte_val), byte_to_key_type(byte_val)
[docs]def byte_to_net_type(byte_val: int) -> int: """Return network type from byte value.""" return byte_val & 240
[docs]def byte_to_key_type(byte_val: int) -> int: """Return key type from byte value.""" return byte_val & 15
[docs]def bs58_net_type(bs58_address: bytes) -> int: """Return network type from bs58 address.""" bs58_bin = bs58_to_bin(bs58_address) byte_val = bs58_bin[0] return byte_to_net_type(byte_val)
[docs]def bs58_key_type(bs58_address: bytes) -> int: """Return key type from bs58 address.""" bs58_bin = bs58_to_bin(bs58_address) byte_val = bs58_bin[0] return byte_to_key_type(byte_val)
[docs]def bs58_version(bs58_address: bytes) -> int: """Return version from bs58 address.""" bs58_bin = b58decode(bs58_address) version = bs58_bin[0] return version
[docs]def bs58_public_key(bs58_address: bytes) -> bytes: """Return public key from bs58 address.""" bs58_bin = bs58_to_bin(bs58_address) public_key = bs58_bin[1:] return public_key