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
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
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)
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
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
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
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
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
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"]
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
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)
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
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
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'))
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)
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
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)
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
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
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 '''
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")
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
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")
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"]
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)
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()
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
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
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()