Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
    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)
Пример #5
0
    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)
Пример #6
0
    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))
Пример #7
0
    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)
Пример #8
0
    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)
Пример #9
0
    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:])
Пример #10
0
    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)
Пример #11
0
    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))
Пример #12
0
    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))
Пример #13
0
    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)
Пример #14
0
    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)
Пример #15
0
    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)
Пример #16
0
    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))
Пример #17
0
    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))
Пример #18
0
    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)
Пример #19
0
    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)