Esempio n. 1
0
    def __EncryptSeedb(seedb: bytes,
                       derived_half_1: bytes,
                       derived_half_2: bytes) -> Tuple[bytes, bytes]:
        """
        Encrypt seedb in two parts.

        Args:
            seedb (bytes)         : Seedb
            derived_half_1 (bytes): First half of derived key
            derived_half_2 (bytes): Second half of derived key

        Returns:
            tuple[bytes, bytes]: Two encrypted parts
        """

        # Use derived_half_2 as AES key
        aes_enc = AesEcbEncrypter(derived_half_2)
        aes_enc.AutoPad(False)

        # Encrypt the first part: seedb[0...15] xor derived_half_1[0...15]
        encrypted_part_1 = aes_enc.Encrypt(BytesUtils.Xor(seedb[:16], derived_half_1[:16]))
        # Encrypt the second part: (encrypted_part_1[8...15] + seedb[16...23])) xor derivedhalf1[16...31]
        encrypted_part_2 = aes_enc.Encrypt(BytesUtils.Xor(encrypted_part_1[8:] + seedb[16:], derived_half_1[16:]))

        return encrypted_part_1, encrypted_part_2
Esempio n. 2
0
    def __EncryptPrivateKey(priv_key_bytes: bytes, derived_half_1: bytes,
                            derived_half_2: bytes) -> Tuple[bytes, bytes]:
        """
        Encrypt private key in two halves.

        Args:
            priv_key_bytes (bytes): Private key
            derived_half_1 (bytes): First half of derived key
            derived_half_2 (bytes): Second half of derived key

        Returns:
            tuple[bytes, bytes]: Two encrypted halves
        """

        # Use derived_half_2 as AES key
        aes_enc = AesEcbEncrypter(derived_half_2)
        aes_enc.AutoPad(False)

        # Encrypt the first half: priv_key[0...15] xor derived_half_1[0...15]
        encrypted_half_1 = aes_enc.Encrypt(
            BytesUtils.Xor(priv_key_bytes[:16], derived_half_1[:16]))
        # Encrypt the second half: priv_key[16...31] xor derived_half_1[16...31]
        encrypted_half_2 = aes_enc.Encrypt(
            BytesUtils.Xor(priv_key_bytes[16:], derived_half_1[16:]))

        return encrypted_half_1, encrypted_half_2
Esempio n. 3
0
    def __DecryptAndGetFactorb(encrypted_part_1_lower: bytes,
                               encrypted_part_2: bytes,
                               derived_half_1: bytes,
                               derived_half_2: bytes) -> bytes:
        """
        Decrypt and get back factorb.

        Args:
            encrypted_part_1_lower (bytes): Lower part of first encrypted part
            encrypted_part_2 (bytes)      : Second encrypted part
            derived_half_1 (bytes)        : First half of derived key
            derived_half_2 (bytes)        : Second half of derived key

        Returns:
            bytes: Factorb
        """

        # Use derived_half_2 as AES key
        aes_dec = AesEcbDecrypter(derived_half_2)
        aes_dec.AutoUnPad(False)

        # Decrypt the second part and get back the higher parts of seedb and encrypted half 1
        decrypted_part_2 = BytesUtils.Xor(aes_dec.Decrypt(encrypted_part_2), derived_half_1[16:])
        encrypted_part_1_higher = decrypted_part_2[:8]
        seedb_part_2 = decrypted_part_2[8:]

        # Decrypt the first part to get the lower part of seedb
        seedb_part_1 = BytesUtils.Xor(aes_dec.Decrypt(encrypted_part_1_lower + encrypted_part_1_higher),
                                      derived_half_1[:16])
        # Rebuild the complete seedb
        seedb = seedb_part_1 + seedb_part_2

        # Compute factorb from seedb
        return CryptoUtils.DoubleSha256(seedb)
Esempio n. 4
0
    def FromBytes(cls, key_bytes: bytes) -> IPublicKey:
        """
        Construct class from key bytes.

        Args:
            key_bytes (bytes): Key bytes

        Returns:
            IPublicKey: IPublicKey object

        Raises:
            ValueError: If key bytes are not valid
        """

        # Remove the 0x00 prefix if present because nacl requires 32-byte length
        if (len(key_bytes) == cls.CompressedLength() and key_bytes[0]
                == BytesUtils.ToInteger(Ed25519KeysConst.PUB_KEY_PREFIX)):
            key_bytes = key_bytes[1:]

        # nacl doesn't check if the point lies on curve
        try:
            ed25519_lib.point_decode(key_bytes)
        except ValueError as ex:
            raise ValueError("Invalid public key bytes") from ex

        try:
            return cls(signing.VerifyKey(key_bytes))
        except (exceptions.RuntimeError, exceptions.ValueError) as ex:
            raise ValueError("Invalid public key bytes") from ex
Esempio n. 5
0
    def __DecryptAndGetPrivKey(encrypted_half_1: bytes,
                               encrypted_half_2: bytes, derived_half_1: bytes,
                               derived_half_2: bytes) -> bytes:
        """
        Decrypt and get back private key.

        Args:
            encrypted_half_1 (bytes): First encrypted half
            encrypted_half_2 (bytes): Second encrypted half
            derived_half_1 (bytes)  : First half of derived key
            derived_half_2 (bytes)  : Second half of derived key

        Returns:
            bytes: Decrypted private key
        """

        # Use derived_half_2 as AES key
        aes_dec = AesEcbDecrypter(derived_half_2)
        aes_dec.AutoUnPad(False)

        # Decrypt using AES256Decrypt
        decrypted_half_1 = aes_dec.Decrypt(encrypted_half_1)
        decrypted_half_2 = aes_dec.Decrypt(encrypted_half_2)

        # Get the private key back by XORing bytes
        return BytesUtils.Xor(decrypted_half_1 + decrypted_half_2,
                              derived_half_1)
Esempio n. 6
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)
Esempio n. 7
0
    def BytesChunkToWords(bytes_chunk: bytes, words_list: MnemonicWordsList,
                          endianness: str) -> List[str]:
        """
        Get words from a bytes chunk.

        Args:
            bytes_chunk (bytes)                  : Bytes chunk
            words_list (MnemonicWordsList object): Mnemonic list
            endianness (str)                     : Bytes endianness

        Returns:
            list[str]: 3 word indexes
        """
        n = words_list.Length()

        int_chunk = BytesUtils.ToInteger(bytes_chunk, endianness=endianness)

        word1_idx = int_chunk % n
        word2_idx = ((int_chunk // n) + word1_idx) % n
        word3_idx = ((int_chunk // n // n) + word2_idx) % n

        return [
            words_list.GetWordAtIdx(w)
            for w in (word1_idx, word2_idx, word3_idx)
        ]
Esempio n. 8
0
    def Decode(cls, hrp: str, addr: str) -> bytes:
        """
        Decode from Bech32.

        Args:
            hrp (str) : Human readable part
            addr (str): Address

        Returns:
            bytes: Decoded address

        Raises:
            ValueError: If the bech32 string is not valid
            Bech32ChecksumError: If the checksum is not valid
        """

        # Decode string
        hrp_got, data = cls._DecodeBech32(addr, Bech32Const.SEPARATOR,
                                          Bech32Const.CHECKSUM_STR_LEN)
        # Check HRP
        if hrp != hrp_got:
            raise ValueError(
                f"Invalid format (HRP not valid, expected {hrp}, got {hrp_got})"
            )

        # Convert back from base32
        return BytesUtils.FromList(Bech32BaseUtils.ConvertFromBase32(data))
Esempio n. 9
0
    def __ComputePrivateKey(passfactor: bytes,
                            factorb: bytes) -> bytes:
        """
        Compute the private key from passfactor and factorb.

        Args:
            passfactor (bytes): Passfactor
            factorb (bytes)   : Factorb

        Returns:
            bytes: Private key
        """

        # Private key: (passfactor * factorb) mod N
        priv_key_int = (BytesUtils.ToInteger(passfactor) * BytesUtils.ToInteger(factorb)) % Secp256k1.Order()
        return IntegerUtils.ToBytes(priv_key_int, bytes_num=Secp256k1PrivateKey.Length())
Esempio n. 10
0
    def __GetFlagbyteOptions(flagbyte: bytes) -> Tuple[Bip38PubKeyModes, bool]:
        """
        Get the options from the flagbyte.

        Args:
            flagbyte (bytes): Flagbyte

        Returns:
            tuple[Bip38PubKeyModes, bool]: Public key mode (index 0), has lot/sequence numbers (index 1)
        """

        # Convert flagbyte to integer
        flagbyte_int = BytesUtils.ToInteger(flagbyte)
        # Get bit set in flagbyte
        has_lot_seq = BitUtils.IsBitSet(flagbyte_int, Bip38EcConst.FLAG_BIT_LOT_SEQ)
        pub_key_mode = (Bip38PubKeyModes.COMPRESSED
                        if BitUtils.IsBitSet(flagbyte_int, Bip38EcConst.FLAG_BIT_COMPRESSED)
                        else Bip38PubKeyModes.UNCOMPRESSED)
        # Check flagbyte
        flagbyte_int = BitUtils.ResetBit(flagbyte_int, Bip38EcConst.FLAG_BIT_LOT_SEQ)
        flagbyte_int = BitUtils.ResetBit(flagbyte_int, Bip38EcConst.FLAG_BIT_COMPRESSED)
        if flagbyte_int != 0:
            raise ValueError(f"Invalid flagbyte ({BytesUtils.ToHexString(flagbyte)})")

        return pub_key_mode, has_lot_seq
Esempio n. 11
0
    def EncodeKey(pub_key: Union[bytes, IPublicKey], **kwargs: Any) -> str:
        """
        Encode a public key to Ethereum address.

        Args:
            pub_key (bytes or IPublicKey): Public key bytes or object

        Other Parameters:
            skip_chksum_enc (bool, optional): True to skip checksum encoding, false otherwise (default)

        Returns:
            str: Address string

        Raised:
            ValueError: If the public key is not valid
            TypeError: If the public key is not secp256k1
        """
        skip_chksum_enc = kwargs.get("skip_chksum_enc", False)

        pub_key_obj = AddrKeyValidator.ValidateAndGetSecp256k1Key(pub_key)

        # First byte of the uncompressed key (i.e. 0x04) is not needed
        kekkak_hex = BytesUtils.ToHexString(
            CryptoUtils.Kekkak256(pub_key_obj.RawUncompressed().ToBytes()[1:]))
        addr = kekkak_hex[EthAddrConst.START_BYTE:]
        return CoinsConf.Ethereum.Params("addr_prefix") + (
            _EthAddrUtils.ChecksumEncode(addr)
            if not skip_chksum_enc else addr)
Esempio n. 12
0
    def FromEntropy(self,
                    entropy_bytes: bytes) -> Mnemonic:
        """
        Generate mnemonic from the specified entropy bytes.
        Because of the mnemonic encoding algorithm used by Electrum, the specified entropy will only be a starting
        point to find a suitable one. Therefore, it's very likely that the actual entropy bytes will be different.
        To get the actual entropy bytes, just decode the generated mnemonic.
        Please note that, to successfully generate a mnemonic, the bits of the big endian integer encoded entropy
        shall be at least 121 (for 12 words) or 253 (for 24 words). Otherwise, a mnemonic generation is not possible
        and a ValueError exception will be raised.

        Args:
            entropy_bytes (bytes): Entropy bytes

        Returns:
            Mnemonic object: Generated mnemonic

        Raises:
            ValueError: If entropy byte length is not valid or a mnemonic cannot be generated
        """

        # Do not waste time trying if the entropy bit are not enough
        if ElectrumV2EntropyGenerator.AreEntropyBitsEnough(entropy_bytes):
            # Same of Electrum: increase the entropy until a valid one is found
            entropy_int = BytesUtils.ToInteger(entropy_bytes)
            for i in range(ElectrumV2MnemonicGeneratorConst.MAX_ATTEMPTS):
                new_entropy_int = entropy_int + i
                try:
                    return self.m_mnemonic_encoder.Encode(IntegerUtils.ToBytes(new_entropy_int))
                except ValueError:
                    continue

        raise ValueError("Unable to generate a valid mnemonic")
Esempio n. 13
0
    def DecodeAddr(addr: str, **kwargs: Any) -> bytes:
        """
        Decode an Ethereum address to bytes.

        Args:
            addr (str): Address string

        Other Parameters:
            skip_chksum_enc (bool, optional): True to skip checksum encoding verification, false otherwise (default)

        Returns:
            bytes: Public key hash bytes

        Raises:
            ValueError: If the address encoding is not valid
        """
        skip_chksum_enc = kwargs.get("skip_chksum_enc", False)

        # Validate and remove prefix
        addr_no_prefix = AddrDecUtils.ValidateAndRemovePrefix(
            addr, CoinsConf.Ethereum.Params("addr_prefix"))
        # Validate length
        AddrDecUtils.ValidateLength(addr_no_prefix, EthAddrConst.ADDR_LEN)
        # Check checksum encoding
        if not skip_chksum_enc and addr_no_prefix != _EthAddrUtils.ChecksumEncode(
                addr_no_prefix):
            raise ValueError("Invalid checksum encode")

        return BytesUtils.FromHexString(addr_no_prefix)
    def FromBytes(cls,
                  key_bytes: bytes) -> IPublicKey:
        """
        Construct class from key bytes.

        Args:
            key_bytes (bytes): Key bytes

        Returns:
            IPublicKey: IPublicKey object

        Raises:
            ValueError: If key bytes are not valid
        """

        # Remove the 0x00 prefix if present
        if (len(key_bytes) == cls.CompressedLength()
                and key_bytes[0] == BytesUtils.ToInteger(Ed25519KeysConst.PUB_KEY_PREFIX)):
            key_bytes = key_bytes[1:]
        # The library does not raise any exception in case of length error
        elif len(key_bytes) != cls.CompressedLength() - 1:
            raise ValueError("Invalid public key bytes")

        # The library doesn't check if the point lies on curve
        try:
            ed25519_lib.point_decode(key_bytes)
        except ValueError as ex:
            raise ValueError("Invalid public key bytes") from ex

        return cls(ed25519_blake2b.VerifyingKey(key_bytes))
Esempio n. 15
0
    def Encode(self,
               entropy_bytes: bytes) -> Mnemonic:
        """
        Encode bytes to mnemonic phrase.

        Args:
            entropy_bytes (bytes): Entropy bytes

        Returns:
            Mnemonic object: Encoded mnemonic

        Raises:
            ValueError: If bytes length is not valid or a mnemonic cannot be generated
        """

        # Check entropy length
        entropy_int = BytesUtils.ToInteger(entropy_bytes)
        if not ElectrumV2EntropyGenerator.AreEntropyBitsEnough(entropy_int):
            raise ValueError("Entropy bit length is not enough for generating a valid mnemonic")

        # Encode to words
        n = self.m_words_list.Length()
        mnemonic = []
        while entropy_int > 0:
            word_idx = entropy_int % n
            entropy_int //= n
            mnemonic.append(self.m_words_list.GetWordAtIdx(word_idx))

        # Check if the mnemonic is valid
        mnemonic_obj = ElectrumV2Mnemonic.FromList(mnemonic)
        if not ElectrumV2MnemonicUtils.IsValidMnemonic(mnemonic_obj, self.m_mnemonic_type):
            raise ValueError("Entropy bytes are not suitable for generating a valid mnemonic")

        return mnemonic_obj
Esempio n. 16
0
    def DecodeAddr(addr: str, **kwargs: Any) -> bytes:
        """
        Decode a Tron address to bytes.

        Args:
            addr (str): Address string
            **kwargs  : Not used

        Returns:
            bytes: Public key hash bytes

        Raises:
            ValueError: If the address encoding is not valid
        """

        try:
            # Decode from base58
            addr_dec = Base58Decoder.CheckDecode(addr)
        except Base58ChecksumError as ex:
            raise ValueError("Invalid base58 checksum") from ex
        else:
            # Validate length
            AddrDecUtils.ValidateLength(
                addr_dec, (EthAddrConst.ADDR_LEN // 2) +
                len(CoinsConf.Tron.Params("addr_prefix")))
            # Validate and remove prefix
            addr_no_prefix = AddrDecUtils.ValidateAndRemovePrefix(
                addr_dec, CoinsConf.Tron.Params("addr_prefix"))

            return EthAddrDecoder.DecodeAddr(
                CoinsConf.Ethereum.Params("addr_prefix") +
                BytesUtils.ToHexString(addr_no_prefix),
                skip_chksum_enc=True)
Esempio n. 17
0
    def DecodeAddr(addr: str,
                   **kwargs: Any) -> bytes:
        """
        Decode a OKEx Chain address to bytes.

        Args:
            addr (str): Address string
            **kwargs  : Not used

        Returns:
            bytes: Public key hash bytes

        Raises:
            ValueError: If the address encoding is not valid
        """
        try:
            addr_dec_bytes = Bech32Decoder.Decode(CoinsConf.OkexChain.Params("addr_hrp"),
                                                  addr)
        except Bech32ChecksumError as ex:
            raise ValueError("Invalid bech32 checksum") from ex
        else:
            return EthAddrDecoder.DecodeAddr(
                CoinsConf.Ethereum.Params("addr_prefix") + BytesUtils.ToHexString(addr_dec_bytes),
                skip_chksum_enc=True
            )
Esempio n. 18
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())
    def Encode(self, entropy_bytes: bytes) -> Mnemonic:
        """
        Encode bytes to mnemonic phrase.

        Args:
            entropy_bytes (bytes): Entropy bytes (accepted lengths in bits: 128, 160, 192, 224, 256)

        Returns:
            Mnemonic object: Encoded mnemonic

        Raises:
            ValueError: If entropy is not valid
        """

        # Check entropy length
        entropy_byte_len = len(entropy_bytes)
        if not Bip39EntropyGenerator.IsValidEntropyByteLen(entropy_byte_len):
            raise ValueError(
                f"Entropy byte length ({entropy_byte_len}) is not valid")

        # Convert entropy to binary string
        entropy_bin_str = BytesUtils.ToBinaryStr(entropy_bytes,
                                                 entropy_byte_len * 8)
        # Get entropy hash as binary string
        entropy_hash_bin_str = BytesUtils.ToBinaryStr(
            CryptoUtils.Sha256(entropy_bytes),
            CryptoUtils.Sha256DigestSize() * 8)
        # Get mnemonic binary string by concatenating entropy and checksum
        mnemonic_bin_str = entropy_bin_str + entropy_hash_bin_str[:entropy_byte_len
                                                                  // 4]

        # Get mnemonic from entropy
        mnemonic = []
        for i in range(
                len(mnemonic_bin_str) // Bip39MnemonicConst.WORD_BIT_LEN):
            # Get current word index
            word_bin_str = (
                mnemonic_bin_str[i * Bip39MnemonicConst.WORD_BIT_LEN:(i + 1) *
                                 Bip39MnemonicConst.WORD_BIT_LEN])
            word_idx = IntegerUtils.FromBinaryStr(word_bin_str)
            # Get word at given index
            mnemonic.append(self.m_words_list.GetWordAtIdx(word_idx))

        return Bip39Mnemonic.FromList(mnemonic)
Esempio n. 20
0
class P2TRConst:
    """Class container for P2TR constants."""

    # Secp256k1 field size
    FIELD_SIZE: int = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
    # SHA256 of "TapTweak"
    TAP_TWEAK_SHA256: bytes = BytesUtils.FromHexString(
        "e80fe1639c9ca050e3af1b39c143c63e429cbceb15d940fbb5c5a1f4af57c5e9"
    )
    # Witness version is fixed to one for P2TR
    WITNESS_VER: int = 1
Esempio n. 21
0
    def ComputeChecksum(payload_bytes: bytes) -> bytes:
        """
        Compute checksum in Stellar format.

        Args:
            payload_bytes (bytes): Payload bytes

        Returns:
            bytes: Computed checksum
        """
        return BytesUtils.Reverse(CryptoUtils.XModemCrc(payload_bytes))
Esempio n. 22
0
    def ComputeChecksum(pub_key_bytes: bytes) -> bytes:
        """
        Compute checksum in Nano format.

        Args:
            pub_key_bytes (bytes): Public key bytes

        Returns:
            bytes: Computed checksum
        """
        return BytesUtils.Reverse(
            CryptoUtils.Blake2b(pub_key_bytes,
                                digest_size=NanoAddrConst.CHECKSUM_BYTE_LEN))
Esempio n. 23
0
    def FromBytes(cls, point_bytes: bytes) -> IPoint:
        """
        Construct class from point bytes.

        Args:
            point_bytes (bytes): Point bytes

        Returns:
            IPoint: IPoint object
        """
        try:
            return cls(
                ellipticcurve.PointJacobi.from_bytes(curve_256, point_bytes))
        except keys.MalformedPointError as ex:
            raise ValueError("Invalid point key bytes") from ex
        # ECDSA < 0.17 doesn't have from_bytes method for PointJacobi
        except AttributeError:
            return cls.FromCoordinates(
                BytesUtils.ToInteger(
                    point_bytes[:EcdsaKeysConst.POINT_COORD_BYTE_LEN]),
                BytesUtils.ToInteger(
                    point_bytes[EcdsaKeysConst.POINT_COORD_BYTE_LEN:]))
Esempio n. 24
0
    def FromBytes(cls, index_bytes: bytes) -> Bip32KeyIndex:
        """
        Construct class from bytes.

        Args:
            index_bytes (bytes): Key index bytes

        Returns:
            Bip32KeyIndex object: Bip32KeyIndex object

        Raises:
            ValueError: If the index is not valid
        """
        return cls(BytesUtils.ToInteger(index_bytes))
Esempio n. 25
0
    def TweakPublicKey(pub_key: IPublicKey) -> bytes:
        """
        Tweak a public key as defined by BIP-0086.
        tweaked_pub_key = lift_x(pub_key.X()) + int(HashTapTweak(bytes(pub_key.X()))) * G

        Args:
            pub_key (IPublicKey object): Public key

        Returns:
            bytes: X coordinate of the tweaked public key
        """
        h = _P2TRUtils.HashTapTweak(pub_key)
        out_point = _P2TRUtils.LiftX(pub_key) + (BytesUtils.ToInteger(h) * Secp256k1.Generator())
        return IntegerUtils.ToBytes(out_point.X())
Esempio n. 26
0
    def ComputeKeys(self,
                    minor_idx: int,
                    major_idx: int) -> Tuple[MoneroPublicKey, MoneroPublicKey]:
        """
        Compute the public keys of the specified subaddress.

        Args:
            minor_idx (int): Minor index (i.e. subaddress index)
            major_idx (int): Major index (i.e. account index)

        Returns:
            tuple[MoneroPublicKey, MoneroPublicKey]: Computed public spend key (index 0) and public view key (index 1)

        Raises:
            ValueError: If one of the indexes is not valid
        """
        if minor_idx < 0 or minor_idx > MoneroSubaddressConst.SUBADDR_MAX_IDX:
            raise ValueError(f"Invalid minor index ({minor_idx})")
        if major_idx < 0 or major_idx > MoneroSubaddressConst.SUBADDR_MAX_IDX:
            raise ValueError(f"Invalid major index ({major_idx})")

        # Subaddress 0,0 is the primary address
        if minor_idx == 0 and major_idx == 0:
            return self.m_pub_skey, self.m_pub_vkey

        # Convert indexes to bytes
        major_idx_bytes = IntegerUtils.ToBytes(major_idx,
                                               bytes_num=MoneroSubaddressConst.SUBADDR_IDX_BYTE_LEN,
                                               endianness="little")
        minor_idx_bytes = IntegerUtils.ToBytes(minor_idx,
                                               bytes_num=MoneroSubaddressConst.SUBADDR_IDX_BYTE_LEN,
                                               endianness="little")

        # m = Kekkak256("SubAddr" + master_priv_vkey + major_idx + minor_idx)
        m = CryptoUtils.Kekkak256(MoneroSubaddressConst.SUBADDR_PREFIX
                                  + self.m_priv_vkey.Raw().ToBytes()
                                  + major_idx_bytes
                                  + minor_idx_bytes)
        m_int = BytesUtils.ToInteger(m, endianness="little")

        # Compute subaddress public spend key
        # D = master_pub_skey + m * B
        subaddr_pub_skey_point = self.m_pub_skey.KeyObject().Point() + (Ed25519Monero.Generator() * m_int)

        # Compute subaddress public view key
        # C = master_priv_vkey * D
        subaddr_pub_vkey_point = subaddr_pub_skey_point * self.m_priv_vkey.Raw().ToInt("little")

        return (MoneroPublicKey.FromBytes(subaddr_pub_skey_point.RawEncoded().ToBytes()),
                MoneroPublicKey.FromBytes(subaddr_pub_vkey_point.RawEncoded().ToBytes()))
    def AreEntropyBitsEnough(entropy: Union[bytes, int]) -> bool:
        """
        Get if the entropy bits are enough to generate a valid mnemonic.

        Args:
            entropy (bytes or int): Entropy

        Returns:
            bool: True if enough, false otherwise
        """
        if isinstance(entropy, bytes):
            entropy = BytesUtils.ToInteger(entropy)
        entropy_bit_len = 0 if entropy <= 0 else math.floor(
            math.log(entropy, 2))
        return ElectrumV2EntropyGenerator.IsValidEntropyBitLen(entropy_bit_len)
Esempio n. 28
0
    def ScReduce(data_bytes: bytes) -> bytes:
        """
        Convert the specified bytes to integer and return its lowest 32-bytes modulo ed25519-order.
        This ensures that the result is a valid ed25519 scalar to be used as Monero private key.

        Args:
            data_bytes (bytes): Data bytes

        Returns:
            bytes: Lowest 32-bytes modulo ed25519-order
        """
        data_int = BytesUtils.ToInteger(data_bytes, endianness="little")
        return IntegerUtils.ToBytes(data_int % Ed25519Monero.Order(),
                                    bytes_num=32,
                                    endianness="little")
Esempio n. 29
0
    def PassPoint(passfactor: bytes) -> bytes:
        """
        Compute the passpoint as specified in BIP38 (with EC multiplication).

        Args:
            passfactor (bytes): Passfactor

        Returns:
            bytes: Passpoint bytes in compressed format
        """

        # Compute passpoint
        passpoint = Secp256k1PublicKey.FromPoint(Secp256k1.Generator() * BytesUtils.ToInteger(passfactor))
        # Return it as a compressed public key
        return passpoint.RawCompressed().ToBytes()
Esempio n. 30
0
    def _CkdPub(self, index: Bip32KeyIndex) -> Bip32Base:
        """
        Create a child key of the specified index using public derivation.

        Args:
            index (Bip32KeyIndex object): Key index

        Returns:
            Bip32Base object: Bip32Base object

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

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

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

        # Compute Z and chain code
        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")

        # Compute the new public key point: PKEY + 8ZL * G
        pub_key_point = self.m_pub_key.Point() + (
            (zl_int * 8) * curve.Generator())
        # If the public key is the identity point (0, 1) discard the child
        if pub_key_point.X() == 0 and pub_key_point.Y() == 1:
            raise Bip32KeyError(
                "Computed public child key is not valid, very unlucky index")

        return Bip32Ed25519Kholaw(
            priv_key=None,
            pub_key=Ed25519KholawPublicKey.FromPoint(pub_key_point),
            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())