def EncodeKey(pub_key: Union[bytes, IPublicKey], **kwargs: Any) -> str: """ Encode a public key to P2PKH address. Args: pub_key (bytes or IPublicKey): Public key bytes or object Other Parameters: net_ver (bytes) : Net address version base58_alph (Base58Alphabets, optional): Base58 alphabet, Bitcoin alphabet by default Returns: str: Address string Raises: ValueError: If the public key is not valid TypeError: If the public key is not secp256k1 """ net_ver_bytes = kwargs["net_ver"] base58_alph = kwargs.get("base58_alph", Base58Alphabets.BITCOIN) pub_key_mode = kwargs.get("pub_key_mode", P2PKHPubKeyModes.COMPRESSED) pub_key_obj = AddrKeyValidator.ValidateAndGetSecp256k1Key(pub_key) pub_key_bytes = (pub_key_obj.RawCompressed().ToBytes() if pub_key_mode == P2PKHPubKeyModes.COMPRESSED else pub_key_obj.RawUncompressed().ToBytes()) return Base58Encoder.CheckEncode( net_ver_bytes + CryptoUtils.Hash160(pub_key_bytes), base58_alph)
def GenerateIntermediatePassphrase(passphrase: str, lot_num: Optional[int] = None, sequence_num: Optional[int] = None) -> str: """ Generate an intermediate passphrase from the user passphrase as specified in BIP38. Args: passphrase (str) : Passphrase lot_num (int, optional) : Lot number sequence_num (int, optional): Sequence number Returns: str: Intermediate passphrase encoded in base58 """ # Get if lot and sequence are used has_lot_seq = lot_num is not None and sequence_num is not None # Compute owner entropy and salt # We can ignore the mypy warning because has_lot_seq checks for variables for being not None owner_entropy = (_Bip38EcUtils.OwnerEntropyWithLotSeq(lot_num, sequence_num) # type: ignore if has_lot_seq else _Bip38EcUtils.OwnerEntropyNoLotSeq()) # Compute passpoint passfactor = _Bip38EcUtils.PassFactor(passphrase, owner_entropy, has_lot_seq) passpoint = _Bip38EcUtils.PassPoint(passfactor) # Get magic magic = Bip38EcConst.INT_PASS_MAGIC_WITH_LOT_SEQ if has_lot_seq else Bip38EcConst.INT_PASS_MAGIC_NO_LOT_SEQ # Build and encode intermediate passphrase return Base58Encoder.CheckEncode(magic + owner_entropy + passpoint)
def EncodeKey(pub_key: Union[bytes, IPublicKey], **kwargs: Any) -> str: """ Encode a public key to Tezos address. Args: pub_key (bytes or IPublicKey): Public key bytes or object Other Parameters: prefix (XtzAddrPrefixes): Address prefix Returns: str: Address string Raises: ValueError: If the public key is not valid TypeError: If the public key is not ed25519 or the prefix is not a XtzAddrPrefixes enum """ # Get and check prefix prefix = kwargs["prefix"] if not isinstance(prefix, XtzAddrPrefixes): raise TypeError( "Address type is not an enumerative of XtzAddrPrefixes") # Get public key pub_key_obj = AddrKeyValidator.ValidateAndGetEd25519Key(pub_key) # Compute Blake2b and encode in base58 with checksum blake_bytes = CryptoUtils.Blake2b( pub_key_obj.RawCompressed().ToBytes()[1:], digest_size=XtzAddrConst.BLAKE2B_BYTE_LEN) return Base58Encoder.CheckEncode(prefix.value + blake_bytes)
def Encode(key_bytes, compr_pub_key = True, net_addr_ver = BitcoinConf.WIF_NET_VER.Main()): """ Encode key bytes into a WIF string. Args: key_bytes (bytes) : Key bytes compr_pub_key (bool) : True if private key corresponds to a compressed public key, false otherwise net_addr_ver (bytes, optional): Net address version, default is Bitcoin main network Returns: str: WIF encoded string Raises: ValueError: If the key is not valid """ # Check key if not KeyUtils.IsPrivate(key_bytes): raise ValueError("Invalid key (%s)" % ConvUtils.BytesToHexString(key_bytes)) # Add suffix if correspond to a compressed public key if compr_pub_key: key_bytes += WifConst.COMPR_PUB_KEY_SUFFIX # Add net address version key_bytes = net_addr_ver + key_bytes # Encode key return Base58Encoder.CheckEncode(key_bytes)
def __CreatePda(seeds_with_bump: List[bytes], program_id_bytes: bytes) -> str: """ Create a PDA (Program Derived Address) for the specified seeds and program ID. Args: seeds_with_bump (list[bytes]): List of seeds bytes with bump program_id_bytes (bytes) : Program ID bytes Returns: str: Created PDA Raises: ValueError: If the created PDA is not valid """ sha256 = Sha256() # Compute SHA256 of seeds with bump for seed in seeds_with_bump: sha256.Update(seed) # Compute SHA256 of program ID and PDA marker for elem in (program_id_bytes, SplTokenConst.PDA_MARKER): sha256.Update(elem) # Get PDA bytes pda_bytes = sha256.Digest() # A PDA shall NOT lie on the ed25519 curve, so it shall not be a valid public key if Ed25519PublicKey.IsValidBytes(pda_bytes): raise ValueError("Invalid created PDA") return Base58Encoder.Encode(pda_bytes)
def EncodeKey(pub_key: Union[bytes, IPublicKey], **kwargs: Any) -> str: """ Encode a public key to Neo address. Args: pub_key (bytes or IPublicKey): Public key bytes or object Other Parameters: ver (bytes): Version Returns: str: Address string Raises: ValueError: If the public key is not valid TypeError: If the public key is not ed25519 """ ver_bytes = kwargs["ver"] pub_key_obj = AddrKeyValidator.ValidateAndGetNist256p1Key(pub_key) # Get payload payload_bytes = (NeoAddrConst.PREFIX + pub_key_obj.RawCompressed().ToBytes() + NeoAddrConst.SUFFIX) # Encode to base58 return Base58Encoder.CheckEncode(ver_bytes + CryptoUtils.Hash160(payload_bytes))
def Serialize(key_bytes: bytes, key_net_ver: bytes, depth: int, fprint: bytes, index: int, chain: bytes) -> str: """ Serialize the specified key bytes. Args: key_bytes (bytes) : Key bytes key_net_ver (bytes): Key net version depth (int): Key depth fprint (bytes): Key fingerprint index (int): Key index chain (bytes): Key chain code Returns: str: Serialized key """ # Get bytes for serializing depth = depth.to_bytes(1, "big") index = index.to_bytes(4, "big") # Serialize key ser_key = key_net_ver + depth + fprint + index + chain + key_bytes # Encode it return Base58Encoder.CheckEncode(ser_key)
def GeneratePrivateKey(int_passphrase: str, pub_key_mode: Bip38PubKeyModes) -> str: """ Generate a random encrypted private key from the intermediate passphrase. Args: int_passphrase (str) : Intermediate passphrase pub_key_mode (Bip38PubKeyModes): Public key mode Returns: str: Encrypted private key Raises: Base58ChecksumError: If base58 checksum is not valid ValueError: If the intermediate code is not valid """ # Decode intermediate passphrase int_passphrase_bytes = Base58Decoder.CheckDecode(int_passphrase) # Check length if len(int_passphrase_bytes) != Bip38EcConst.INT_PASS_ENC_BYTE_LEN: raise ValueError(f"Invalid intermediate code length ({len(int_passphrase_bytes)})") # Get all the parts back magic = int_passphrase_bytes[:8] owner_entropy = int_passphrase_bytes[8:16] passpoint = Secp256k1PublicKey.FromBytes(int_passphrase_bytes[16:]) # Check magic if magic not in (Bip38EcConst.INT_PASS_MAGIC_NO_LOT_SEQ, Bip38EcConst.INT_PASS_MAGIC_WITH_LOT_SEQ): raise ValueError(f"Invalid magic ({BytesUtils.ToHexString(magic)})") # Generate seedb seedb = os.urandom(Bip38EcConst.SEED_B_BYTE_LEN) # Compute factorb from seedb factorb = CryptoUtils.DoubleSha256(seedb) # Compute address hash address_hash = Bip38Addr.AddressHash( Secp256k1PublicKey.FromPoint(passpoint.Point() * BytesUtils.ToInteger(factorb)), pub_key_mode ) # Derive key halves from the passpoint, address hash and owner entropy derived_half_1, derived_half_2 = _Bip38EcUtils.DeriveKeyHalves(passpoint.RawCompressed().ToBytes(), address_hash, owner_entropy) # Encrypt seedb in two parts encrypted_part_1, encrypted_part_2 = Bip38EcKeysGenerator.__EncryptSeedb(seedb, derived_half_1, derived_half_2) # Get flagbyte by setting bits flagbyte = Bip38EcKeysGenerator.__SetFlagbyteBits(magic, pub_key_mode) # Concatenate all parts enc_key_bytes = (Bip38EcConst.ENC_KEY_PREFIX + flagbyte + address_hash + owner_entropy + encrypted_part_1[:8] + encrypted_part_2) # Encode in Base58Check return Base58Encoder.CheckEncode(enc_key_bytes)
def EncodeKey(pub_key: Union[bytes, IPublicKey], **kwargs: Any) -> str: """ Encode a public key to Solana address. Args: pub_key (bytes or IPublicKey): Public key bytes or object **kwargs : Not used Returns: str: Address string Raises: ValueError: If the public key is not valid TypeError: If the public key is not ed25519 """ pub_key_obj = AddrKeyValidator.ValidateAndGetEd25519Key(pub_key) return Base58Encoder.Encode(pub_key_obj.RawCompressed().ToBytes()[1:])
def Encrypt(priv_key: Union[bytes, IPrivateKey], passphrase: str, pub_key_mode: Bip38PubKeyModes) -> str: """ Encrypt the specified private key. Args: priv_key (bytes or IPrivateKey): Private key bytes or object passphrase (str) : Passphrase pub_key_mode (Bip38PubKeyModes): Public key mode Returns: str: Encrypted private key Raises: TypeError: If the private key is not a Secp256k1PrivateKey ValueError: If the private key bytes are not valid """ # Convert to private key to check if bytes are valid if isinstance(priv_key, bytes): priv_key = Secp256k1PrivateKey.FromBytes(priv_key) elif not isinstance(priv_key, Secp256k1PrivateKey): raise TypeError("A secp256k1 private key is required") # Compute address hash priv_key_bytes = priv_key.Raw().ToBytes() address_hash = _Bip38NoEcUtils.AddressHash(priv_key_bytes, pub_key_mode) # Derive key halves from the passphrase and address hash derived_half_1, derived_half_2 = _Bip38NoEcUtils.DeriveKeyHalves( passphrase, address_hash) # Encrypt private key in two halves encrypted_half_1, encrypted_half_2 = Bip38NoEcEncrypter.__EncryptPrivateKey( priv_key_bytes, derived_half_1, derived_half_2) # Get flagbyte flagbyte = (Bip38NoEcConst.FLAGBYTE_COMPRESSED if pub_key_mode == Bip38PubKeyModes.COMPRESSED else Bip38NoEcConst.FLAGBYTE_UNCOMPRESSED) # Concatenate all parts enc_key_bytes = Bip38NoEcConst.ENC_KEY_PREFIX + flagbyte + address_hash + encrypted_half_1 + encrypted_half_2 # Encode in Base58Check return Base58Encoder.CheckEncode(enc_key_bytes)
def ToAddress(pub_key_bytes): """ Get address in Tron format. Args: pub_key_bytes (bytes): Public key bytes Returns: str: Address string Raised: ValueError: If the key is not a public uncompressed key """ # Get address in Ethereum format (remove "0x" at the beginning) addr = EthAddr.ToAddress(pub_key_bytes)[2:] # Add prefix and encode return Base58Encoder.CheckEncode(binascii.unhexlify(TrxAddrConst.PREFIX + addr))
def ToAddress(pub_key_bytes, net_addr_ver=BitcoinConf.P2SH_NET_VER.Main()): """ Get address in P2SH format. Args: pub_key_bytes (bytes) : Public key bytes net_addr_ver (bytes, optional): Net address version, default is Bitcoin main network Returns: str: Address string Raises: ValueError: If the key is not a public compressed key """ if not KeyUtils.IsPublicCompressed(pub_key_bytes): raise ValueError("Public compressed key is required for P2SH") # Final address: Base58Check(addr_prefix | address_bytes) return Base58Encoder.CheckEncode(net_addr_ver + P2SHUtils.AddScriptSig(pub_key_bytes))
def Serialize(key_bytes: bytes, key_data: Bip32KeyData, key_net_ver_bytes: bytes) -> str: """ Serialize the specified key bytes. Args: key_bytes (bytes) : Key bytes key_data (BipKeyData object): Key data key_net_ver_bytes (bytes) : Key net version bytes Returns: str: Serialized key """ # Serialize key ser_key = (key_net_ver_bytes + bytes(key_data.Depth()) + bytes(key_data.ParentFingerPrint()) + bytes(key_data.Index()) + bytes(key_data.ChainCode()) + key_bytes) # Encode it return Base58Encoder.CheckEncode(ser_key)
def ToAddress(pub_key_bytes, net_addr_ver=BitcoinConf.P2PKH_NET_VER.Main(), base58_alph=Base58Alphabets.BITCOIN): """ Get address in P2PKH format. Args: pub_key_bytes (bytes) : Public key bytes net_addr_ver (bytes, optional) : Net address version, default is Bitcoin main network base58_alph (Base58Alphabets, optional): Base58 alphabet, Bitcoin by default Returns: str: Address string Raises: ValueError: If the key is not a public compressed key """ if not KeyUtils.IsPublicCompressed(pub_key_bytes): raise ValueError("Public compressed key is required for P2PKH") return Base58Encoder.CheckEncode( net_addr_ver + CryptoUtils.Hash160(pub_key_bytes), base58_alph)
def Encode(data_bytes: bytes, ss58_format: int) -> str: """ Encode bytes into a SS58 string. Args: data_bytes (bytes): Data bytes (32-byte length) ss58_format (int) : SS58 format Returns: str: SS58 encoded string Raises: ValueError: If parameters are not valid """ # Check parameters if len(data_bytes) != SS58Const.DATA_BYTE_LEN: raise ValueError(f"Invalid data length ({len(data_bytes)})") if ss58_format < 0 or ss58_format > SS58Const.FORMAT_MAX_VAL: raise ValueError(f"Invalid SS58 format ({ss58_format})") if ss58_format in SS58Const.RESERVED_FORMATS: raise ValueError(f"Invalid SS58 format ({ss58_format})") # Simple account if ss58_format <= SS58Const.SIMPLE_ACCOUNT_FORMAT_MAX_VAL: ss58_format_bytes = IntegerUtils.ToBytes(ss58_format) # Full address else: # 0b00HHHHHH_MMLLLLLL -> (0b01LLLLLL, 0bHHHHHHMM) ss58_format_bytes = bytes([ ((ss58_format & 0x00FC) >> 2) | 0x0040, (ss58_format >> 8) | ((ss58_format & 0x0003) << 6) ]) # Get payload payload = ss58_format_bytes + data_bytes # Compute checksum checksum = _SS58Utils.ComputeChecksum(payload) # Encode return Base58Encoder.Encode(payload + checksum)
def EncodeKey(pub_key: Union[bytes, IPublicKey], **kwargs: Any) -> str: """ Encode a public key to Tron address. Args: pub_key (bytes or IPublicKey): Public key bytes or object **kwargs : Not used Returns: str: Address string Raised: ValueError: If the public key is not valid TypeError: If the public key is not secp256k1 """ # Get address in Ethereum format (remove "0x" at the beginning) eth_addr = EthAddrEncoder.EncodeKey(pub_key)[2:] # Add prefix and encode return Base58Encoder.CheckEncode( CoinsConf.Tron.Params("addr_prefix") + BytesUtils.FromHexString(eth_addr))
def EncodeKey(pub_key: Union[bytes, IPublicKey], **kwargs: Any) -> str: """ Encode a public key to P2SH address. Args: pub_key (bytes or IPublicKey) : Public key bytes or object Other Parameters: net_ver (bytes): Net address version Returns: str: Address string Raises: ValueError: If the public key is not valid TypeError: If the public key is not secp256k1 """ net_ver_bytes = kwargs["net_ver"] pub_key_obj = AddrKeyValidator.ValidateAndGetSecp256k1Key(pub_key) return Base58Encoder.CheckEncode(net_ver_bytes + _P2SHAddrUtils.AddScriptSig(pub_key_obj))
def EncodeKey(pub_key: Union[bytes, IPublicKey], **kwargs: Any) -> str: """ Encode a public key to EOS address. Args: pub_key (bytes or IPublicKey): Public key bytes or object **kwargs : Not used Returns: str: Address string Raised: ValueError: If the public key is not valid TypeError: If the public key is not secp256k1 """ pub_key_obj = AddrKeyValidator.ValidateAndGetSecp256k1Key(pub_key) pub_key_bytes = pub_key_obj.RawCompressed().ToBytes() checksum_bytes = _EosAddrUtils.ComputeChecksum(pub_key_bytes) return CoinsConf.Eos.Params("addr_prefix") + Base58Encoder.Encode( pub_key_bytes + checksum_bytes)
def Encode(priv_key: Union[bytes, IPrivateKey], net_ver: bytes = CoinsConf.BitcoinMainNet.Params("wif_net_ver"), pub_key_mode: WifPubKeyModes = WifPubKeyModes.COMPRESSED) -> str: """ Encode key bytes into a WIF string. Args: priv_key (bytes or IPrivateKey) : Private key bytes or object net_ver (bytes, optional) : Net version (Bitcoin main net by default) pub_key_mode (WifPubKeyModes, optional): Specify if the private key corresponds to a compressed public key Returns: str: WIF encoded string Raises: TypeError: If pub_key_mode is not a WifPubKeyModes enum or the private key is not a valid Secp256k1PrivateKey ValueError: If the key is not valid """ if not isinstance(pub_key_mode, WifPubKeyModes): raise TypeError("Public key mode is not an enumerative of WifPubKeyModes") # Convert to private key to check if bytes are valid if isinstance(priv_key, bytes): priv_key = Secp256k1PrivateKey.FromBytes(priv_key) elif not isinstance(priv_key, Secp256k1PrivateKey): raise TypeError("A secp256k1 private key is required") priv_key = priv_key.Raw().ToBytes() # Add suffix if correspond to a compressed public key if pub_key_mode == WifPubKeyModes.COMPRESSED: priv_key += WifConst.COMPR_PUB_KEY_SUFFIX # Add net address version priv_key = net_ver + priv_key # Encode key return Base58Encoder.CheckEncode(priv_key)