Prova de Existência de Dados no Tempo

Marcos Gabbardo
7 min readOct 5, 2018

--

Registrar dados ou documentos em um determinado tempo para provar sua existência é algo que já existe a vários anos.

Este tipo de registro surgiu com a necessidade de se provar que aquela informação (seja um documento ou um dado qualquer) existia realmente em um período do tempo, servindo para provar, por exemplo, que um contrato fora assinado antes de uma determinada data, trazendo inclusive implicações legais para discussão.

Contudo, para ser imparcial no registro no tempo, a engenhosidade empregada para provar “tempo” foi feita de várias maneiras ao longo do últimos séculos.

Uma maneira de trivial muito utilizada para comprovar a data de um documento é o carimbo, amplamente utilizado pelos correios, o carimbo apresenta em que foi carimbado, conferindo a entidade que fez o carimbo a confiança de utilizá-lo corretamente, no caso abaixo, os correios tem fé pública dada pelo estado para garantir a veracidade da data.

http://www.postal-reporter.com/blog/court-finds-date-usps-self-service-kiosk-label-not-postmark/

Este modelo de “timestamp” como é denominado em inglês continua sendo utilizado para provar documentos, dados e cartas atualmente. Inclusive um caso em Illinois, USA, ficou bastante conhecido quando uma corte americana deste estado não reconheceu um carimbo do serviço postal americano por que o carimbo foi feito em um kiosk self-service.

Outros modelos mais elaborados e menos vinculados a confiança existem, dentre eles um processo bem engenhoso para vincular a idéia de data através de publicações de jornais.

Um jornal é um documento público, com alta tiragem que é impresso (atualmente pouca coisa é impressa, mas no século 20 a grande maioria era impressa), e o mais importante: tem normalmente uma emissão diária. Assim, um dado ou um documento publicado em um jornal teria sua prova de existência facilmente provada, confiando-se apenas que um determinado jornal não emita cópias diferentes de seu jornal em um mesmo dia.

Mas como registrar uma informação privada em um jornal público?

Para isso é possível se utilizar de funções hashs e árvores de hashs que trazem a escalabilidade necessária para este tipo de situação.

OBS: maiores informações sobre funções hashs e árvores de hashs (merkle trees) podem ser encontradas neste artigo:

Então basicamente a idéia de publicar dados privados em um jornal é: gerar hash dos dados ou documentos, concatenar e fazer hash de hashs de forma a ter um hash final que é obrigatoriamente formado pelos hashs dos dados/documentos, sendo que quem tem a lista de operações de concatenação e de hashs geradas consegue provar que um documento ou dado existia na data da emissão do jornal.

Abaixo um exemplo de jornal com hash de dados gravado:

Registro no blockchain

Atualmente novas formas de registro de dados e documentos no tempo começaram a ser possíveis, utilizando-se para isso o blockchain.

OBS: Neste tópico trataremos exclusivamente do registro no blockchain do Bitcoin, utilizando-se para isso o Opentimestamps.

O blockchain permite um novo tipo de registro, que denominamos trusteless timestamp, e que diferentemente do trusted timestamp não depende da confiança em nenhuma instituição ou entidade para ser registrado ou validado. Lembre-se que dos casos que mencionamos anteriormente, quem registra obrigatoriamente tem que confiar cegamente nos correios ou no jornal, acreditando que eles vão carimbar a data certa ou publicar a informação correta no jornal.

Basicamente o registro no blockchain (do bitcoin) utiliza-se de funções hashs para comprimir e gravar dados de maneira privada e eficiente no OP_RETURN, um espaço que comporta até 80 bytes de dados.

No Tivea utilizamos o framework Opentimestamps, lançado inicialmente pelo Peter Todd, dev do Bicoin core para fazermos registro eficiente no blockchain do bitcoin.

O Opentimestamps se utiliza do OP_RETURN para gravar o root hash (ou merkle root) de uma merkle tree que é construído com todos os documentos ou arquivos enviados para ele até o lançamento da transação efetivamente no blockchain.

No Opentimestamps foram seguidos 3 pilares:

  • Confiança: possibilitar o registro em blockchain descentralizado sem uma autoridade certificadora.
  • Custo: ser escalável sem aumento de custos proporcionais, ou seja, quanto mais registros no blockchain menor o “custo por registro”
  • Conveniência: possibilitar que entidades externas possam validar independentemente o registro no blockchain, sem necessariamente ter que aguardar o registro propriamente dito no bloco.

O diferencial do Opentimestamps é que ele utiliza Merkle Trees, e assim como no protocolo do Bitcoin consegue garantir uma estrutura de hashs que possibilita a inclusão de centenas de milhares de documentos ou dados nos 80 bytes do OP_RETURN ao custo de uma única transação no blockchain.

A imagem acima mostra que é possível gerar uma merkle tree de dados (Da, Db, Dc, Dd) localmente através de agregação destes dados, e posteriormente (de período em período), lançar uma transação (Txd) para o blockchain do Bitcoin. Note que a partir da transação, o próprio protocolo do blockchain também se utiliza de Merkle Tree para agrupar as transações em uma mesma raiz (Merkle Root) de validação de um bloco.

Utilizando o Opentimestamps existem 4 funções básicas que podem ser realizadas:

  • Stamp: a função stamp, como o nome já diz, é a função que faz a requisição de registro de um documento ao server do opentimestamps, o retorno desta função é um arquivo com extensão .ots, que pode ser entendido como um recibo, ou prova de registro.
  • Upgrade: como o registro de um documento não acontece imediatamente, por causa do tempo do blockchain, mas também porque o opentimestamps faz a agregação de N documentos para poder escalar custo, o retorno .ots da função Stamp é PARCIAL, ou seja, somente após o registro efetivo no blockchain ele conterá todas as operações para que seja possível utilizar somente ele para validar/provar o registro no tempo. Para isso, a função Upgrade serve justamente para atualizar o arquivo binário de extensão .ots quando invocada.
  • Verify: a função Verify serve como uma forma automática de verificar o registro no blockchain para um determinado documento. Para isso ela necessita do próprio documento e do seu recibo (.ots). O retorno dela é um OK ou NOK com a atestação de registro no blockchain.
  • Info: a função Info funciona como um “tradutor” do arquivo .ots. O arquivo .ots é um arquivo binário, sem informações “human — readable” ou seja, sem entendimento com leitura por humanos, para que seja possível ler as informações contidas no .ots, é necessário invocar a função Info, que recebe o arquivo .ots e apresenta cada uma das operações realizadas no documento/dado até seu registro no blockchain.

Exemplo de registro utilizando Opentimestamps

Abaixo apresentamos um resumo de operações para registrar o documento de hash = 5f5bdf028bb8092e2c1b42007d12148324723384a52b39ad53b1a7b6c48b43e9

Primeiramente o hash do documento recebe a concatenação de outro hash (provavelmente outro hash de outro documento), posteriormente os hashs concatenados, são novamente passados por uma função hash (aqui no exemplo sempre apresentado com a função SHA256, um tipo de função hash). E assim subsequentemente novas concatenações e novos hashs são realizados.

Em um determinado momento, o opentimestamps server, que detém a árvore de hashs para ser gravado no blockchain, emite uma transação para o blockchain que tem basicamente a Merkle Root da árvore e paga a fee (taxa) para ser processada pelos mineradores.

Após a transação ser realizada, é possível notar o mesmo processo de concatenação de hashs (agora de transações do próprio blockchain) junto com operações de duplo hash SHA256 (que é o padrão do blockchain do bitcoin), até que ao final é apresentado o número do bloco e a Merkle Root do bloco de blockchain onde está processada (e atestada) a transação, e nesta transação pode ser verificado o merkle root da árvore construída pelo opentimestamps.

Note que o o último hash antes da transação ser realizada

32c0d78a01b6bde4204e5544afdac6428d18e3f3fe3aee6e13dd97adcfb2bb5b

é o mesmo valor se consultarmos o RETURN PUSHDATA(32) da transação no block explorer.

Isso prova que todas as operações realizadas, levaram ao hash que está na transação e que a transação está processada no bloco = 544398, processado as 2018–10–04 20:45:17.

Finalmente temos a prova de que o arquivo de hash:

5f5bdf028bb8092e2c1b42007d12148324723384a52b39ad53b1a7b6c48b43e9

Existia na data 2018–10–04 20:45:17.

OBS: O arquivo .ots completo utilizado para este exemplo pode ser encontrado aqui.

--

--