Todos os posts

11 min de leitura

Um registro para milhares de arquivos: agrupamento Merkle

Uma raiz Merkle permite que um único registro Label 309 se comprometa com milhares ou milhões de hashes de arquivos e, mais tarde, prove qualquer item isolado com uma pequena prova de inclusão — sem colocar cada item na cadeia.

Um único registro Label 309 pode provar que milhares ou milhões de arquivos existiam em um determinado momento.

Em vez de publicar uma transação de blockchain por arquivo, você calcula o hash de cada arquivo, dobra esses hashes em uma árvore Merkle e publica uma única raiz Merkle de 32 bytes. Depois, você consegue provar que qualquer arquivo fazia parte daquele lote com uma pequena prova de inclusão — sem revelar o restante e sem colocar cada item na cadeia.

É assim que a Proof of Existence (prova de existência) escala de um documento para um conjunto arbitrariamente grande.

Que problema o agrupamento Merkle resolve?

Blockchains são lugares ruins para guardar listas longas. Cada byte custa uma taxa, e uma transação Cardano tem um teto rígido de tamanho.

Se um sistema gera um fluxo contínuo de artefatos — logs, saídas de modelos, builds de lançamento, faturas, relatórios, entradas de evidências —, publicar cada hash como seu próprio registro na cadeia fica caro e ruidoso muito rápido.

O agrupamento Merkle comprime uma lista ordenada de hashes em um único compromisso de raiz. A raiz tem tamanho fixo (32 bytes), o lote pode ser ilimitado, e a prova de qualquer item isolado permanece pequena — ela cresce apenas com o logaritmo do tamanho do lote. Isso torna compromissos regulares viáveis para fluxos de trabalho de alto volume.

O que é uma raiz Merkle?

Uma raiz Merkle é um único hash que se compromete com toda uma lista ordenada.

Comece com uma lista de folhas. Em um fluxo de trabalho de Proof of Existence, cada folha costuma ser o hash de um arquivo, de um evento ou de uma entrada de manifesto. As folhas são combinadas aos pares, subindo por uma árvore binária, e o hash no topo é a raiz Merkle.

O compromisso é exato de três maneiras:

  • Se qualquer folha muda, a raiz muda.
  • Se a ordem das folhas muda, a raiz muda.
  • O compromisso também registra quantas folhas existem, de modo que uma lista de tamanho diferente não possa se passar pelo mesmo lote.

Publicar a raiz é como publicar uma impressão digital de toda a lista ordenada.

O que realmente vai para a cadeia?

Apenas a raiz. A lista completa de folhas permanece fora da cadeia.

Um registro Label 309 carrega o compromisso em um campo merkle dedicado, separado dos hashes comuns por arquivo. Cada compromisso é uma estrutura pequena e fixa:

  • o algoritmo do compromisso (o Label 309 v1 registra rfc9162-sha256: o Merkle Tree Hash do RFC 9162 com SHA-256);
  • a raiz de 32 bytes;
  • a contagem de folhas, que vincula a raiz ao tamanho da lista fora da cadeia;
  • URIs opcionais endereçadas por conteúdo (ar:// ou ipfs://) apontando para o arquivo da lista de folhas.

O registro na cadeia permanece minúsculo — uma única raiz se compromete com uma lista ilimitada a um custo fixo de 32 bytes. O detalhe vive fora da cadeia, na lista ordenada de folhas. (Para saber onde mora o restante de um registro, veja o que vai para a blockchain.)

Como você prova um arquivo depois?

Você produz uma prova de inclusão.

Uma prova de inclusão é a curta lista de hashes irmãos ao longo do caminho de uma folha até a raiz. Um verificador dobra a folha e esses irmãos de volta, subindo pela árvore, e aceita a prova somente se a raiz recalculada for exatamente igual à raiz publicada.

Na prática, a verificação tem quatro entradas:

  1. o hash do arquivo ou item que você está provando;
  2. a prova de inclusão (o caminho dos irmãos);
  3. a raiz Merkle no registro Label 309;
  4. o tempo de bloco Cardano da transação que a carregou.

Se a dobra reproduz a raiz publicada, o item estava na lista comprometida — e o tempo de bloco testemunha quando essa lista existiu. O verificador precisa do item isolado e de sua prova; ele nunca precisa dos outros arquivos do lote.

Vale manter dois detalhes claros. A construção é sensível à ordem, então as folhas devem ser mantidas na mesma sequência em que foram publicadas. E uma "árvore" de folha única não é um carimbo de tempo útil: a raiz de uma árvore de uma folha não é a própria folha, então, para provar um único arquivo, você publica um hash de conteúdo simples, não um compromisso Merkle de um item.

Por que construir e verificar totalmente offline é um ponto forte?

Porque o único passo que toca um servidor é publicar a raiz.

Construir a árvore, derivar provas de inclusão e verificá-las são pura computação. Qualquer pessoa que tenha a lista ordenada de folhas pode recalcular a raiz e voltar a derivar qualquer prova — sem conta, sem gateway, sem rede e sem cooperação de quem originalmente publicou. Quem publica nunca está envolvido no momento da verificação.

Isso importa para evidências que precisam sobreviver a ferramentas e fornecedores. Uma prova que você consegue verificar offline contra um explorador público de Cardano continua funcionando muito depois de qualquer serviço específico ter desaparecido. Você pode verificar um compromisso de lote do mesmo jeito que verificaria qualquer registro Label 309, e pode ligar a verificação de inclusão diretamente ao CI com a ferramenta de linha de comando de código aberto cardanowall (merkle-build para dobrar uma pasta em uma raiz, merkle-verify para confirmar que um item pertence a ela).

Por que isso é útil para fluxos de trabalho de alto volume?

Porque muitas provas reais têm formato de lote, não de arquivo único. Uma equipe pode precisar mostrar:

  • o que um pipeline de CI/CD construiu e quais artefatos foram entregues em um lançamento;
  • qual software bill of materials (SBOM) existia antes de uma vulnerabilidade ser divulgada;
  • quais saídas de IA foram produzidas em um determinado dia;
  • qual instantâneo do conjunto de dados existia antes de uma execução de treinamento;
  • quais logs de conformidade existiam antes de uma auditoria;
  • quais arquivos de provas jurídicas foram preservados antes de uma ordem de retenção;
  • quais reservas um balanço patrimonial registrou em um determinado momento.

Nenhum desses casos se encaixa bem em um modelo de um arquivo por transação. O agrupamento Merkle permite que você publique um único compromisso por lote — sem expor cada item privado e sem metadados na cadeia que crescem linearmente com o tamanho do lote.

A lista de folhas pode permanecer privada?

Sim. A raiz publicada não revela nada sobre as folhas com as quais se compromete.

Você pode manter a lista de folhas dentro do seu próprio sistema de evidências, arquivo de lançamento, sala de dados ou repositório de conformidade e, mais tarde, revelar apenas o que precisar:

  • um arquivo e sua prova de inclusão;
  • uma linha de conjunto de dados, um documento ou um artefato de lançamento;
  • uma entrada de log de auditoria;
  • um subconjunto da lista;
  • ou a lista de folhas inteira.

Esse é o padrão para quando você quer um compromisso público e com carimbo de tempo sem tornar públicos os dados subjacentes — algo intimamente ligado à divulgação confidencial sem arquivos públicos e à prova de reservas com raízes Merkle.

A contrapartida é responsabilidade. Uma raiz prova que alguma lista de tamanho conhecido existiu em um momento conhecido; ela não permite, por si só, que alguém prove quais itens específicos estavam nela. Se você mantém a lista de folhas privada, precisa preservá-la. Perca tanto a lista de folhas quanto qualquer prova de inclusão salva, e você fica com o carimbo de tempo, mas perde a capacidade de provar que um item específico foi comprometido.

O que uma folha deve ser?

Uma folha deve representar exatamente aquilo que você talvez precise provar depois.

Para arquivos, a folha é o hash dos bytes do arquivo. Para dados estruturados, costuma ser o hash de uma entrada de manifesto canônica. Para CI/CD, uma folha pode ser um digest de artefato, um digest de SBOM, um digest de log de build, uma referência de commit ou uma entrada de manifesto de lançamento assinada. Para proveniência de IA, uma folha pode ser um hash de arquivo de saída, uma entrada de manifesto de prompt/saída, um compromisso de item de conjunto de dados ou um hash de manifesto de proveniência de conteúdo.

A disciplina que importa é a consistência. Se as folhas forem geradas de maneiras diferentes ao longo das execuções, fica difícil confiar nas provas de inclusão posteriores. Fixe a definição da folha e a canonicalização uma vez e aplique-as do mesmo jeito sempre.

Você deve publicar a lista de folhas ou mantê-la privada?

Depende do que você está provando e de quem deve ver.

Publicar a lista de folhas torna a verificação por terceiros trivial: qualquer pessoa pode buscar a lista, recalcular a raiz e inspecionar o conjunto comprometido. Mantê-la privada lhe dá confidencialidade e divulgação seletiva — você revela provas de inclusão apenas quando necessário. Muitos fluxos de trabalho fazem as duas coisas: uma lista de folhas pública para lançamentos de código aberto, uma privada para logs de conformidade internos, uma selada para evidências sensíveis.

A raiz é o compromisso público. A política da lista de folhas é uma escolha à parte, feita por cima dele.

Com que frequência você deve publicar raízes?

Ajuste a cadência ao fluxo de trabalho.

Um sistema de CI/CD pode publicar uma raiz por lançamento, build ou janela de implantação. Um sistema de conformidade pode publicar uma raiz por hora, por dia ou por período de controle. Uma plataforma de IA pode publicar raízes por lote de conteúdo gerado, por instantâneo de treinamento ou por evento de versão de modelo. Um sistema de provas jurídicas pode publicar uma raiz por pacote de caso, janela de entrada ou marco de cadeia de custódia.

A cadência certa equilibra custo, simplicidade operacional e quão precisa é a linha do tempo que você pode precisar provar depois.

O que uma raiz Merkle não prova?

Uma raiz Merkle prova o compromisso com uma lista em um determinado momento. Ela não prova as afirmações de negócio construídas em torno dessa lista. Como qualquer Proof of Existence, ela mostra que bytes específicos existiam até um tempo público — não que sejam verdadeiros, lícitos, de autoria de alguém em particular ou de propriedade de alguém (veja o que uma prova não prova).

Concretamente:

  • Ela não prova que um build de software era seguro. Pode provar quais artefatos ou manifestos foram incluídos em um lançamento.
  • Ela não prova que um conjunto de dados foi coletado de forma lícita. Pode provar que um compromisso de conjunto de dados existia antes de um determinado tempo.
  • Ela não prova que uma entrada de log é verdadeira. Pode provar que a entrada fazia parte de um lote comprometido.
  • Ela não prova autoria — a menos que o registro ou o processo ao redor acrescente assinaturas e controles de identidade.

No Label 309, a autoria é opcional e explícita: um registro pode carregar assinaturas destacadas, mas elas nunca são obrigatórias, e um compromisso Merkle por si só não faz nenhuma afirmação sobre quem produziu a lista. A raiz dá o compromisso com carimbo de tempo; o processo em torno dela dá o significado de negócio.

Como o Label 309 se encaixa?

O Label 309 é o padrão aberto e neutro quanto ao fornecedor para Proof of Existence em Cardano; ele foi submetido ao processo de CIP da Cardano e está em análise pelos editores de CIP como uma proposta da categoria Metadata. O agrupamento Merkle não é um produto separado — é a camada de escala embutida no padrão.

Um compromisso de lote usa o mesmo registro e o mesmo caminho de verificação que uma prova de arquivo único. Um registro sob o rótulo de metadados 309 pode carregar uma raiz Merkle e, junto a ela, as mesmas peças opcionais que qualquer registro suporta: hashes comuns por arquivo, URIs de armazenamento endereçado por conteúdo, um ponteiro de substituição para um registro anterior e assinaturas de autoria. Assim, uma prova de lote herda tudo que uma prova única tem:

  • uma testemunha de tempo de bloco Cardano;
  • uma estrutura de registro padronizada e fechada;
  • verificação autônoma e offline contra um explorador público;
  • as mesmas ferramentas, bibliotecas e CLI de código aberto em todas as linguagens.

Calcule o hash de cada item, construa uma árvore Merkle ordenada, publique uma raiz em um registro Label 309 e guarde a lista de folhas e quaisquer provas de que você possa precisar. Depois, prove que qualquer item isolado fazia parte do lote comprometido — sem colocar cada item na cadeia. É isso que torna a Proof of Existence prática para CI/CD, proveniência de IA, conjuntos de dados, conformidade, provas jurídicas e outros fluxos de trabalho de alto volume.

Leitura adicional

merkleproof-of-existencelabel-309