Exemple #1
0
    def DecodeAddr(addr: str, **kwargs: Any) -> bytes:
        """
        Decode a P2PKH address to bytes.

        Args:
            addr (str): Address string

        Other Parameters:
            net_ver (bytes)                        : Net address version
            base58_alph (Base58Alphabets, optional): Base58 alphabet, Bitcoin alphabet by default

        Returns:
            bytes: Public key hash bytes

        Raises:
            ValueError: If the address encoding is not valid
        """
        net_ver_bytes = kwargs["net_ver"]
        base58_alph = kwargs.get("base58_alph", Base58Alphabets.BITCOIN)

        try:
            addr_dec_bytes = Base58Decoder.CheckDecode(addr, base58_alph)
        except Base58ChecksumError as ex:
            raise ValueError("Invalid base58 checksum") from ex
        else:
            # Validate length
            AddrDecUtils.ValidateLength(
                addr_dec_bytes,
                CryptoUtils.Hash160DigestSize() + len(net_ver_bytes))
            # Validate and remove prefix
            return AddrDecUtils.ValidateAndRemovePrefix(
                addr_dec_bytes, net_ver_bytes)
Exemple #2
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)
    def DeserializeKey(self,
                       key_net_ver: KeyNetVersions) -> None:
        """ Deserialize a key.

        Args:
            key_net_ver (KeyNetVersions object): Key net versions object
        """

        # Decode key
        key_bytes = Base58Decoder.CheckDecode(self.m_key_str)

        # Check length
        if len(key_bytes) != Bip32KeyDeserConst.EXTENDED_KEY_LEN:
            raise Bip32KeyError("Invalid extended key (wrong length)")

        # Get if key is public/private depending on net version
        if key_bytes[:4] == key_net_ver.Public():
            self.m_is_public = True
        elif key_bytes[:4] == key_net_ver.Private():
            self.m_is_public = False
        else:
            raise Bip32KeyError("Invalid extended key (wrong net version)")

        # De-serialize key
        self.m_depth = key_bytes[4]
        self.m_fprint = key_bytes[5:9]
        self.m_index = ConvUtils.BytesToInteger(key_bytes[9:13])
        self.m_chain = key_bytes[13:45]
        self.m_secret = key_bytes[45:78]
Exemple #4
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)
Exemple #5
0
    def Decode(data_str: str) -> Tuple[int, bytes]:
        """
        Decode bytes from a SS58 string.

        Args:
            data_str (string): Data string

        Returns:
            tuple[int, bytes]: SS58 format and data bytes

        Raises:
            SS58ChecksumError: If checksum is not valid
            ValueError: If the string is not a valid SS58 format
        """

        # Decode string
        dec_bytes = Base58Decoder.Decode(data_str)

        # Full address
        if dec_bytes[0] & 0x40:
            ss58_format_len = 2
            ss58_format = ((dec_bytes[0] & 0x3F) << 2) | (dec_bytes[1] >> 6) | \
                          ((dec_bytes[1] & 0x3F) << 8)
        # Simple account
        else:
            ss58_format_len = 1
            ss58_format = dec_bytes[0]

        # Check format
        if ss58_format in SS58Const.RESERVED_FORMATS:
            raise ValueError(f"Invalid SS58 format ({ss58_format})")

        # Get back data and checksum
        data_bytes = dec_bytes[ss58_format_len:-SS58Const.CHECKSUM_BYTE_LEN]
        checksum_bytes = dec_bytes[-SS58Const.CHECKSUM_BYTE_LEN:]

        # Check data length
        if len(data_bytes) != SS58Const.DATA_BYTE_LEN:
            raise ValueError(f"Invalid data length ({len(data_bytes)})")

        # Compute checksum
        checksum_bytes_got = _SS58Utils.ComputeChecksum(
            dec_bytes[:-SS58Const.CHECKSUM_BYTE_LEN])

        # Verify checksum
        if checksum_bytes != checksum_bytes_got:
            raise SS58ChecksumError(
                f"Invalid checksum (expected {BytesUtils.ToHexString(checksum_bytes_got)}, "
                f"got {BytesUtils.ToHexString(checksum_bytes)})")

        return ss58_format, data_bytes
Exemple #6
0
    def Decode(wif_str: str,
               net_ver: bytes = CoinsConf.BitcoinMainNet.Params("wif_net_ver")) -> Tuple[bytes, WifPubKeyModes]:
        """
        Decode key bytes from a WIF string.

        Args:
            wif_str (str)            : WIF string
            net_ver (bytes, optional): Net version (Bitcoin main net by default)

        Returns:
            tuple[bytes, WifPubKeyModes]: Key bytes (index 0), public key mode (index 1)

        Raises:
            Base58ChecksumError: If the base58 checksum is not valid
            ValueError: If the resulting key is not valid
        """

        # Decode string
        priv_key_bytes = Base58Decoder.CheckDecode(wif_str)

        # Check net version
        if priv_key_bytes[0] != ord(net_ver):
            raise ValueError(
                f"Invalid net version (expected 0x{ord(net_ver):02X}, got 0x{priv_key_bytes[0]:02X})"
            )

        # Remove net version
        priv_key_bytes = priv_key_bytes[1:]

        # Remove suffix if correspond to a compressed public key
        if Secp256k1PrivateKey.IsValidBytes(priv_key_bytes[:-1]):
            # Check the compressed public key suffix
            if priv_key_bytes[-1] != ord(WifConst.COMPR_PUB_KEY_SUFFIX):
                raise ValueError(
                    f"Invalid compressed public key suffix (expected 0x{ord(WifConst.COMPR_PUB_KEY_SUFFIX):02X}, "
                    f"got 0x{priv_key_bytes[-1]:02X})"
                )
            # Remove it
            priv_key_bytes = priv_key_bytes[:-1]
            pub_key_mode = WifPubKeyModes.COMPRESSED
        else:
            if not Secp256k1PrivateKey.IsValidBytes(priv_key_bytes):
                raise ValueError(f"Invalid decoded key ({BytesUtils.ToHexString(priv_key_bytes)})")
            pub_key_mode = WifPubKeyModes.UNCOMPRESSED

        return priv_key_bytes, pub_key_mode
Exemple #7
0
    def Decode(
        wif_str: str, net_addr_ver: bytes = BitcoinConf.WIF_NET_VER.Main()
    ) -> bytes:
        """ Decode key bytes from a WIF string.

        Args:
            wif_str (str)                 : WIF string
            net_addr_ver (bytes, optional): Net address version, default is Bitcoin main network

        Returns:
            bytes: Key bytes

        Raises:
            Base58ChecksumError: If the base58 checksum is not valid
            ValueError: If the resulting key is not valid
        """

        # Decode string
        key_bytes = Base58Decoder.CheckDecode(wif_str)

        # Check net version
        if key_bytes[0] != ord(net_addr_ver):
            raise ValueError("Invalid net version (expected %x, got %x)" %
                             (ord(net_addr_ver), key_bytes[0]))

        # Remove net version
        key_bytes = key_bytes[1:]

        # Remove suffix if correspond to a compressed public key
        if KeyUtils.IsPrivate(key_bytes[:-1]):
            # Check the compressed public key suffix
            if key_bytes[-1] != ord(WifConst.COMPR_PUB_KEY_SUFFIX):
                raise ValueError(
                    "Invalid compressed public key suffix (expected %x, got %x)"
                    % (ord(WifConst.COMPR_PUB_KEY_SUFFIX), key_bytes[-1]))
            # Remove it
            key_bytes = key_bytes[:-1]

        # Check if valid
        if not KeyUtils.IsValid(key_bytes):
            raise ValueError("Invalid decoded key (%s)" %
                             ConvUtils.BytesToHexString(key_bytes))

        return key_bytes
    def DeserializeKey(
        cls,
        ser_key_str: str,
        key_net_ver: Bip32KeyNetVersions = Bip32Const.MAIN_NET_KEY_NET_VERSIONS
    ) -> Bip32DeserializedKey:
        """
        Deserialize a key.

        Args:
            ser_key_str (str)                                 : Serialized key string
            key_net_ver (Bip32KeyNetVersions object, optional): Key net versions (BIP32 main net version by default)

        Returns:
            Bip32DeserializedKey object: Bip32DeserializedKey object

        Raises:
            Bip32KeyError: If the key is not valid
        """

        # Decode key
        ser_key_bytes = Base58Decoder.CheckDecode(ser_key_str)

        # Get if key is public/private depending on the net version
        is_public = cls.__GetIfPublic(ser_key_bytes, key_net_ver)

        # Validate length
        if is_public and len(
                ser_key_bytes) != Bip32KeySerConst.SERIALIZED_PUB_KEY_BYTE_LEN:
            raise Bip32KeyError(
                f"Invalid extended public key (wrong length: {len(ser_key_bytes)})"
            )
        if not is_public and len(
                ser_key_bytes
        ) not in Bip32KeySerConst.SERIALIZED_PRIV_KEY_BYTE_LEN:
            raise Bip32KeyError(
                f"Invalid extended private key (wrong length: {len(ser_key_bytes)})"
            )

        # Get parts back
        key_bytes, key_data = cls.__GetPartsFromBytes(ser_key_bytes, is_public)

        return Bip32DeserializedKey(key_bytes, key_data, is_public)
Exemple #9
0
    def DecodeAddr(addr: str, **kwargs: Any) -> bytes:
        """
        Decode a Tezos address to bytes.

        Args:
            addr (str): Address string

        Other Parameters:
            prefix (XtzAddrPrefixes): Address prefix

        Returns:
            bytes: Public key hash bytes

        Raises:
            ValueError: If the address encoding is not valid
            TypeError: If 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")

        # Decode from base58
        try:
            addr_dec_bytes = Base58Decoder.CheckDecode(addr)
        except Base58ChecksumError as ex:
            raise ValueError("Invalid base58 checksum") from ex
        else:
            # Validate length
            AddrDecUtils.ValidateLength(
                addr_dec_bytes,
                len(prefix.value) + XtzAddrConst.BLAKE2B_BYTE_LEN)
            # Validate and remove prefix
            blake_bytes = AddrDecUtils.ValidateAndRemovePrefix(
                addr_dec_bytes, prefix.value)

            return blake_bytes
Exemple #10
0
    def DecodeAddr(addr: str, **kwargs: Any) -> bytes:
        """
        Decode a Solana address to bytes.

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

        Returns:
            bytes: Public key bytes

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

        # Decode from base58
        addr_dec_bytes = Base58Decoder.Decode(addr)
        # Validate length
        AddrDecUtils.ValidateLength(addr_dec_bytes,
                                    Ed25519PublicKey.CompressedLength() - 1)
        # Validate public key
        AddrDecUtils.ValidatePubKey(addr_dec_bytes, Ed25519PublicKey)

        return addr_dec_bytes
Exemple #11
0
    def DecodeAddr(addr: str, **kwargs: Any) -> bytes:
        """
        Decode a Neo address to bytes.

        Args:
            addr (str): Address string

        Other Parameters:
            ver (bytes): Version

        Returns:
            bytes: Public key hash bytes

        Raises:
            ValueError: If the address encoding is not valid
        """
        ver_bytes = kwargs["ver"]

        try:
            # Decode from base58
            addr_dec_bytes = Base58Decoder.CheckDecode(addr)
        except Base58ChecksumError as ex:
            raise ValueError("Invalid base58 checksum") from ex
        else:
            # Validate length
            AddrDecUtils.ValidateLength(
                addr_dec_bytes,
                CryptoUtils.Hash160DigestSize() + len(ver_bytes))
            # Check version
            ver_got = IntegerUtils.ToBytes(addr_dec_bytes[0])
            if ver_bytes != ver_got:
                raise ValueError(
                    f"Invalid version (expected {BytesUtils.ToHexString(ver_bytes)}, "
                    f"got {BytesUtils.ToHexString(ver_got)})")

            return addr_dec_bytes[1:]
Exemple #12
0
    def DecodeAddr(addr: str, **kwargs: Any) -> bytes:
        """
        Decode an EOS address to bytes.

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

        Returns:
            bytes: Public key bytes

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

        # Validate and remove prefix
        addr_no_prefix = AddrDecUtils.ValidateAndRemovePrefix(
            addr, CoinsConf.Eos.Params("addr_prefix"))
        # Decode from base58
        addr_dec_bytes = Base58Decoder.Decode(addr_no_prefix)
        # Validate length
        AddrDecUtils.ValidateLength(
            addr_dec_bytes,
            Secp256k1PublicKey.CompressedLength() +
            EosAddrConst.CHECKSUM_BYTE_LEN)

        # Get back checksum and public key bytes
        pub_key_bytes, checksum_bytes = AddrDecUtils.SplitPartsByChecksum(
            addr_dec_bytes, EosAddrConst.CHECKSUM_BYTE_LEN)
        # Validate checksum
        AddrDecUtils.ValidateChecksum(pub_key_bytes, checksum_bytes,
                                      _EosAddrUtils.ComputeChecksum)
        # Validate public key
        AddrDecUtils.ValidatePubKey(pub_key_bytes, Secp256k1PublicKey)

        return pub_key_bytes
Exemple #13
0
    def Decrypt(priv_key_enc: str,
                passphrase: str) -> Tuple[bytes, Bip38PubKeyModes]:
        """
        Decrypt the specified private key.

        Args:
            priv_key_enc (str): Encrypted private key bytes
            passphrase (str)  : Passphrase

        Returns:
            tuple[bytes, Bip38PubKeyModes]: Decrypted private key (index 0), public key mode (index 1)

        Raises:
            Base58ChecksumError: If base58 checksum is not valid
            ValueError: If the encrypted key is not valid
        """

        # Decode private key
        priv_key_enc_bytes = Base58Decoder.CheckDecode(priv_key_enc)
        # Check encrypted length
        if len(priv_key_enc_bytes) != Bip38EcConst.ENC_BYTE_LEN:
            raise ValueError(f"Invalid encrypted length ({len(priv_key_enc_bytes)})")

        # Get all the parts back
        prefix = priv_key_enc_bytes[:2]
        flagbyte = IntegerUtils.ToBytes(priv_key_enc_bytes[2])
        address_hash = priv_key_enc_bytes[3:7]
        owner_entropy = priv_key_enc_bytes[7:15]
        encrypted_part_1_lower = priv_key_enc_bytes[15:23]
        encrypted_part_2 = priv_key_enc_bytes[23:]

        # Check prefix
        if prefix != Bip38EcConst.ENC_KEY_PREFIX:
            raise ValueError(f"Invalid prefix ({BytesUtils.ToHexString(prefix)})")
        # Get flagbyte options
        pub_key_mode, has_lot_seq = Bip38EcDecrypter.__GetFlagbyteOptions(flagbyte)

        # Compute passfactor
        passfactor = _Bip38EcUtils.PassFactor(passphrase, owner_entropy, has_lot_seq)
        # Derive key halves from the passpoint, address hash and owner entropy
        derived_half_1, derived_half_2 = _Bip38EcUtils.DeriveKeyHalves(_Bip38EcUtils.PassPoint(passfactor),
                                                                       address_hash,
                                                                       owner_entropy)

        # Get factorb back by decrypting
        factorb = Bip38EcDecrypter.__DecryptAndGetFactorb(encrypted_part_1_lower,
                                                          encrypted_part_2,
                                                          derived_half_1,
                                                          derived_half_2)
        # Compute private key
        priv_key_bytes = Bip38EcDecrypter.__ComputePrivateKey(passfactor, factorb)

        # Verify the address hash
        address_hash_got = Bip38Addr.AddressHash(Secp256k1PrivateKey.FromBytes(priv_key_bytes).PublicKey(),
                                                 pub_key_mode)
        if address_hash != address_hash_got:
            raise ValueError(
                f"Invalid address hash (expected: {BytesUtils.ToHexString(address_hash)}, "
                f"got: {BytesUtils.ToHexString(address_hash_got)})"
            )

        return priv_key_bytes, pub_key_mode
Exemple #14
0
    def Decrypt(priv_key_enc: str,
                passphrase: str) -> Tuple[bytes, Bip38PubKeyModes]:
        """
        Decrypt the specified private key.

        Args:
            priv_key_enc (str): Encrypted private key bytes
            passphrase (str)  : Passphrase

        Returns:
            tuple[bytes, Bip38PubKeyModes]: Decrypted private key (index 0), public key mode (index 1)

        Raises:
            Base58ChecksumError: If base58 checksum is not valid
            ValueError: If the encrypted key is not valid
        """

        # Decode private key
        priv_key_enc_bytes = Base58Decoder.CheckDecode(priv_key_enc)
        # Check length
        if len(priv_key_enc_bytes) != Bip38NoEcConst.ENC_KEY_BYTE_LEN:
            raise ValueError(
                f"Invalid encrypted key length ({len(priv_key_enc_bytes)})")

        # Get all the parts back
        prefix = priv_key_enc_bytes[:2]
        flagbyte = IntegerUtils.ToBytes(priv_key_enc_bytes[2])
        address_hash = priv_key_enc_bytes[3:7]
        encrypted_half_1 = priv_key_enc_bytes[7:23]
        encrypted_half_2 = priv_key_enc_bytes[23:]

        # Check prefix and flagbyte
        if prefix != Bip38NoEcConst.ENC_KEY_PREFIX:
            raise ValueError(
                f"Invalid prefix ({BytesUtils.ToHexString(prefix)})")
        if flagbyte not in (Bip38NoEcConst.FLAGBYTE_COMPRESSED,
                            Bip38NoEcConst.FLAGBYTE_UNCOMPRESSED):
            raise ValueError(
                f"Invalid flagbyte ({BytesUtils.ToHexString(flagbyte)})")

        # Derive key halves from the passphrase and address hash
        derived_half_1, derived_half_2 = _Bip38NoEcUtils.DeriveKeyHalves(
            passphrase, address_hash)
        # Get the private key back by decrypting
        priv_key_bytes = Bip38NoEcDecrypter.__DecryptAndGetPrivKey(
            encrypted_half_1, encrypted_half_2, derived_half_1, derived_half_2)

        # Get public key mode
        pub_key_mode = (Bip38PubKeyModes.COMPRESSED
                        if flagbyte == Bip38NoEcConst.FLAGBYTE_COMPRESSED else
                        Bip38PubKeyModes.UNCOMPRESSED)

        # Verify the address hash
        address_hash_got = _Bip38NoEcUtils.AddressHash(priv_key_bytes,
                                                       pub_key_mode)
        if address_hash != address_hash_got:
            raise ValueError(
                f"Invalid address hash (expected: {BytesUtils.ToHexString(address_hash)}, "
                f"got: {BytesUtils.ToHexString(address_hash_got)})")

        return priv_key_bytes, pub_key_mode