示例#1
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.
        """

        grs_encoded = False
        try:
            data = a2b_hashed_base58(text)
        except EncodingError:
            data = a2b_hashed_base58_grs(text)
            grs_encoded = True
        netcode, key_type, length = netcode_and_type_for_data(data)
        if grs_encoded:
            netcode = 'GRS'
        data = data[1:]

        if key_type in ("pub32", "prv32"):
            # TODO: fix this... it doesn't belong here
            from pycoin_grs.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)
示例#2
0
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)
示例#3
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 = ecdsa.sign(ecdsa.generator_secp256k1, self.secret_exponent(),
                       val)
     return sigencode_der(r, s)
示例#4
0
    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)
示例#5
0
 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 * ecdsa.generator_secp256k1
     x, y = self.public_pair()
     p2 = ecdsa.Point(ecdsa.generator_secp256k1.curve(), x, y, ORDER)
     p = p1 + p2
     return Key(public_pair=p.pair(), prefer_uncompressed=True)
示例#6
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
示例#7
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 = ecdsa.possible_public_pairs_for_signature(
             ecdsa.generator_secp256k1, 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 ecdsa.verify(ecdsa.generator_secp256k1, pubkey, val, rs)