Пример #1
0
    def info_for_p2wit(self, hrp, data):
        decoded = segwit_addr.convertbits(data[1:], 5, 8, False)
        decoded_data = b''.join(int2byte(d) for d in decoded)
        ldd = len(decoded_data)
        version_byte = int2byte(data[0])
        script = version_byte + int2byte(ldd) + decoded_data

        if version_byte == 0:
            if ldd == 20:
                return dict(
                    type="address",
                    address_type="p2pkh_wit",
                    hash160=data,
                    create_f=lambda: self._pay_to.script_for_p2pkh_wit(data))

            if ldd == 32:
                return dict(
                    type="address",
                    address_type="p2sh_wit",
                    hash256=data,
                    create_f=lambda: self._pay_to.script_for_p2sh_wit(data))

        return dict(type="address",
                    address_type="wit_other",
                    version_byte=version_byte,
                    create_f=lambda: script)
Пример #2
0
    def test_compile_push_data_list(self):

        def test_bytes(as_bytes):
            script = ScriptTools.compile_push_data_list([as_bytes])
            # this is a pretty horrible hack to test the vm with long scripts. But it works
            tx_context = TxContext()
            tx_context.signature_for_hash_type_f = None
            tx_context.flags = 0
            tx_context.traceback_f = None
            vm = BitcoinVM(script, tx_context, tx_context.signature_for_hash_type_f, flags=0)
            vm.MAX_SCRIPT_LENGTH = int(1e9)
            vm.MAX_BLOB_LENGTH = int(1e9)
            stack = vm.eval_script()
            assert len(stack) == 1
            assert stack[0] == as_bytes

        def test_val(n):
            as_bytes = IntStreamer.int_to_script_bytes(n)
            test_bytes(as_bytes)

        for i in range(100):
            test_val(100)
        for i in range(0xfff0, 0x10004):
            test_val(i)
        for i in range(0xfffff0, 0x1000005):
            test_val(i)

        for l in (1, 2, 3, 254, 255, 256, 257, 258, 0xfff9, 0xfffe, 0xffff, 0x10000, 0x10001, 0x10005):
            for v in (1, 2, 3, 4, 15, 16, 17, 18):
                b = int2byte(v) * l
                test_bytes(b)

        b = int2byte(30) * (0x1000000+1)
        for l in (0x1000000-1, 0x1000000, 0x1000000+1):
            test_bytes(b[:l])
Пример #3
0
    def test_bin_script(self):
        def test_bytes(as_bytes):
            script = bin_script([as_bytes])
            stack = []
            eval_script(script,
                        None,
                        lock_time=0,
                        stack=stack,
                        disallow_long_scripts=False)
            assert len(stack) == 1
            assert stack[0] == as_bytes

        def test_val(n):
            as_bytes = int_to_script_bytes(n)
            test_bytes(as_bytes)

        for i in range(100):
            test_val(100)
        for i in range(0xfff0, 0x10004):
            test_val(i)
        for i in range(0xfffff0, 0x1000005):
            test_val(i)

        for l in (1, 2, 3, 254, 255, 256, 257, 258, 0xfff9, 0xfffe, 0xffff,
                  0x10000, 0x10001, 0x10005):
            for v in (1, 2, 3, 4, 15, 16, 17, 18):
                b = int2byte(v) * l
                test_bytes(b)

        b = int2byte(30) * (0x1000000 + 1)
        for l in (0x1000000 - 1, 0x1000000, 0x1000000 + 1):
            test_bytes(b[:l])
Пример #4
0
    def test_compile_push_data_list(self):

        def test_bytes(as_bytes):
            script = network.script.compile_push_data_list([as_bytes])
            # this is a pretty horrible hack to test the vm with long scripts. But it works
            tx_context = TxContext()
            tx_context.signature_for_hash_type_f = None
            tx_context.flags = 0
            tx_context.traceback_f = None
            vm = BitcoinVM(script, tx_context, tx_context.signature_for_hash_type_f, flags=0)
            vm.MAX_SCRIPT_LENGTH = int(1e9)
            vm.MAX_BLOB_LENGTH = int(1e9)
            stack = vm.eval_script()
            assert len(stack) == 1
            assert stack[0] == as_bytes

        def test_val(n):
            as_bytes = IntStreamer.int_to_script_bytes(n)
            test_bytes(as_bytes)

        for i in range(100):
            test_val(100)
        for i in range(0xfff0, 0x10004):
            test_val(i)
        for i in range(0xfffff0, 0x1000005):
            test_val(i)

        for l in (1, 2, 3, 254, 255, 256, 257, 258, 0xfff9, 0xfffe, 0xffff, 0x10000, 0x10001, 0x10005):
            for v in (1, 2, 3, 4, 15, 16, 17, 18):
                b = int2byte(v) * l
                test_bytes(b)

        b = int2byte(30) * (0x1000000+1)
        for l in (0x1000000-1, 0x1000000, 0x1000000+1):
            test_bytes(b[:l])
Пример #5
0
def encode_length(l):
    assert l >= 0
    if l < 0x80:
        return int2byte(l)
    s = "%x" % l
    if len(s) % 2:
        s = "0" + s
    s = binascii.unhexlify(s)
    llen = len(s)
    return int2byte(0x80 | llen) + s
Пример #6
0
def encode_length(l):
    assert l >= 0
    if l < 0x80:
        return int2byte(l)
    s = "%x" % l
    if len(s) % 2:
        s = "0"+s
    s = binascii.unhexlify(s)
    llen = len(s)
    return int2byte(0x80 | llen) + s
Пример #7
0
def encode_integer(r):
    assert r >= 0  # can't support negative numbers yet
    h = "%x" % r
    if len(h) % 2:
        h = "0" + h
    s = binascii.unhexlify(h.encode("utf8"))
    if ord(s[:1]) <= 0x7f:
        return b"\x02" + int2byte(len(s)) + s
    else:
        # DER integers are two's complement, so if the first byte is
        # 0x80-0xff then we need an extra 0x00 byte to prevent it from
        # looking negative.
        return b"\x02" + int2byte(len(s)+1) + b"\x00" + s
Пример #8
0
def encode_integer(r):
    assert r >= 0  # can't support negative numbers yet
    h = "%x" % r
    if len(h) % 2:
        h = "0" + h
    s = binascii.unhexlify(h.encode("utf8"))
    if ord(s[:1]) <= 0x7f:
        return b"\x02" + int2byte(len(s)) + s
    else:
        # DER integers are two's complement, so if the first byte is
        # 0x80-0xff then we need an extra 0x00 byte to prevent it from
        # looking negative.
        return b"\x02" + int2byte(len(s) + 1) + b"\x00" + s
Пример #9
0
    def test_sign_verify_mutual_compatability(self):
        if libsecp256k1 is None:
            raise unittest.SkipTest("no libsecp256k1")
        ctx = libsecp256k1.ctx
        signature = create_string_buffer(64)
        sighash = to_bytes_32(1000)
        secret_key = to_bytes_32(100)

        public_key = create_string_buffer(64)
        r = libsecp256k1.secp256k1_ec_pubkey_create(ctx, public_key,
                                                    secret_key)
        self.assertEqual(r, 1)
        self.assertEqual(
            b2h(public_key),
            '880f50f7ceb4210289266a40b306e33ef52bb75f834c172e65175e3ce2ac3bed'
            '6e2835e3d57ae1fcd0954808be17bd97bf871f7a8a5edadcffcc8812576f7ae5')

        r = libsecp256k1.secp256k1_ecdsa_sign(ctx, signature, sighash,
                                              secret_key, None, None)
        self.assertEqual(r, 1)

        r = libsecp256k1.secp256k1_ecdsa_verify(ctx, signature, sighash,
                                                public_key)
        self.assertEqual(r, 1)

        signature1 = signature[:-1] + int2byte(byte2int(signature[-1]) ^ 1)
        r = libsecp256k1.secp256k1_ecdsa_verify(ctx, signature1, sighash,
                                                public_key)
        self.assertEqual(r, 0)
Пример #10
0
 def _segwit(self, s, blob_len, segwit_attr):
     script_f = getattr(self._network.contract, segwit_attr, None)
     if script_f is None:
         return None
     pair = parse_bech32(s)
     if pair is None or pair[0] != self._bech32_hrp or pair[1] is None:
         return None
     data = pair[1]
     version_byte = int2byte(data[0])
     decoded = segwit_addr.convertbits(data[1:], 5, 8, False)
     decoded_data = b''.join(int2byte(d) for d in decoded)
     if version_byte != b'\0' or len(decoded_data) != blob_len:
         return None
     script = script_f(decoded_data)
     script_info = self._network.contract.info_for_script(script)
     return Contract(script_info, self._network)
Пример #11
0
    def test_sign_verify_mutual_compatability(self):
        if libsecp256k1 is None:
            raise unittest.SkipTest("no libsecp256k1")
        ctx = libsecp256k1.ctx
        signature = create_string_buffer(64)
        sighash = to_bytes_32(1000)
        secret_key = to_bytes_32(100)

        public_key = create_string_buffer(64)
        r = libsecp256k1.secp256k1_ec_pubkey_create(ctx, public_key, secret_key)
        self.assertEqual(r, 1)
        self.assertEqual(
            b2h(public_key),
            '880f50f7ceb4210289266a40b306e33ef52bb75f834c172e65175e3ce2ac3bed'
            '6e2835e3d57ae1fcd0954808be17bd97bf871f7a8a5edadcffcc8812576f7ae5'
        )

        r = libsecp256k1.secp256k1_ecdsa_sign(ctx, signature, sighash, secret_key, None, None)
        self.assertEqual(r, 1)

        r = libsecp256k1.secp256k1_ecdsa_verify(ctx, signature, sighash, public_key)
        self.assertEqual(r, 1)

        signature1 = signature[:-1] + int2byte(byte2int(signature[-1]) ^ 1)
        r = libsecp256k1.secp256k1_ecdsa_verify(ctx, signature1, sighash, public_key)
        self.assertEqual(r, 0)
Пример #12
0
 def _segwit(self, s, blob_len, segwit_attr):
     script_f = getattr(self._network.contract, segwit_attr, None)
     if script_f is None:
         return None
     pair = parse_bech32(s)
     if pair is None or pair[0] != self._bech32_hrp or pair[1] is None:
         return None
     data = pair[1]
     version_byte = int2byte(data[0])
     decoded = segwit_addr.convertbits(data[1:], 5, 8, False)
     decoded_data = b''.join(int2byte(d) for d in decoded)
     if version_byte != b'\0' or len(decoded_data) != blob_len:
         return None
     script = script_f(decoded_data)
     script_info = self._network.contract.info_for_script(script)
     return Contract(script_info, self._network)
Пример #13
0
 def _create_script_signature(
         self, secret_exponent, signature_for_hash_type_f, signature_type, script):
     sign_value = signature_for_hash_type_f(signature_type, script)
     order = secp256k1_generator.order()
     r, s = secp256k1_generator.sign(secret_exponent, sign_value)
     if s + s > order:
         s = order - s
     return der.sigencode_der(r, s) + int2byte(signature_type)
Пример #14
0
    def f(solved_values, **kwargs):
        signature_type = kwargs.get("signature_type", DEFAULT_SIGNATURE_TYPE)
        generator_for_signature_type_f = kwargs[
            "generator_for_signature_type_f"]
        signature_for_hash_type_f = m["signature_for_hash_type_f"]
        existing_script = kwargs.get("existing_script", b'')
        existing_signatures, secs_solved = _find_signatures(
            existing_script, generator_for_signature_type_f,
            signature_for_hash_type_f, len(m["sig_list"]), m["sec_list"])

        sec_keys = m["sec_list"]
        signature_variables = m["sig_list"]

        signature_placeholder = kwargs.get("signature_placeholder",
                                           DEFAULT_PLACEHOLDER_SIGNATURE)

        db = kwargs.get("hash160_lookup", {})
        # we reverse this enumeration to make the behaviour look like the old signer. BRAIN DAMAGE
        for signature_order, sec_key in reversed(list(enumerate(sec_keys))):
            sec_key = solved_values.get(sec_key, sec_key)
            if sec_key in secs_solved:
                continue
            if len(existing_signatures) >= len(signature_variables):
                break
            result = db.get(hash160(sec_key))
            if result:
                secret_exponent = result[0]
                sig_hash = signature_for_hash_type_f(signature_type)
                generator = result[3]
                r, s = generator.sign(secret_exponent, sig_hash)
            else:
                # try existing signatures
                generator = generator_for_signature_type_f(signature_type)
                public_pair = sec_to_public_pair(sec_key, generator=generator)
                for sig in all_signature_hints(public_pair,
                                               signature_for_hash_type_f,
                                               **kwargs):
                    sig_hash = signature_for_hash_type_f(indexbytes(sig, -1))
                    sig_pair = der.sigdecode_der(sig[:-1])
                    if generator.verify(public_pair, sig_hash, sig_pair):
                        r, s = sig_pair
                        break
                else:
                    continue
            order = generator.order()
            if s + s > order:
                s = order - s
            binary_signature = der.sigencode_der(r,
                                                 s) + int2byte(signature_type)
            existing_signatures.append((signature_order, binary_signature))

        # pad with placeholder signatures
        if signature_placeholder is not None:
            while len(existing_signatures) < len(signature_variables):
                existing_signatures.append((-1, signature_placeholder))
        existing_signatures.sort()
        return dict(
            zip(signature_variables, (es[-1] for es in existing_signatures)))
Пример #15
0
    def info_for_p2wit(self, hrp, data):
        decoded = segwit_addr.convertbits(data[1:], 5, 8, False)
        decoded_data = b''.join(int2byte(d) for d in decoded)
        ldd = len(decoded_data)
        version_byte = int2byte(data[0])
        script = version_byte + int2byte(ldd) + decoded_data

        if version_byte == 0:
            if ldd == 20:
                return dict(type="address", address_type="p2pkh_wit", hash160=data,
                            create_f=lambda: self._pay_to.script_for_p2pkh_wit(data))

            if ldd == 32:
                return dict(type="address", address_type="p2sh_wit", hash256=data,
                            create_f=lambda: self._pay_to.script_for_p2sh_wit(data))

        return dict(type="address", address_type="wit_other", version_byte=version_byte,
                    create_f=lambda: script)
Пример #16
0
def sigmake(a_key, a_hash_for_sig, a_sig_type):
    """
    Signs a_hash_for_sig with a_key and returns a DER-encoded signature
    with a_sig_type appended.
    """
    order = secp256k1_generator.order()
    r, s = secp256k1_generator.sign(a_key.secret_exponent(), a_hash_for_sig)

    if s + s > order:
        s = order - s

    return sigencode_der(r, s) + int2byte(a_sig_type)
Пример #17
0
def sigmake(a_key, a_hash_for_sig, a_sig_type=SIGHASH_ALL):
    """
    Signs a_hash_for_sig with a_key and returns a DER-encoded signature
    with a_sig_type appended.
    """
    order = secp256k1_generator.order()
    r, s = secp256k1_generator.sign(a_key.secret_exponent(), a_hash_for_sig)

    if s + s > order:
        s = order - s

    return sigencode_der(r, s) + int2byte(a_sig_type)
Пример #18
0
    def f(solved_values, **kwargs):
        signature_type = kwargs.get("signature_type", DEFAULT_SIGNATURE_TYPE)
        signature_hints = kwargs.get("signature_hints", [])
        generator_for_signature_type_f = kwargs["generator_for_signature_type_f"]
        signature_for_hash_type_f = m["signature_for_hash_type_f"]
        existing_script = kwargs.get("existing_script", b'')
        existing_signatures, secs_solved = _find_signatures(
            existing_script, generator_for_signature_type_f, signature_for_hash_type_f,
            len(m["sig_list"]), m["sec_list"])

        sec_keys = m["sec_list"]
        signature_variables = m["sig_list"]

        signature_placeholder = kwargs.get("signature_placeholder", DEFAULT_PLACEHOLDER_SIGNATURE)

        db = kwargs.get("hash160_lookup", {})
        # we reverse this enumeration to make the behaviour look like the old signer. BRAIN DAMAGE
        for signature_order, sec_key in reversed(list(enumerate(sec_keys))):
            sec_key = solved_values.get(sec_key, sec_key)
            if sec_key in secs_solved:
                continue
            if len(existing_signatures) >= len(signature_variables):
                break
            result = db.get(hash160(sec_key))
            if result:
                secret_exponent = result[0]
                sig_hash = signature_for_hash_type_f(signature_type)
                generator = result[3]
                r, s = generator.sign(secret_exponent, sig_hash)
            else:
                # try existing signatures
                for sig in signature_hints:
                    sig_hash = signature_for_hash_type_f(indexbytes(sig, -1))
                    generator = generator_for_signature_type_f(signature_type)
                    public_pair = sec_to_public_pair(sec_key, generator=generator)
                    sig_pair = der.sigdecode_der(sig[:-1])
                    if generator.verify(public_pair, sig_hash, sig_pair):
                        r, s = sig_pair
                        break
                else:
                    continue
            order = generator.order()
            if s + s > order:
                s = order - s
            binary_signature = der.sigencode_der(r, s) + int2byte(signature_type)
            existing_signatures.append((signature_order, binary_signature))

        # pad with placeholder signatures
        if signature_placeholder is not None:
            while len(existing_signatures) < len(signature_variables):
                existing_signatures.append((-1, signature_placeholder))
        existing_signatures.sort()
        return dict(zip(signature_variables, (es[-1] for es in existing_signatures)))
Пример #19
0
    def signature_for_message_hash(self, secret_exponent, msg_hash, is_compressed):
        """
        Return a signature, encoded in Base64, of msg_hash.
        """
        r, s, recid = self._generator.sign_with_recid(secret_exponent, msg_hash)

        # See http://bitcoin.stackexchange.com/questions/14263 and key.cpp
        # for discussion of the proprietary format used for the signature

        first = 27 + recid + (4 if is_compressed else 0)
        sig = b2a_base64(int2byte(first) + to_bytes_32(r) + to_bytes_32(s)).strip()
        sig = sig.decode("utf8")
        return sig
Пример #20
0
    def signature_for_message_hash(self, secret_exponent, msg_hash, is_compressed):
        """
        Return a signature, encoded in Base64, of msg_hash.
        """
        r, s, recid = self._generator.sign_with_recid(secret_exponent, msg_hash)

        # See http://bitcoin.stackexchange.com/questions/14263 and key.cpp
        # for discussion of the proprietary format used for the signature

        first = 27 + recid + (4 if is_compressed else 0)
        sig = b2a_base64(int2byte(first) + to_bytes_32(r) + to_bytes_32(s)).strip()
        sig = sig.decode("utf8")
        return sig
Пример #21
0
def generate_default_placeholder_signature():
    order = ecdsa.generator_secp256k1.order()
    r, s = order - 1, order // 2
    return der.sigencode_der(r, s) + int2byte(1)
Пример #22
0
def generate_default_placeholder_signature():
    order = secp256k1_generator.order()
    r, s = order - 1, order // 2
    return der.sigencode_der(r, s) + int2byte(1)