Пример #1
0
    def mine(self):

        # Create hash of transactions with a Merkle Tree

        tree = MerkleTree()
        for t in self.transactions:
            tree.encryptRecord(t.id.encode())  # make bytestring
        merkle_hash = tree.rootHash

        # 32-bit sized nonce
        for nonce in range(2 << 32):
            # header consists ofev_hash, nonce, merkle of transactions
            # and the block timestamps.
            # see: https://en.bitcoin.it/wiki/Block_hashing_algorithm
            nonce = hex(nonce).encode()
            timestamp = str(time()).encode()
            header = self.previous_hash + nonce + merkle_hash + timestamp
            h = SHA256.new()
            # apply hashing 2 times
            hash_value = h.new(h.new(header).digest()).hexdigest()
            hash_value = str(hash_value[::-1])  # reverse, little endian
            if int(hash_value[0:config.DIFFICULTY], 16) == 0:
                solved = True
                break
        if solved:
            self.hash = hash_value.encode()
            self.nonce = nonce
            self.timestamp = timestamp
        else:
            self.mine()
Пример #2
0
    def importarDicionario(self, dicionario):

        _tArvore = dicionario["arvoreDeMerkle"]
        _tTransacoesDict = OrderedDict()
        _tTransacoesDict = dicionario["transacoes"]

        _tTransacoes = blocosDeTransacoesFinal()
        _tTransacoes.importarDicionarios(_tTransacoesDict["transacoes"])

        _tArvoreJson = open("tmp.json", "w")
        json.dump(_tArvore, _tArvoreJson)
        _tArvoreJson.close()

        _tArvoreMerkle = MerkleTree.loadFromFile("tmp.json")

        if _tArvoreMerkle != MerkleTree(*_tTransacoes.dados()):
            raise arvoreDeMerkleInvalida

        self.transacoes = _tTransacoes
        self.arvoreDeMerkle = _tArvoreMerkle

        _tArvoreJson = open("tmp.json", "w")
        Utilitarios.remover_seguramente("tmp.json", 5)
        _tArvoreJson.close()

        return self
Пример #3
0
def test_UndecodableRecordError_with_encryptRecord(_byte, _encoding,
                                                   _security):

    _tree = MerkleTree('a', 'b', 'c', encoding=_encoding, security=_security)
    _output = _tree.encryptRecord(_byte)

    assert _output == 1 and _tree.length == 3
Пример #4
0
def test_deserialization_error():
    """
    Tests JSONDecodeError upon trying to encrypt a non-deserializable
    .json file
    """
    tree = MerkleTree()
    with pytest.raises(json.JSONDecodeError):
        tree.encryptJSONFromFile(
            os.path.join(parent_dir, 'json_files/bad.json'))
Пример #5
0
def test_UndecodableRecord_with_encryptRecord(byte, encoding, security):
    tree = MerkleTree('a',
                      'b',
                      'c',
                      encoding=encoding,
                      raw_bytes=False,
                      security=security)
    with pytest.raises(UndecodableRecord):
        tree.encryptRecord(byte)
Пример #6
0
def test_deserialization_error():
    """Tests that the .encryptObjectFromFile() method raises JSONDecodeError
    when the provided .json file cannot be deserialized
    """

    tree = MerkleTree()

    with pytest.raises(json.JSONDecodeError):
        tree.encryptObjectFromFile(
            os.path.join(os.path.dirname(__file__), 'objects/bad.json'))
Пример #7
0
def test_WronJSONFormat():
    """Tests that the .encryptFilePerObject() method raises WrongJSONFormat
    when the deserialized object loaded from the provided file is not a list
    """

    tree = MerkleTree()

    with pytest.raises(WrongJSONFormat):
        tree.encryptFilePerObject(
            os.path.join(os.path.dirname(__file__), 'objects/sample.json'))
def test_encryptFilePerObject(tree, hash_machine):
    tree.clear()
    tree.encryptFilePerObject(objects_file_path, sort_keys=False, indent=0)

    clone_tree = MerkleTree(hash_type=tree.hash_type,
                            encoding=tree.encoding,
                            security=tree.security)

    for object in list_of_objects:
        clone_tree.update(record=json.dumps(object, sort_keys=False, indent=0))

    assert tree.rootHash() == clone_tree.rootHash()
Пример #9
0
def test_encryptFilePerObject(_tree, _hash_machine):

    _tree.clear()
    _tree.encryptFilePerObject(objects_list_file, sort_keys=False, indent=0)

    _clone = MerkleTree(hash_type=_tree.hash_type,
                        encoding=_tree.encoding,
                        security=_tree.security)

    for _object in objects_list:
        _clone.update(record=json.dumps(_object, sort_keys=False, indent=0))

    assert _tree.rootHash == _clone.rootHash
def test_encryptFilePerLog(tree):
    tree.clear()
    # Update original tree directly from file
    tree.encryptFilePerLog(short_APACHE_log_path)

    clone_tree = MerkleTree(hash_type=tree.hash_type,
                            encoding=tree.encoding,
                            security=tree.security)

    for record in records:
        clone_tree.update(record)

    assert tree.rootHash() == clone_tree.rootHash()
Пример #11
0
    def validate_hash(self):
        # validate block hash value

        tree = MerkleTree()
        for t in self.transactions:
            tree.encryptRecord(t.id.encode())  # make bytestring
        merkle_hash = tree.rootHash

        header = self.previous_hash + self.nonce+\
                merkle_hash + self.timestamp
        h = SHA256.new()
        hash_value = str(h.new(h.new(header).digest()).hexdigest()[::-1])
        return (int(hash_value[0:config.DIFFICULTY], 16) == 0)
Пример #12
0
def test_tree_constructor_with_records():
    tree_1 = MerkleTree(*(bytes('{}-th record'.format(i), 'utf-8')
                          for i in range(0, 1000)))
    tree_2 = MerkleTree()
    for i in range(1000):
        tree_2.update('{}-th record'.format(i))
    assert tree_1.rootHash() == tree_2.rootHash()
Пример #13
0
def test_validationReceipt():

    _tree = MerkleTree(*['%d-th record' % i for i in range(5)])

    _audit_proof = _tree.auditProof(3)
    _receipt = validationReceipt(target=_tree.rootHash,
                                 proof=_audit_proof,
                                 dirpath=os.path.join(
                                     os.path.dirname(__file__), 'receipts'))

    _receipt_path = os.path.join(os.path.dirname(__file__), 'receipts',
                                 '%s.json' % _receipt.header['uuid'])

    with open(_receipt_path) as _file:
        _clone = json.load(_file)
        assert _receipt.serialize() == _clone
Пример #14
0
def test_defense_against_second_preimage_attack(original_tree):

    # Construct forged record
    leaves = original_tree.leaves
    encoding = original_tree.encoding
    if original_tree.raw_bytes:
        F = leaves[2].digest
        G = leaves[3].digest
    else:
        F = leaves[2].digest.decode(encoding)
        G = leaves[3].digest.decode(encoding)
    forged_record = F + G

    # Attacker's tree
    attacker_tree = MerkleTree(
        'a',
        'b',
        forged_record,  # forged records
        hash_type=original_tree.hash_type,
        encoding=original_tree.encoding,
        raw_bytes=original_tree.raw_bytes,
        security=original_tree.security)

    # Check if the attacker has replicated the original root-hash
    if original_tree.security:
        assert original_tree.rootHash != attacker_tree.rootHash
    else:
        assert original_tree.rootHash == attacker_tree.rootHash
Пример #15
0
    def __init__(self,
                 eleicao,
                 abrangencia,
                 endereco,
                 zona,
                 secao,
                 blocoTF=None,
                 arvore=None):

        if blocoTF != None:
            if len(blocoTF.dados()) == 0:
                raise quantidadeMenorQueUm
            elif isinstance(blocoTF, blocosDeTransacoesFinal):
                for transacao in blocoTF:
                    if isinstance(transacao, Transacoes):
                        pass
                    else:
                        raise tipoDeTransacaoDesconhecido
                if blocoTF.validaSequencia():
                    _tArvore = MerkleTree(*blocoTF.dados())
                    if arvore:
                        if arvore != _tArvore:
                            raise arvoreDeMerkleInvalida
                    self.votos = blocoTF
                    self.arvoreDeMerkle = _tArvore
                    self.abrangencia = abrangencia
                    self.endereco = endereco
                    self.zona = zona
                    self.secao = secao
                    self.eleicao = eleicao

                else:
                    raise sequenciaDeHashesInvalida
            else:
                raise deveSerBlocoDeTransacaoFinal
Пример #16
0
def test_validation_get_receipt():
    tree = MerkleTree(*['%d-th record' % _ for _ in range(5)])

    audit_proof = tree.auditProof(b'2-th record')
    receipt = validateProof(target=tree.rootHash,
                            proof=audit_proof,
                            get_receipt=True,
                            dirpath=os.path.join(os.path.dirname(__file__),
                                                 'receipts'))

    receipt_path = os.path.join(os.path.dirname(__file__), 'receipts',
                                '%s.json' % receipt.header['uuid'])

    with open(receipt_path) as __file:
        clone = json.load(__file)
        assert receipt.serialize() == clone
Пример #17
0
    def create_tree(self):
        """Create the tree

        Args:
            output_folder (str): The folder where the parts will be written.
        """
        self.tree = MerkleTree(hash_type=self.hash_type,
                               security=False,
                               raw_bytes=True)

        # Creating tree
        for i, f in enumerate(self.get_parts()):
            x = self.tree.update(f)

        # Creating proofs
        for i, f in enumerate(self._parts):
            self.proofs.append(self.tree.auditProof(i).serialize())
Пример #18
0
 def arvoreDeMerkle(self, arvore):
     if not self.votos:
         raise registroSemTransacoes
     _tArvore = MerkleTree(*self.transacoes.dados())
     if arvore != _tArvore:
         raise arvoreDeMerkleInvalida
     else:
         self._arvoreDeMerkle = arvore
Пример #19
0
def test_defense_against_second_preimage_attack(original_tree):
    # Construct forged record
    F = original_tree.leaves[2].stored_hash.decode(
        encoding=original_tree.encoding)
    G = original_tree.leaves[3].stored_hash.decode(
        encoding=original_tree.encoding)
    forged_record = '%s%s' % (F, G)
    # Construct attacker's tree
    attacker_tree = MerkleTree('a',
                               'b',
                               forged_record,
                               hash_type=original_tree.hash_type,
                               encoding=original_tree.encoding,
                               security=original_tree.security)
    # Check if the attacker has found the original root-hash
    if original_tree.security:
        assert original_tree.rootHash() != attacker_tree.rootHash()
    else:
        assert original_tree.rootHash() == attacker_tree.rootHash()
Пример #20
0
    def __init__(self, file=None):
        """sets up the underlying merkle tree
        
        Parameters:
        file (str): Optional recovery of tree state dumped by export().
        """
        if file is None:
            self.merkle = MerkleTree(
                b"hello world",
                b"Hello world",
                b"hello World",
                b"Hello World",
                b"hello world!",
                b"Hello World!",  # include  enough hello worlds to construct a path
                raw_bytes=False,
            )

        else:
            self.merkle = MerkleTree.loadFromFile(file)
 def merkle_root(self):
     tree = MerkleTree()
     tree = MerkleTree(hash_type='sha256',
                       encoding='utf-8',
                       raw_bytes=True,
                       security=True)
     tree.update(str(self.pending_transactions))
     #tree.export('tree-without-root-hash.json')
     return str(tree.rootHash.decode())
Пример #22
0
def test_encryptFilePerLog(_tree):

    _tree.clear()
    _output = _tree.encryptFilePerLog(short_APACHE_log)

    if _tree.encoding not in EXTENDED:

        _clone = MerkleTree(*records,
                            hash_type=_tree.hash_type,
                            encoding=_tree.encoding,
                            security=_tree.security)

        assert _output == 0 and _tree.rootHash == _clone.rootHash

    else:
        assert _output == 1 and not _tree
Пример #23
0
def test_encryptFilePerLog(tree):
    if tree.raw_bytes:
        tree.clear()
        encrypted = tree.encryptFilePerLog(short_APACHE_log)
        clone = MerkleTree(*records,
                           hash_type=tree.hash_type,
                           encoding=tree.encoding,
                           raw_bytes=tree.raw_bytes,
                           security=tree.security)
        assert tree.rootHash == clone.rootHash
    elif tree.encoding in ('iso8859_8', 'iso2022_kr', 'iso8859_3', 'ascii',
                           'utf_7', 'utf_32_be', 'iso2022_jp_1', 'utf_32_le',
                           'utf_32', 'iso2022_jp_3', 'iso2022_jp_2004', 'hz',
                           'iso8859_7', 'iso8859_6', 'iso2022_jp_ext',
                           'utf_16', 'cp424', 'iso2022_jp_2', 'utf_16_le',
                           'utf_16_be', 'iso2022_jp'):
        with pytest.raises(UndecodableRecord):
            tree.encryptFilePerLog(short_APACHE_log)
import pytest
import os
import json
from pymerkle import MerkleTree

# Clean exports dir before running the test
for file in os.listdir(os.path.join(os.path.dirname(__file__), 'exports')):
    os.remove(os.path.join(os.path.dirname(__file__), 'exports', file))

tree = MerkleTree()
for i in range(12):
    tree.update(record='{}-th record'.format(i))
export_path = os.path.join(os.path.dirname(__file__), 'exports',
                           '{}.json'.format(tree.uuid))
tree.export(file_path=export_path)
with open(export_path, 'r') as f:
    exported_version = json.load(f)


def test_export():
    assert exported_version == {
        "header": {
            "encoding": "utf_8",
            "hash_type": "sha256",
            "security": True
        },
        "hashes": [
            "a08665f5138f40a07987234ec9821e5be05ecbf5d7792cd4155c4222618029b6",
            "3dbbc4898d7e909de7fc7bb1c0af36feba78abc802102556e4ea52c28ccb517f",
            "45c44059cf0f5a447933f57d851a6024ac78b44a41603738f563bcbf83f35d20",
            "b5db666b0b34e92c2e6c1d55ba83e98ff37d6a98dda532b125f049b43d67f802",
Пример #25
0
import pytest
from pymerkle import MerkleTree, hashing, encodings

# Generate trees for all combinations of hash and encoding types
# (including both security modes for each)
HASH_TYPES = hashing.HASH_TYPES
ENCODINGS = encodings.ENCODINGS
trees = []
for security in (True, False):
    for hash_type in HASH_TYPES:
        for encoding in ENCODINGS:
            trees.append(
                MerkleTree(
                    'a',
                    'b',
                    'c',
                    'd',  # original records
                    hash_type=hash_type,
                    encoding=encoding,
                    security=security))


@pytest.mark.parametrize("original_tree", trees)
def test_defense_against_second_preimage_attack(original_tree):
    # Construct forged record
    F = original_tree.leaves[2].stored_hash.decode(
        encoding=original_tree.encoding)
    G = original_tree.leaves[3].stored_hash.decode(
        encoding=original_tree.encoding)
    forged_record = '%s%s' % (F, G)
    # Construct attacker's tree
    attacker_tree = MerkleTree('a',
def test_loadFromFile():
    assert tree.rootHash() == MerkleTree.loadFromFile(
        file_path=export_path).rootHash()
import json
from pymerkle import MerkleTree, hashing, encodings

HASH_TYPES = hashing.HASH_TYPES
ENCODINGS = encodings.ENCODINGS

# Generate trees and corresoponding hash machines for all combinations of
# hash and encoding types (including both security modes for each)
trees = []
hash_machines = []
for security in (True, False):
    for hash_type in HASH_TYPES:
        for encoding in ENCODINGS:
            trees.append(
                MerkleTree(hash_type=hash_type,
                           encoding=encoding,
                           security=security))
            hash_machines.append(
                hashing.hash_machine(hash_type=hash_type,
                                     encoding=encoding,
                                     security=security))


@pytest.mark.parametrize("tree, hash_machine", [(trees[i], hash_machines[i])
                                                for i in range(len(trees))])
def test_encryptRecord(tree, hash_machine):
    tree.encryptRecord('some kind of record...')
    assert tree.rootHash() == hash_machine.hash('some kind of record...')


large_APACHE_log_path = os.path.join(os.path.dirname(__file__),
Пример #28
0
"""pymerkle demo"""

from pymerkle import MerkleTree, validateProof

if __name__ == '__main__':

    tree = MerkleTree(hash_type='sha256',
                      encoding='utf-8',
                      raw_bytes=True,
                      security=True)

    for i in range(7):
        tree.encryptRecord('%d-th record' % i)

    print(repr(tree))

    challenge = {
        'checksum':
        '45c44059cf0f5a447933f57d851a6024ac78b44a41603738f563bcbf83f35d20'
    }

    proof = tree.merkleProof(challenge)
    print(proof)

    assert validateProof(proof)

    receipt = validateProof(proof, get_receipt=True)
    print(receipt)
Пример #29
0
import json

from pymerkle import MerkleTree
from pymerkle.hashing import HashMachine, HASH_TYPES
from pymerkle.exceptions import UndecodableRecord

from tests.conftest import ENCODINGS

trees__hash_machines = []
for raw_bytes in (True, False):
    for security in (True, False):
        for hash_type in HASH_TYPES:
            for encoding in ENCODINGS:

                trees__hash_machines.append((MerkleTree(hash_type=hash_type,
                                                        encoding=encoding,
                                                        raw_bytes=raw_bytes,
                                                        security=security),
                                             HashMachine(hash_type=hash_type,
                                                         encoding=encoding,
                                                         raw_bytes=raw_bytes,
                                                         security=security)))

single_records = []
for (tree, hash_machine) in trees__hash_machines:

    single_records.extend([(tree, hash_machine, 'string record'),
                           (tree, hash_machine,
                            bytes('bytes record', tree.encoding))])


@pytest.mark.parametrize("tree, hash_machine, record", single_records)
Пример #30
0
class GeradorDeUrna:
    auxCriptografia = Criptografia()
    util = Utilitarios()
    eleicao = None
    idSecao = None
    zona = None
    secao = None
    saldoInicial = None
    nonce = None
    timestamp = None
    endereco = None
    chavePublica = None
    arvoreDeMerkle = MerkleTree()
    candidatos = []
    eleitores = []
    cedulas = Cedulas()

    def __init__(self, eleicao, zona, secao):
        self.eleicao = eleicao
        self.zona = zona
        self.secao = secao
        self.timestamp = datetime.utcnow().timestamp()
        self.saldoInicial = 0

    def incluirEleitor(self, eleitor_):
        if isinstance(eleitor_, tEleitor):
            _tEleitor = regEleitor(eleitor_.endereco, eleitor_.titulo)
            self.eleitores.append(_tEleitor)
            self.saldoInicial += 1

    def serializarEleitores(self):
        _dicionarios = []
        for _eleitor in self.eleitores:
            _dicionario = {
                "endereco": _eleitor.endereco,
                "titulo": _eleitor.titulo
            }
            _dicionarios.append(_dicionario)
        return _dicionarios

    def importarEleitor(self, dEleitor_):
        if dEleitor_["tipo"] == "eleitor":
            _e = tEleitor(dEleitor_["nome"], dEleitor_["titulo"],
                          dEleitor_["endereco"], dEleitor_["chavePublica"],
                          dEleitor_["aleatorio"], dEleitor_["timestamp"],
                          dEleitor_["assinatura"])
            self.incluirEleitor(_e)

    def incluirCandidato(self, candidato_):
        if isinstance(candidato_, tCandidato):
            _tCandidato = regCandidato(candidato_.numero,
                                       candidato_.abrangencia,
                                       candidato_.endereco, candidato_.nome)
            self.candidatos.append(_tCandidato)

    def importarCandidato(self, candidato_):
        if candidato_["tipo"] == "candidato":
            _c = tCandidato(candidato_["abrangencia"], candidato_["nome"],
                            candidato_["titulo"], candidato_["cargo"],
                            candidato_["numero"], candidato_["processo"],
                            candidato_["endereco"], candidato_["timestamp"])
            self.incluirCandidato(_c)

    def serializarCandidatos(self):
        _dicionarios = []
        for _candidato in self.candidatos:
            _dicionario = {
                "numero": _candidato.numero,
                "abrangencia": _candidato.abrangencia,
                "endereco": _candidato.endereco,
                "nome": _candidato.nome,
                "saldo": _candidato.saldo
            }
            _dicionarios.append(_dicionario)
        return _dicionarios

    def gerarCedulas(self):
        if len(self.candidatos) > 0 and len(self.eleitores) > 0:
            self.cedulas.criarCedulas(self.saldoInicial)
        else:
            raise saldoInconsistente

    def gerarChaves(self):
        _sk = self.auxCriptografia.gerarChavePrivada()
        self.auxCriptografia.exportarChavePrivada(
            _sk, "tmp/PrivUrnaZona{}Secao{}.pem".format(self.zona, self.secao))
        self.chavePublica = _sk.verifying_key

    def gerarEndereco(self):
        if self.chavePublica:
            self.endereco = self.util.gerarEndereco(
                "tmp/PrivUrnaZona{}Secao{}.pem".format(self.zona, self.secao))

    def dados(self):
        return "{}{}{}{}{}{}{}".format(self.eleicao, self.zona, self.secao,
                                       self.endereco, self.saldoInicial,
                                       self.nonce,
                                       self.arvoreDeMerkle.rootHash)

    def calcularArvoreDeMerkle(self):
        for _c in self.cedulas:
            self.arvoreDeMerkle.update(_c.retornaIdCedula())
        for _e in self.eleitores:
            self.arvoreDeMerkle.update(_e.dados())
        for _cD in self.candidatos:
            self.arvoreDeMerkle.update(_cD.dados())

    def importarCedulas(self, dicCedulas_):
        if isinstance(dicCedulas_, Cedulas):
            self.cedulas.importarDicionario(dicCedulas_["cedulas"])

    def calcularHash(self):
        self.nonce = 0
        gerador = hashing.HashMachine()
        _hash = ''
        while not _hash.startswith('00000'):
            _hash = gerador.hash(self.dados())
            self.nonce += 1
        return _hash

    def serializar(self):
        return {
            "eleicao": self.eleicao,
            "zona": self.zona,
            "secao": self.secao,
            "endereco": self.endereco,
            "saldoInicial": self.saldoInicial,
            "timestamp": self.timestamp,
            "nonce": self.nonce,
            "hashRaiz": self.arvoreDeMerkle.rootHash,
            "hash": self.calcularHash(),
            "arvoreDeMerkle": self.arvoreDeMerkle.serialize(),
            "cedulas": self.cedulas.serializar(),
            "eleitores": self.serializarEleitores(),
            "candidatos": self.serializarCandidatos()
        }