Пример #1
0
    def test_verify_proof(self):
        claim1_name = 97  # 'a'
        claim1_txid = 'bd9fa7ffd57d810d4ce14de76beea29d847b8ac34e8e536802534ecb1ca43b68'
        claim1_outpoint = 0
        claim1_height = 10
        claim1_node_hash = claims.get_hash_for_outpoint(
            binascii.unhexlify(claim1_txid)[::-1], claim1_outpoint,
            claim1_height)

        claim2_name = 98  # 'b'
        claim2_txid = 'ad9fa7ffd57d810d4ce14de76beea29d847b8ac34e8e536802534ecb1ca43b68'
        claim2_outpoint = 1
        claim2_height = 5
        claim2_node_hash = claims.get_hash_for_outpoint(
            binascii.unhexlify(claim2_txid)[::-1], claim2_outpoint,
            claim2_height)
        to_hash1 = claim1_node_hash
        hash1 = Hash(to_hash1)
        to_hash2 = chr(claim1_name) + hash1 + chr(
            claim2_name) + claim2_node_hash

        root_hash = Hash(to_hash2)

        proof = {
            'last takeover height':
            claim1_height,
            'txhash':
            claim1_txid,
            'nOut':
            claim1_outpoint,
            'nodes': [
                {
                    'children': [{
                        'character': 97
                    }, {
                        'character':
                        98,
                        'nodeHash':
                        claim2_node_hash[::-1].encode('hex')
                    }]
                },
                {
                    'children': []
                },
            ]
        }
        out = claims.verify_proof(proof, root_hash[::-1].encode('hex'), 'a')
        self.assertEqual(out, True)
Пример #2
0
 def update_signatures(self, raw):
     """Add new signatures to a transaction"""
     d = deserialize(raw)
     for i, txin in enumerate(self.inputs()):
         sigs1 = txin.get('signatures')
         sigs2 = d['inputs'][i].get('signatures')
         for sig in sigs2:
             if sig in sigs1:
                 continue
             for_sig = Hash(self.tx_for_sig(i).decode('hex'))
             # der to string
             order = ecdsa.ecdsa.generator_secp256k1.order()
             r, s = ecdsa.util.sigdecode_der(sig.decode('hex'), order)
             sig_string = ecdsa.util.sigencode_string(r, s, order)
             pubkeys = txin.get('pubkeys')
             compressed = True
             for recid in range(4):
                 public_key = MyVerifyingKey.from_signature(sig_string,
                                                            recid,
                                                            for_sig,
                                                            curve=SECP256k1)
                 pubkey = point_to_ser(public_key.pubkey.point,
                                       compressed).encode('hex')
                 if pubkey in pubkeys:
                     public_key.verify_digest(
                         sig_string,
                         for_sig,
                         sigdecode=ecdsa.util.sigdecode_string)
                     j = pubkeys.index(pubkey)
                     print_error("adding sig", i, j, pubkey, sig)
                     self._inputs[i]['signatures'][j] = sig
                     self._inputs[i]['x_pubkeys'][j] = pubkey
                     break
     # redo raw
     self.raw = self.serialize()
Пример #3
0
    def verify_message(cls, address, sig, message):
        if len(sig) != 65:
            raise Exception("Wrong encoding")
        nV = ord(sig[0])
        if nV < 27 or nV >= 35:
            raise Exception("Bad encoding")
        if nV >= 31:
            compressed = True
            nV -= 4
        else:
            compressed = False
        recid = nV - 27

        h = Hash(msg_magic(message))
        public_key = MyVerifyingKey.from_signature(sig[1:],
                                                   recid,
                                                   h,
                                                   curve=SECP256k1)
        # check public key
        public_key.verify_digest(sig[1:],
                                 h,
                                 sigdecode=ecdsa.util.sigdecode_string)
        pubkey = point_to_ser(public_key.pubkey.point, compressed)
        # check that we get the original signing address
        addr = public_key_to_bc_address(pubkey)
        if address != addr:
            raise Exception("Bad signature")
Пример #4
0
 def sign(self, keypairs):
     for i, txin in enumerate(self.inputs()):
         num = txin['num_sig']
         for x_pubkey in txin['x_pubkeys']:
             signatures = filter(None, txin['signatures'])
             if len(signatures) == num:
                 # txin is complete
                 break
             if x_pubkey in keypairs.keys():
                 print_error("adding signature for", x_pubkey)
                 # add pubkey to txin
                 txin = self._inputs[i]
                 x_pubkeys = txin['x_pubkeys']
                 ii = x_pubkeys.index(x_pubkey)
                 sec = keypairs[x_pubkey]
                 pubkey = public_key_from_private_key(sec)
                 txin['x_pubkeys'][ii] = pubkey
                 txin['pubkeys'][ii] = pubkey
                 self._inputs[i] = txin
                 # add signature
                 for_sig = Hash(self.tx_for_sig(i).decode('hex'))
                 pkey = regenerate_key(sec)
                 secexp = pkey.secret
                 private_key = MySigningKey.from_secret_exponent(secexp, curve=SECP256k1)
                 public_key = private_key.get_verifying_key()
                 sig = private_key.sign_digest_deterministic(for_sig, hashfunc=hashlib.sha256,
                                                             sigencode=ecdsa.util.sigencode_der)
                 assert public_key.verify_digest(sig, for_sig,
                                                 sigdecode=ecdsa.util.sigdecode_der)
                 txin['signatures'][ii] = sig.encode('hex')
                 self._inputs[i] = txin
     print_error("is_complete", self.is_complete())
     self.raw = self.serialize()
Пример #5
0
def hash_160_to_bc_address(h160, addrtype=0):
    if addrtype == PUBKEY_ADDRESS[0]:
        c = chr(PUBKEY_ADDRESS[1])
    elif addrtype == SCRIPT_ADDRESS[0]:
        c = chr(SCRIPT_ADDRESS[1])

    vh160 = c + h160
    h = Hash(vh160)
    addr = vh160 + h[0:4]
    return base_encode(addr, base=58)
Пример #6
0
def DecodeBase58Check(psz):
    vchRet = base_decode(psz, None, base=58)
    key = vchRet[0:-4]
    csum = vchRet[-4:]
    hash = Hash(key)
    cs32 = hash[0:4]
    if cs32 != csum:
        return None
    else:
        return key
Пример #7
0
def pw_decode(s, password):
    if password is not None:
        secret = Hash(password)
        try:
            d = DecodeAES(secret, s).decode("utf8")
        except Exception:
            raise InvalidPassword()
        return d
    else:
        return s
Пример #8
0
 def sign_message(self, message, compressed, address):
     signature = self.sign(Hash(msg_magic(message)))
     for i in range(4):
         sig = chr(27 + i + (4 if compressed else 0)) + signature
         try:
             self.verify_message(address, sig, message)
             return sig
         except Exception:
             log.exception("error: cannot sign message")
             continue
     raise Exception("error: cannot sign message")
Пример #9
0
def bc_address_to_hash_160(addr):
    bytes = base_decode(addr, 25, base=58)
    addr_without_checksum, addr_checksum = bytes[:21], bytes[21:]
    if Hash(addr_without_checksum)[:4] != addr_checksum:
        raise Exception("Invalid address checksum")
    if bytes[0] == chr(PUBKEY_ADDRESS[1]):
        return PUBKEY_ADDRESS[0], bytes[1:21]
    elif bytes[0] == chr(SCRIPT_ADDRESS[1]):
        return SCRIPT_ADDRESS[0], bytes[1:21]
    else:
        raise Exception("Invalid address prefix")
Пример #10
0
def hash_160_to_bc_address(h160, addrtype=0):
    if addrtype == PUBKEY_ADDRESS[0]:
        c = chr(PUBKEY_ADDRESS[1])
    elif addrtype == SCRIPT_ADDRESS[0]:
        c = chr(SCRIPT_ADDRESS[1])
    else:
        raise Exception("Invalid address prefix")

    vh160 = c + h160
    h = Hash(vh160)
    addr = vh160 + h[0:4]
    return base_encode(addr, base=58)
Пример #11
0
 def tx_response(self, response):
     params, result = self.parse_response(response)
     if not params:
         return
     tx_hash, tx_height = params
     assert tx_hash == hash_encode(Hash(result.decode('hex')))
     tx = Transaction(result)
     try:
         tx.deserialize()
     except Exception:
         log.info("cannot deserialize transaction, skipping: %s", tx_hash)
         return
     self.wallet.receive_tx_callback(tx_hash, tx, tx_height)
     self.requested_tx.remove((tx_hash, tx_height))
     log.info("received tx %s height: %d bytes: %d", tx_hash, tx_height, len(tx.raw))
     # callbacks
     self.network.trigger_callback('new_transaction', tx)
     if not self.requested_tx:
         self.network.trigger_callback('updated')
Пример #12
0
def pw_encode(s, password):
    if password:
        secret = Hash(password)
        return EncodeAES(secret, s.encode("utf8"))
    else:
        return s
Пример #13
0
 def hash(self):
     return Hash(self.raw.decode('hex'))[::-1].encode('hex')
Пример #14
0
def verify_proof(proof, rootHash, name):
    previous_computed_hash = None
    reverse_computed_name = ''
    verified_value = False
    for i, node in enumerate(proof['nodes'][::-1]):
        found_child_in_chain = False
        to_hash = ''
        previous_child_character = None
        for child in node['children']:
            if child['character'] < 0 or child['character'] > 255:
                raise InvalidProofError(
                    "child character not int between 0 and 255")
            if previous_child_character:
                if previous_child_character >= child['character']:
                    raise InvalidProofError("children not in increasing order")
            previous_child_character = child['character']
            to_hash += chr(child['character'])
            if 'nodeHash' in child:
                if len(child['nodeHash']) != 64:
                    raise InvalidProofError("invalid child nodeHash")
                to_hash += binascii.unhexlify(child['nodeHash'])[::-1]
            else:
                if previous_computed_hash is None:
                    raise InvalidProofError("previous computed hash is None")
                if found_child_in_chain is True:
                    raise InvalidProofError(
                        "already found the next child in the chain")
                found_child_in_chain = True
                reverse_computed_name += chr(child['character'])
                to_hash += previous_computed_hash

        if not found_child_in_chain:
            if i != 0:
                raise InvalidProofError("did not find the alleged child")
        if i == 0 and 'txhash' in proof and 'nOut' in proof and 'last takeover height' in proof:
            if len(proof['txhash']) != 64:
                raise InvalidProofError("txhash was invalid: {}".format(
                    proof['txhash']))
            if not isinstance(proof['nOut'], (long, int)):
                raise InvalidProofError("nOut was invalid: {}".format(
                    proof['nOut']))
            if not isinstance(proof['last takeover height'], (long, int)):
                raise InvalidProofError(
                    'last takeover height was invalid: {}'.format(
                        proof['last takeover height']))
            to_hash += get_hash_for_outpoint(
                binascii.unhexlify(proof['txhash'])[::-1], proof['nOut'],
                proof['last takeover height'])
            verified_value = True
        elif 'valueHash' in node:
            if len(node['valueHash']) != 64:
                raise InvalidProofError("valueHash was invalid")
            to_hash += binascii.unhexlify(node['valueHash'])[::-1]

        previous_computed_hash = Hash(to_hash)

    if previous_computed_hash != binascii.unhexlify(rootHash)[::-1]:
        raise InvalidProofError("computed hash does not match roothash")
    if 'txhash' in proof and 'nOut' in proof:
        if not verified_value:
            raise InvalidProofError("mismatch between proof claim and outcome")
    if 'txhash' in proof and 'nOut' in proof:
        if name != reverse_computed_name[::-1]:
            raise InvalidProofError("name did not match proof")
    if not name.startswith(reverse_computed_name[::-1]):
        raise InvalidProofError("name fragment does not match proof")
    return True
Пример #15
0
 def hash_merkle_root(self, merkle_s, target_hash, pos):
     h = hash_decode(target_hash)
     for i, item in enumerate(merkle_s):
         h = Hash(hash_decode(item) +
                  h) if ((pos >> i) & 1) else Hash(h + hash_decode(item))
     return hash_encode(h)
Пример #16
0
def EncodeBase58Check(vchIn):
    hash = Hash(vchIn)
    return base_encode(vchIn + hash[0:4], base=58)
Пример #17
0
 def hash_header(self, header):
     if header is None:
         return '0' * 64
     return hash_encode(Hash(self.serialize_header(header).decode('hex')))
Пример #18
0
def get_hash_for_outpoint(txhash, nOut, nHeightOfLastTakeover):
    txhash_hash = Hash(txhash)
    nOut_hash = Hash(str(nOut))
    height_of_last_takeover_hash = Hash(height_to_vch(nHeightOfLastTakeover))
    outPointHash = Hash(txhash_hash + nOut_hash + height_of_last_takeover_hash)
    return outPointHash