def proof_of_work(difficulty,data,digest_size=32): ''' ever so simplistic : difficulty number of leading zeros : data some string of stuff, e.g. block header return hash, nonce, iterations ''' if not isinstance(data,str): data = '{}'.format(data) index = 1 new_hash = None nonce = None while 1: n_seed = bytes('{}'.format(index),'utf8') nonce = blake2(n_seed,digest_size=8).hexdigest() __ = bytes(data + '{}'.format(nonce),'utf8') h = blake2(__,digest_size=digest_size) if h.hexdigest()[:difficulty] == "0" * difficulty: new_hash = h.hexdigest() break index += 1 return new_hash, nonce, index
def encrypt_int(self, actual_int): ''' ''' encrypted_int = blake2(self.hash_seed) start_idx = 1 end_idx = actual_int + 1 encrypted_int = [ blake2(encrypted_int.digest()) for i in range(start_idx, end_idx) ][-1] return encrypted_int
def get_proof(self, actual_int, provable_int): ''' ''' proof = blake2(self.hash_seed) start_idx = 1 end_idx = actual_int - provable_int + 1 for i in range(start_idx, end_idx): proof = blake2(proof.digest()) return proof
def _hash(self, payload, k, f='blake2'): if isinstance(payload, str): payload = payload.encode('utf8') if f=='mmh3': return mmh3.hash(payload,k) % len(self.array) if f=='blake2': return int(blake2(payload,salt=bytes([k])).hexdigest(), 16) % len(self.array)
def verify_proof(self, proof, provable_int): ''' ''' verified_int = proof start_idx = 0 end_idx = provable_int verified_int = [ blake2(verified_int.digest()) for i in range(start_idx, end_idx) ][-1] return verified_int
def hashed_pairs(l_node, r_node): assert l_node is not None and r_node is not None s = '' if l_node is None: s = r_node.hash elif r_node is None: s = l_node.hash else: s = r_node.hash + l_node.hash return b'0x' + blake2(s, digest_size=16).hexdigest().encode('utf8')
def _provr(self, actual_age, provable_age): ''' ''' proof = blake2(self.hash_seed) start_idx = 1 end_idx = actual_age - provable_age + 1 for i in range(start_idx, end_idx): proof = blake2(proof.digest()) encrypted_age = blake2(self.hash_seed) start_idx = 1 end_idx = actual_age + 1 encrypted_age = [ blake2(encrypted_age.digest()) for i in range(start_idx, end_idx) ][-1] verified_age = proof start_idx = 0 end_idx = provable_age verified_age = [ blake2(verified_age.digest()) for i in range(start_idx, end_idx) ][-1] return proof, encrypted_age, verified_age
def pow_performance_check(difficulties,max_rounds): ''' thredaing isn't really the answer. i want the processing times as pure as possible ont eh respective platforms and the ec2 t instances are choking enough with one run as is. ''' local_dir = os.path.abspath(os.path.dirname(sys.argv[0])) log_dir = os.path.abspath(os.path.join(local_dir,'..','logs')) if not os.path.exists(log_dir): os.mkdir(log_dir) fake_data = blake2(bytes(datetime.datetime.utcnow().isoformat(),'utf8'),digest_size=32).hexdigest() result = {} for d in difficulties: result[d] = {} __ = {'td':[],'n':[]} for m in range(max_rounds): start_dt = datetime.datetime.now() h,n,i = proof_of_work(d,fake_data) fake_data = h + n end_dt = datetime.datetime.now() __['td'].append((end_dt - start_dt).total_seconds()) __['n'].append(i) result[d]['rounds'] = max_rounds result[d]['run-time'] = {} result[d]['hash-iters'] = {} result[d]['run-time']['avg'] = round(mean(__['td']),4) result[d]['run-time']['median'] = round(median(__['td']),4) result[d]['run-time']['stdev'] = round(stdev(__['td']),4) result[d]['run-time']['min'] = round(min(__['td']),4) result[d]['run-time']['max'] = round(max(__['td']),4) result[d]['hash-iters']['avg'] = round(mean(__['n']),4) result[d]['hash-iters']['median'] = round(median(__['n']),4) result[d]['hash-iters']['stdev'] = round(stdev(__['n']),4) result[d]['hash-iters']['min'] = round(min(__['n']),4) result[d]['hash-iters']['max'] = round(max(__['n']),4) dt = datetime.datetime.utcnow().replace(microsecond=0) fname = 'pow_runtime_stats_{}.txt'.format(dt.isoformat()) results_path = os.path.join(log_dir,fname) with open(results_path,'w') as fd: fd.write('{}\n'.format(result)) return result
def test_pow(difficulty=4,result_variance=False): ''' ''' start_dt = datetime.datetime.utcnow() last_hash = 'Howdy' last_height = 10 data = last_hash + str(last_height) if result_variance: data += start_dt.isoformat() h,n,i = proof_of_work(difficulty,data) end_dt = datetime.datetime.utcnow() v = blake2(bytes(data + n,'utf8'),digest_size=32).hexdigest() _assert = v==h vals = (difficulty,(end_dt - start_dt).total_seconds(),i,h,n,v,_assert) msg = 'pow test run with verification assert:\n' msg += 'difficulty: {}, run time: {}, iterations: {}\n' msg +='pow hash: {}, pow nonce: {},verification hash: {}\n' msg +='pow == verification hash: {}' sys.stdout.write(msg.format(*vals)) return _assert
def hasher(payload): # TODO: clean that up : to _bytes() if not isinstance(payload, bytes): payload = '{}'.format(payload).encode('utf8') return b'0x' + blake2(payload, digest_size=16).hexdigest().encode('utf8')