Exemple #1
0
 def privkey_to_wif(cls, priv):
     # refuse to WIF-ify something that we don't recognize
     # as a private key; ignoring the return value of this
     # function as we only want to raise whatever Exception
     # it does:
     btc.read_privkey(priv)
     return btc.bin_to_b58check(priv, cls.WIF_PREFIX)
def test_read_raw_privkeys():
    badkeys = ['', '\x07'*31,'\x07'*34, '\x07'*33]
    for b in badkeys:
        with pytest.raises(Exception) as e_info:
            c, k = btc.read_privkey(b)
    goodkeys = [('\x07'*32, False), ('\x07'*32 + '\x01', True)]
    for g in goodkeys:
        c, k = btc.read_privkey(g[0])
        assert c == g[1]
def test_ecdh():
    """Using private key test vectors from Bitcoin Core.
    1. Import a set of private keys from the json file.
    2. Calculate the corresponding public keys.
    3. Do ECDH on the cartesian product (x, Y), with x private
    and Y public keys, for all combinations.
    4. Compare the result from CoinCurve with the manual
    multiplication xY following by hash (sha256). Note that
    sha256(xY) is the default hashing function used for ECDH
    in libsecp256k1.

    Since there are about 20 private keys in the json file, this
    creates around 400 test cases (note xX is still valid).
    """
    with open(os.path.join(testdir, "base58_keys_valid.json"), "r") as f:
        json_data = f.read()
        valid_keys_list = json.loads(json_data)
        extracted_privkeys = []
        for a in valid_keys_list:
            key, hex_key, prop_dict = a
            if prop_dict["isPrivkey"]:
                c, k = btc.read_privkey(hextobin(hex_key))
                extracted_privkeys.append(k)
    extracted_pubkeys = [btc.privkey_to_pubkey(x) for x in extracted_privkeys]
    for p in extracted_privkeys:
        for P in extracted_pubkeys:
            c, k = btc.read_privkey(p)
            shared_secret = btc.ecdh(k, P)
            assert len(shared_secret) == 32
            # try recreating the shared secret manually:
            pre_secret = btc.multiply(p, P)
            derived_secret = hashlib.sha256(pre_secret).digest()
            assert derived_secret == shared_secret

    # test some important failure cases; null key, overflow case
    privkeys_invalid = [
        b'\x00' * 32,
        hextobin(
            'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141')
    ]
    for p in privkeys_invalid:
        with pytest.raises(Exception) as e_info:
            shared_secret = btc.ecdh(p, extracted_pubkeys[0])
    pubkeys_invalid = [b'0xff' + extracted_pubkeys[0][1:], b'0x00' * 12]
    for p in extracted_privkeys:
        with pytest.raises(Exception) as e_info:
            shared_secret = btc.ecdh(p, pubkeys_invalid[0])
        with pytest.raises(Exception) as e_info:
            shared_secret = btc.ecdh(p, pubkeys_invalid[1])
Exemple #4
0
def test_ecies():
    """Using private key test vectors from Bitcoin Core.
    1. Import a set of private keys from the json file.
    2. Calculate the corresponding public keys.
    3. Do ECDH on the cartesian product (x, Y), with x private
    and Y public keys, for all combinations.
    4. Compare the result from CoinCurve with the manual
    multiplication xY following by hash (sha256). Note that
    sha256(xY) is the default hashing function used for ECDH
    in libsecp256k1.

    Since there are about 20 private keys in the json file, this
    creates around 400 test cases (note xX is still valid).
    """
    with open(os.path.join(testdir, "base58_keys_valid.json"), "r") as f:
        json_data = f.read()
        valid_keys_list = json.loads(json_data)
        print("got valid keys list")
        extracted_privkeys = []
        for a in valid_keys_list:
            key, hex_key, prop_dict = a
            if prop_dict["isPrivkey"]:
                c, k = btc.read_privkey(hextobin(hex_key))

                extracted_privkeys.append(k)
    extracted_pubkeys = [btc.privkey_to_pubkey(x) for x in extracted_privkeys]
    for (priv, pub) in zip(extracted_privkeys, extracted_pubkeys):
        test_message = base64.b64encode(os.urandom(15) * 20)
        assert btc.ecies_decrypt(priv, btc.ecies_encrypt(test_message,
                                                         pub)) == test_message
Exemple #5
0
    def wif_to_privkey(cls, wif):
        raw = btc.b58check_to_bin(wif)[1]
        # see note to `privkey_to_wif`; same applies here.
        # We only handle valid private keys, not any byte string.
        btc.read_privkey(raw)

        vbyte = struct.unpack('B', btc.get_version_byte(wif))[0]

        if (struct.unpack('B', btc.BTC_P2PK_VBYTE[get_network()])[0] + \
            struct.unpack('B', cls.WIF_PREFIX)[0]) & 0xff == vbyte:
            key_type = TYPE_P2PKH
        elif (struct.unpack('B', btc.BTC_P2SH_VBYTE[get_network()])[0] + \
              struct.unpack('B', cls.WIF_PREFIX)[0]) & 0xff == vbyte:
            key_type = TYPE_P2SH_P2WPKH
        else:
            key_type = None
        return raw, key_type
Exemple #6
0
    def wif_to_privkey(cls, wif):
        """ Note July 2020: the `key_type` construction below is
        custom and is not currently used. Future code should
        not use this returned `key_type` variable.
        """
        raw = btc.b58check_to_bin(wif)[1]
        # see note to `privkey_to_wif`; same applies here.
        # We only handle valid private keys, not any byte string.
        btc.read_privkey(raw)

        vbyte = struct.unpack('B', btc.get_version_byte(wif))[0]

        if (struct.unpack('B', btc.BTC_P2PK_VBYTE[get_network()])[0] + \
            struct.unpack('B', cls.WIF_PREFIX)[0]) & 0xff == vbyte:
            key_type = TYPE_P2PKH
        elif (struct.unpack('B', btc.BTC_P2SH_VBYTE[get_network()])[0] + \
              struct.unpack('B', cls.WIF_PREFIX)[0]) & 0xff == vbyte:
            key_type = TYPE_P2SH_P2WPKH
        else:
            key_type = None
        return raw, key_type
def test_ecies():
    """Tests encryption and decryption of random messages using
    the ECIES module.
    TODO these tests are very minimal.
    """
    with open(os.path.join(testdir,"base58_keys_valid.json"), "r") as f:
        json_data = f.read()
        valid_keys_list = json.loads(json_data)
        print("got valid keys list")
        extracted_privkeys = []
        for a in valid_keys_list:
            key, hex_key, prop_dict = a
            if prop_dict["isPrivkey"]:
                c, k = btc.read_privkey(hextobin(hex_key))

                extracted_privkeys.append(k)
    extracted_pubkeys = [btc.privkey_to_pubkey(x) for x in extracted_privkeys]
    for (priv, pub) in zip(extracted_privkeys, extracted_pubkeys):
        test_message = base64.b64encode(os.urandom(15)*20)
        assert btc.ecies_decrypt(priv, btc.ecies_encrypt(test_message, pub)) == test_message