Beispiel #1
0
 def test_sec(self):
     pair_blob = h2b("0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483a"
                     "da7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8")
     sec_to_public_pair(pair_blob, secp256k1_generator, strict=False)
     try:
         sec_to_public_pair(pair_blob, secp256k1_generator, strict=True)
         self.fail("sec_to_public_pair unexpectedly succeeded")
     except EncodingError:
         pass
Beispiel #2
0
 def test_sec(self):
     pair_blob = h2b(
         "0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483a"
         "da7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8")
     sec_to_public_pair(pair_blob, secp256k1_generator, strict=False)
     try:
         sec_to_public_pair(pair_blob, secp256k1_generator, strict=True)
         self.fail("sec_to_public_pair unexpectedly succeeded")
     except 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)

            key = BitcoinMainnet.ui.parse(wif)
            exponent = key.secret_exponent()
            compressed = not key._use_uncompressed()
            self.assertEqual(exponent, secret_exponent)
            self.assertFalse(compressed)

            key = BitcoinMainnet.ui.parse(c_wif)
            exponent = key.secret_exponent()
            compressed = not key._use_uncompressed()
            self.assertEqual(exponent, secret_exponent)
            self.assertTrue(compressed)

            public_pair = secret_exponent * secp256k1_generator

            pk_public_pair = sec_to_public_pair(sec, secp256k1_generator)
            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, secp256k1_generator)
            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 info_for_sec(self, prefix, text):
     sec = h2b(text)
     public_pair = sec_to_public_pair(sec, self._generator)
     is_compressed = is_sec_compressed(sec)
     kwargs = dict(public_pair=public_pair, is_compressed=is_compressed)
     return dict(type="key", key_type="sec", is_private=False, kwargs=kwargs,
                 key_class=self._key_class, create_f=lambda: self._key_class(**kwargs))
Beispiel #5
0
 def from_sec(class_, sec, generator=None):
     """
     Create a key from an sec bytestream (which is an encoding of a public pair).
     """
     generator = generator or class_._default_generator
     public_pair = sec_to_public_pair(sec, generator)
     return class_(public_pair=public_pair, is_compressed=is_sec_compressed(sec))
Beispiel #6
0
 def info_for_sec(self, prefix, text):
     sec = h2b(text)
     public_pair = sec_to_public_pair(sec, self._generator)
     is_compressed = is_sec_compressed(sec)
     kwargs = dict(public_pair=public_pair, is_compressed=is_compressed)
     return dict(type="key", key_type="sec", is_private=False, kwargs=kwargs,
                 key_class=self._key_class, create_f=lambda: self._key_class(**kwargs))
Beispiel #7
0
 def from_sec(class_, sec, generator):
     """
     Create a key from an sec bytestream (which is an encoding of a public pair).
     """
     public_pair = sec_to_public_pair(sec, generator)
     return class_(public_pair=public_pair,
                   is_compressed=is_sec_compressed(sec))
Beispiel #8
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)))
        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)

            key = network.parse.wif(wif)
            exponent = key.secret_exponent()
            compressed = key.is_compressed()
            self.assertEqual(exponent, secret_exponent)
            self.assertFalse(compressed)

            key = network.parse.wif(c_wif)
            exponent = key.secret_exponent()
            compressed = key.is_compressed()
            self.assertEqual(exponent, secret_exponent)
            self.assertTrue(compressed)

            public_pair = secret_exponent * key._generator

            pk_public_pair = sec_to_public_pair(sec, key._generator)
            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, key._generator)
            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 #10
0
        def do_test(as_public_pair, as_sec, is_compressed, as_hash160_sec, as_bitcoin_address):
            self.assertEqual(sec_to_public_pair(as_sec, secp256k1_generator), as_public_pair)
            self.assertEqual(public_pair_to_sec(as_public_pair, compressed=is_compressed), as_sec)
            self.assertEqual(is_sec_compressed(as_sec), is_compressed)
            self.assertEqual(public_pair_to_hash160_sec(as_public_pair, compressed=is_compressed),
                             as_hash160_sec)

            self.assertEqual(BitcoinMainnet.ui.address_for_p2pkh(as_hash160_sec), as_bitcoin_address)
            self.assertTrue(is_address_valid(as_bitcoin_address))
            bad_address = as_bitcoin_address[:17] + chr(ord(as_bitcoin_address[17]) + 1) + as_bitcoin_address[18:]
            self.assertFalse(is_address_valid(bad_address))
Beispiel #11
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)))
Beispiel #12
0
    def info_for_data(self, data, is_private):
        parent_fingerprint, child_index = struct.unpack(">4sL", data[5:13])

        d = dict(generator=self._generator, chain_code=data[13:45],
                 depth=ord(data[4:5]), parent_fingerprint=parent_fingerprint,
                 child_index=child_index)
        if is_private:
            if data[45:46] != b'\0':
                return None
            d["secret_exponent"] = from_bytes_32(data[46:])
        else:
            d["public_pair"] = sec_to_public_pair(data[45:], self._generator)
        return dict(type="key", key_type="bip32", bip32_type="plain", is_private=is_private,
                    kwargs=d, key_class=self._bip32node_class, create_f=lambda: self._bip32node_class(**d))
Beispiel #13
0
        def do_test(as_public_pair, as_sec, is_compressed, as_hash160_sec,
                    as_bitcoin_address):
            self.assertEqual(sec_to_public_pair(as_sec, secp256k1_generator),
                             as_public_pair)
            self.assertEqual(
                public_pair_to_sec(as_public_pair, compressed=is_compressed),
                as_sec)
            self.assertEqual(is_sec_compressed(as_sec), is_compressed)
            self.assertEqual(
                public_pair_to_hash160_sec(as_public_pair,
                                           compressed=is_compressed),
                as_hash160_sec)

            self.assertEqual(network.address.for_p2pkh(as_hash160_sec),
                             as_bitcoin_address)
            self.assertIsNotNone(network.parse.address(as_bitcoin_address))
            bad_address = as_bitcoin_address[:17] + chr(
                ord(as_bitcoin_address[17]) + 1) + as_bitcoin_address[18:]
            self.assertIsNone(network.parse.address(bad_address))
Beispiel #14
0
        def do_test(as_public_pair, as_sec, is_compressed, as_hash160_sec,
                    as_bitcoin_address):
            self.assertEqual(sec_to_public_pair(as_sec, secp256k1_generator),
                             as_public_pair)
            self.assertEqual(
                public_pair_to_sec(as_public_pair, compressed=is_compressed),
                as_sec)
            self.assertEqual(is_sec_compressed(as_sec), is_compressed)
            self.assertEqual(
                public_pair_to_hash160_sec(as_public_pair,
                                           compressed=is_compressed),
                as_hash160_sec)

            self.assertEqual(
                BitcoinMainnet.ui.address_for_p2pkh(as_hash160_sec),
                as_bitcoin_address)
            self.assertTrue(is_address_valid(as_bitcoin_address))
            bad_address = as_bitcoin_address[:17] + chr(
                ord(as_bitcoin_address[17]) + 1) + as_bitcoin_address[18:]
            self.assertFalse(is_address_valid(bad_address))
Beispiel #15
0
def _find_signatures(script_blobs, generator_for_signature_type_f, signature_for_hash_type_f, max_sigs, sec_keys):
    signatures = []
    secs_solved = set()
    seen = 0
    for data in script_blobs:
        if seen >= max_sigs:
            break
        try:
            sig_pair, signature_type = parse_signature_blob(data)
            generator = generator_for_signature_type_f(signature_type)
            seen += 1
            for idx, sec_key in enumerate(sec_keys):
                public_pair = sec_to_public_pair(sec_key, generator)
                sign_value = signature_for_hash_type_f(signature_type)
                v = generator.verify(public_pair, sign_value, sig_pair)
                if v:
                    signatures.append((idx, data))
                    secs_solved.add(sec_key)
                    break
        except (ValueError, EncodingError, der.UnexpectedDER, ScriptError):
            # if public_pair is invalid, we just ignore it
            pass
    return signatures, secs_solved
Beispiel #16
0
def _find_signatures(script_blobs, generator_for_signature_type_f,
                     signature_for_hash_type_f, max_sigs, sec_keys):
    signatures = []
    secs_solved = set()
    seen = 0
    for data in script_blobs:
        if seen >= max_sigs:
            break
        try:
            sig_pair, signature_type = parse_signature_blob(data)
            generator = generator_for_signature_type_f(signature_type)
            seen += 1
            for idx, sec_key in enumerate(sec_keys):
                public_pair = sec_to_public_pair(sec_key, generator)
                sign_value = signature_for_hash_type_f(signature_type)
                v = generator.verify(public_pair, sign_value, sig_pair)
                if v:
                    signatures.append((idx, data))
                    secs_solved.add(sec_key)
                    break
        except (ValueError, EncodingError, der.UnexpectedDER, ScriptError):
            # if public_pair is invalid, we just ignore it
            pass
    return signatures, secs_solved