Exemple #1
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)
Exemple #2
0
    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)
Exemple #3
0
    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)
Exemple #4
0
 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 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.secret_exponent():
         return self.__class__(
             generator=self._generator,
             master_private_key=((self.master_private_key() + offset) %
                                 self._generator.order()))
     p1 = offset * self._generator
     x, y = self.public_pair()
     p2 = self._generator.Point(x, y)
     p = p1 + p2
     return self.__class__(public_pair=p, generator=self._generator)
Exemple #6
0
 def verify(self, h, sig, generator=None):
     """
     Return whether a signature is valid for hash h using this key.
     """
     generator = generator or self._generator
     if not generator:
         raise ValueError("generator must be specified")
     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 = 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 generator.verify(pubkey, val, rs)
Exemple #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()
     return self._generator.verify(pubkey, val, sigdecode_der(sig))
Exemple #8
0
    def __init__(self,
                 generator,
                 initial_key=None,
                 master_private_key=None,
                 public_pair=None,
                 master_public_key=None):
        if [initial_key, public_pair, master_private_key, master_public_key
            ].count(None) != 3:
            raise ValueError(
                "exactly one of initial_key, master_private_key, master_public_key must be non-None"
            )
        self._initial_key = initial_key
        self._generator = generator

        if initial_key is not None:
            master_private_key = initial_key_to_master_key(initial_key)
        if master_public_key:
            public_pair = tuple(
                from_bytes_32(master_public_key[idx:idx + 32])
                for idx in (0, 32))
        super(ElectrumWallet,
              self).__init__(generator=generator,
                             secret_exponent=master_private_key,
                             public_pair=public_pair,
                             prefer_uncompressed=True)
Exemple #9
0
 def verify(self, h, sig, generator=None):
     """
     Return whether a signature is valid for hash h using this key.
     """
     generator = generator or self._generator
     if not generator:
         raise ValueError("generator must be specified")
     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 = 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 generator.verify(pubkey, val, rs)
Exemple #10
0
 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 #11
0
    def info_for_E(self, prefix, data):
        bin_data = h2b(data)

        size = len(bin_data)
        if size not in (16, 32, 64):
            return

        is_private = (size != 64)

        if size == 16:
            kwargs = dict(initial_key=data, generator=self._generator)
            electrum_type = "seed"

        if size == 32:
            kwargs = dict(master_private_key=from_bytes_32(bin_data),
                          generator=self._generator)
            electrum_type = "private"

        if size == 64:
            kwargs = dict(master_public_key=bin_data,
                          generator=self._generator)
            electrum_type = "public"

        return dict(type="key",
                    key_type="electrum",
                    electrum_type=electrum_type,
                    is_private=is_private,
                    key_class=self._electrum_class,
                    kwargs=kwargs,
                    create_f=lambda: self._electrum_class(**kwargs))
Exemple #12
0
 def electrum_prv(self, s):
     """
     Parse an electrum private key from a text string in seed form ("E:xxx" where xxx
     is a 64-character hex string).
     Return a :class:`ElectrumWallet <pycoin.key.electrum.ElectrumWallet>` or None.
     """
     blob = self._electrum_to_blob(s)
     if blob and len(blob) == 32:
         mpk = from_bytes_32(blob)
         return self._network.keys.electrum_private(master_private_key=mpk)
Exemple #13
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 = self._generator.sign(self.secret_exponent(), val)
     return sigencode_der(r, s)
Exemple #14
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)
Exemple #15
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 = self._generator.sign(self.secret_exponent(), val)
     return sigencode_der(r, s)
Exemple #16
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)
Exemple #17
0
 def electrum_prv(self, s):
     """
     Parse an electrum private key from a text string in seed form ("E:xxx" where xxx
     is a 64-character hex string).
     Return a :class:`ElectrumWallet <pycoin.key.electrum.ElectrumWallet>` or None.
     """
     blob = self._electrum_to_blob(s)
     if blob and len(blob) == 32:
         mpk = from_bytes_32(blob)
         return self._network.keys.electrum_private(master_private_key=mpk)
Exemple #18
0
    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)
Exemple #19
0
def ascend_bip32(bip32_pub_node, secret_exponent, child):
    """
    Given a BIP32Node with public derivation child "child" with a known private key,
    return the secret exponent for the bip32_pub_node.
    """
    i_as_bytes = struct.pack(">l", child)
    sec = public_pair_to_sec(bip32_pub_node.public_pair(), compressed=True)
    data = sec + i_as_bytes
    I64 = hmac.HMAC(key=bip32_pub_node._chain_code, msg=data, digestmod=hashlib.sha512).digest()
    I_left_as_exponent = from_bytes_32(I64[:32])
    return (secret_exponent - I_left_as_exponent) % bip32_pub_node._generator.order()
Exemple #20
0
    def info_for_wif(self, data):
        data = data[1:]
        is_compressed = (len(data) > 32)
        if is_compressed:
            data = data[:-1]
        se = from_bytes_32(data)
        kwargs = dict(secret_exponent=se, generator=self._generator,
                      prefer_uncompressed=not is_compressed)

        return dict(type="key", key_type="wif", is_private=True, kwargs=kwargs,
                    key_class=self._key_class, create_f=lambda: self._key_class(**kwargs))
Exemple #21
0
    def __init__(self, initial_key=None, master_private_key=None, public_pair=None, master_public_key=None):
        if [initial_key, public_pair, master_private_key, master_public_key].count(None) != 3:
            raise ValueError(
                "exactly one of initial_key, master_private_key, master_public_key must be non-None")
        self._initial_key = initial_key

        if initial_key is not None:
            master_private_key = initial_key_to_master_key(initial_key)
        if master_public_key:
            public_pair = 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=public_pair, is_compressed=False)
Exemple #22
0
    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)
Exemple #23
0
def ascend_bip32(bip32_pub_node, secret_exponent, child):
    """
    Given a BIP32Node with public derivation child "child" with a known private key,
    return the secret exponent for the bip32_pub_node.
    """
    i_as_bytes = struct.pack(">l", child)
    sec = public_pair_to_sec(bip32_pub_node.public_pair(), compressed=True)
    data = sec + i_as_bytes
    I64 = hmac.HMAC(key=bip32_pub_node._chain_code,
                    msg=data,
                    digestmod=hashlib.sha512).digest()
    I_left_as_exponent = from_bytes_32(I64[:32])
    return (secret_exponent - I_left_as_exponent) % ORDER
    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)
Exemple #25
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))
Exemple #26
0
 def wif(self, s):
     """
     Parse a WIF.
     Return a :class:`Key <pycoin.key.Key>` or None.
     """
     data = self.parse_b58_hashed(s)
     if data is None or not data.startswith(self._wif_prefix):
         return None
     data = data[len(self._wif_prefix):]
     is_compressed = (len(data) > 32)
     if is_compressed:
         data = data[:-1]
     se = from_bytes_32(data)
     return self._network.keys.private(se, is_compressed=is_compressed)
Exemple #27
0
 def wif(self, s):
     """
     Parse a WIF.
     Return a :class:`Key <pycoin.key.Key>` or None.
     """
     data = self.parse_b58_hashed(s)
     if data is None or not data.startswith(self._wif_prefix):
         return None
     data = data[len(self._wif_prefix):]
     is_compressed = (len(data) > 32)
     if is_compressed:
         data = data[:-1]
     se = from_bytes_32(data)
     return self._network.keys.private(se, is_compressed=is_compressed)
Exemple #28
0
    def info_for_wif(self, data):
        data = data[1:]
        is_compressed = (len(data) > 32)
        if is_compressed:
            data = data[:-1]
        se = from_bytes_32(data)
        kwargs = dict(secret_exponent=se,
                      generator=self._generator,
                      prefer_uncompressed=not is_compressed)

        return dict(type="key",
                    key_type="wif",
                    is_private=True,
                    kwargs=kwargs,
                    key_class=self._key_class,
                    create_f=lambda: self._key_class(**kwargs))
Exemple #29
0
    def info_for_E(self, prefix, data):
        bin_data = h2b(data)

        size = len(bin_data)
        if size not in (16, 32, 64):
            return

        is_private = (size != 64)

        if size == 16:
            kwargs = dict(initial_key=data, generator=self._generator)
            electrum_type = "seed"

        if size == 32:
            kwargs = dict(master_private_key=from_bytes_32(bin_data), generator=self._generator)
            electrum_type = "private"

        if size == 64:
            kwargs = dict(master_public_key=bin_data, generator=self._generator)
            electrum_type = "public"

        return dict(type="key", key_type="electrum", electrum_type=electrum_type, is_private=is_private,
                    key_class=self._electrum_class, kwargs=kwargs, create_f=lambda: self._electrum_class(**kwargs))
Exemple #30
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.secret_exponent():
         return self.__class__(
             master_private_key=((self.master_private_key() + offset) % self._generator.order())
         )
     p1 = offset * self._generator
     x, y = self.public_pair()
     p2 = self._generator.Point(x, y)
     p = p1 + p2
     return self.__class__(public_pair=p)
Exemple #31
0
 def deserialize(class_, blob):
     if len(blob) == 32:
         return class_(master_private_key=from_bytes_32(blob))
     if len(blob) == 64:
         return class_(master_public_key=blob)
Exemple #32
0
 def _signature_for_hash_type_segwit(self, script, tx_in_idx, hash_type):
     return from_bytes_32(sha256(self._segwit_signature_preimage(script, tx_in_idx, hash_type)))
Exemple #33
0
 def _signature_for_hash_type_segwit(self, script, tx_in_idx, hash_type):
     hash_type |= self.FORKID_BTG << 8
     return from_bytes_32(double_sha256(self._segwit_signature_preimage(script, tx_in_idx, hash_type)))
Exemple #34
0
 def _signature_for_hash_type_segwit(self, script, tx_in_idx, hash_type):
     return from_bytes_32(
         sha256(
             self._segwit_signature_preimage(script, tx_in_idx, hash_type)))
Exemple #35
0
from coininfo import COINS, Coin
from connections import connectionmanager
from keyseeder import generate_key
from models import *
from transaction import UnsignedTransactionBuilder, SignedTransaction, FEERATE_NETWORK, FEERATE_POOLSUBSIDY, TransactionInput as UnsignedTransactionInput, NotEnoughCoinsException
from indexer import import_address
from indexer.models import *

MIN_CONSOLIDATION_UTXOS = 100
MAX_CONSOLIDATION_UTXOS = 650

TXIN_VSIZES = {TXOUT_TYPES.P2PKH: 149, TXOUT_TYPES.P2WPKH: 68}

PrivateKey = lambda raw_key: Key.make_subclass(None, secp256k1_generator)(
    from_bytes_32(raw_key))


class AccountExistsException(Exception):
    pass


class InvalidAccountName(Exception):
    pass


class Wallet(object):
    def __init__(self, manager):
        self.manager = manager

    @classmethod
 def _signature_for_hash_type_segwit(self, script, tx_in_idx, hash_type):
     hash_type |= self.FORKID_BTG << 8
     return from_bytes_32(
         double_sha256(
             self._segwit_signature_preimage(script, tx_in_idx, hash_type)))
Exemple #37
0
 def entropy_to_wif(self, entropy):
     return BTC.keys.private(
         secret_exponent=from_bytes_32(entropy[:32])).wif()
Exemple #38
0
 def deserialize(class_, blob):
     if len(blob) == 32:
         return class_(master_private_key=from_bytes_32(blob))
     if len(blob) == 64:
         return class_(master_public_key=blob)