def Encode(cls, value: Any) -> bytes:
        """
        Encode the specified value to bytes.

        Args:
            value (any): Value to be encoded

        Returns:
            bytes: Encoded value
        """

        # Single-byte mode
        if value <= SubstrateScaleCUintEncoderConst.SINGLE_BYTE_MODE_MAX_VAL:
            return IntegerUtils.ToBytes(value << 2, 1, endianness="little")
        # Two-byte mode
        if value <= SubstrateScaleCUintEncoderConst.TWO_BYTE_MODE_MAX_VAL:
            return IntegerUtils.ToBytes((value << 2) | 0b01,
                                        2,
                                        endianness="little")
        # Four-byte mode
        if value <= SubstrateScaleCUintEncoderConst.FOUR_BYTE_MODE_MAX_VAL:
            return IntegerUtils.ToBytes((value << 2) | 0b10,
                                        4,
                                        endianness="little")
        # Big-integer mode
        if value <= SubstrateScaleCUintEncoderConst.BIG_INTEGER_MODE_MAX_VAL:
            value_bytes = IntegerUtils.ToBytes(value, endianness="little")
            len_bytes = IntegerUtils.ToBytes(
                (len(value_bytes) - 4 << 2) | 0b11, 1, endianness="little")
            return len_bytes + value_bytes

        raise ValueError(f"Out of range integer value ({value})")
Exemplo n.º 2
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()))
Exemplo n.º 3
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")
Exemplo n.º 4
0
    def OwnerEntropyWithLotSeq(lot_num: int,
                               sequence_num: int) -> bytes:
        """
        Compute the owner entropy as specified in BIP38 (with EC multiplication) with lot and sequence numbers.

        Args:
            lot_num (int)     : Lot number
            sequence_num (int): Sequence number

        Returns:
            bytes: Owner entropy

        Raises:
            ValueError: If lot or sequence number is not valid
        """

        # Check lot and sequence numbers
        if lot_num < Bip38EcConst.LOT_NUM_MIN_VAL or lot_num > Bip38EcConst.LOT_NUM_MAX_VAL:
            raise ValueError(f"Invalid lot number ({lot_num})")
        if sequence_num < Bip38EcConst.SEQ_NUM_MIN_VAL or sequence_num > Bip38EcConst.SEQ_NUM_MAX_VAL:
            raise ValueError(f"Invalid sequence number ({sequence_num})")

        # Generate random owner salt (4 bytes)
        owner_salt = os.urandom(Bip38EcConst.OWNER_SALT_WITH_LOT_SEQ_BYTE_LEN)
        # Compute lot sequence
        lot_sequence = IntegerUtils.ToBytes((lot_num * (Bip38EcConst.SEQ_NUM_MAX_VAL + 1)) + sequence_num,
                                            bytes_num=4)
        # Compute owner entropy
        return owner_salt + lot_sequence
Exemplo n.º 5
0
    def EncodeKey(pub_key: Union[bytes, IPublicKey],
                  **kwargs: Any) -> str:
        """
        Encode a public key to Stellar address.

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

        Other Parameters:
            addr_type (XlmAddrTypes): Address type

        Returns:
            str: Address string

        Raises:
            ValueError: If the public key is not valid
            TypeError: If the public key is not ed25519 or address type is not a XlmAddrTypes enum
        """

        # Get and check address type
        addr_type = kwargs["addr_type"]
        if not isinstance(addr_type, XlmAddrTypes):
            raise TypeError("Address type is not an enumerative of XlmAddrTypes")

        # Get public key
        pub_key_obj = AddrKeyValidator.ValidateAndGetEd25519Key(pub_key)
        payload_bytes = IntegerUtils.ToBytes(addr_type) + pub_key_obj.RawCompressed().ToBytes()[1:]

        # Compute checksum
        checksum_bytes = _XlmAddrUtils.ComputeChecksum(payload_bytes)
        # Encode to base32
        return Base32Encoder.EncodeNoPadding(payload_bytes + checksum_bytes)
Exemplo n.º 6
0
    def WordsToBytesChunk(word1: str, word2: str, word3: str,
                          words_list: MnemonicWordsList,
                          endianness: str) -> bytes:
        """
        Get bytes chunk from words.

        Args:
            word1 (str)                          : Word 1
            word2 (str)                          : Word 2
            word3 (str)                          : Word 3
            words_list (MnemonicWordsList object): Mnemonic list
            endianness (str)                     : Bytes endianness

        Returns:
            bytes: Bytes chunk
        """
        n = words_list.Length()

        # Get the word indexes
        word1_idx = words_list.GetWordIdx(word1)
        word2_idx = words_list.GetWordIdx(word2) % n
        word3_idx = words_list.GetWordIdx(word3) % n

        # Get back the bytes chunk
        bytes_chunk = word1_idx + (n *
                                   ((word2_idx - word1_idx) % n)) + (n * n * (
                                       (word3_idx - word2_idx) % n))

        return IntegerUtils.ToBytes(bytes_chunk,
                                    bytes_num=4,
                                    endianness=endianness)
Exemplo n.º 7
0
    def RawDecoded(self) -> DataBytes:
        """
        Return the decoded point raw bytes.

        Returns:
            DataBytes object: DataBytes object
        """
        try:
            return DataBytes(self.m_point.to_bytes())
        # ECDSA < 0.17 doesn't have to_bytes method for PointJacobi
        except AttributeError:
            x_bytes = IntegerUtils.ToBytes(self.m_point.x(),
                                           EcdsaKeysConst.POINT_COORD_BYTE_LEN)
            y_bytes = IntegerUtils.ToBytes(self.m_point.y(),
                                           EcdsaKeysConst.POINT_COORD_BYTE_LEN)

            return DataBytes(x_bytes + y_bytes)
Exemplo n.º 8
0
    def ToBytes(self) -> bytes:
        """
        Get the depth as bytes.

        Returns:
            bytes: Depth bytes
        """
        return IntegerUtils.ToBytes(self.m_depth, bytes_num=self.Length())
Exemplo n.º 9
0
    def Generate(self) -> bytes:
        """
        Generate random entropy bytes.

        Returns:
            bytes: Generated entropy bytes
        """
        return (os.urandom(self.m_bit_len // 8) if self.m_bit_len % 8 == 0 else
                IntegerUtils.ToBytes(secrets.randbits(self.m_bit_len)))
    def __mul__(self,
                scalar: int) -> IPoint:
        """
        Multiply point by a scalar.

        Args:
            scalar (int): scalar

        Returns:
            IPoint object: IPoint object
        """
        return Secp256k1PointCoincurve(self.m_pub_key.multiply(IntegerUtils.ToBytes(scalar)))
Exemplo n.º 11
0
    def ToBytes(self, endianness: str = "big") -> bytes:
        """
        Get the key index as bytes.

        Args:
            endianness (str): Endianness

        Returns:
            bytes: Key bytes
        """
        return IntegerUtils.ToBytes(self.m_idx,
                                    bytes_num=self.Length(),
                                    endianness=endianness)
Exemplo n.º 12
0
    def HashTapTweak(pub_key: IPublicKey) -> bytes:
        """
        Compute the HashTapTweak of the specified public key.

        Args:
            pub_key (IPublicKey object): Public key

        Returns:
            bytes: Computed hash
        """

        # Use the pre-computed SHA256 of "TapTweak" for speeding up
        return _P2TRUtils.TaggedHash(P2TRConst.TAP_TWEAK_SHA256,
                                     IntegerUtils.ToBytes(pub_key.Point().X()))
Exemplo n.º 13
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())
Exemplo n.º 14
0
    def ComputeChecksum(pub_key_hash: bytes,
                        addr_type: FillAddrTypes) -> bytes:
        """
        Compute checksum in EOS format.

        Args:
            pub_key_hash (bytes)     : Public key hash
            addr_type (FillAddrTypes): Address type

        Returns:
            bytes: Computed checksum
        """
        addr_type_byte = IntegerUtils.ToBytes(addr_type)
        return CryptoUtils.Blake2b(addr_type_byte + pub_key_hash,
                                   digest_size=FilAddrConst.CHECKSUM_BYTE_LEN)
Exemplo n.º 15
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")
Exemplo n.º 16
0
    def __DeriveKey(self, change_idx: int, addr_idx: int) -> IPrivateKey:
        """
        Derive the key with the specified change and address indexes.

        Args:
            change_idx (int): Change index
            addr_idx (int)  : Address index

        Returns:
            Bip32Base object: Bip32Base object
        """
        seq_bytes = self.__GetSequence(change_idx, addr_idx)
        priv_key_int = (self.MasterPrivateKey().Raw().ToInt() +
                        BytesUtils.ToInteger(seq_bytes)) % Secp256k1.Order()
        return Secp256k1PrivateKey.FromBytes(
            IntegerUtils.ToBytes(priv_key_int, Secp256k1PrivateKey.Length()))
Exemplo n.º 17
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())
Exemplo 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())
Exemplo n.º 19
0
    def RawEncoded(self) -> DataBytes:
        """
        Return the encoded point raw bytes.

        Returns:
            DataBytes object: DataBytes object
        """
        try:
            return DataBytes(self.m_point.to_bytes("compressed"))
        # ECDSA < 0.17 doesn't have to_bytes method for PointJacobi
        except AttributeError:
            x_bytes = IntegerUtils.ToBytes(self.m_point.x(),
                                           EcdsaKeysConst.POINT_COORD_BYTE_LEN)
            if self.m_point.y() & 1:
                enc_bytes = b"\x03" + x_bytes
            else:
                enc_bytes = b"\x02" + x_bytes
            return DataBytes(enc_bytes)
Exemplo n.º 20
0
    def _EncodeWithBytesLength(value: Any, bytes_len: int) -> bytes:
        """
        Encode the specified value to bytes with the specified bytes length.

        Args:
            value (any)    : Value to be encoded
            bytes_len (int): Bytes length

        Returns:
            bytes: Encoded value
        """
        if isinstance(value, str):
            value = int(value)

        max_val = (1 << (bytes_len * 8)) - 1
        if value < 0 or value > max_val:
            raise ValueError(f"Invalid integer value ({value})")
        return IntegerUtils.ToBytes(value, bytes_len, endianness="little")
Exemplo n.º 21
0
    def __SetFlagbyteBits(magic: bytes,
                          pub_key_mode: Bip38PubKeyModes) -> bytes:
        """
        Set flagbyte bits and return it.

        Args:
            magic (bytes)                  : Magic
            pub_key_mode (Bip38PubKeyModes): Public key mode

        Returns:
            bytes: Flagbyte
        """
        flagbyte_int = 0
        if pub_key_mode == Bip38PubKeyModes.COMPRESSED:
            flagbyte_int = BitUtils.SetBit(flagbyte_int, Bip38EcConst.FLAG_BIT_COMPRESSED)
        if magic == Bip38EcConst.INT_PASS_MAGIC_WITH_LOT_SEQ:
            flagbyte_int = BitUtils.SetBit(flagbyte_int, Bip38EcConst.FLAG_BIT_LOT_SEQ)

        return IntegerUtils.ToBytes(flagbyte_int)
Exemplo n.º 22
0
    def Decode(self, mnemonic: Union[str, Mnemonic]) -> bytes:
        """
        Decode a mnemonic phrase to bytes (no checksum).

        Args:
            mnemonic (str or Mnemonic object): Mnemonic

        Returns:
            bytes: Decoded bytes

        Raises:
            MnemonicChecksumError: If checksum is not valid
            ValueError: If mnemonic is not valid
        """
        mnemonic_obj = ElectrumV2Mnemonic.FromString(mnemonic) if isinstance(
            mnemonic, str) else mnemonic

        # Check mnemonic length
        if mnemonic_obj.WordsCount(
        ) not in ElectrumV2MnemonicConst.MNEMONIC_WORD_NUM:
            raise ValueError(
                f"Mnemonic words count is not valid ({mnemonic_obj.WordsCount()})"
            )

        # Check mnemonic validity:
        if not ElectrumV2MnemonicUtils.IsValidMnemonic(mnemonic_obj,
                                                       self.m_mnemonic_type):
            raise ValueError("Invalid mnemonic")

        # Get words
        words = mnemonic_obj.ToList()
        # Detect language if it was not specified at construction
        words_list, _ = self._FindLanguage(mnemonic_obj)

        # Decode words
        n = words_list.Length()
        entropy_int = 0
        for word in reversed(words):
            entropy_int = (entropy_int * n) + words_list.GetWordIdx(word)

        return IntegerUtils.ToBytes(entropy_int)
Exemplo n.º 23
0
    def Encode(data_bytes: bytes, ss58_format: int) -> str:
        """
        Encode bytes into a SS58 string.

        Args:
            data_bytes (bytes): Data bytes (32-byte length)
            ss58_format (int) : SS58 format

        Returns:
            str: SS58 encoded string

        Raises:
            ValueError: If parameters are not valid
        """

        # Check parameters
        if len(data_bytes) != SS58Const.DATA_BYTE_LEN:
            raise ValueError(f"Invalid data length ({len(data_bytes)})")
        if ss58_format < 0 or ss58_format > SS58Const.FORMAT_MAX_VAL:
            raise ValueError(f"Invalid SS58 format ({ss58_format})")
        if ss58_format in SS58Const.RESERVED_FORMATS:
            raise ValueError(f"Invalid SS58 format ({ss58_format})")

        # Simple account
        if ss58_format <= SS58Const.SIMPLE_ACCOUNT_FORMAT_MAX_VAL:
            ss58_format_bytes = IntegerUtils.ToBytes(ss58_format)
        # Full address
        else:
            # 0b00HHHHHH_MMLLLLLL -> (0b01LLLLLL, 0bHHHHHHMM)
            ss58_format_bytes = bytes([
                ((ss58_format & 0x00FC) >> 2) | 0x0040,
                (ss58_format >> 8) | ((ss58_format & 0x0003) << 6)
            ])

        # Get payload
        payload = ss58_format_bytes + data_bytes
        # Compute checksum
        checksum = _SS58Utils.ComputeChecksum(payload)
        # Encode
        return Base58Encoder.Encode(payload + checksum)
Exemplo n.º 24
0
    def FindPda(cls, seeds: List[bytes], program_id: str) -> str:
        """
        Find a valid PDA (Program Derived Address) and its corresponding bump seed.

        Args:
            seeds (list[bytes]): List of seeds bytes
            program_id (str)   : Program ID

        Returns:
            str: Found PDA

        Raises:
            ValueError: If the PDA cannot be found or the specified seeds or program ID are not valid
        """

        # Check if seeds are valid
        if len(seeds) > SplTokenConst.SEEDS_MAX_NUM:
            raise ValueError(f"Seeds length is not valid ({len(seeds)})")
        for seed in seeds:
            if len(seed) > Ed25519PublicKey.CompressedLength() - 1:
                raise ValueError(f"Seed length is not valid ({len(seeds)})")

        program_id_bytes = SolAddrDecoder.DecodeAddr(program_id)
        bump_seed = SplTokenConst.SEED_BUMP_MAX_VAL
        for _ in range(SplTokenConst.SEED_BUMP_MAX_VAL):
            # Add bump to seeds
            seeds_with_bump = list(seeds)
            seeds_with_bump.append(IntegerUtils.ToBytes(bump_seed))
            # Try to create PDA
            try:
                return cls.__CreatePda(seeds_with_bump, program_id_bytes)
            except ValueError:
                # Continue with the next bump seed if PDA is not valid
                bump_seed -= 1

        # Very unlucky case
        raise ValueError("Unable to find a valid PDA")
Exemplo n.º 25
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:]
Exemplo n.º 26
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
Exemplo n.º 27
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())
Exemplo n.º 28
0
def encode_int(int_val: int) -> bytes:
    return IntegerUtils.ToBytes(int_val, 32, endianness="little")
Exemplo n.º 29
0
    b"e9b6062841bb977ad21de71ec961900633c26f21384e015b014a637a614995",
]

# Private keys with invalid lengths
TEST_VECT_PRIV_KEY_INVALID_LEN = [
    b"132750b8489385430d8bfa3871ade97da7f5d5ef134a5c85184f88743b526e",
    b"132750b8489385430d8bfa3871ade97da7f5d5ef134a5c85184f88743b526e71d0",
]

# Tests for ed25519 invalid private keys
TEST_VECT_ED25519_PRIV_KEY_INVALID = TEST_VECT_PRIV_KEY_INVALID_LEN

# Tests for ed25519-monero invalid private keys (add key equal to curve order)
TEST_VECT_ED25519_MONERO_PRIV_KEY_INVALID = TEST_VECT_PRIV_KEY_INVALID_LEN + [
    binascii.hexlify(
        IntegerUtils.ToBytes(
            Ed25519Monero.Order(), bytes_num=32, endianness="little")),
]

# Tests for nist256p1 invalid private keys (add zero key and key equal to curve order)
TEST_VECT_NIST256P1_PRIV_KEY_INVALID = TEST_VECT_PRIV_KEY_INVALID_LEN + [
    b"0000000000000000000000000000000000000000000000000000000000000000",
    binascii.hexlify(IntegerUtils.ToBytes(Nist256p1.Order(), bytes_num=32)),
]
# Tests for secp256k1 invalid private keys (add zero key and key equal to curve order)
TEST_VECT_SECP256K1_PRIV_KEY_INVALID = TEST_VECT_PRIV_KEY_INVALID_LEN + [
    b"0000000000000000000000000000000000000000000000000000000000000000",
    binascii.hexlify(IntegerUtils.ToBytes(Secp256k1.Order(), bytes_num=32)),
]

# Tests for sr25519 invalid private keys
TEST_VECT_SR25519_PRIV_KEY_INVALID = [
Exemplo n.º 30
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