import hashlib import hmac from typing import ( Union, ) import unicodedata from eth_keys import ( keys, ) from eth_utils import ( ValidationError, ) from hexbytes import ( HexBytes, ) PBKDF2_ROUNDS = 2048 SECP256K1_N = int( "FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_BAAEDCE6_AF48A03B_BFD25E8C_D0364141", 16 ) def unicode_decompose_string(txt: Union[str, bytes]) -> str: if isinstance(txt, bytes): utxt = txt.decode("utf8") elif isinstance(txt, str): utxt = txt else: raise ValidationError("String value expected") return unicodedata.normalize("NFKD", utxt) def unicode_compose_string(txt: Union[str, bytes]) -> str: if isinstance(txt, bytes): utxt = txt.decode("utf8") elif isinstance(txt, str): utxt = txt else: raise ValidationError("String value expected") return unicodedata.normalize("NFKC", utxt) def sha256(data: bytes) -> bytes: return hashlib.sha256(data).digest() def hmac_sha512(chain_code: bytes, data: bytes) -> bytes: """ As specified by RFC4231 - https://tools.ietf.org/html/rfc4231 . """ return hmac.new(chain_code, data, hashlib.sha512).digest() def pbkdf2_hmac_sha512(passcode: str, salt: str) -> bytes: return hashlib.pbkdf2_hmac( "sha512", passcode.encode("utf-8"), salt.encode("utf-8"), PBKDF2_ROUNDS, ) def ec_point(pkey: bytes) -> bytes: """ Compute `point(p)`, where `point` is ecdsa point multiplication. Note: Result is ecdsa public key serialized to compressed form """ return keys.PrivateKey(HexBytes(pkey)).public_key.to_compressed_bytes()