示例#1
0
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)
示例#2
0
    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
示例#3
0
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')
示例#4
0
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!')
示例#5
0
    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()
示例#6
0
    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
示例#7
0
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
示例#8
0
    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()
示例#9
0
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
示例#10
0
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
示例#11
0
 def __init__(self, k_manager: ElGamalKeysManager):
     self.__k_manager = k_manager
     self.__h = SpongeHash()