Ejemplo n.º 1
0
    def __init__(self, raw_pubkey=None, raw_privkey=None):
        if raw_privkey:
            assert not raw_pubkey
            raw_pubkey = privtopub(raw_privkey)
        if raw_pubkey:
            assert len(raw_pubkey) == 64
            _, pubkey_x, pubkey_y, _ = self._decode_pubkey(raw_pubkey)
        else:
            pubkey_x, pubkey_y = None, None
        while True:
            pyelliptic.ECC.__init__(self,
                                    pubkey_x=pubkey_x,
                                    pubkey_y=pubkey_y,
                                    raw_privkey=raw_privkey,
                                    curve=self.curve)
            try:
                if self.raw_privkey:
                    bitcoin.get_privkey_format(
                        self.raw_privkey)  # failed for some keys
                valid_priv_key = True
            except AssertionError:
                valid_priv_key = False
            if len(self.raw_pubkey) == 64 and valid_priv_key:
                break
            elif raw_privkey or raw_pubkey:
                raise Exception('invalid priv or pubkey')

        assert len(self.raw_pubkey) == 64
Ejemplo n.º 2
0
    def __init__(self, raw_pubkey=None, raw_privkey=None):
        if raw_privkey:
            assert not raw_pubkey
            raw_pubkey = privtopub(raw_privkey)
        if raw_pubkey:
            assert len(raw_pubkey) == 64
            _, pubkey_x, pubkey_y, _ = self._decode_pubkey(raw_pubkey)
        else:
            pubkey_x, pubkey_y = None, None
        while True:
            pyelliptic.ECC.__init__(self,
                                    pubkey_x=pubkey_x,
                                    pubkey_y=pubkey_y,
                                    raw_privkey=raw_privkey,
                                    curve=self.curve)
            # XXX: when raw_privkey is generated by pyelliptic it sometimes
            #      has 31 bytes so we try again!
            if self.raw_privkey and len(self.raw_privkey) != 32:
                continue
            try:
                if self.raw_privkey:
                    bitcoin.get_privkey_format(
                        self.raw_privkey)  # failed for some keys
                valid_priv_key = True
            except AssertionError:
                valid_priv_key = False
            if len(self.raw_pubkey) == 64 and valid_priv_key:
                break
            elif raw_privkey or raw_pubkey:
                raise Exception('invalid priv or pubkey')

        assert len(self.raw_pubkey) == 64
Ejemplo n.º 3
0
    def __init__(self, raw_pubkey=None, raw_privkey=None):
        if raw_privkey:
            assert not raw_pubkey
            raw_pubkey = privtopub(raw_privkey)
        if raw_pubkey:
            assert len(raw_pubkey) == 64
            _, pubkey_x, pubkey_y, _ = self._decode_pubkey(raw_pubkey)
        else:
            pubkey_x, pubkey_y = None, None
        while True:
            pyelliptic.ECC.__init__(
                self, pubkey_x=pubkey_x, pubkey_y=pubkey_y, raw_privkey=raw_privkey, curve=self.curve
            )
            try:
                if self.raw_privkey:
                    bitcoin.get_privkey_format(self.raw_privkey)  # failed for some keys
                valid_priv_key = True
            except AssertionError:
                valid_priv_key = False
            if len(self.raw_pubkey) == 64 and valid_priv_key:
                break
            elif raw_privkey or raw_pubkey:
                raise Exception("invalid priv or pubkey")

        assert len(self.raw_pubkey) == 64
Ejemplo n.º 4
0
def test_wif_privkeys_invalid(setup_keys):
    #first try to create wif privkey from key of wrong length
    bad_privs = ['\x01\x02'*17] #some silly private key but > 33 bytes

    #next try to create wif with correct length but wrong compression byte
    bad_privs.append('\x07'*32 + '\x02')
    
    for priv in bad_privs:
        with pytest.raises(Exception) as e_info:
            fake_wif = btc.wif_compressed_privkey(binascii.hexlify(priv))

    #Create a wif with wrong length
    bad_wif1 = btc.bin_to_b58check('\x01\x02'*34, 128)
    #Create a wif with wrong compression byte
    bad_wif2 = btc.bin_to_b58check('\x07'*33, 128)
    for bw in [bad_wif1, bad_wif2]:
        with pytest.raises(Exception) as e_info:
            fake_priv = btc.from_wif_privkey(bw)

    #Some invalid b58 from bitcoin repo;
    #none of these are valid as any kind of key or address
    with open("test/base58_keys_invalid.json", "r") as f:
        json_data = f.read()
    invalid_key_list = json.loads(json_data)
    for k in invalid_key_list:
        bad_key = k[0]
        for netval in ["mainnet", "testnet"]:
            jm_single().config.set("BLOCKCHAIN", "network", netval)
            #if using py.test -s ; sanity check to see what's actually being tested
            print 'testing this key: ' + bad_key
            if "decode_privkey" in dir(btc):
                try:
                    bad_key_format = btc.get_privkey_format(bad_key)
                    print 'has correct format: ' + bad_key_format
                except:
                    pass
            #should throw exception
            with pytest.raises(Exception) as e_info:
                if "decode_privkey" in dir(btc):
                    from_wif_key = btc.decode_privkey(bad_key)
                else:
                    from_wif_key = btc.from_wif_compressed_privkey(
                        bad_key, btc.get_version_byte(bad_key))
                #in case the b58 check encoding is valid, we should
                #also check if the leading version byte is in the
                #expected set, and throw an error if not.
                if chr(btc.get_version_byte(bad_key)) not in '\x80\xef':
                    raise Exception("Invalid version byte")
                #the bitcoin library should throw
                #if the compression byte is not there (test not needed
                #for secp256k1 branch since the wif_compressed function checks)
                if "decode_privkey" in dir(btc):
                    if "compressed" in btc.get_privkey_format(bad_key) and \
                   btc.b58check_to_bin(x)[-1] != '\x01':
                        raise Exception("Invalid compression byte")
Ejemplo n.º 5
0
def test_wif_privkeys_invalid(setup_keys):
    #first try to create wif privkey from key of wrong length
    bad_privs = ['\x01\x02' * 17]  #some silly private key but > 33 bytes

    #next try to create wif with correct length but wrong compression byte
    bad_privs.append('\x07' * 32 + '\x02')

    for priv in bad_privs:
        with pytest.raises(Exception) as e_info:
            fake_wif = btc.wif_compressed_privkey(binascii.hexlify(priv))

    #Create a wif with wrong length
    bad_wif1 = btc.bin_to_b58check('\x01\x02' * 34, 128)
    #Create a wif with wrong compression byte
    bad_wif2 = btc.bin_to_b58check('\x07' * 33, 128)
    for bw in [bad_wif1, bad_wif2]:
        with pytest.raises(Exception) as e_info:
            fake_priv = btc.from_wif_privkey(bw)

    #Some invalid b58 from bitcoin repo;
    #none of these are valid as any kind of key or address
    with open("test/base58_keys_invalid.json", "r") as f:
        json_data = f.read()
    invalid_key_list = json.loads(json_data)
    for k in invalid_key_list:
        bad_key = k[0]
        for netval in ["mainnet", "testnet"]:
            jm_single().config.set("BLOCKCHAIN", "network", netval)
            #if using py.test -s ; sanity check to see what's actually being tested
            print 'testing this key: ' + bad_key
            if "decode_privkey" in dir(btc):
                try:
                    bad_key_format = btc.get_privkey_format(bad_key)
                    print 'has correct format: ' + bad_key_format
                except:
                    pass
            #should throw exception
            with pytest.raises(Exception) as e_info:
                if "decode_privkey" in dir(btc):
                    from_wif_key = btc.decode_privkey(bad_key)
                else:
                    from_wif_key = btc.from_wif_compressed_privkey(
                        bad_key, btc.get_version_byte(bad_key))
                #in case the b58 check encoding is valid, we should
                #also check if the leading version byte is in the
                #expected set, and throw an error if not.
                if chr(btc.get_version_byte(bad_key)) not in '\x80\xef':
                    raise Exception("Invalid version byte")
                #the bitcoin library should throw
                #if the compression byte is not there (test not needed
                #for secp256k1 branch since the wif_compressed function checks)
                if "decode_privkey" in dir(btc):
                    if "compressed" in btc.get_privkey_format(bad_key) and \
                   btc.b58check_to_bin(x)[-1] != '\x01':
                        raise Exception("Invalid compression byte")
Ejemplo n.º 6
0
 def has_valid_keys(self):
     try:
         try:
             # failed for some keys
             bitcoin.get_privkey_format(self.raw_privkey)
         except AssertionError:
             raise exceptions.CryptoError('Invalid privkey')
         assert len(self.raw_pubkey) == 64
         raw_check_result = self.raw_check_key(
             self.raw_privkey,
             *self._decode_pubkey(self.raw_pubkey)[1:3])
         if raw_check_result != 0:
             raise exceptions.InvalidKeys()
     except (AssertionError, Exception):
         return False
     return True
Ejemplo n.º 7
0
 def has_valid_keys(self):
     try:
         try:
             # failed for some keys
             bitcoin.get_privkey_format(self.raw_privkey)
         except AssertionError:
             raise exceptions.InvalidKeys('Invalid privkey')
         verify_pubkey(self.raw_pubkey)
         raw_check_result = self.raw_check_key(
             self.raw_privkey,
             *self._decode_pubkey(self.raw_pubkey)[1:3],
         )
         if raw_check_result != 0:
             raise exceptions.InvalidKeys()
     except Exception:  # pylint: disable=broad-except
         return False
     return True
Ejemplo n.º 8
0
def bip38_encrypt(privkey, passphrase):
    """
    BIP0038 non-ec-multiply encryption. Returns BIP0038 encrypted privkey.
    """
    privformat = get_privkey_format(privkey)
    if privformat in ['wif_compressed','hex_compressed']:
        compressed = True
        flagbyte = b'\xe0'
        if privformat == 'wif_compressed':
            privkey = encode_privkey(privkey,'hex_compressed')
            privformat = get_privkey_format(privkey)
    if privformat in ['wif', 'hex']:
        compressed = False
        flagbyte = b'\xc0'
    if privformat == 'wif':
        privkey = encode_privkey(privkey,'hex')
        privformat = get_privkey_format(privkey)

    pubkey = privtopub(privkey)
    addr = pubtoaddr(pubkey)

    passphrase = normalize('NFC', unicode(passphrase))
    if is_py2:
        ascii_key = addr
        passphrase = passphrase.encode('utf8')
    else:
        ascii_key = bytes(addr,'ascii')

    salt = sha256(sha256(ascii_key).digest()).digest()[0:4]
    key = scrypt.hash(passphrase, salt, 16384, 8, 8)
    derivedhalf1, derivedhalf2 = key[:32], key[32:]

    aes = AES.new(derivedhalf2)
    encryptedhalf1 = aes.encrypt(unhexlify('%0.32x' % (long(privkey[0:32], 16) ^ long(hexlify(derivedhalf1[0:16]), 16))))
    encryptedhalf2 = aes.encrypt(unhexlify('%0.32x' % (long(privkey[32:64], 16) ^ long(hexlify(derivedhalf1[16:32]), 16))))

    payload = b'\x01' + b'\x42' + flagbyte + salt + encryptedhalf1 + encryptedhalf2
    checksum   = sha256(sha256(payload).digest()).digest()[:4] # b58check for encrypted privkey
    privatkey  = hexlify(payload + checksum).decode('ascii')
    return changebase(privatkey, 16, 58)
Ejemplo n.º 9
0
    def _init_ecc(self, raw_public_key, raw_private_key):
        if raw_private_key:
            assert not raw_public_key
            raw_public_key = crypto_utils.private_to_public_key(
                raw_private_key)
        if raw_public_key:
            assert len(raw_public_key) == eth_common_constants.PUBLIC_KEY_LEN
            _, pubkey_x, pubkey_y, _ = self._decode_pubkey(raw_public_key)
        else:
            pubkey_x, pubkey_y = None, None

        while True:
            pyelliptic.ECC.__init__(self,
                                    pubkey_x=pubkey_x,
                                    pubkey_y=pubkey_y,
                                    raw_privkey=raw_private_key,
                                    curve=eth_common_constants.ECIES_CURVE)

            # when raw_private_key is generated by pyelliptic it sometimes has 31 bytes so we try again!
            if self.get_raw_private_key() and len(self.get_raw_private_key(
            )) != eth_common_constants.PRIVATE_KEY_LEN:
                continue
            try:
                if self.get_raw_private_key():
                    bitcoin.get_privkey_format(
                        self.get_raw_private_key())  # failed for some keys
                valid_private_key = True
            except AssertionError:
                valid_private_key = False
            if len(self.get_raw_public_key(
            )) == eth_common_constants.PUBLIC_KEY_LEN and valid_private_key:
                break
            elif raw_private_key or raw_public_key:
                raise Exception("invalid private or public key")

        assert len(
            self.get_raw_public_key()) == eth_common_constants.PUBLIC_KEY_LEN
Ejemplo n.º 10
0
    def __init__(self, private_key=None, compressed=False):
        """ Takes in a private key/secret exponent.
        """
        self._compressed = compressed
        if not private_key:
            secret_exponent = random_secret_exponent(self._curve.order)
        else:
            secret_exponent = encode_privkey(private_key, 'decimal')
            if get_privkey_format(private_key).endswith('compressed'):
                self._compressed = True

        # make sure that: 1 <= secret_exponent < curve_order
        if not is_secret_exponent(secret_exponent, self._curve.order):
            raise IndexError(_errors["EXPONENT_OUTSIDE_CURVE_ORDER"])

        self._ecdsa_private_key = ecdsa.keys.SigningKey.from_secret_exponent(
            secret_exponent, self._curve, self._hash_function)
Ejemplo n.º 11
0
    def __init__(self, private_key=None, compressed=False):
        """ Takes in a private key/secret exponent.
        """
        self._compressed = compressed
        if not private_key:
            secret_exponent = random_secret_exponent(self._curve.order)
        else:
            secret_exponent = encode_privkey(private_key, 'decimal')
            if get_privkey_format(private_key).endswith('compressed'):
                self._compressed = True

        # make sure that: 1 <= secret_exponent < curve_order
        if not is_secret_exponent(secret_exponent, self._curve.order):
            raise IndexError(_errors["EXPONENT_OUTSIDE_CURVE_ORDER"])

        self._ecdsa_private_key = ecdsa.keys.SigningKey.from_secret_exponent(
            secret_exponent, self._curve, self._hash_function
        )
Ejemplo n.º 12
0
def sign(tx_hash: bytes, private_key: str):
    msg_hash = tx_hash
    z = bitcoin.hash_to_int(msg_hash)
    k = bitcoin.deterministic_generate_k(msg_hash, private_key)

    r, y = bitcoin.fast_multiply(bitcoin.G, k)
    s = bitcoin.inv(k, bitcoin.N) * (
        z + r * bitcoin.decode_privkey(private_key)) % bitcoin.N

    v, r, s = 27 + ((y % 2) ^ (0 if s * 2 < bitcoin.N else 1)
                    ), r, s if s * 2 < bitcoin.N else bitcoin.N - s
    if 'compressed' in bitcoin.get_privkey_format(private_key):
        v += 4
    hex_str_r = hex(r)[2:]
    if len(hex_str_r) < 64:
        hex_str_r = ((64 - len(hex_str_r)) * "0") + hex_str_r
    hex_str_s = hex(s)[2:]
    if len(hex_str_s) < 64:
        hex_str_s = ((64 - len(hex_str_s)) * "0") + hex_str_s
    signature = hex_str_r + hex_str_s
    recovery = v - 27
    return signature, recovery
Ejemplo n.º 13
0
    print(
        "WARNING: This imported key will not be recoverable with your 12 "
        + "word mnemonic seed. Make sure you have backups."
    )
    print(
        "WARNING: Handling of raw ECDSA bitcoin private keys can lead to "
        "non-intuitive behaviour and loss of funds.\n  Recommended instead "
        "is to use the 'sweep' feature of sendpayment.py "
    )
    privkeys = raw_input("Enter private key(s) to import: ")
    privkeys = privkeys.split(",") if "," in privkeys else privkeys.split()
    # TODO read also one key for each line
    for privkey in privkeys:
        # TODO is there any point in only accepting wif format? check what
        # other wallets do
        privkey_format = btc.get_privkey_format(privkey)
        if privkey_format not in ["wif", "wif_compressed"]:
            print("ERROR: privkey not in wallet import format")
            print(privkey, "skipped")
            continue
        if privkey_format == "wif":
            # TODO if they actually use an unc privkey, make sure the unc
            # address is used

            # r = raw_input('WARNING: Using uncompressed private key, the vast ' +
            #   'majority of JoinMarket transactions use compressed keys\n' +
            #       'being so unusual is bad for privacy. Continue? (y/n):')
            # if r != 'y':
            #   sys.exit(0)
            print("Uncompressed privkeys not supported (yet)")
            print(privkey, "skipped")
Ejemplo n.º 14
0
    words = mn_encode(hexseed)
    print('Wallet recovery seed\n\n' + ' '.join(words) + '\n')
elif method == 'importprivkey':
    print('WARNING: This imported key will not be recoverable with your 12 ' +
          'word mnemonic seed. Make sure you have backups.')
    print('WARNING: Handling of raw ECDSA bitcoin private keys can lead to '
          'non-intuitive behaviour and loss of funds.\n  Recommended instead '
          'is to use the \'sweep\' feature of sendpayment.py ')
    privkeys = raw_input('Enter private key(s) to import: ')
    privkeys = privkeys.split(',') if ',' in privkeys else privkeys.split()
    # TODO read also one key for each line
    for privkey in privkeys:
        # TODO is there any point in only accepting wif format? check what
        # other wallets do
        if not btc.secp_present:
            privkey_format = btc.get_privkey_format(privkey)
            if privkey_format not in ['wif', 'wif_compressed']:
                print('ERROR: privkey not in wallet import format')
                print(privkey, 'skipped')
                continue
            if privkey_format == 'wif':
                # TODO if they actually use an unc privkey, make sure the unc
                # address is used

                # r = raw_input('WARNING: Using uncompressed private key, the vast ' +
                #   'majority of JoinMarket transactions use compressed keys\n' +
                #       'being so unusual is bad for privacy. Continue? (y/n):')
                # if r != 'y':
                #   sys.exit(0)
                print('Uncompressed privkeys not supported (yet)')
                print(privkey, 'skipped')
Ejemplo n.º 15
0
def test_verify_pri_key():
    assert get_privkey_format(pri_key) == 'wif_compressed'
    assert decode_privkey(pri_key, 'wif_compressed') == key