def multiply(self, p, e):
        """Multiply a point by an integer."""
        e %= self.order()
        if p == self._infinity or e == 0:
            return self._infinity
        pubkey = create_string_buffer(64)
        public_pair_bytes = b'\4' + to_bytes_32(p[0]) + to_bytes_32(p[1])
        r = libsecp256k1.secp256k1_ec_pubkey_parse(libsecp256k1.ctx, pubkey,
                                                   public_pair_bytes,
                                                   len(public_pair_bytes))
        if not r:
            return False
        r = libsecp256k1.secp256k1_ec_pubkey_tweak_mul(libsecp256k1.ctx,
                                                       pubkey, to_bytes_32(e))
        if not r:
            return self._infinity

        pubkey_serialized = create_string_buffer(65)
        pubkey_size = c_size_t(65)
        libsecp256k1.secp256k1_ec_pubkey_serialize(libsecp256k1.ctx,
                                                   pubkey_serialized,
                                                   byref(pubkey_size), pubkey,
                                                   SECP256K1_EC_UNCOMPRESSED)
        x = from_bytes_32(pubkey_serialized[1:33])
        y = from_bytes_32(pubkey_serialized[33:])
        return self.Point(x, y)
    def test_sign(self):
        if libsecp256k1 is None:
            raise unittest.SkipTest("no libsecp256k1")
        ctx = libsecp256k1.ctx
        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'
        )

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

        compact_signature = create_string_buffer(64)
        libsecp256k1.secp256k1_ecdsa_signature_serialize_compact(ctx, compact_signature, signature)
        r = from_bytes_32(compact_signature[:32])
        s = from_bytes_32(compact_signature[32:])
        signature = (r, s)

        pubkey_size = c_size_t(65)
        pubkey_serialized = create_string_buffer(65)
        libsecp256k1.secp256k1_ec_pubkey_serialize(
            ctx, pubkey_serialized, byref(pubkey_size), public_key, SECP256K1_EC_UNCOMPRESSED)
        x = from_bytes_32(pubkey_serialized[1:33])
        y = from_bytes_32(pubkey_serialized[33:])

        legacy_secp256k1_group.verify((x, y), 1000, signature)
    def sign(self, secret_exponent, val, gen_k=None):
        nonce_function = None
        if gen_k is not None:
            k_as_bytes = to_bytes_32(gen_k(self.order(), secret_exponent, val))

            def adaptor(nonce32_p, msg32_p, key32_p, algo16_p, data, attempt):
                nonce32_p.contents[:] = list(iterbytes(k_as_bytes))
                return 1

            p_b32 = POINTER(c_byte * 32)
            nonce_function = CFUNCTYPE(c_int, p_b32, p_b32, p_b32,
                                       POINTER(c_byte * 16), c_void_p,
                                       c_uint)(adaptor)

        sig = create_string_buffer(64)
        sig_hash_bytes = to_bytes_32(val)
        libsecp256k1.secp256k1_ecdsa_sign(libsecp256k1.ctx, sig,
                                          sig_hash_bytes,
                                          to_bytes_32(secret_exponent),
                                          nonce_function, None)
        compact_signature = create_string_buffer(64)
        libsecp256k1.secp256k1_ecdsa_signature_serialize_compact(
            libsecp256k1.ctx, compact_signature, sig)
        r = from_bytes_32(compact_signature[:32])
        s = from_bytes_32(compact_signature[32:])
        return (r, s)
 def __mul__(self, e):
     e %= self.order()
     if e == 0:
         return self._infinity
     pubkey = create_string_buffer(65)
     libsecp256k1.secp256k1_ec_pubkey_create(libsecp256k1.ctx, pubkey,
                                             c_char_p(to_bytes_32(e)))
     pubkey_size = c_size_t(65)
     pubkey_serialized = create_string_buffer(65)
     libsecp256k1.secp256k1_ec_pubkey_serialize(libsecp256k1.ctx,
                                                pubkey_serialized,
                                                byref(pubkey_size), pubkey,
                                                SECP256K1_EC_UNCOMPRESSED)
     x = from_bytes_32(pubkey_serialized[1:33])
     y = from_bytes_32(pubkey_serialized[33:])
     return self.Point(x, y)
Exemple #5
0
    def from_text(class_, text, is_compressed=False):
        """
        This function will accept a BIP0032 wallet string, a WIF, or a bitcoin address.

        The "is_compressed" parameter is ignored unless a public address is passed in.
        """

        data = a2b_hashed_base58(text)
        netcode, key_type, length = netcode_and_type_for_data(data)
        data = data[1:]

        if key_type in ("pub32", "prv32"):
            # TODO: fix this... it doesn't belong here
            from pycoinzpub.key.BIP32Node import BIP32Node
            return BIP32Node.from_wallet_key(text)

        if key_type == 'wif':
            is_compressed = (len(data) > 32)
            if is_compressed:
                data = data[:-1]
            return Key(
                secret_exponent=from_bytes_32(data),
                prefer_uncompressed=not is_compressed, netcode=netcode)
        if key_type == 'address':
            return Key(hash160=data, is_compressed=is_compressed, netcode=netcode)
        raise EncodingError("unknown text: %s" % text)
Exemple #6
0
 def sign(self, h):
     """
     Return a der-encoded signature for a hash h.
     Will throw a RuntimeError if this key is not a private key
     """
     if not self.is_private():
         raise RuntimeError("Key must be private to be able to sign")
     val = from_bytes_32(h)
     r, s = secp256k1_generator.sign(self.secret_exponent(), val)
     return sigencode_der(r, s)
def initial_key_to_master_key(initial_key):
    """
    initial_key:
        a hex string of length 32
    """
    b = initial_key.encode("utf8")
    orig_input = b
    for i in range(100000):
        b = hashlib.sha256(b + orig_input).digest()
    return from_bytes_32(b)
Exemple #8
0
 def verify(self, h, sig):
     """
     Return whether a signature is valid for hash h using this key.
     """
     val = from_bytes_32(h)
     pubkey = self.public_pair()
     rs = sigdecode_der(sig)
     if self.public_pair() is None:
         # find the pubkey from the signature and see if it matches
         # our key
         possible_pubkeys = secp256k1_generator.possible_public_pairs_for_signature(val, rs)
         hash160 = self.hash160()
         for candidate in possible_pubkeys:
             if hash160 == public_pair_to_hash160_sec(candidate, True):
                 pubkey = candidate
                 break
             if hash160 == public_pair_to_hash160_sec(candidate, False):
                 pubkey = candidate
                 break
         else:
             # signature is using a pubkey that's not this key
             return False
     return secp256k1_generator.verify(pubkey, val, rs)
 def subkey(self, path):
     """
     path:
         of the form "K" where K is an integer index, or "K/N" where N is usually
         a 0 (deposit address) or 1 (change address)
     """
     t = path.split("/")
     if len(t) == 2:
         n, for_change = t
     else:
         n, = t
         for_change = 0
     b = (str(n) + ':' + str(for_change) +
          ':').encode("utf8") + self.master_public_key()
     offset = from_bytes_32(double_sha256(b))
     if self.master_private_key():
         return Key(secret_exponent=((self.master_private_key() + offset) %
                                     ORDER),
                    prefer_uncompressed=True)
     p1 = offset * secp256k1_generator
     x, y = self.public_pair()
     p2 = secp256k1_generator.Point(x, y)
     p = p1 + p2
     return Key(public_pair=p, prefer_uncompressed=True)
Exemple #10
0
    def __init__(self,
                 initial_key=None,
                 master_private_key=None,
                 master_public_key=None,
                 netcode='BTC'):
        if [initial_key, master_private_key, master_public_key
            ].count(None) != 2:
            raise ValueError(
                "exactly one of initial_key, master_private_key, master_public_key must be non-None"
            )
        self._initial_key = initial_key
        self._netcode = netcode

        if initial_key is not None:
            master_private_key = initial_key_to_master_key(initial_key)
        pp = None
        if master_public_key:
            pp = tuple(
                from_bytes_32(master_public_key[idx:idx + 32])
                for idx in (0, 32))
        super(ElectrumWallet,
              self).__init__(secret_exponent=master_private_key,
                             public_pair=pp)
        self._master_public_key = None