Beispiel #1
0
 def sign_data(cls, pri_key: bytes, digest_bytes: bytes):
     privkey = PrivateKey(pri_key)
     # we expect to have a private key as bytes. unhexlify it before passing.
     item = cls()
     item.pub_key = privkey.public_key.format()
     item.digest_bytes = digest_bytes
     item.sig_ser = privkey.sign(digest_bytes, hasher=None)
     return item
Beispiel #2
0
 async def sign_message(cls, pri_key: bytes, message):
     # we expect to have a private key as bytes. unhexlify it before passing
     privkey = PrivateKey(pri_key)
     item = cls()
     message = VarInt(len(message)).encode() + message
     item.pub_key = privkey.public_key.format()
     # item.digest_bytes = digest_bytes
     item.sig_ser = privkey.sign(MESSAGE_TEMPLATE.format(message).encode())
     return item
Beispiel #3
0
class Wallet(BaseWallet):

    HD_PATH = "44'/714'/0'/0/0"

    def __init__(self, private_key, env: Optional[BinanceEnvironment] = None):
        super().__init__(env)
        self._private_key = private_key
        self._pk = PrivateKey(bytes.fromhex(self._private_key))
        self._public_key = self._pk.public_key.format(compressed=True)
        self._address = address_from_public_key(self._public_key,
                                                self._env.hrp)

    @classmethod
    def create_random_wallet(
            cls,
            language: MnemonicLanguage = MnemonicLanguage.ENGLISH,
            env: Optional[BinanceEnvironment] = None):
        """ Create wallet with random mnemonic code """
        m = Mnemonic(language.value)
        phrase = m.generate()
        return cls.create_wallet_from_mnemonic(phrase, env=env)

    @classmethod
    def create_wallet_from_mnemonic(cls,
                                    mnemonic: str,
                                    env: Optional[BinanceEnvironment] = None):
        """ Create wallet with random mnemonic code """
        seed = Mnemonic.to_seed(mnemonic)
        new_wallet = Bip32Wallet.from_master_secret(seed=seed, network='BTC')
        child = new_wallet.get_child_for_path(Wallet.HD_PATH)
        return cls(child.get_private_key_hex().decode(), env=env)

    @property
    def private_key(self):
        return self._private_key

    def sign_message(self, msg_bytes):
        # check if ledger wallet
        sig = self._pk.sign(msg_bytes)
        return serialize_compact(raw_sig=der_to_cdata(der=sig))
class BaseKey:
    """This class represents a point on the elliptic curve secp256k1 and
    provides all necessary cryptographic functionality. You shouldn't use
    this class directly.

    :param wif: A private key serialized to the Wallet Import Format. If the
                argument is not supplied, a new private key will be created.
                The WIF compression flag will be adhered to, but the version
                byte is disregarded. Compression will be used by all new keys.
    :type wif: ``str``
    :raises TypeError: If ``wif`` is not a ``str``.
    """
    def __init__(self, wif=None):
        if wif:
            if isinstance(wif, str):
                private_key_bytes, compressed, version = wif_to_bytes(wif)
                self._pk = ECPrivateKey(private_key_bytes)
            elif isinstance(wif, ECPrivateKey):
                self._pk = wif
                compressed = True
            else:
                raise TypeError('Wallet Import Format must be a string.')
        else:
            self._pk = ECPrivateKey()
            compressed = True

        self._public_point = None
        self._public_key = self._pk.public_key.format(compressed=compressed)

    @property
    def public_key(self):
        """The public point serialized to bytes."""
        return self._public_key

    @property
    def public_point(self):
        """The public point (x, y)."""
        if self._public_point is None:
            self._public_point = Point(*public_key_to_coords(self._public_key))
        return self._public_point

    def sign(self, data):
        """Signs some data which can be verified later by others using
        the public key.

        :param data: The message to sign.
        :type data: ``bytes``
        :returns: A signature compliant with BIP-62.
        :rtype: ``bytes``
        """
        return self._pk.sign(data)

    def verify(self, signature, data):
        """Verifies some data was signed by this private key.

        :param signature: The signature to verify.
        :type signature: ``bytes``
        :param data: The data that was supposedly signed.
        :type data: ``bytes``
        :rtype: ``bool``
        """
        return self._pk.public_key.verify(signature, data)

    def pub_to_hex(self):
        """:rtype: ``str`` """
        return bytes_to_hex(self.public_key)

    def to_hex(self):
        """:rtype: ``str``"""
        return self._pk.to_hex()

    def to_bytes(self):
        """:rtype: ``bytes``"""
        return self._pk.secret

    def to_der(self):
        """:rtype: ``bytes``"""
        return self._pk.to_der()

    def to_pem(self):
        """:rtype: ``bytes``"""
        return self._pk.to_pem()

    def to_int(self):
        """:rtype: ``int``"""
        return self._pk.to_int()

    def is_compressed(self):
        """Returns whether or not this private key corresponds to a compressed
        public key.

        :rtype: ``bool``
        """
        return True if len(self.public_key) == 33 else False

    def __eq__(self, other):
        return self.to_int() == other.to_int()