Esempio n. 1
0
    def __init__(self, bip32: Bip32Base, coin_conf: BipCoinConf) -> None:
        """
        Construct class.

        Args:
            bip32 (Bip32Base object): Bip32Base object
            coin_conf (BipCoinConf) : BipCoinConf object

        Returns:
            Bip44DepthError: If the Bip32 object depth is not valid
        """
        depth = bip32.Depth()

        # If the Bip32 is public-only, the depth shall start from the account level because hardened derivation is
        # used below it, which is not possible with public keys
        if bip32.IsPublicOnly():
            if depth < Bip44Levels.ACCOUNT or depth > Bip44Levels.ADDRESS_INDEX:
                raise Bip44DepthError(
                    f"Depth of the public-only Bip32 object ({depth}) is below account level or "
                    f"beyond address index level")
        # If the Bip32 object is not public-only, any depth is fine as long as it is not greater
        # than address index level
        else:
            if depth < 0 or depth > Bip44Levels.ADDRESS_INDEX:
                raise Bip44DepthError(
                    f"Depth of the Bip32 object ({depth}) is invalid or beyond address index level"
                )

        # Finally, initialize class
        self.m_bip32 = bip32
        self.m_coin_conf = coin_conf
Esempio n. 2
0
    def _AddressIndexGeneric(cls, bip_obj: Bip44Base,
                             addr_idx: int) -> Bip44Base:
        """
        Derive a child key from the specified address index and return a new Bip44Base object.
        It shall be called from a child class.

        Args:
            bip_obj (Bip44Base object): Bip44Base object
            addr_idx (int)            : Address index

        Returns:
            Bip44Base object: Bip44Base object

        Raises:
            Bip44DepthError: If the current depth is not suitable for deriving keys
            Bip32KeyError: If the derivation results in an invalid key
        """
        if not cls.IsLevel(bip_obj, Bip44Levels.CHANGE):
            raise Bip44DepthError(
                f"Current depth ({bip_obj.m_bip32.Depth().ToInt()}) is not suitable for deriving address"
            )

        # Use hardened derivation if not-hardended is not supported
        if not bip_obj.m_bip32.IsPrivateUnhardenedDerivationSupported():
            addr_idx = Bip32Utils.HardenIndex(addr_idx)

        return cls(bip_obj.m_bip32.ChildKey(addr_idx), bip_obj.m_coin_conf)
Esempio n. 3
0
    def _ChangeGeneric(cls, bip_obj: Bip44Base,
                       change_type: Bip44Changes) -> Bip44Base:
        """
        Derive a child key from the specified chain type and return a new Bip44Base object.
        It shall be called from a child class.

        Args:
            bip_obj (Bip44Base object): Bip44Base object
            change_type (Bip44Changes): Change type, must a Bip44Changes enum

        Returns:
            Bip44Base object: Bip44Base object

        Raises:
            TypeError: If chain index is not a Bip44Changes enum
            Bip44DepthError: If the current depth is not suitable for deriving keys
            Bip32KeyError: If the derivation results in an invalid key
        """
        if not isinstance(change_type, Bip44Changes):
            raise TypeError(
                "Change index is not an enumerative of Bip44Changes")

        if not cls.IsLevel(bip_obj, Bip44Levels.ACCOUNT):
            raise Bip44DepthError(
                f"Current depth ({bip_obj.m_bip32.Depth().ToInt()}) is not suitable for deriving change"
            )

        # Use hardened derivation if not-hardended is not supported
        if not bip_obj.m_bip32.IsPrivateUnhardenedDerivationSupported():
            change_idx = Bip32Utils.HardenIndex(int(change_type))
        else:
            change_idx = int(change_type)

        return cls(bip_obj.m_bip32.ChildKey(change_idx), bip_obj.m_coin_conf)
Esempio n. 4
0
    def _DeriveDefaultPathGeneric(cls, bip_obj: Bip44Base,
                                  purpose: int) -> Bip44Base:
        """
        Derive the default coin path and return a new Bip44Base object.
        It shall be called from a child class.

        Args:
            bip_obj (Bip44Base object): Bip44Base object
            purpose (int)             : Purpose

        Returns:
            Bip44Base object: Bip44Base object

        Raises:
            Bip44DepthError: If the current depth is not suitable for deriving keys
            Bip32KeyError: If the derivation results in an invalid key
        """
        if not cls.IsLevel(bip_obj, Bip44Levels.MASTER):
            raise Bip44DepthError(
                f"Current depth ({bip_obj.m_bip32.Depth().ToInt()}) is not suitable for deriving default path"
            )

        # Derive purpose and coin by default
        bip_obj = cls._PurposeGeneric(bip_obj, purpose)
        bip_obj = cls._CoinGeneric(bip_obj)

        # Derive the remaining path
        return cls(
            bip_obj.m_bip32.DerivePath(bip_obj.m_coin_conf.DefaultPath()),
            bip_obj.m_coin_conf)
Esempio n. 5
0
    def _PurposeGeneric(cls, bip_obj: Bip44Base, purpose: int) -> Bip44Base:
        """
        Derive a child key from the purpose and return a new Bip44Base object.
        It shall be called from a child class.

        Args:
            bip_obj (Bip44Base object): Bip44Base object
            purpose (int)             : Purpose

        Returns:
            Bip44Base object: Bip44Base object

        Raises:
            Bip44DepthError: If the current depth is not suitable for deriving keys
            Bip32KeyError: If the derivation results in an invalid key
        """
        if not cls.IsLevel(bip_obj, Bip44Levels.MASTER):
            raise Bip44DepthError(
                f"Current depth ({bip_obj.m_bip32.Depth().ToInt()}) is not suitable for deriving purpose"
            )

        return cls(bip_obj.m_bip32.ChildKey(purpose), bip_obj.m_coin_conf)
Esempio n. 6
0
    def _AccountGeneric(cls, bip_obj: Bip44Base, acc_idx: int) -> Bip44Base:
        """
        Derive a child key from the specified account index and return a new Bip44Base object.
        It shall be called from a child class.

        Args:
            bip_obj (Bip44Base object): Bip44Base object
            acc_idx (int)             : Account index

        Returns:
            Bip44Base object: Bip44Base object

        Raises:
            Bip44DepthError: If the current depth is not suitable for deriving keys
            Bip32KeyError: If the derivation results in an invalid key
        """
        if not cls.IsLevel(bip_obj, Bip44Levels.COIN):
            raise Bip44DepthError(
                f"Current depth ({bip_obj.m_bip32.Depth().ToInt()}) is not suitable for deriving account"
            )

        return cls(bip_obj.m_bip32.ChildKey(Bip32Utils.HardenIndex(acc_idx)),
                   bip_obj.m_coin_conf)
Esempio n. 7
0
    def _CoinGeneric(cls, bip_obj: Bip44Base) -> Bip44Base:
        """
        Derive a child key from the coin type specified at construction and return a new Bip44Base object.
        It shall be called from a child class.

        Args:
            bip_obj (Bip44Base object): Bip44Base object

        Returns:
            Bip44Base object: Bip44Base object

        Raises:
            Bip44DepthError: If the current depth is not suitable for deriving keys
            Bip32KeyError: If the derivation results in an invalid key
        """
        if not cls.IsLevel(bip_obj, Bip44Levels.PURPOSE):
            raise Bip44DepthError(
                f"Current depth ({bip_obj.m_bip32.Depth().ToInt()}) is not suitable for deriving coin"
            )

        coin_idx = bip_obj.m_coin_conf.CoinIndex()

        return cls(bip_obj.m_bip32.ChildKey(Bip32Utils.HardenIndex(coin_idx)),
                   bip_obj.m_coin_conf)