Beispiel #1
0
    def get_key(self, compressed=None):
        """Get the hex-encoded key.

        :param compressed: False if you want a standard 65 Byte key (the most
            standard option). True if you want the compressed 33 Byte form.
            Defaults to None, which in turn uses the self.compressed attribute.
        :type compressed: bool

        PublicKeys consist of an ID byte, the x, and the y coordinates
        on the elliptic curve.

        In the case of uncompressed keys, the ID byte is 04.
        Compressed keys use the SEC1 format:
            If Y is odd: id_byte = 03
            else: id_byte = 02

        Note that I pieced this algorithm together from the pycoin source.

        This is documented in http://www.secg.org/collateral/sec1_final.pdf
        but, honestly, it's pretty confusing.

        I guess this is a pretty big warning that I'm not *positive* this
        will do the right thing in all cases. The tests pass, and this does
        exactly what pycoin does, but I'm not positive pycoin works either!
        """
        if compressed is None:
            compressed = self.compressed
        if compressed:
            parity = 2 + (self.y & 1)  # 0x02 even, 0x03 odd
            return ensure_bytes(
                long_to_hex(parity, 2) + long_to_hex(self.x, 64))
        else:
            return ensure_bytes(b'04' + long_to_hex(self.x, 64) +
                                long_to_hex(self.y, 64))
Beispiel #2
0
    def from_hex_key(cls, key, network=BitcoinMainNet):
        """Load the PublicKey from a compressed or uncompressed hex key.

        This format is defined in PublicKey.get_key()
        """
        if len(key) == 130 or len(key) == 66:
            # It might be a hexlified byte array
            try:
                key = unhexlify(ensure_bytes(key))
            except (TypeError, binascii.Error):
                pass
        key = ensure_bytes(key)

        compressed = False
        id_byte = key[0]
        if not isinstance(id_byte, six.integer_types):
            id_byte = ord(id_byte)
        if id_byte == 4:
            # Uncompressed public point
            # 1B ID + 32B x coord + 32B y coord = 65 B
            if len(key) != 65:
                raise KeyParseError("Invalid key length")
            public_pair = PublicPair(long_or_int(hexlify(key[1:33]), 16),
                                     long_or_int(hexlify(key[33:]), 16))
        elif id_byte in [2, 3]:
            # Compressed public point!
            compressed = True
            if len(key) != 33:
                raise KeyParseError("Invalid key length")
            y_odd = bool(id_byte & 0x01)  # 0 even, 1 odd
            x = long_or_int(hexlify(key[1:]), 16)
            # The following x-to-pair algorithm was lifted from pycoin
            # I still need to sit down an understand it. It is also described
            # in http://www.secg.org/collateral/sec1_final.pdf
            curve = SECP256k1.curve
            p = curve.p()
            # For SECP256k1, curve.a() is 0 and curve.b() is 7, so this is
            # effectively (x ** 3 + 7) % p, but the full equation is kept
            # for just-in-case-the-curve-is-broken future-proofing
            alpha = (pow(x, 3, p) + curve.a() * x + curve.b()) % p
            beta = square_root_mod_prime(alpha, p)
            y_even = not y_odd
            if y_even == bool(beta & 1):
                public_pair = PublicPair(x, p - beta)
            else:
                public_pair = PublicPair(x, beta)
        else:
            raise KeyParseError("The given key is not in a known format.")
        return cls.from_public_pair(public_pair,
                                    network=network,
                                    compressed=compressed)
Beispiel #3
0
    def get_extended_key(self):
        """Get the extended key.

        Extended keys contain the network bytes and the public or private
        key.
        """
        network_hex_chars = hexlify(chr_py2(self.network.SECRET_KEY))
        return ensure_bytes(network_hex_chars + self.get_key())
Beispiel #4
0
 def from_hex_key(cls, key, network=BitcoinMainNet):
     if len(key) == 32:
         # Oh! we have bytes instead of a hex string
         key = hexlify(key)
     key = ensure_bytes(key)
     if not is_hex_string(key) or len(key) != 64:
         raise ValueError("Invalid hex key")
     return cls(long_or_int(key, 16), network)
Beispiel #5
0
    def from_master_password(cls, password, network=BitcoinMainNet):
        """Generate a new key from a master password.

        This password is hashed via a single round of sha256 and is highly
        breakable, but it's the standard brainwallet approach.

        See `PrivateKey.from_master_password_slow` for a slightly more
        secure generation method (which will still be subject to a rainbow
        table attack :\)
        """
        password = ensure_bytes(password)
        key = sha256(password).hexdigest()
        return cls.from_hex_key(key, network)
Beispiel #6
0
    def to_address(self, compressed=None):
        """Create a public address from this key.

        :param compressed: False if you want a normal uncompressed address
            (the most standard option). True if you want the compressed form.
            Note that most clients will not accept compressed addresses.
            Defaults to None, which in turn uses the self.compressed attribute.
        :type compressed: bool

        https://en.bitcoin.it/wiki/Technical_background_of_Bitcoin_addresses
        """
        key = unhexlify(ensure_bytes(self.get_key(compressed)))
        # First get the hash160 of the key
        hash160_bytes = hash160(key)
        # Prepend the network address byte
        network_hash160_bytes = \
            chr_py2(self.network.PUBKEY_ADDRESS) + hash160_bytes
        # Return a base58 encoded address with a checksum
        return ensure_str(base58.b58encode_check(network_hash160_bytes))
Beispiel #7
0
    def export_to_wif(self, compressed=None):
        """Export a key to WIF.

        :param compressed: False if you want a standard WIF export (the most
            standard option). True if you want the compressed form (Note that
            not all clients will accept this form). Defaults to None, which
            in turn uses the self.compressed attribute.
        :type compressed: bool
        See https://en.bitcoin.it/wiki/Wallet_import_format for a full
        description.
        """
        # Add the network byte, creating the "extended key"
        extended_key_hex = self.get_extended_key()
        extended_key_bytes = unhexlify(ensure_bytes(extended_key_hex))
        if compressed is None:
            compressed = self.compressed
        if compressed:
            extended_key_bytes += b'\01'
        # And return the base58-encoded result with a checksum
        return ensure_str(base58.b58encode_check(extended_key_bytes))
Beispiel #8
0
import socket
from time import ctime

import utils


HOST = ''
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST, PORT)

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(ADDR)
sock.listen(5)

while True:
    print("waiting for connection...")
    client_sock, addr = sock.accept()
    print("connection from: ", addr)

    while True:
        data = client_sock.recv(BUFSIZE)
        if not data:
            break
        msg = '[%s] %s' % (ctime(), utils.ensure_unicode(data))
        print('Received: ', msg)
        client_sock.send(utils.ensure_bytes(msg))
    client_sock.close()
sock.close()
import socket

import utils

HOST = 'localhost'
service = 'daytime'

port = socket.getservbyname(service)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.connect((HOST, port))
sock.send(utils.ensure_bytes(service))
data = sock.recvfrom(1024)
print(utils.ensure_unicode(data))
sock.close()
Beispiel #10
0
 def get_key(self):
     """Get the key - a hex formatted private exponent for the curve."""
     return ensure_bytes(hexlify(self._private_key.to_string()))
Beispiel #11
0
 def handle(self):
     print("...connection from: ", self.client_address)
     msg = '[%s] %s' % (ctime(), utils.ensure_unicode(self.rfile.readline()).strip())
     print(msg)
     self.wfile.write(utils.ensure_bytes(msg))