Пример #1
0
def compute_seeds(b):
    """
    Computes the AES keys seed1, seed2 of a block header.
    """

    packed_data = []
    packed_data.extend(b["parentid"].decode('hex'))
    packed_data.extend(b["root"].decode('hex'))
    packed_data.extend(pack('>Q', long(b["difficulty"])))
    packed_data.extend(pack('>Q', long(b["timestamp"])))
    packed_data.extend(pack('>Q', long(b["nonces"][0])))
    packed_data.append(chr(b["version"]))
    if len(packed_data) != 89:
        print("invalid length of packed data")
    h = H()
    h.update(''.join(packed_data))
    seed = h

    data2 = seed.digest()

    if len(data2) != 32:
        print("invalid length of packed data")
    h = H()
    h.update(data2)
    seed2 = h

    return seed, seed2
Пример #2
0
def compute_seeds(b):
    """
    Computes the ciphers Ai, Aj, Bi, Bj of a block header.
    """

    packed_data = []
    packed_data.extend(b["parentid"].decode('hex'))
    packed_data.extend(b["root"].decode('hex'))
    packed_data.extend(pack('>Q', long(b["difficulty"])))
    packed_data.extend(pack('>Q', long(b["timestamp"])))
    packed_data.extend(pack('>Q', long(b["nonces"][0])))
    packed_data.append(chr(b["version"]))
    if len(packed_data) != 89:
        print "invalid length of packed data"
    h = H()
    h.update(''.join(packed_data))
    seed = h.digest()

    if len(seed) != 32:
        print "invalid length of packed data"
    h = H()
    h.update(seed)
    seed2 = h.digest()

    return seed, seed2
Пример #3
0
    def build_tree(self):
        # Compute the hashes
        nodes = []
        for value in self.values:
            hash_value = H(bytes(value, "utf-8")).hexdigest()
            node = Node(hash=hash_value, height=0)
            nodes.append(node)

        # Combining hashes together
        while len(nodes) > 1:
            temp = []
            while len(nodes) > 0:
                daughter = nodes.pop(0)
                if len(nodes) != 0:
                    son = nodes.pop(0)
                    hash_value = H(bytes(daughter.hash + son.hash,
                                         "utf-8")).hexdigest()
                    node = Node(hash=hash_value, height=daughter.height + 1,\
                        children=[daughter, son])
                    # Make parents
                    daughter.parents.append(node)
                    son.parents.append(node)
                else:
                    # When there is only one node left
                    hash_value = H(bytes(daughter.hash, "utf-8")).hexdigest()
                    node = Node(hash=hash_value, height=daughter.height + 1, \
                        children=[daughter])
                    # Make parents
                    daughter.parents.append(node)
                temp.append(node)
            nodes = temp.copy()

        # Update root
        assert (len(nodes) == 1)
        self.root = nodes.pop(0)
Пример #4
0
 def accrueTransactionFee(self, receiver):
     receiverInp = []
     receiverOut = [{
         "value": mergesplit_network.Network.mergesplitFee,
         "pubkey": receiver.publicKey
     }]
     serializedInput = "".join([
         str(inp['number']) + str(inp['output']['value']) +
         str(inp['output']['pubkey']) for inp in receiverInp
     ])
     serializedOutput = "".join(
         [str(out['value']) + str(out['pubkey']) for out in receiverOut])
     # message to sign for mergesplit fee
     message = str.encode(serializedInput + serializedOutput)
     # sign the message
     signed = receiver.privateKey.sign(message,
                                       encoder=nacl.encoding.HexEncoder)
     sig = str(signed.signature, 'utf-8')
     number = H(str.encode(serializedInput + serializedOutput +
                           sig)).hexdigest()
     # construct mergesplit transaction
     transaction = buildingblocks.Transaction(number, receiverInp,
                                              receiverOut, sig)
     tx = utils.Utils.serializeTransaction(transaction)
     chain = self.nodes[0].chain
     prev = H(
         str.encode(utils.Utils.serializeBlock(
             chain.longestChain().block))).hexdigest()
     block = buildingblocks.Block(tx, prev, False, True)
     # add mergesplit fee block to every node's chain
     for node in self.nodes:
         node.chain.addBlock(block)
     # update stake of receiver of the fee
     receiver.stake += mergesplit_network.Network.mergesplitFee
     return True
Пример #5
0
    def contains(self, layers):
        # Layers should be a dict(height: hash)
        # Make the node first
        node = layers.pop(-1)[0]

        # Now construct the hash of the root
        current = 0
        while len(layers) > 0:
            if current in layers:
                # regular case
                sibling = layers.pop(current)
                if sibling[1]:
                    node = H(bytes(sibling[0] + node, "utf-8")).hexdigest()
                else:
                    node = H(bytes(node + sibling[0], "utf-8")).hexdigest()

            elif current + 1 in layers:
                # If your node is accidentally a far right, lonely node
                node = H(bytes(node, "utf-8")).hexdigest()
            else:
                raise MissingNodeError("Not providing enough nodes in layers")

            current += 1

        # Check with hash of the root
        if current == self.root.height and node == self.root.hash:
            return True
        return False
Пример #6
0
    def prove(self, pos):
        '''
        Construct a dict path of your merkle tree

        Return: A dict (height: (value, True/False))
        '''
        layers = dict()
        height = 0
        nodes = []
        for value in self.values:
            hash_value = H(bytes(value, "utf-8")).hexdigest()
            node = Node(hash=hash_value, height=0)
            nodes.append(node)

        # Need to add 2 in the first layer

        # Complementary node here
        if pos % 2 == 0:
            layers[-1] = (nodes[pos].hash, True)
            layers[height] = (nodes[pos + 1].hash, False)
        else:
            layers[-1] = (nodes[pos - 1].hash, True)
            layers[height] = (nodes[pos].hash, False)
        pos = pos // 2
        height += 1

        while (len(nodes) > 1):
            temp = []
            while (len(nodes) > 0):
                daughter = nodes.pop(0)
                if len(nodes) != 0:
                    son = nodes.pop(0)
                    hash_value = H(bytes(daughter.hash + son.hash,
                                         "utf-8")).hexdigest()
                    node = Node(hash=hash_value, height=daughter.height + 1,\
                        children=[daughter, son])
                    # Make parents
                    daughter.parents.append(node)
                    son.parents.append(node)
                else:
                    # When there is only one node left
                    hash_value = H(bytes(daughter.hash, "utf-8")).hexdigest()
                    node = Node(hash=hash_value, height=daughter.height + 1, \
                        children=[daughter])
                    # Make parents
                    daughter.parents.append(node)

                temp.append(node)

            nodes = temp.copy()
            if len(nodes) > 1:
                # Take the complementary
                if pos % 2 == 0:
                    layers[height] = (nodes[pos + 1].hash, False)
                else:
                    layers[height] = (nodes[pos - 1].hash, True)
            pos = pos // 2
            height += 1
        return layers
Пример #7
0
def sign(msg, params, keys):
    p, q, g = params
    y, x = keys
    k = randint(2, q - 1)
    r = pow(g, k, p) % q
    if r == 0: sign(msg, params, keys)
    print(int("0x" + H(msg).hexdigest(), 0) + x * r)
    print(modinv(k, q))
    s = (modinv(k, q) * (int("0x" + H(msg).hexdigest(), 0) + x * r)) % q
    if s == 0: sign(msg, params, keys)
    return r, s
Пример #8
0
    def createGenesisBlock(self):
        genesisTx = self.__getGenesisTx(self)
        genesisPrev = H(b'genesis prev').hexdigest()
        genesisNonce = 0
        genesisPOW = H(b'genesis POW').hexdigest()

        genesisBlock = Block(genesisTx, genesisPrev, genesisNonce, genesisPOW)

        # self.chain.append(self.genesisBlock)
        logger.info('Genesis Block has been created successfully!')
        return genesisBlock
Пример #9
0
def hash_block_to_hex(b):
    """
    Computes the hex-encoded hash of a block header. First builds an array of
    bytes with the correct endianness and length for each arguments. Then hashes
    the concatenation of these bytes and encodes to hexidecimal.

    Not used for mining since it includes all 3 nonces, but serves as the unique
    identifier for a block when querying the explorer.
    """
    packed_data = []
    packed_data.extend(b["parentid"].decode('hex'))
    packed_data.extend(b["root"].decode('hex'))
    packed_data.extend(pack('>Q', long(b["difficulty"])))
    packed_data.extend(pack('>Q', long(b["timestamp"])))
    #   Bigendian 64bit unsigned
    for n in b["nonces"]:
        #   Bigendian 64bit unsigned
        packed_data.extend(pack('>Q', long(n)))
    packed_data.append(chr(b["version"]))
    if len(packed_data) != 105:
        print "invalid length of packed data"
    h = H()
    h.update(''.join(packed_data))
    b["hash"] = h.digest().encode('hex')
    return b["hash"]
Пример #10
0
    def writeGenesisSplitTransaction(self, new_chain_balances):
        inp = []
        out = []
        total = 0

        # create a new output genesis transaction with the balances owned by each pubkey as output
        for key in new_chain_balances.keys():
            coins = new_chain_balances[key]
            out.append({"value": coins, "pubkey": key})
            total += coins

        sig = H(str.encode(str(inp) + str(out))).hexdigest()
        number = H(str.encode(str(inp) + str(out) + sig)).hexdigest()
        transaction = buildingblocks.Transaction(number, inp, out, sig)

        return transaction, total
Пример #11
0
def createGenesisTransaction(transactionList, result, pubkeys):
    inp, out = [], []
    for pubkey in pubkeys:
        coins = random.randint(1, 100)
        out.append({"value": coins, "pubkey": pubkey})
    sig = H(str.encode(str(inp) + str(out))).hexdigest()
    number = H(str.encode(str(inp) + str(out) + sig)).hexdigest()
    transaction = Transaction(number, inp, out, sig)
    transactionList.append(transaction)
    transactionAsJSON = {
        'number': number,
        'input': inp,
        'output': out,
        'sig': sig
    }
    result.append(transactionAsJSON)
Пример #12
0
 def sign_exchange(self, exchange, type):
     '''
     Sign the exchange after verifying it
     '''
     signature = str(encode(self.signing_key.sign(H(bytes(str(exchange), "utf-8")).digest())),'utf-8')
     exchange.sign(signature, type)
     return
Пример #13
0
def sign(msg, params):
    k = randint(2, q - 1)
    r = pow(g, k, p) % q
    if r == 0: sign(msg, params)
    s = (modinv(k) * (H(msg).hexdigest() + x * r)) % q
    if s == 0: sign(msg, params)
    return r, s
Пример #14
0
    def dataReceived(self, data):
        h = H(data.strip()).hexdigest()
        if test(h):
            self.transport.write("Thanks for the c0ff33! \
Here you go: {}\n".format(FLAG).encode('utf-8'))
        else:
            self.transport.write("I can\'t digest {}! \
There\'s no coffee!\n".format(h).encode('utf-8'))
Пример #15
0
 def setGenesis(self, genesis):
     front = buildingblocks.BlockNode(genesis)
     genesisSerialized = H(str.encode(
         utils.Utils.serializeBlock(genesis))).hexdigest()
     self.blockToNode[genesisSerialized] = front
     self.blockToIndex[genesisSerialized] = 0
     self.longestLength = 1
     self.chains.append(front)
Пример #16
0
def verify(sig, params, y):
    r, s = sig
    p, q, g = params
    if r < 0 or r > q or s < 0 or s > q: return False
    w = modinv(s, q) % q
    u1 = (int("0x" + H(msg).hexdigest(), 0) * w) % q
    u2 = (r * w) % q
    v = ((pow(g, u1, p) * pow(y, u2, p)) % p) % q
    return v == r
Пример #17
0
    def add(self, entry):
        """ Add an entry at the end of the chain. Returns the index of the new entry. """

        # Create the new node head:
        entryH = H(entry).digest()

        nodeDigest = H(pack("L", len(self.entries)))
        nodeDigest.update(entryH)

        # Gather which other nodes are to be included:
        for i in pointFingers(len(self.entries)):
            nodeDigest.update(self.nodes[i])

        nodeH = nodeDigest.digest()

        self.entries.append(entryH)
        self.nodes.append(nodeH)

        return len(self.entries) - 1
def createValidTX(data, listKeys):
    #get a random previous transaction
    prevtx = data[random.randint(0, len(data) - 1)]

    #compute the output totals from this transaction
    outputs = prevtx.getOutputs()
    prevTxNum = prevtx.getNum()
    inputs = []
    keyVals = {}
    for txVal, pkEncoded in outputs:
        inputs.append([prevTxNum, [txVal, pkEncoded]])
        if pkEncoded in keyVals:
            keyVals[pkEncoded] += txVal
        else:
            keyVals[pkEncoded] = txVal

    #Randomly create output for this transaction
    newOutput = []

    #randomly select person giving
    fromPkEncoded = random.choice(list(keyVals))
    fromSK = None
    for sk, pk in listKeys:
        if pk == fromPkEncoded:
            fromSK = sk

    val = keyVals[fromPkEncoded]

    #randomly select the number of transactions
    numberOfTxs = random.randint(0, len(listKeys))

    for i in range(numberOfTxs):
        #randomly select a person to give the value
        toSK, toPkEncoded = listKeys[random.randint(0, len(listKeys)) - 1]

        #randomly select the amount to give to that person
        newVal = random.randint(0, val)
        val -= newVal
        newOutput.append([newVal, toPkEncoded])
        if val == 0:
            break
        elif val <= 1:
            newOutput.append([val, fromPkEncoded])
            val = 0
            break

    if val != 0:
        newOutput.append([val, fromPkEncoded])

    txSig = fromSK.sign((str(inputs) + str(newOutput)).encode(),
                        encoder=HexEncoder)
    txNumber = H((str(inputs) + str(newOutput) +
                  str(txSig.signature)).encode()).hexdigest()
    return Transaction(txNumber, inputs, newOutput, txSig)
Пример #19
0
 def checkForValidNumber(self, transaction):
     serializedInput = "".join([
         str(inp['number']) + str(inp['output']['value']) +
         str(inp['output']['pubkey']) for inp in transaction.inp
     ])
     serializedOutput = "".join([
         str(out['value']) + str(out['pubkey']) for out in transaction.out
     ])
     h = H(str.encode(serializedInput + serializedOutput +
                      transaction.sig)).hexdigest()
     return h == transaction.number
Пример #20
0
def check_evidence(head, seq, evidence, entry=None, node=None):
    """ Check that a bundle of evidence is correct, and correspond to,
    a known head, and optionally a known entry and known node. Returns
    True or raises an exception. """
    entries, nodes = evidence
    head_index = max(entries.keys())

    # CHECK 1: the head equals the head
    if not (head == nodes[head_index]):
        raise Exception("Wrong Head")

    # CHECK 2: all the hashes match
    target = head_index
    while target != seq:

        new_target = target

        # Make the digest
        d = H(pack("L", target))
        d.update(entries[target])
        for i in pointFingers(target):
            d.update(nodes[i])
            if i >= seq:
                new_target = i

        if d.digest() != nodes[target]:
            raise Exception("Broken Chain")

        target = new_target

    # CHECK 3: is the node correct?
    if node:
        if not (node == nodes[seq]):
            raise Exception("Wrong end node")

    # CHECK 4: is the actual entry correct?
    if entry:
        if not (H(entry).digest() == entries[seq]):
            raise Exception("Wrong end entry")

    return True
Пример #21
0
    def merge(self, neighbor):
        # Query all nodes in both community to see if they want to merge
        approved = 0
        neighborNodes = neighbor.getCommunityNodes()
        for node in neighborNodes:
            if node.approveMerge():
                approved += 1

        if approved < (neighbor.nodeCount * 2 / 3):
            return False, None

        approved = 0
        for node in self.nodes:
            if node.approveMerge():
                approved += 1
        if approved < (self.nodeCount * 2 / 3):
            return False, None

        transaction = self.generateMergeTransaction(neighbor)
        transaction = utils.Utils.serializeTransaction(transaction)

        # add a new merge block to remaining nodes blockchain
        serialSelf = utils.Utils.serializeBlock(
            self.fetchUpToDateBlockchain().longestChain().block)
        serialNeighbor = utils.Utils.serializeBlock(
            neighbor.fetchUpToDateBlockchain().longestChain().block)
        mergeBlock = buildingblocks.Block(
            transaction,
            H(str.encode(serialSelf)).hexdigest(),
            isMerge=True,
            mergePrev2=H(str.encode(serialNeighbor)).hexdigest())
        for node in self.nodes:
            node.chain.addBlock(mergeBlock)
        '''
        for node in neighbor.nodes:
            node.chain.addBlock(mergeBlock)
            self.nodes.append(node)'''

        return True, self
        '''       
Пример #22
0
    def writeMergeTransaction(self, chain_one, chain_two):
        inp = []
        out = []
        input_val = 0
        output_val = 0

        # set put all viable outputs to the input & output of this new transaction
        for (number, value, pubkey) in chain_one:
            inp.append({
                "number": number,
                "output": {
                    "value": value,
                    "pubkey": pubkey
                }
            })
            input_val += value
            out.append({"value": value, "pubkey": pubkey})
            output_val += value

        # set put all viable outputs to the input & output of this new transaction
        for (number, value, pubkey) in chain_two:
            inp.append({
                "number": number,
                "output": {
                    "value": value,
                    "pubkey": pubkey
                }
            })
            input_val += value
            out.append({"value": value, "pubkey": pubkey})
            output_val += value

        sig = H(str.encode(str(inp) + str(out))).hexdigest()
        number = H(str.encode(str(inp) + str(out) + sig)).hexdigest()
        transaction = buildingblocks.Transaction(number, inp, out, sig)

        if input_val == output_val:
            return transaction
        else:
            print("ERROR TRANSACTION INPUT NOT EQUAL TO OUTPUT")
Пример #23
0
    def split(self):
        # randomly select half the nodes to split
        newCommunityNodes = []
        np.random.shuffle(self.nodes)
        for i in range(int(self.nodeCount / 2)):
            newCommunityNodes.append(self.nodes[i])

        # Query all nodes in both communities to see if they want to split
        approved = 0
        for node in self.nodes:
            if node.approveSplit():
                approved += 1
        if approved < self.nodeCount / 2:
            return False, None, None

        pubkeys = []
        for newNode in newCommunityNodes:
            pubkeys.append(newNode.publicKey)
            self.nodes.remove(newNode)

        transaction, newTransaction = self.generateSplitTransactions(pubkeys)
        transaction = utils.Utils.serializeTransaction(transaction)
        newTransaction = utils.Utils.serializeTransaction(newTransaction)

        # add a new split block to remaining nodes blockchain
        serial = utils.Utils.serializeBlock(
            self.fetchUpToDateBlockchain().longestChain().block)
        splitBlock = buildingblocks.Block(transaction,
                                          H(str.encode(serial)).hexdigest(),
                                          isSplit=True)
        for node in self.nodes:
            node.chain.addBlock(splitBlock)

        # create a new blockchain for all nodes that are in the new community
        newBlock = buildingblocks.Block(newTransaction, None)
        for node in newCommunityNodes:
            newBlockChain = blockchain.BlockChain()
            newBlockChain.setGenesis(newBlock)
            node.setBlockChain(newBlockChain)

        community1 = Community(self.network,
                               random.randint(0, 10**10),
                               pool=self.pool,
                               keys=None,
                               nodeList=self.nodes)
        community2 = Community(self.network,
                               random.randint(0, 10**10),
                               pool=self.pool,
                               keys=None,
                               nodeList=newCommunityNodes)
        return True, community1, community2
Пример #24
0
    def writeSplitTransaction(self, old_chain_to_zero, old_chain_retain):
        inp = []
        out = []
        input_val = 0
        output_val = 0
        output_pairs = [
            item for item in old_chain_retain if item not in old_chain_to_zero
        ]

        # set put all viable outputs to the input of this new transaction
        for (number, value, pubkey) in old_chain_retain:
            inp.append({
                "number": number,
                "output": {
                    "value": value,
                    "pubkey": pubkey
                }
            })
            input_val += value

        # set all inputs not remaining in the old chain to output to 0
        for (number, value, pubkey) in old_chain_to_zero:
            out.append({"value": 0, "pubkey": pubkey})

        # set all inputs remaining in the old chain to output to their original output value
        for (number, value, pubkey) in output_pairs:
            out.append({"value": value, "pubkey": pubkey})
            output_val += value

        sig = H(str.encode(str(inp) + str(out))).hexdigest()
        number = H(str.encode(str(inp) + str(out) + sig)).hexdigest()
        transaction = buildingblocks.Transaction(number, inp, out, sig)

        if input_val > output_val:
            return transaction, input_val - output_val
        else:
            print("ERROR TRANSACTION INPUT GREATER THAN OUTPUT")
Пример #25
0
def hash_block_to_hex(b):
    """Computes the hex-encoded hash of a block header."""
    packed_data = []
    packed_data.extend(b["parentid"].decode('hex'))
    packed_data.extend(b["root"].decode('hex'))
    packed_data.extend(pack('>Q', long(b["difficulty"])))
    packed_data.extend(pack('>Q', long(b["timestamp"])))
    for n in b["nonces"]:
        packed_data.extend(pack('>Q', long(n)))
    packed_data.append(chr(b["version"]))
    if len(packed_data) != 105:
        print "invalid length of packed data"
    h = H()
    h.update(''.join(packed_data))
    b["hash"] = h.digest().encode('hex')
    return b["hash"]
Пример #26
0
    def check_dir(self, base_path):
        from os import listdir, readlink
        from os.path import join, basename
        from hashlib import sha512 as H

        names = listdir(base_path)
        names.sort()

        for name in names:
            p = join(base_path, name)
            specs = patterns.get(name, ())
            try:
                dst_name = readlink(p)
            except OSError:
                pass
            else:
                dst_name = basename(dst_name)
                if self.NODE_NAME_DISK_RE.match(dst_name):
                    di = self.disks.setdefault(dst_name, DiskInfo(name))
                    di.check_num += len(specs)

            for (off, length, hd_want, desc) in specs:
                f = open(p, 'rb')
                f.seek(off)
                h = H()
                while (length > 0):
                    rl = min(length, 16777216)
                    data = f.read(rl)
                    if (len(data) == 0):
                        break
                    h.update(data)
                    length -= len(data)
                hd_have = h.hexdigest()

                if (hd_have == hd_want):
                    self.n_ok += 1
                    print('{} {}: {}'.format(desc, c_green('OK'), hd_have),
                          flush=True)
                else:
                    self.n_fail += 1
                    print('{} {}:'.format(desc, c_red('FAIL')), flush=True)
                    for (x, y) in ((0, 64), (64, 128)):
                        ws = hd_want[x:y]
                        print(c_yellow(ws), flush=True)
                        hs = hd_have[x:y]
                        print(c_red(hs), flush=True)
Пример #27
0
 def __init__(self, info, uploader, reward, pubkey, filesize, merkle):
     self.data = info
     self.timelock = 100
     self.uploader = uploader
     self.withdrawer = uploader
     self.pub = pubkey
     self.filesize = filesize
     self.sig = None
     self.contentHash = merkle
     if reward > 0: 
         self.reward = reward
     else:
         raise NotEnoughMoney("please deposit some reward")
     #python doesn't have constants
     #this is pseudo contract bc anyone can modify
     #also python doesn't take into consideration of timezone
     self.timestamp = datetime.datetime.now()
     self.id = H(bytes(str(self.timestamp), "utf-8")).hexdigest()
Пример #28
0
    def my_hash(self, gv, gx_i, signerID):
        """ signerID is a string """
        g_product = (self.g*gv*gx_i)%self.q
        int_signerID = int(signerID)
        int_hash = r.fast_exp_w_mod(g_product, int_signerID, self.q)

        # Adding this to decrease the size of the number to be hashed
        # otherwise the to_bytes function does not work
        int_hash = int_hash%10000

        sha_hashing = H(int_hash.to_bytes(2, "big"))
        sha_hashing_int = int(sha_hashing.hexdigest(), 16)
        num = sha_hashing_int
        while num > 10:
            num = r.sum_digits(num)

        # print("The h value is", num)
        return num
Пример #29
0
 def log(self, filename=None):
     current = self.longestChain()
     output = []
     while current:
         d = {
             "tx": H(str.encode(current.block.tx)).hexdigest(),
             "prev": current.block.prev
         }
         dict(sorted(d.items()))
         output.append(d)
         current = current.prev
     if filename:
         with open(filename, 'w') as outfile:
             json.dump(output,
                       outfile,
                       sort_keys=False,
                       indent=4,
                       ensure_ascii=False)
     return output
Пример #30
0
def hash_block_nonce_i(b, i):
    """
    Computes the hex-encoded hash of a block header, using only nonce i. First
    builds an array of bytes with the correct endianness and length for each
    arguments. Then hashes the concatenation of these bytes and encodes to
    hexidecimal.
    """

    packed_data = []
    packed_data.extend(b["parentid"].decode('hex'))
    packed_data.extend(b["root"].decode('hex'))
    packed_data.extend(pack('>Q', long(b["difficulty"])))
    packed_data.extend(pack('>Q', long(b["timestamp"])))
    #   Bigendian 64bit unsigned
    packed_data.extend(pack('>Q', long(b["nonces"][i])))
    packed_data.append(chr(b["version"]))
    if len(packed_data) != 89:
        print "invalid length of packed data"
    h = H()
    h.update(''.join(packed_data))
    return h.digest()