def generate(): """ CLI to generate a hash from a file and store it :return: """ message, filename_message, q_pressed = file_loader( "Fichier du dossier data à hasher (test.txt par défaut) :", "test.txt", path_data) if q_pressed: return print( "Fichier du dossier data où stocker le hash (test_hash.txt par défaut) :" ) filename_hash = input() if filename_hash == 'q': return if filename_hash == '': filename_hash = 'test_hash.txt' h = SpongeHash() result_hash = h.hash(message) print('Hash de ', filename_message, ' :') print(result_hash) write_file(path.join(path_data, filename_hash), result_hash)
def verify(message: str, signature: list, public_key: list) -> bool: """ Checks if the signature is valid :param message: String of the message to verify :param signature: List composed of the two elements of the ElGamal signature :param public_key: List containing the public elements of the signer of the message (public, prime, generator) :return: True if the signature is valid, else false """ public = public_key[0] prime = public_key[1] generator = public_key[2] # Convert the signature back to integer s1 = int(signature[0], 16) s2 = int(signature[1], 16) # Hash the message to verify h = SpongeHash() h_digest = h.hash(message, False) hs1 = square_and_multiply(public, s1, prime) s1s2 = square_and_multiply(s1, s2, prime) check1 = (hs1 * s1s2) % prime check2 = square_and_multiply(generator, h_digest, prime) return check1 == check2
def all(): """ Does all the possible actions in hash :return: """ print('Hash\n') message = read_file(path.join(path_data, 'test.txt')) print('Texte brut :\n', message) h = SpongeHash() hash_result = h.hash(message) print('Texte hashé :\n', hash_result) hash_check_result = h.hash(message) print('Hashage du même texte :\n', message) if hash_result == hash_check_result: print('Hashs identiques!') else: print('Hashs différents') hash_check_result = h.hash('a' + message) print('Hashage du texte différent :\n', 'a' + message) if hash_result == hash_check_result: print('Hashs identiques!') else: print('Hashs différents')
def check(): """ CLI to check if a file matches to a hash :return: """ message, _, q_pressed = file_loader( "Fichier du dossier data à vérifier (test.txt par défaut) :", "test.txt", path_data) if q_pressed: return hash_value, _, q_pressed = file_loader( "Fichier du dossier data à vérifier (test_hash.txt par défaut) :", "test_hash.txt", path_data) if q_pressed: return h = SpongeHash() if h.hash(message) == hash_value: print('Le hash correspond au message!') else: print('Le hash ne correspond pas au message!')
def __init__(self, index: int = None, transactions: list = None, previous_hash: str = None, timestamp: datetime = datetime.now(), miner: str = None, block_str: str = None): self.__xorshift = XORShift() self.__hash = SpongeHash() if block_str is not None: # Create a block from string self.__transactions = [] block_lines = block_str.splitlines() self.__index = int(block_lines[0].split(' ')[1]) # Add transactions for trans_str in block_lines[1:-4]: self.__transactions.append( Transaction(transaction_str=trans_str)) self.__timestamp = datetime.strptime(block_lines[-4], '%Y-%m-%d %H:%M:%S.%f') self.__miner = block_lines[-3] self.__previous_hash = block_lines[-2] self.__proof = block_lines[-1] else: # Create a block from parameters self.__index = index self.__transactions = transactions self.__previous_hash = previous_hash self.__timestamp = timestamp self.__miner = miner self.__proof = None self.__create_proof()
def verify(message: str, signature: str, public_key: list) -> bool: """ Checks if the signature is valid :param message: String of the message to verify :param signature: Signature of the message in hexadecimal string :param public_key: List composed of e and n :return: True if the signature is valid, else false """ # Convert the signature back to integer signature = int(signature, 16) # Hash the message to verify h = SpongeHash() h_digest = h.hash(message, to_hex=False) # Get the values from the public key e = public_key[0] n = public_key[1] hash_verify = square_and_multiply(signature, e, n) # (H(m))^(e*d) mod n = H(m) return h_digest == hash_verify
class RSASignature(Signature): def __init__(self, k_manager: RSAKeysManager): self.__k_manager = k_manager self.__h = SpongeHash() def sign(self, message: str) -> str: """ Signs the given message with RSA signature :param message: String of the message to sign :return: The signature of the message as an hexadecimal string """ h_digest = self.__h.hash(message, to_hex=False) n = self.__k_manager.get_public()[1] # n is public in RSA signature = square_and_multiply(h_digest, self.__k_manager.get_private_key(), n) return hex(signature).lstrip('0x') @staticmethod def verify(message: str, signature: str, public_key: list) -> bool: """ Checks if the signature is valid :param message: String of the message to verify :param signature: Signature of the message in hexadecimal string :param public_key: List composed of e and n :return: True if the signature is valid, else false """ # Convert the signature back to integer signature = int(signature, 16) # Hash the message to verify h = SpongeHash() h_digest = h.hash(message, to_hex=False) # Get the values from the public key e = public_key[0] n = public_key[1] hash_verify = square_and_multiply(signature, e, n) # (H(m))^(e*d) mod n = H(m) return h_digest == hash_verify
def __init__(self, blockchain_file: str = None, satoshi_nakamoto: str = None): """ Creates a new or loads an existing blockchain :param blockchain_file: :param satoshi_nakamoto: Genesis block miner """ self.__blocks = [] self.__pending_transactions = [] if blockchain_file is None: blockchain_file = 'blockchain.txt' # Default blockchain file self.__blockchain_file = blockchain_file if path.exists(path.join(path_data, blockchain_file)): # Load blockchain self.__load_blockchain(blockchain_file) self.__load_pending_transactions() else: # The blockchain file does not exist # Create a new blockchain # Create a genesis block if satoshi_nakamoto is None: satoshi_nakamoto = input('Mineur du block genesis : ') genesis_block = Block(index=0, transactions=[], previous_hash=SpongeHash().hash( 'The Times 03/Jan/2009 ' 'Chancellor on brink of ' 'second bailout for ' 'banks.'), miner=satoshi_nakamoto) self.__blocks.append(genesis_block) self.__save_blockchain()
class Block: proof_complexity = 3 miner_reward = 10 proof_bitsize = 128 def __init__(self, index: int = None, transactions: list = None, previous_hash: str = None, timestamp: datetime = datetime.now(), miner: str = None, block_str: str = None): self.__xorshift = XORShift() self.__hash = SpongeHash() if block_str is not None: # Create a block from string self.__transactions = [] block_lines = block_str.splitlines() self.__index = int(block_lines[0].split(' ')[1]) # Add transactions for trans_str in block_lines[1:-4]: self.__transactions.append( Transaction(transaction_str=trans_str)) self.__timestamp = datetime.strptime(block_lines[-4], '%Y-%m-%d %H:%M:%S.%f') self.__miner = block_lines[-3] self.__previous_hash = block_lines[-2] self.__proof = block_lines[-1] else: # Create a block from parameters self.__index = index self.__transactions = transactions self.__previous_hash = previous_hash self.__timestamp = timestamp self.__miner = miner self.__proof = None self.__create_proof() def hash(self) -> str: block_str = '' for transaction in self.__transactions: block_str += str(transaction) block_str += self.__previous_hash block_str += self.__proof return self.__hash.hash(block_str) @property def index(self): return self.__index @property def transactions(self): return self.__transactions @property def previous_hash(self): return self.__previous_hash @property def timestamp(self): return self.__timestamp @property def miner(self): return self.__miner @property def proof(self): return self.__proof def __str__(self) -> str: block_str = 'block ' + str(self.__index) + '\n' for transaction in self.__transactions: block_str += str(transaction) + '\n' block_str += str(self.__timestamp) + '\n' block_str += self.__miner + '\n' block_str += self.__previous_hash + '\n' block_str += self.__proof + '\n\n' return block_str def __create_proof(self): """ Creates a proof of work for the block :return: """ # Create the block base on which the salt will be concatenated base_block_str = '' for transaction in self.__transactions: base_block_str += str(transaction) base_block_str += self.__previous_hash # Find a salt that creates the right hash while True: guess_salt = hex(self.__xorshift.getrandbits( self.proof_bitsize)).lstrip('0x') guess = base_block_str + guess_salt hash_try = self.__hash.hash(guess) if hash_try.endswith('0' * self.proof_complexity): self.__proof = guess_salt return
class ElGamalSignature(Signature): """ Implementation of the ElGamal signature using SpongeHash """ __k_manager = None __h = None def __init__(self, k_manager: ElGamalKeysManager): self.__k_manager = k_manager self.__h = SpongeHash() def sign(self, message: str) -> list: """ Signs the given message with ElGamal signature :param message: String of the message to sign :return: The signature composed of 2 hexadecimal strings """ # Hash the message to sign h_digest = self.__h.hash(message, False) # Random parameter for the signature while True: y = random.randint(1, self.__k_manager.get_prime() - 2) if gcd(y, self.__k_manager.get_prime() - 1) == 1: break inv_y = inverse(y, self.__k_manager.get_prime() - 1) s1 = square_and_multiply(self.__k_manager.get_generator(), y, self.__k_manager.get_prime()) s2 = (inv_y * (h_digest - self.__k_manager.get_private_key() * s1)) % ( self.__k_manager.get_prime() - 1) return [hex(s1).lstrip('0x'), hex(s2).lstrip('0x')] @staticmethod def verify(message: str, signature: list, public_key: list) -> bool: """ Checks if the signature is valid :param message: String of the message to verify :param signature: List composed of the two elements of the ElGamal signature :param public_key: List containing the public elements of the signer of the message (public, prime, generator) :return: True if the signature is valid, else false """ public = public_key[0] prime = public_key[1] generator = public_key[2] # Convert the signature back to integer s1 = int(signature[0], 16) s2 = int(signature[1], 16) # Hash the message to verify h = SpongeHash() h_digest = h.hash(message, False) hs1 = square_and_multiply(public, s1, prime) s1s2 = square_and_multiply(s1, s2, prime) check1 = (hs1 * s1s2) % prime check2 = square_and_multiply(generator, h_digest, prime) return check1 == check2
def __init__(self, k_manager: ElGamalKeysManager): self.__k_manager = k_manager self.__h = SpongeHash()