Beispiel #1
0
 def test_sec(self):
     pair_blob = h2b('0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8')
     public_pair = encoding.sec_to_public_pair(pair_blob, strict=False)
     try:
         public_pair = encoding.sec_to_public_pair(pair_blob, strict=True)
         self.fail("sec_to_public_pair unexpectedly succeeded")
     except encoding.EncodingError:
         pass
Beispiel #2
0
 def test_sec(self):
     pair_blob = h2b(
         "0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"
     )
     public_pair = encoding.sec_to_public_pair(pair_blob, strict=False)
     try:
         public_pair = encoding.sec_to_public_pair(pair_blob, strict=True)
         self.fail("sec_to_public_pair unexpectedly succeeded")
     except encoding.EncodingError:
         pass
Beispiel #3
0
        def do_test(exp_hex, wif, c_wif, public_pair_sec, c_public_pair_sec,
                    address_b58, c_address_b58):
            secret_exponent = int(exp_hex, 16)
            sec = h2b(public_pair_sec)
            c_sec = h2b(c_public_pair_sec)

            self.assertEqual(
                secret_exponent_to_wif(secret_exponent, compressed=False), wif)
            self.assertEqual(
                secret_exponent_to_wif(secret_exponent, compressed=True),
                c_wif)

            exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(
                wif)
            self.assertEqual(exponent, secret_exponent)
            self.assertFalse(compressed)

            exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(
                c_wif)
            self.assertEqual(exponent, secret_exponent)
            self.assertTrue(compressed)

            public_pair = public_pair_for_secret_exponent(
                generator_secp256k1, secret_exponent)

            pk_public_pair = sec_to_public_pair(sec)
            compressed = is_sec_compressed(sec)
            self.assertEqual(pk_public_pair, public_pair)
            self.assertFalse(is_sec_compressed(sec))
            self.assertEqual(
                public_pair_to_sec(pk_public_pair, compressed=False), sec)

            pk_public_pair = sec_to_public_pair(c_sec)
            compressed = is_sec_compressed(c_sec)
            self.assertEqual(pk_public_pair, public_pair)
            self.assertTrue(compressed)
            self.assertEqual(
                public_pair_to_sec(pk_public_pair, compressed=True), c_sec)

            bca = public_pair_to_bitcoin_address(pk_public_pair,
                                                 compressed=True)
            self.assertEqual(bca, c_address_b58)

            self.assertEqual(
                bitcoin_address_to_hash160_sec(c_address_b58),
                public_pair_to_hash160_sec(pk_public_pair, compressed=True))

            bca = public_pair_to_bitcoin_address(pk_public_pair,
                                                 compressed=False)
            self.assertEqual(bca, address_b58)

            self.assertEqual(
                bitcoin_address_to_hash160_sec(address_b58),
                public_pair_to_hash160_sec(pk_public_pair, compressed=False))
Beispiel #4
0
def pcode_to_public_node(pcode):
    pcode_bytes = b58_to_pcode(pcode)
    sec = pcode_bytes[2:35]
    public_pair = encoding.sec_to_public_pair(sec)
    chain_code = pcode_bytes[36:68]
    node = BIP32Node( netcode=NETCODE, chain_code=chain_code, public_pair=public_pair )
    return node
Beispiel #5
0
    def solve_finalize_commit(self, **kwargs):
        hash160_lookup = kwargs.get("hash160_lookup")
        sign_value = kwargs.get("sign_value")
        signature_type = kwargs.get("signature_type")
        existing_script = kwargs.get("existing_script")

        # FIXME validate on receiving the commit
        # validate payer sig
        opcode, data, pc = tools.get_opcode(existing_script, 0)  # OP_0
        opcode, payer_sig, pc = tools.get_opcode(existing_script, pc)
        sig_pair, actual_signature_type = parse_signature_blob(payer_sig)
        try:
            public_pair = encoding.sec_to_public_pair(self.payer_sec)
            sig_pair, signature_type = parse_signature_blob(payer_sig)
            valid = ecdsa.verify(ecdsa.generator_secp256k1, public_pair,
                                 sign_value, sig_pair)
            if not valid:
                raise Exception("Invalid payer public_pair!")
        except (encoding.EncodingError, UnexpectedDER):
            raise Exception("Invalid payer public_pair!")

        # sign
        private_key = hash160_lookup.get(encoding.hash160(self.payee_sec))
        secret_exponent, public_pair, compressed = private_key
        payee_sig = self._create_script_signature(
            secret_exponent, sign_value, signature_type
        )

        script_text = "OP_0 {payer_sig} {payee_sig} OP_1".format(
            payer_sig=b2h(payer_sig), payee_sig=b2h(payee_sig)
        )
        return tools.compile(script_text)
Beispiel #6
0
 def from_sec(class_, sec):
     """
     Create a key from an sec bytestream (which is an encoding of a public pair).
     """
     public_pair = sec_to_public_pair(sec)
     return Key(public_pair=public_pair,
                prefer_uncompressed=not is_sec_compressed(sec))
def is_pubkey_valid(pubkey):
    try:
        sec=encoding.binascii.unhexlify(pubkey)
        public_pair=encoding.sec_to_public_pair(sec)
        return curves.ecdsa.point_is_valid(ecdsa.generator_secp256k1, public_pair[0], public_pair[1])
    except TypeError:
        return False
Beispiel #8
0
def pubkey_to_address(pubkey_hex):
    sec = binascii.unhexlify(pubkey_hex)
    compressed = encoding.is_sec_compressed(sec)
    public_pair = encoding.sec_to_public_pair(sec)
    address_prefix = b'\x6f' if config.TESTNET else b'\x00'
    return encoding.public_pair_to_bitcoin_address(
        public_pair, compressed=compressed, address_prefix=address_prefix)
def is_pubkey_valid(pubkey):
    try:
        sec=encoding.binascii.unhexlify(pubkey)
        public_pair=encoding.sec_to_public_pair(sec)
        return curves.ecdsa.point_is_valid(ecdsa.generator_secp256k1, public_pair[0], public_pair[1])
    except TypeError:
        return False
    def decrypt(self, raw, mac=16):
        """Decrypt a message sent to the holder of this key.
        """
        # get the nonce-point
        x, y = sec_to_public_pair(raw[:33])
        # validation that this point lies on the curve happens in
        #  initialization
        nonce_point = PubKey(BasePoint.curve(), x, y)

        # message gives us the ciphered message
        message = raw[33:-mac]
        # checksum makes sure everything is transmitted properly
        checksum = raw[-mac:]

        # calculate the shared secret
        tmp = nonce_point * self.exponent
        shared_secret = PubKey(tmp.curve(), tmp.x(), tmp.y())

        # derive keys
        key = nonce_point.kdf(shared_secret)
        cipher = AES.new(key[:32])

        # verify the checksum
        checksum_maker = hmac.new(key[32:], digestmod=hashlib.sha256)
        checksum_maker.update(message)
        if checksum_maker.digest()[:mac] != checksum:
            raise RuntimeError("Invalid checksum on encoded message string")

        return cipher.decrypt(message)
def encrypt_message(address, message):
    """Encrypts a message to an address.
    """
    hex_public_key = get_public_key_from_address(address)
    x, y = sec_to_public_pair(hex_public_key.decode('hex'))
    public_key = PubKey(BasePoint.curve(), x, y)
    encrypted = b64encode(public_key.encrypt(message))
    return encrypted
Beispiel #12
0
 def from_sec(class_, sec, netcode=None):
     """
     Create a key from an sec bytestream (which is an encoding of a public pair).
     """
     public_pair = sec_to_public_pair(sec)
     return class_(public_pair=public_pair,
                   is_compressed=is_sec_compressed(sec),
                   netcode=netcode)
Beispiel #13
0
def add_sec_annotations(a1, data, address_prefix):
    pair = sec_to_public_pair(data)
    is_compressed = is_sec_compressed(data)
    a1.append(
        "SEC for %scompressed %s" %
        ("" if is_compressed else "un",
         public_pair_to_bitcoin_address(
             pair, compressed=is_compressed, address_prefix=address_prefix)))
Beispiel #14
0
 def do_test(as_public_pair, as_sec, is_compressed, as_hash160_sec, as_bitcoin_address):
     self.assertEqual(encoding.sec_to_public_pair(as_sec), as_public_pair)
     self.assertEqual(encoding.public_pair_to_sec(as_public_pair, compressed=is_compressed), as_sec)
     self.assertEqual(encoding.is_sec_compressed(as_sec), is_compressed)
     self.assertEqual(encoding.public_pair_to_hash160_sec(as_public_pair, compressed=is_compressed),
                      as_hash160_sec)
     self.assertEqual(encoding.hash160_sec_to_bitcoin_address(as_hash160_sec), as_bitcoin_address)
     self.assertEqual(encoding.public_pair_to_bitcoin_address(as_public_pair, compressed=is_compressed), as_bitcoin_address)
     self.assertTrue(encoding.is_valid_bitcoin_address(as_bitcoin_address))
     bad_address = as_bitcoin_address[:17] + chr(ord(as_bitcoin_address[17]) + 1) + as_bitcoin_address[18:]
     self.assertFalse(encoding.is_valid_bitcoin_address(bad_address))
Beispiel #15
0
def compress_pubkey(uncompressed_pubkey):
    """ Convert uncompressed public key to compressed public key.

    Args:
        pubkey (str): Hex encoded 65Byte uncompressed public key

    Return:
        str: Hex encoded 33Byte compressed public key
    """
    public_pair = encoding.sec_to_public_pair(h2b(uncompressed_pubkey))
    return b2h(encoding.public_pair_to_sec(public_pair, compressed=True))
Beispiel #16
0
    def parse_sig(script_hex):
        """Takes a hex string of the script signature and returns the corresponding user obj
        Its in the format: [3a05e435... 027efd7...]
                    where: [Signature,  Sec_pubkey]

        """         
        
        pubkey_hex = script_hex.split(' ')[1]
        sec = sec_to_public_pair(a2b_hex(pubkey_hex))
        addr = public_pair_to_bitcoin_address(sec, address_prefix=NETWORK)
        return Username(addr)
Beispiel #17
0
def uncompress_pubkey(pubkey):
    """ Convert compressed public key to uncompressed public key.

    Args:
        pubkey (str): Hex encoded 33Byte compressed public key

    Return:
        str: Hex encoded uncompressed 65byte public key (4 + x + y).
    """
    public_pair = encoding.sec_to_public_pair(h2b(pubkey))
    return b2h(encoding.public_pair_to_sec(public_pair, compressed=False))
 def do_test(as_public_pair, as_sec, is_compressed, as_hash160_sec, as_bitcoin_address):
     self.assertEqual(encoding.sec_to_public_pair(as_sec), as_public_pair)
     self.assertEqual(encoding.public_pair_to_sec(as_public_pair, compressed=is_compressed), as_sec)
     self.assertEqual(encoding.is_sec_compressed(as_sec), is_compressed)
     self.assertEqual(encoding.public_pair_to_hash160_sec(as_public_pair, compressed=is_compressed),
                      as_hash160_sec)
     self.assertEqual(encoding.hash160_sec_to_bitcoin_address(as_hash160_sec), as_bitcoin_address)
     self.assertEqual(encoding.public_pair_to_bitcoin_address(as_public_pair, compressed=is_compressed), as_bitcoin_address)
     self.assertTrue(encoding.is_valid_bitcoin_address(as_bitcoin_address))
     bad_address = as_bitcoin_address[:17] + chr(ord(as_bitcoin_address[17]) + 1) + as_bitcoin_address[18:]
     self.assertFalse(encoding.is_valid_bitcoin_address(bad_address))
Beispiel #19
0
    def solve_finalize_commit(self, **kwargs):
        hash160_lookup = kwargs.get("hash160_lookup")
        signature_type = kwargs.get("signature_type")
        existing_script = kwargs.get("existing_script")

        # validate existing script
        reference_script_hex = _compile_commit_scriptsig(
            "deadbeef", "deadbeef", b2h(self.script))
        _validate(reference_script_hex, b2h(existing_script))

        # check provided payer signature
        try:
            opcode, data, pc = tools.get_opcode(existing_script, 0)  # OP_0
            opcode, payer_sig, pc = tools.get_opcode(existing_script, pc)

            # verify signature type
            sig_r_s, actual_signature_type = parse_signature_blob(payer_sig)
            assert (signature_type == actual_signature_type)

            # verify payer signature
            public_pair = encoding.sec_to_public_pair(self.payer_sec)
            sign_value = kwargs.get("sign_value")

            public_pair = encoding.sec_to_public_pair(self.payer_sec)
            sign_value = kwargs["signature_for_hash_type_f"](
                signature_type, kwargs["script_to_hash"])

            if not ecdsa.verify(ecdsa.generator_secp256k1, public_pair,
                                sign_value, sig_r_s):
                raise InvalidPayerSignature("invalid r s values")
        except UnexpectedDER:
            raise InvalidPayerSignature("not in DER format")

        # sign
        private_key = hash160_lookup.get(encoding.hash160(self.payee_sec))
        secret_exponent, public_pair, compressed = private_key
        payee_sig = self._create_sig(secret_exponent, **kwargs)

        script_asm = COMMIT_SCRIPTSIG.format(payer_sig=b2h(payer_sig),
                                             payee_sig=b2h(payee_sig))
        return tools.compile(script_asm)
        def do_test(exp_hex, wif, c_wif, public_pair_sec, c_public_pair_sec, address_b58, c_address_b58):
            secret_exponent = int(exp_hex, 16)
            sec = h2b(public_pair_sec)
            c_sec = h2b(c_public_pair_sec)

            self.assertEqual(secret_exponent_to_wif(secret_exponent, compressed=False), wif)
            self.assertEqual(secret_exponent_to_wif(secret_exponent, compressed=True), c_wif)

            exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(wif)
            self.assertEqual(exponent, secret_exponent)
            self.assertFalse(compressed)

            exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(c_wif)
            self.assertEqual(exponent, secret_exponent)
            self.assertTrue(compressed)

            public_pair = secret_exponent * secp256k1_generator

            pk_public_pair = sec_to_public_pair(sec)
            compressed = is_sec_compressed(sec)
            self.assertEqual(pk_public_pair, public_pair)
            self.assertFalse(is_sec_compressed(sec))
            self.assertEqual(public_pair_to_sec(pk_public_pair, compressed=False), sec)

            pk_public_pair = sec_to_public_pair(c_sec)
            compressed = is_sec_compressed(c_sec)
            self.assertEqual(pk_public_pair, public_pair)
            self.assertTrue(compressed)
            self.assertEqual(public_pair_to_sec(pk_public_pair, compressed=True), c_sec)

            bca = public_pair_to_bitcoin_address(pk_public_pair, compressed=True)
            self.assertEqual(bca, c_address_b58)

            self.assertEqual(bitcoin_address_to_hash160_sec(c_address_b58),
                             public_pair_to_hash160_sec(pk_public_pair, compressed=True))

            bca = public_pair_to_bitcoin_address(pk_public_pair, compressed=False)
            self.assertEqual(bca, address_b58)

            self.assertEqual(bitcoin_address_to_hash160_sec(address_b58),
                             public_pair_to_hash160_sec(pk_public_pair, compressed=False))
Beispiel #21
0
def address_from_pubkey(pubkey, netcode="BTC"):
    """ Get bitcoin address from given public key.

    Args:
        pubkey (str): Hex encoded 33Byte compressed public key
        netcode (str): Netcode for resulting bitcoin address.

    Return:
        str: Bitcoin address
    """
    prefix = networks.address_prefix_for_netcode(netcode)
    public_pair = encoding.sec_to_public_pair(h2b(pubkey))
    return encoding.public_pair_to_bitcoin_address(public_pair,
                                                   address_prefix=prefix)
Beispiel #22
0
def verify(pubkey, signature, data):
    """ Verify data is signed by private key.

    Args:
        pubkey (str): Hex encoded 33Byte compressed public key
        signature (str): Hex encoded signature in DER format.

    Return:
        bool: True if signature is valid.
    """
    public_pair = encoding.sec_to_public_pair(h2b(pubkey))
    val = util.bytestoint(h2b(data))
    sig = ecdsa.util.sigdecode_der(h2b(signature), G.order())
    return ecdsa_verify(G, public_pair, val, sig)
Beispiel #23
0
 def address_h160_from_script (script):
     s = disassemble(script).split(' ')
     if 'OP_HASH160' in s:
         p = s.index('OP_HASH160')
         if len(s) > p+1:
             return h2b(s[p+1])
     elif 'OP_CHECKSIG' in s:
         p = s.index('OP_CHECKSIG')
         if len(s[p-1]) in (66, 130):
             # public key
             sec = h2b(s[p-1])
             return public_pair_to_hash160_sec(sec_to_public_pair(sec), is_sec_compressed(sec))
     else:
         logger.warn("Can't parse address from script: %s" % (s))
         return None
Beispiel #24
0
 def bitcoin_address_for_script(self, is_test=False):
     try:
         r = self.match_script_to_templates()
         if len(r) != 1 or len(r[0]) != 2:
             return None
         if r[0][0] == opcodes.OP_PUBKEYHASH:
             return hash160_sec_to_bitcoin_address(r[0][1], is_test=is_test)
         if r[0][0] == opcodes.OP_PUBKEY:
             sec = r[0][1]
             return public_pair_to_bitcoin_address(
                 sec_to_public_pair(sec),
                 compressed=is_sec_compressed(sec),
                 is_test=is_test)
     except SolvingError:
         pass
     return None
Beispiel #25
0
 def bitcoin_address_for_script(self, is_test=False):
     try:
         r = self.match_script_to_templates()
         if len(r) != 1 or len(r[0]) != 2:
             return None
         if r[0][0] == opcodes.OP_PUBKEYHASH:
             return hash160_sec_to_bitcoin_address(r[0][1], is_test=is_test)
         if r[0][0] == opcodes.OP_PUBKEY:
             sec = r[0][1]
             return public_pair_to_bitcoin_address(
                 sec_to_public_pair(sec),
                 compressed=is_sec_compressed(sec),
                 is_test=is_test)
     except SolvingError:
         pass
     return None
Beispiel #26
0
    def __call__(self, tx_out_script, signature_hash, signature_type):
        """Figure out how to create a signature for the incoming transaction, and sign it.

        tx_out_script: the tx_out script that needs to be "solved"
        signature_hash: the bignum hash value of the new transaction reassigning the coins
        signature_type: always SIGHASH_ALL (1)
        """

        if signature_hash == 0:
            raise SolvingError("signature_hash can't be 0")

        tx_script = TxScript(tx_out_script)
        opcode_value_list = tx_script.match_script_to_templates()

        ba = bytearray()

        compressed = True
        for opcode, v in opcode_value_list:
            if opcode == opcodes.OP_PUBKEY:
                public_pair = sec_to_public_pair(v)
                bitcoin_address = public_pair_to_bitcoin_address(
                    public_pair, compressed=compressed)
            elif opcode == opcodes.OP_PUBKEYHASH:
                bitcoin_address = hash160_sec_to_bitcoin_address(v)
            else:
                raise SolvingError("can't determine how to sign this script")

            secret_exponent = self.wallet.getsecretexponent(bitcoin_address)

            r, s = ecdsa.sign(ecdsa.generator_secp256k1, secret_exponent,
                              signature_hash)
            sig = der.sigencode_der(r, s) + bytes_from_int(signature_type)
            ba += tools.compile(binascii.hexlify(sig).decode("utf8"))
            if opcode == opcodes.OP_PUBKEYHASH:
                public_pair = ecdsa.public_pair_for_secret_exponent(
                    ecdsa.generator_secp256k1, secret_exponent)
                ba += tools.compile(
                    binascii.hexlify(
                        public_pair_to_sec(
                            public_pair,
                            compressed=compressed)).decode("utf8"))

        return bytes(ba)
Beispiel #27
0
def parse_as_public_pair(s):
    try:
        if s[:2] in (["02", "03", "04"]):
            return encoding.sec_to_public_pair(encoding.h2b(s))
    except (encoding.EncodingError, binascii.Error):
        pass
    for c in ",/":
        if c in s:
            s0, s1 = s.split(c, 1)
            v0 = parse_as_number(s0)
            if v0:
                if s1 in ("even", "odd"):
                    return ecdsa.public_pair_for_x(ecdsa.generator_secp256k1, v0, is_even=(s1=='even'))
                v1 = parse_as_number(s1)
                if v1:
                    if not ecdsa.is_public_pair_valid(ecdsa.generator_secp256k1, (v0, v1)):
                        sys.stderr.write("invalid (x, y) pair\n")
                        sys.exit(1)
                    return (v0, v1)
    def __call__(self, tx_out_script, signature_hash, signature_type):
        """Figure out how to create a signature for the incoming transaction, and sign it.

        tx_out_script: the tx_out script that needs to be "solved"
        signature_hash: the bignum hash value of the new transaction reassigning the coins
        signature_type: always SIGHASH_ALL (1)
        """

        if signature_hash == 0:
            raise SolvingError("signature_hash can't be 0")

        tx_script = TxScript(tx_out_script)
        opcode_value_list = tx_script.match_script_to_templates()

        ba = bytearray()

        compressed = True
        for opcode, v in opcode_value_list:
            if opcode == opcodes.OP_PUBKEY:
                public_pair = sec_to_public_pair(v)
                bitcoin_address = public_pair_to_bitcoin_address(public_pair, compressed=compressed)
            elif opcode == opcodes.OP_PUBKEYHASH:
                bitcoin_address = hash160_sec_to_bitcoin_address(v)
            else:
                raise SolvingError("can't determine how to sign this script")

            secret_exponent = self.wallet.getsecretexponent(bitcoin_address)

            r, s = ecdsa.sign(ecdsa.generator_secp256k1, secret_exponent, signature_hash)
            sig = der.sigencode_der(r, s) + bytes_from_int(signature_type)
            ba += tools.compile(binascii.hexlify(sig).decode("utf8"))
            if opcode == opcodes.OP_PUBKEYHASH:
                public_pair = ecdsa.public_pair_for_secret_exponent(ecdsa.generator_secp256k1, secret_exponent)
                ba += tools.compile(
                    binascii.hexlify(public_pair_to_sec(public_pair, compressed=compressed)).decode("utf8")
                )

        return bytes(ba)
Beispiel #29
0
def pubkey_to_address(pubkey_hex):
    sec = binascii.unhexlify(pubkey_hex)
    compressed = encoding.is_sec_compressed(sec)
    public_pair = encoding.sec_to_public_pair(sec)
    address_prefix = b'\x6f' if config.TESTNET else b'\x00'
    return encoding.public_pair_to_bitcoin_address(public_pair, compressed=compressed, address_prefix=address_prefix)
cec_key.set_secretbytes(bitcoin.core.x(my_secret_exp))

print("Private Key dec: ", random_nbr)
print("Private Key hex: ", my_secret_exp)
privkey_wif = encoding.secret_exponent_to_wif(eval('0x' + my_secret_exp),
                                              wif_prefix=my_privkey_prefix)
print("Private key WIF: ", privkey_wif)
privkey_wif = encoding.secret_exponent_to_wif(eval('0x' + my_secret_exp),
                                              False,
                                              wif_prefix=my_privkey_prefix)
print("   uncompressed: ", privkey_wif)

cec_key.set_compressed(True)

print()
pubkey_pair = encoding.sec_to_public_pair(cec_key.get_pubkey())
print("Public key pair: ", pubkey_pair)

(pub_key_x, pub_key_y) = pubkey_pair
compressed_indicator = True if (pub_key_y % 2) == 0 else False
print("Public key y parity? ", 'even' if compressed_indicator else 'odd')

#print("Private key hexlify: ", hexlify(cec_key.get_privkey()))
print("Public  key    hex: ", bitcoin.core.b2x(cec_key.get_pubkey()))
cec_key.set_compressed(False)
print("      uncompressed: ", bitcoin.core.b2x(cec_key.get_pubkey()))

addr_compressed = encoding.public_pair_to_bitcoin_address(
    pubkey_pair, True, address_prefix=my_pubaddr_prefix)
addr_uncompressed = encoding.public_pair_to_bitcoin_address(
    pubkey_pair, False, address_prefix=my_pubaddr_prefix)
Beispiel #31
0
    def onJoin(self, data):
        print('Welcome to GreenAddress mnemonic login example')
        print('\nThis script will login to GA in full mode')
        self.mnemonic_phrase = getpass('Please write your mnemonic phrase and press enter: ')
        self.mnemonic_phrase = "hotel helmet envelope amazing often proud scorpion myth shaft differ put expand equal scout piece million hair crater annual echo net eye middle replace"
        
        #Generate GA-side wallet path and key info
        GA_pubkey = binascii.unhexlify("036307e560072ed6ce0aa5465534fb5c258a2ccfbc257f369e8e7a181b16d897b3")
        GA_pair = sec_to_public_pair(GA_pubkey)
        GA_chaincode = binascii.unhexlify("b60befcc619bb1c212732770fe181f2f1aa824ab89f8aab49f2e13e3a56f0f04")
        gawallet = BIP32Node.BIP32Node('XTN', GA_chaincode, public_pair=GA_pair)
        if sys.version_info.major < 3:
            m = hmac.new(bytearray(self.mnemonic_phrase), bytearray('GreenAddress!!!'), hashlib.sha512)
        else:
            m = hmac.new(bytearray(self.mnemonic_phrase, 'utf-8'), bytearray('GreenAddress!!!', 'utf-8'), hashlib.sha512)
        gawalletpath = binascii.hexlify(m.digest())
        gawalletpath_bin = binascii.unhexlify(gawalletpath)
        gawalletpath_str = '/'.join(str(struct.unpack('!H', gawalletpath_bin[i*2:(i+1)*2])[0]) for i in range(32))

        # 1. Master wallet
        seed = mnemonic.Mnemonic.to_seed(self.mnemonic_phrase)
        self.wallet = BIP32Node.BIP32Node.from_master_secret(seed, 'XTN')
        # Change 'BTC' to 'XTN' for Testnet

        # 2. Login wallet
        path = '%X' % random.randint(0, 2**64-1)
        while len(path) < 16:
            path = '0' + path
        path_bin = binascii.unhexlify(path)
        path_str = '/'.join(str(struct.unpack('!H', path_bin[i*2:(i+1)*2])[0]) for i in range(4))
        wallet_login = self.wallet.subkey_for_path(path_str)

        # 3. Get challenge
        print('\nLogging in with mnemonic passphrase, requesting challenge')
        challenge = yield self.call(
            'com.greenaddress.login.get_challenge',
            self.wallet.bitcoin_address(),
            # disclose_me is required for authentication
            options=CallOptions(disclose_me=True)
        )

        # 4. Login
        signature = pycoin_ecdsa.sign(pycoin_ecdsa.generator_secp256k1, wallet_login.secret_exponent(), int(challenge))
        if signature[1]+signature[1] > pycoin_ecdsa.generator_secp256k1.order():
            signature = (signature[0], pycoin_ecdsa.generator_secp256k1.order() - signature[1])
        login_data = yield self.call(
            "com.greenaddress.login.authenticate",
            list(map(str, signature)),
            False,
            path,
            options=CallOptions(disclose_me=True)
        )

        if data and login_data:
            print(login_data)
            last_login = (login_data['last_login']['at'], login_data['last_login']['country'], login_data['last_login']['ip'])
            print('\nLogin successful! Last login on %s, from country %s, ip address: %s' % last_login)
        else: print('\nLogin failed')

        
        p2sh_addr = yield self.call(
                "com.greenaddress.vault.fund",
                return_pointer=True,
                options=CallOptions(disclose_me=True))

        print(p2sh_addr)
        validateGAAddr(p2sh_addr, self.wallet)

        syncWallet(p2sh_addr, self.wallet, gawallet, gawalletpath_str)
        '''
        balance = yield self.call(
                "com.greenaddress.txs.get_balance",
                options=CallOptions(disclose_me=True))
        print(balance)

        
        prep_tx = yield self.call(
                "com.greenaddress.vault.prepare_tx",
                rcpt_ad="2MtXwJyVCWLUmNeeNsQt958sV9658ZEpAdn",
                value="10000",
                add_fee='sender',
                priv_data={},
                options=CallOptions(disclose_me=True))
        print(prep_tx)
        '''
        

        reactor.stop()
Beispiel #32
0
def pubkey_to_address(pubkey_hex):
    sec = binascii.unhexlify(pubkey_hex)
    compressed = encoding.is_sec_compressed(sec)
    public_pair = encoding.sec_to_public_pair(sec)
    return encoding.public_pair_to_bitcoin_address(public_pair, compressed=compressed)
Beispiel #33
0
def solve(self, **kwargs):
    """
    The kwargs required depend upon the script type.
    hash160_lookup:
        dict-like structure that returns a secret exponent for a hash160
    existing_script:
        existing solution to improve upon (optional)
    sign_value:
        the integer value to sign (derived from the transaction hash)
    signature_type:
        usually SIGHASH_ALL (1)
    """
    # we need a hash160 => secret_exponent lookup
    db = kwargs.get("hash160_lookup")
    if db is None:
        raise SolvingError("missing hash160_lookup parameter")

    sign_value = kwargs.get("sign_value")
    signature_type = kwargs.get("signature_type")

    secs_solved = set()
    existing_signatures = []
    existing_script = kwargs.get("existing_script")
    if existing_script:
        pc = 0
        opcode, data, pc = tools.get_opcode(existing_script, pc)
        # ignore the first opcode
        while pc < len(existing_script):
            opcode, data, pc = tools.get_opcode(existing_script, pc)
            sig_pair, actual_signature_type = parse_signature_blob(data)
            for sec_key in self.sec_keys:
                try:
                    public_pair = encoding.sec_to_public_pair(sec_key)
                    sig_pair, signature_type = parse_signature_blob(data)
                    v = ecdsa.verify(ecdsa.generator_secp256k1, public_pair, sign_value, sig_pair)
                    if v:
                        existing_signatures.append(data)
                        secs_solved.add(sec_key)
                        break
                except encoding.EncodingError:
                    # if public_pair is invalid, we just ignore it
                    pass

    for sec_key in self.sec_keys:
        if sec_key in secs_solved:
            continue
        if len(existing_signatures) >= self.n:
            break
        hash160 = encoding.hash160(sec_key)
        result = db.get(hash160)
        if result is None:
            continue
        secret_exponent, public_pair, compressed = result
        binary_signature = self._create_script_signature(secret_exponent, sign_value, signature_type)
        existing_signatures.append(b2h(binary_signature))
    DUMMY_SIGNATURE = "OP_0"
    while len(existing_signatures) < self.n:
        existing_signatures.append(DUMMY_SIGNATURE)

    script = "OP_0 %s" % " ".join(s for s in existing_signatures)
    solution = tools.compile(script)
    return solution
Beispiel #34
0
def solve(self, **kwargs):
    """
    The kwargs required depend upon the script type.
    hash160_lookup:
        dict-like structure that returns a secret exponent for a hash160
    existing_script:
        existing solution to improve upon (optional)
    sign_value:
        the integer value to sign (derived from the transaction hash)
    signature_type:
        usually SIGHASH_ALL (1)
    """
    # we need a hash160 => secret_exponent lookup
    db = kwargs.get("hash160_lookup")
    if db is None:
        raise SolvingError("missing hash160_lookup parameter")

    sign_value = kwargs.get("sign_value")
    signature_type = kwargs.get("signature_type")

    secs_solved = set()
    existing_signatures = []
    existing_script = kwargs.get("existing_script")
    if existing_script:
        pc = 0
        opcode, data, pc = tools.get_opcode(existing_script, pc)
        # ignore the first opcode
        while pc < len(existing_script):
            opcode, data, pc = tools.get_opcode(existing_script, pc)
            sig_pair, actual_signature_type = parse_signature_blob(data)
            for sec_key in self.sec_keys:
                try:
                    public_pair = encoding.sec_to_public_pair(sec_key)
                    sig_pair, signature_type = parse_signature_blob(data)
                    v = ecdsa.verify(ecdsa.generator_secp256k1, public_pair,
                                     sign_value, sig_pair)
                    if v:
                        existing_signatures.append(data)
                        secs_solved.add(sec_key)
                        break
                except encoding.EncodingError:
                    # if public_pair is invalid, we just ignore it
                    pass

    for sec_key in self.sec_keys:
        if sec_key in secs_solved:
            continue
        if len(existing_signatures) >= self.n:
            break
        hash160 = encoding.hash160(sec_key)
        result = db.get(hash160)
        if result is None:
            continue
        secret_exponent, public_pair, compressed = result
        binary_signature = self._create_script_signature(
            secret_exponent, sign_value, signature_type)
        existing_signatures.append(b2h(binary_signature))
    DUMMY_SIGNATURE = "OP_0"
    while len(existing_signatures) < self.n:
        existing_signatures.append(DUMMY_SIGNATURE)

    script = "OP_0 %s" % " ".join(s for s in existing_signatures)
    solution = tools.compile(script)
    return solution
def get_compressed_pubkey_format(pubkey):
    public_pair=encoding.sec_to_public_pair(encoding.binascii.unhexlify(pubkey))
    return encoding.binascii.hexlify(encoding.public_pair_to_sec(public_pair))
def get_address_of_pubkey(pubkey):
    public_pair=encoding.sec_to_public_pair(encoding.binascii.unhexlify(pubkey))
    return encoding.public_pair_to_bitcoin_address(public_pair)
def get_address_of_pubkey(pubkey):
    public_pair=encoding.sec_to_public_pair(encoding.binascii.unhexlify(pubkey))
    return encoding.public_pair_to_bitcoin_address(public_pair)
Beispiel #38
0
 def from_sec(class_, sec):
     """
     Create a key from an sec bytestream (which is an encoding of a public pair).
     """
     public_pair = sec_to_public_pair(sec)
     return Key(public_pair=public_pair, prefer_uncompressed=not is_sec_compressed(sec))
def get_compressed_pubkey_format(pubkey):
    public_pair=encoding.sec_to_public_pair(encoding.binascii.unhexlify(pubkey))
    return encoding.binascii.hexlify(encoding.public_pair_to_sec(public_pair))
Beispiel #40
0
 def _is_valid_pubkey(self, k):
     try:
         sec_to_public_pair(binascii.unhexlify(k.encode("ascii")))
         return True
     except EncodingError:
         return False
Beispiel #41
0
def test_bitcoind_cosigning(dev, bitcoind, start_sign, end_sign, import_ms_wallet, clear_ms, explora, try_sign, need_keypress, addr_style):
    # Make a P2SH wallet with local bitcoind as a co-signer (and simulator)
    # - send an receive various
    # - following text of <https://github.com/bitcoin/bitcoin/blob/master/doc/psbt.md>
    # - the constructed multisig walelt will only work for a single pubkey on core side
    # - before starting this test, have some funds already deposited to bitcoind testnet wallet
    from pycoin.encoding import sec_to_public_pair
    from binascii import a2b_hex
    import re

    if addr_style == 'legacy':
        addr_fmt = AF_P2SH
    elif addr_style == 'p2sh-segwit':
        addr_fmt = AF_P2WSH_P2SH
    elif addr_style == 'bech32':
        addr_fmt = AF_P2WSH
    
    try:
        addr, = bitcoind.getaddressesbylabel("sim-cosign").keys()
    except:
        addr = bitcoind.getnewaddress("sim-cosign")

    info = bitcoind.getaddressinfo(addr)
    #pprint(info)

    assert info['address'] == addr
    bc_xfp = swab32(int(info['hdmasterfingerprint'], 16))
    bc_deriv = info['hdkeypath']        # example: "m/0'/0'/3'"
    bc_pubkey = info['pubkey']          # 02f75ae81199559c4aa...

    pp = sec_to_public_pair(a2b_hex(bc_pubkey))

    # No means to export XPUB from bitcoind! Still. In 2019.
    # - this fake will only work for for one pubkey value, the first/topmost
    node = BIP32Node('XTN', b'\x23'*32, depth=len(bc_deriv.split('/'))-1,
                        parent_fingerprint=a2b_hex('%08x' % bc_xfp), public_pair=pp)

    keys = [
        (bc_xfp, None, node),
        (1130956047, None, BIP32Node.from_hwif('tpubD8NXmKsmWp3a3DXhbihAYbYLGaRNVdTnr6JoSxxfXYQcmwVtW2hv8QoDwng6JtEonmJoL3cNEwfd2cLXMpGezwZ2vL2dQ7259bueNKj9C8n')),     # simulator: m/45'
    ]

    M,N=2,2

    clear_ms()
    import_ms_wallet(M, N, keys=keys, accept=1, name="core-cosign")

    cc_deriv = "m/45'/55"
    cc_pubkey = B2A(BIP32Node.from_hwif(simulator_fixed_xprv).subkey_for_path(cc_deriv[2:]).sec())

    

    # NOTE: bitcoind doesn't seem to implement pubkey sorting. We have to do it.
    resp = bitcoind.addmultisigaddress(M, list(sorted([cc_pubkey, bc_pubkey])),
                                                'shared-addr-'+addr_style, addr_style)
    ms_addr = resp['address']
    bc_redeem = a2b_hex(resp['redeemScript'])

    assert bc_redeem[0] == 0x52

    def mapper(cosigner_idx):
        return list(str2ipath(cc_deriv if cosigner_idx else bc_deriv))

    scr, pubkeys, xfp_paths = make_redeem(M, keys, mapper)

    assert scr == bc_redeem

    # check Coldcard calcs right address to match
    got_addr = dev.send_recv(CCProtocolPacker.show_p2sh_address(
                                M, xfp_paths, scr, addr_fmt=addr_fmt), timeout=None)
    assert got_addr == ms_addr
    time.sleep(.1)
    need_keypress('x')      # clear screen / start over

    print(f"Will be signing an input from {ms_addr}")

    if xfp2str(bc_xfp) in ('5380D0ED', 'EDD08053'):
        # my own expected values
        assert ms_addr in ( '2NDT3ymKZc8iMfbWqsNd1kmZckcuhixT5U4',
                            '2N1hZJ5mazTX524GQTPKkCT4UFZn5Fqwdz6',
                            'tb1qpcv2rkc003p5v8lrglrr6lhz2jg8g4qa9vgtrgkt0p5rteae5xtqn6njw9')

    # Need some UTXO to sign
    #
    # - but bitcoind can't give me that (using listunspent) because it's only a watched addr??
    #
    did_fund = False
    while 1:
        rr = explora('address', ms_addr, 'utxo')
        pprint(rr)

        avail = []
        amt = 0
        for i in rr:
            txn = i['txid']
            vout = i['vout']
            avail.append( (txn, vout) )
            amt += i['value']

            # just use first UTXO available; save other for later tests
            break

        else:
            # doesn't need to confirm, but does need to reach public testnet/blockstream
            assert not amt and not avail

            if not did_fund:
                print(f"Sending some XTN to {ms_addr}  (wait)")
                bitcoind.sendtoaddress(ms_addr, 0.0001, 'fund testing')
                did_fund = True
            else:
                print(f"Still waiting ...")

            time.sleep(2)

        if amt: break

    ret_addr = bitcoind.getrawchangeaddress()

    ''' If you get insufficent funds, even tho we provide the UTXO (!!), do this:

            bitcoin-cli importaddress "2NDT3ymKZc8iMfbWqsNd1kmZckcuhixT5U4" true true

        Better method: always fund addresses for testing here from same wallet (ie.
        got from non-multisig to multisig on same bitcoin-qt instance).
        -> Now doing that, automated, above.
    '''
    resp = bitcoind.walletcreatefundedpsbt([dict(txid=t, vout=o) for t,o in avail],
               [{ret_addr: amt/1E8}], 0,
                {'subtractFeeFromOutputs': [0], 'includeWatching': True}, True)

    assert resp['changepos'] == -1
    psbt = b64decode(resp['psbt'])

    open('debug/funded.psbt', 'wb').write(psbt)

    # patch up the PSBT a little ... bitcoind doesn't know the path for the CC's key
    ex = BasicPSBT().parse(psbt)
    cxpk = a2b_hex(cc_pubkey)
    for i in ex.inputs:
        assert cxpk in i.bip32_paths, 'input not to be signed by CC?'
        i.bip32_paths[cxpk] = pack('<3I', keys[1][0], *str2ipath(cc_deriv))

    psbt = ex.as_bytes()

    open('debug/patched.psbt', 'wb').write(psbt)

    _, updated = try_sign(psbt, finalize=False)

    open('debug/cc-updated.psbt', 'wb').write(updated)

    # have bitcoind do the rest of the signing
    rr = bitcoind.walletprocesspsbt(b64encode(updated).decode('ascii'))
    pprint(rr)

    open('debug/bc-processed.psbt', 'wt').write(rr['psbt'])
    assert rr['complete']

    # finalize and send
    rr = bitcoind.finalizepsbt(rr['psbt'], True)
    open('debug/bc-final-txn.txn', 'wt').write(rr['hex'])
    assert rr['complete']

    txn_id = bitcoind.sendrawtransaction(rr['hex'])
    print(txn_id)
Beispiel #42
0
def add_sec_annotations(a1, data, address_prefix):
    pair = sec_to_public_pair(data)
    is_compressed = is_sec_compressed(data)
    a1.append("SEC for %scompressed %s" % (
            "" if is_compressed else "un", public_pair_to_bitcoin_address(
                pair, compressed=is_compressed, address_prefix=address_prefix)))
Beispiel #43
0
 def from_sec(class_, sec, netcode="BTC"):
     """
     Create a key from an sec bytestream (which is an encoding of a public pair).
     """
     public_pair = sec_to_public_pair(sec)
     return class_(public_pair=public_pair, is_compressed=is_sec_compressed(sec), netcode=netcode)
Beispiel #44
0
def pubkey_to_address(pubkey_hex):
    sec = binascii.unhexlify(pubkey_hex)
    compressed = encoding.is_sec_compressed(sec)
    public_pair = encoding.sec_to_public_pair(sec)
    return encoding.public_pair_to_bitcoin_address(public_pair,
                                                   compressed=compressed)