Exemple #1
0
    def __GetElemIndex(path_elem: str) -> Optional[int]:
        """ Get index of a path element.

        Args:
            path_elem (str): Path element

        Returns:
            int: Index of the element
            None: If the element is not a valid index
        """

        # Get if hardened
        is_hardened = len(path_elem) > 0 and path_elem[
            -1] in Bip32PathParserConst.HARDENED_CHARS

        # If hardened, remove the last character from the string
        if is_hardened:
            path_elem = path_elem[:-1]

        # The remaining string shall be numeric
        if not path_elem.isnumeric():
            return None

        return int(path_elem) if not is_hardened else Bip32Utils.HardenIndex(
            int(path_elem))
Exemple #2
0
class Bip44Const:
    """ Class container for BIP44 constants. """

    # Specification name
    SPEC_NAME = "BIP-0044"
    # Purpose
    PURPOSE = Bip32Utils.HardenIndex(44)
    # Allowed coins
    ALLOWED_COINS = \
        [
            Bip44Coins.BITCOIN            , Bip44Coins.BITCOIN_TESTNET,
            Bip44Coins.BITCOIN_CASH       , Bip44Coins.BITCOIN_CASH_TESTNET,
            Bip44Coins.BITCOIN_SV         , Bip44Coins.BITCOIN_SV_TESTNET,
            Bip44Coins.LITECOIN           , Bip44Coins.LITECOIN_TESTNET,
            Bip44Coins.DOGECOIN           , Bip44Coins.DOGECOIN_TESTNET,
            Bip44Coins.DASH               , Bip44Coins.DASH_TESTNET,
            Bip44Coins.ZCASH              , Bip44Coins.ZCASH_TESTNET,
            Bip44Coins.ETHEREUM           ,
            Bip44Coins.ETHEREUM_CLASSIC   ,
            Bip44Coins.RIPPLE             ,
            Bip44Coins.TRON               ,
            Bip44Coins.VECHAIN            ,
            Bip44Coins.COSMOS             ,
            Bip44Coins.BAND_PROTOCOL      ,
            Bip44Coins.KAVA               ,
            Bip44Coins.IRIS_NET           ,
            Bip44Coins.BINANCE_CHAIN      ,
            Bip44Coins.BINANCE_SMART_CHAIN,
            Bip44Coins.NINE_CHRONICLES_GOLD,
        ]
    # Map from Bip44Coins to coin classes
    COIN_TO_CLASS = \
        {
            Bip44Coins.BITCOIN              : Bip44BitcoinMainNet,
            Bip44Coins.BITCOIN_TESTNET      : Bip44BitcoinTestNet,
            Bip44Coins.BITCOIN_CASH         : Bip44BitcoinCashMainNet,
            Bip44Coins.BITCOIN_CASH_TESTNET : Bip44BitcoinCashTestNet,
            Bip44Coins.BITCOIN_SV           : Bip44BitcoinSvMainNet,
            Bip44Coins.BITCOIN_SV_TESTNET   : Bip44BitcoinSvTestNet,
            Bip44Coins.LITECOIN             : Bip44LitecoinMainNet,
            Bip44Coins.LITECOIN_TESTNET     : Bip44LitecoinTestNet,
            Bip44Coins.DOGECOIN             : Bip44DogecoinMainNet,
            Bip44Coins.DOGECOIN_TESTNET     : Bip44DogecoinTestNet,
            Bip44Coins.DASH                 : Bip44DashMainNet,
            Bip44Coins.DASH_TESTNET         : Bip44DashTestNet,
            Bip44Coins.ZCASH                : Bip44ZcashMainNet,
            Bip44Coins.ZCASH_TESTNET        : Bip44ZcashTestNet,
            Bip44Coins.ETHEREUM             : Bip44Ethereum,
            Bip44Coins.ETHEREUM_CLASSIC     : Bip44EthereumClassic,
            Bip44Coins.RIPPLE               : Bip44Ripple,
            Bip44Coins.TRON                 : Bip44Tron,
            Bip44Coins.VECHAIN              : Bip44VeChain,
            Bip44Coins.COSMOS               : Bip44Cosmos,
            Bip44Coins.BAND_PROTOCOL        : Bip44BandProtocol,
            Bip44Coins.KAVA                 : Bip44Kava,
            Bip44Coins.IRIS_NET             : Bip44IrisNet,
            Bip44Coins.BINANCE_CHAIN        : Bip44BinanceChain,
            Bip44Coins.BINANCE_SMART_CHAIN  : Bip44BinanceSmartChain,
            Bip44Coins.NINE_CHRONICLES_GOLD : Bip44NineChroniclesGold,
        }
Exemple #3
0
    def __CkdPub(self, index: int) -> 'Bip32':
        """ Create a publicly derived child key of the specified index.

        Args:
            index (int): Index

        Returns:
            Bip32 object: Bip32 object constructed with the child parameters

        Raises:
            Bip32KeyError: If the index is hardened or results in an invalid key
        """

        # Check if index is hardened
        if Bip32Utils.IsHardenedIndex(index):
            raise Bip32KeyError(
                "Public child derivation cannot be used to create a hardened child key"
            )

        # Data for HMAC, same of __CkdPriv() for public child key
        data = self.EcdsaPublicKey().RawCompressed().ToBytes(
        ) + index.to_bytes(4, "big")

        # Get HMAC of data
        i_l, i_r = self.__HmacHalves(data)

        # Construct curve point i_l*G+K
        point = ConvUtils.BytesToInteger(
            i_l) * generator_secp256k1 + self.m_ver_key.pubkey.point

        # Try to construct public key from the curve point
        try:
            k_i = ecdsa.VerifyingKey.from_public_point(point, curve=SECP256k1)
        except ecdsa.keys.MalformedPointError as ex:
            raise Bip32KeyError(
                "Computed public child key is not valid, very unlucky index"
            ) from ex

        # Construct and return a new Bip32 object
        return Bip32(secret=k_i,
                     chain=i_r,
                     depth=self.m_depth + 1,
                     index=index,
                     fprint=self.FingerPrint(),
                     is_public=True,
                     key_net_ver=self.m_key_net_ver)
Exemple #4
0
    def __CkdPriv(self, index: int) -> 'Bip32':
        """ Create a child key of the specified index.

        Args:
            index (int): Index

        Returns:
            Bip32 object: Bip32 object constructed with the child parameters

        Raises:
            Bip32KeyError: If the index results in an invalid key
        """

        # Index as bytes
        index_bytes = index.to_bytes(4, "big")

        # Data for HMAC
        if Bip32Utils.IsHardenedIndex(index):
            data = b"\x00" + self.EcdsaPrivateKey().Raw().ToBytes(
            ) + index_bytes
        else:
            data = self.EcdsaPublicKey().RawCompressed().ToBytes(
            ) + index_bytes

        # Compute HMAC halves
        i_l, i_r = self.__HmacHalves(data)

        # Construct new key secret from i_l and current private key
        i_l_int = ConvUtils.BytesToInteger(i_l)
        key_int = ConvUtils.BytesToInteger(self.m_key.to_string())
        new_key_int = (i_l_int + key_int) % Bip32Const.CURVE_ORDER

        # Convert to string and left pad with zeros
        secret = ConvUtils.IntegerToBytes(new_key_int)
        secret = b"\x00" * (32 - len(secret)) + secret

        # Construct and return a new Bip32 object
        return Bip32(secret=secret,
                     chain=i_r,
                     depth=self.m_depth + 1,
                     index=index,
                     fprint=self.FingerPrint(),
                     is_public=False,
                     key_net_ver=self.m_key_net_ver)
Exemple #5
0
    def _AccountGeneric(cls, bip_obj, acc_idx):
        """ Derive a child key from the specified account index and return a new Bip object (e.g. BIP44, BIP49, BIP84).
        It shall be called from a child class.

        Args:
            bip_obj (Bip44Base child object): Bip44Base child object (e.g. BIP44, BIP49, BIP84)
            acc_idx (int)                   : Account index

        Returns:
            Bip44Base child object: Bip44Base child 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("Current depth (%d) is not suitable for deriving account" % bip_obj.m_bip32.Depth())

        return cls(bip_obj.m_bip32.ChildKey(Bip32Utils.HardenIndex(acc_idx)), bip_obj.m_coin_type)
Exemple #6
0
    def _CoinGeneric(cls, bip_obj):
        """ Derive a child key from the coin type specified at construction and return a new Bip object (e.g. BIP44, BIP49, BIP84).
        It shall be called from a child class.

        Args:
            bip_obj (Bip44Base child object): Bip44Base child object (e.g. BIP44, BIP49, BIP84)

        Returns:
            Bip44Base child object: Bip44Base child 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("Current depth (%d) is not suitable for deriving coin" % bip_obj.m_bip32.Depth())

        coin_idx = Bip44BaseConst.COIN_TO_IDX[bip_obj.m_coin_type]

        return cls(bip_obj.m_bip32.ChildKey(Bip32Utils.HardenIndex(coin_idx)), bip_obj.m_coin_type)
Exemple #7
0
class Bip49Const:
    """ Class container for BIP44 constants. """

    # Specification name
    SPEC_NAME: str = "BIP-0049"
    # Purpose
    PURPOSE: int = Bip32Utils.HardenIndex(49)
    # Allowed coins
    ALLOWED_COINS: List[Bip44Coins] = [
        Bip44Coins.BITCOIN,
        Bip44Coins.BITCOIN_TESTNET,
        Bip44Coins.BITCOIN_CASH,
        Bip44Coins.BITCOIN_CASH_TESTNET,
        Bip44Coins.BITCOIN_SV,
        Bip44Coins.BITCOIN_SV_TESTNET,
        Bip44Coins.LITECOIN,
        Bip44Coins.LITECOIN_TESTNET,
        Bip44Coins.DOGECOIN,
        Bip44Coins.DOGECOIN_TESTNET,
        Bip44Coins.DASH,
        Bip44Coins.DASH_TESTNET,
        Bip44Coins.ZCASH,
        Bip44Coins.ZCASH_TESTNET,
    ]
    # Map from Bip44Coins to coin classes
    COIN_TO_CLASS: Dict[Bip44Coins, Type[BipCoinBase]] = {
        Bip44Coins.BITCOIN: Bip49BitcoinMainNet,
        Bip44Coins.BITCOIN_TESTNET: Bip49BitcoinTestNet,
        Bip44Coins.BITCOIN_CASH: Bip49BitcoinCashMainNet,
        Bip44Coins.BITCOIN_CASH_TESTNET: Bip49BitcoinCashTestNet,
        Bip44Coins.BITCOIN_SV: Bip49BitcoinSvMainNet,
        Bip44Coins.BITCOIN_SV_TESTNET: Bip49BitcoinSvTestNet,
        Bip44Coins.LITECOIN: Bip49LitecoinMainNet,
        Bip44Coins.LITECOIN_TESTNET: Bip49LitecoinTestNet,
        Bip44Coins.DOGECOIN: Bip49DogecoinMainNet,
        Bip44Coins.DOGECOIN_TESTNET: Bip49DogecoinTestNet,
        Bip44Coins.DASH: Bip49DashMainNet,
        Bip44Coins.DASH_TESTNET: Bip49DashTestNet,
        Bip44Coins.ZCASH: Bip49ZcashMainNet,
        Bip44Coins.ZCASH_TESTNET: Bip49ZcashTestNet,
    }
Exemple #8
0
class Bip84Const:
    """ Class container for BIP44 constants. """

    # Specification name
    SPEC_NAME: str = "BIP-0084"
    # Purpose
    PURPOSE: int = Bip32Utils.HardenIndex(84)
    # Allowed coins
    ALLOWED_COINS: List[Bip44Coins] = [
        Bip44Coins.BITCOIN,
        Bip44Coins.BITCOIN_TESTNET,
        Bip44Coins.LITECOIN,
        Bip44Coins.LITECOIN_TESTNET,
    ]
    # Map from Bip44Coins to coin classes
    COIN_TO_CLASS: Dict[Bip44Coins, Type[BipCoinBase]] = {
        Bip44Coins.BITCOIN: Bip84BitcoinMainNet,
        Bip44Coins.BITCOIN_TESTNET: Bip84BitcoinTestNet,
        Bip44Coins.LITECOIN: Bip84LitecoinMainNet,
        Bip44Coins.LITECOIN_TESTNET: Bip84LitecoinTestNet,
    }