Exemplo n.º 1
0
    def _ValidateAndCkdPub(self, index: Bip32KeyIndex) -> Bip32Base:
        """
        Check the key index validity and create a child key of the specified index using public derivation.

        Args:
            index (Bip32KeyIndex object): Key index

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

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

        # Check if supported
        if not self.IsPublicDerivationSupported():
            raise Bip32KeyError("Public child derivation is not supported")

        # Hardened index is not supported for public derivation
        if index.IsHardened():
            raise Bip32KeyError(
                "Public child derivation cannot be used to create a hardened child key"
            )

        return self._CkdPub(index)
Exemplo n.º 2
0
    def _CkdPrivEcdsa(cls,
                      bip32_obj: Bip32Base,
                      index: Bip32KeyIndex) -> Bip32Base:
        """
        Create a child key of the specified index using private derivation.

        Args:
            bip32_obj (Bip32Base object): Bip32Base object
            index (Bip32KeyIndex object): Key index

        Returns:
            Bip32Base object: Bip32Base object

        Raises:
            Bip32KeyError: If the index results in an invalid key
        """
        assert bip32_obj.m_priv_key is not None

        # Get elliptic curve
        curve = EllipticCurveGetter.FromType(bip32_obj.CurveType())

        # Data for HMAC
        if index.IsHardened():
            data_bytes = b"\x00" + bip32_obj.m_priv_key.Raw().ToBytes() + bytes(index)
        else:
            data_bytes = bip32_obj.m_pub_key.RawCompressed().ToBytes() + bytes(index)

        # Compute HMAC halves
        i_l, i_r = Bip32BaseUtils.HmacSha512Halves(bip32_obj.ChainCode().ToBytes(), data_bytes)

        # Construct new key secret from i_l and current private key
        i_l_int = BytesUtils.ToInteger(i_l)
        key_int = BytesUtils.ToInteger(bip32_obj.m_priv_key.Raw().ToBytes())
        new_key_int = (i_l_int + key_int) % curve.Order()

        # Convert to string and pad with zeros
        new_priv_key_bytes = IntegerUtils.ToBytes(new_key_int).rjust(curve.PrivateKeyClass().Length(), b"\x00")

        # Construct and return a new Bip32 object
        return cls(priv_key=new_priv_key_bytes,
                   pub_key=None,
                   key_data=Bip32KeyData(chain_code=i_r,
                                         depth=bip32_obj.Depth().Increase(),
                                         index=index,
                                         parent_fprint=bip32_obj.m_pub_key.FingerPrint()),
                   curve_type=bip32_obj.CurveType(),
                   key_net_ver=bip32_obj.KeyNetVersions())
Exemplo n.º 3
0
    def _ValidateAndCkdPriv(self, index: Bip32KeyIndex) -> Bip32Base:
        """
        Check the key index validity and create a child key of the specified index using private derivation.

        Args:
            index (Bip32KeyIndex object): Key index

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

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

        # Check if supported
        if not index.IsHardened(
        ) and not self.IsPrivateUnhardenedDerivationSupported():
            raise Bip32KeyError(
                "Private child derivation with not-hardened index is not supported"
            )

        return self._CkdPriv(index)
Exemplo n.º 4
0
    def _CkdPriv(self, index: Bip32KeyIndex) -> Bip32Base:
        """
        Create a child key of the specified index using private derivation.

        Args:
            index (Bip32KeyIndex object): Key index

        Returns:
            Bip32Base object: Bip32Base object

        Raises:
            Bip32KeyError: If the index results in an invalid key
        """
        assert self.m_priv_key is not None

        # Get elliptic curve
        curve = EllipticCurveGetter.FromType(self.CurveType())

        # Get index bytes
        index_bytes = index.ToBytes(endianness="little")

        # Compute Z and chain code
        if index.IsHardened():
            z_bytes = CryptoUtils.HmacSha512(
                self.ChainCode().ToBytes(),
                b"\x00" + self.m_priv_key.Raw().ToBytes() + index_bytes)
            chain_code_bytes = Bip32BaseUtils.HmacSha512Halves(
                self.ChainCode().ToBytes(),
                b"\x01" + self.m_priv_key.Raw().ToBytes() + index_bytes)[1]
        else:
            z_bytes = CryptoUtils.HmacSha512(
                self.ChainCode().ToBytes(), b"\x02" +
                self.m_pub_key.RawCompressed().ToBytes()[1:] + index_bytes)
            chain_code_bytes = Bip32BaseUtils.HmacSha512Halves(
                self.ChainCode().ToBytes(), b"\x03" +
                self.m_pub_key.RawCompressed().ToBytes()[1:] + index_bytes)[1]

        # ZL is the left 28-byte part of Z
        zl_int = BytesUtils.ToInteger(z_bytes[:28], endianness="little")
        # ZR is the right 32-byte part of Z
        zr_int = BytesUtils.ToInteger(z_bytes[32:], endianness="little")

        # Compute kL
        kl_int = (zl_int * 8) + BytesUtils.ToInteger(
            self.m_priv_key.Raw().ToBytes()[:32], endianness="little")
        if kl_int % curve.Order() == 0:
            raise Bip32KeyError(
                "Computed private child key is not valid, very unlucky index")
        # Compute kR
        kr_int = (zr_int +
                  BytesUtils.ToInteger(self.m_priv_key.Raw().ToBytes()[32:],
                                       endianness="little")) % 2**256
        # Compute private key
        priv_key = Ed25519KholawPrivateKey.FromBytes(
            IntegerUtils.ToBytes(kl_int,
                                 Ed25519KholawPrivateKey.Length() // 2,
                                 endianness="little") +
            IntegerUtils.ToBytes(kr_int,
                                 Ed25519KholawPrivateKey.Length() // 2,
                                 endianness="little"))

        return Bip32Ed25519Kholaw(
            priv_key=priv_key,
            pub_key=None,
            key_data=Bip32KeyData(chain_code=chain_code_bytes,
                                  depth=self.Depth().Increase(),
                                  index=index,
                                  parent_fprint=self.m_pub_key.FingerPrint()),
            curve_type=self.CurveType(),
            key_net_ver=self.KeyNetVersions())