Metodologia: como um sorteio pode ser verificado por qualquer pessoa
Resumo: um sorteio é verificável quando a lista é fixada antes de a aleatoriedade existir, o número aleatório vem de uma fonte pública e o cálculo é determinístico e aberto. Assim, qualquer pessoa refaz o sorteio depois e chega ao mesmo resultado.
Versão: o sorteio aplica este
método (sorteio-v1) no seu navegador. O certificado acrescenta
carimbos do tempo emitidos por autoridades independentes e a página pública
de conferência.
Qual é o problema dos sorteios comuns?
Em um sorteador comum, o resultado sai de um número aleatório gerado no computador de quem opera a ferramenta. Você precisa acreditar que ninguém mexeu na lista, que o sorteio não foi repetido até sair o resultado desejado e que o algoritmo faz o que diz. Depois do evento, não há como conferir nada.
Uma planilha com a função de número aleatório tem o mesmo problema, e ainda um agravante: a função recalcula a cada alteração, então o resultado que estava na tela some.
Como funciona o método, passo a passo?
1. A lista é normalizada e recebe um hash
A lista é padronizada (codificação UTF-8, normalização Unicode, espaços aparados, linhas vazias removidas) e a ordem original é preservada. Depois se calcula o hash SHA-256 dela. O hash funciona como uma impressão digital: qualquer mudança, mesmo de uma letra, produz um hash completamente diferente. As regras do sorteio (quantos sorteados, suplentes, tratamento de repetidos) também recebem um hash.
2. A lista é fixada antes de o número existir (compromisso)
No sorteio com certificado, o registro tem dois momentos. Ao confirmar, os hashes da lista e das regras recebem um carimbo do tempo (padrão RFC 3161) de duas autoridades independentes: a “trava”. Quando a pessoa clica em “Realizar sorteio”, o sistema escolhe uma rodada futura da rede de aleatoriedade pública e registra um compromisso com os hashes da lista, das regras e dessa rodada, que também é carimbado. O segundo carimbo prova que a rodada foi escolhida antes de ser publicada; o primeiro prova desde quando a lista e as regras estavam fixadas.
3. O número aleatório vem de uma rede pública
O drand é uma rede distribuída, operada por várias organizações independentes, que publica a cada poucos segundos um número aleatório acompanhado de uma assinatura criptográfica. Como o número da rodada escolhida ainda não existia no momento do compromisso, nem o operador do sorteio nem quem forneceu a lista conseguem prevê-lo ou escolhê-lo.
4. O resultado sai de um cálculo determinístico
A semente do sorteio é derivada dos três ingredientes:
semente = SHA-256("sorteio-v1\n" + número_público + "\n" + hash_da_lista + "\n" + hash_das_regras)
Com essa semente, a lista é embaralhada pelo método de Fisher-Yates, usando amostragem por rejeição para evitar viés no sorteio de posições. Os sorteados são as primeiras posições; os suplentes, as seguintes. Como não há nenhuma escolha humana nem número gerado localmente, o cálculo é reproduzível.
5. Qualquer pessoa pode verificar
Um verificador independente, de código aberto, confere:
- se a lista informada corresponde ao hash registrado;
- se a assinatura do número da rodada é válida e a rodada é posterior ao carimbo do tempo;
- se os carimbos do tempo são válidos para a trava e para o compromisso;
- se o cálculo refeito produz o mesmo resultado.
Você pode fazer isso na página de verificação, que roda no seu navegador, ou pela linha de comando. O verificador também funciona sem consultar a nossa plataforma: a assinatura do drand é conferida com a chave pública da rede.
Qual é a especificação exata da versão sorteio-v1?
Para que qualquer pessoa implemente a verificação por conta própria, estes são os detalhes que definem o resultado:
- Lista: uma entrada por linha; cada item em Unicode NFC e sem espaços nas pontas; linhas vazias descartadas; a ordem original é preservada. Se a regra for "remover repetidos", fica só a primeira ocorrência de cada item (comparação sem diferenciar maiúsculas de minúsculas).
-
Hash da lista: SHA-256 do texto JSON do array de itens
(por exemplo
["Ana","Bruno"], sem espaços), codificado em UTF-8, em hexadecimal minúsculo. -
Hash das regras: SHA-256 do texto JSON do objeto
{"algoritmo","modo","sorteados","suplentes","duplicados"}, nesta ordem de chaves, sem espaços. -
Número público: o campo
randomnessda rodada do drand (redequicknet), que é o SHA-256 da assinatura da rodada. A assinatura (BLS12-381) é verificada contra a chave pública da rede. - Semente: a fórmula acima, com os três valores em hexadecimal minúsculo e a codificação UTF-8.
- Fluxo pseudoaleatório: o bloco de índice i é SHA-256(semente ‖ i em 4 bytes big-endian); cada bloco rende oito inteiros de 32 bits (big-endian), consumidos em ordem.
-
Inteiro em [0, n): amostragem por rejeição: descarta
valores iguais ou maiores que
⌊2³² / n⌋ × ne usa o resto da divisão por n. - Embaralhamento: Fisher-Yates com i de n−1 até 1, trocando a posição i com uma posição j sorteada em [0, i]. Sorteados são as primeiras posições; suplentes, as seguintes.
Uma implementação de referência independente (em Python, apenas com a biblioteca padrão) é conferida automaticamente contra a implementação do site em testes, e produz exatamente os mesmos resultados.
O que esse método prova e o que ele não prova?
Prova
- que a lista e as regras não foram alteradas depois do compromisso;
- que o resultado vem de uma fonte aleatória que ninguém controla;
- que o resultado pode ser refeito por terceiros;
- quando o compromisso foi registrado.
Não prova
- que a lista de entrada estava correta ou completa (um sorteio verificável sobre uma lista errada é fielmente errado);
- que o sorteio cumpre exigências legais ou formais do caso (ata, ato público exigido por edital, estatuto ou convenção, autorização de ações promocionais);
- quem assinou o documento: isso depende da assinatura que o responsável aplicar no PDF, por exemplo com o gov.br.
Perguntas frequentes sobre a metodologia
Por que travar a lista antes do sorteio?
Porque, se a lista pudesse mudar depois de o número aleatório ser conhecido, alguém poderia ajustá-la para favorecer um resultado. O hash e o carimbo do tempo provam que a lista já estava fixa quando o número foi gerado.
O que o carimbo do tempo prova?
Prova que um conjunto de dados (aqui, o compromisso com a lista) existia em determinado momento e não foi alterado depois. Ele não diz se a lista está correta, apenas quando ela foi fixada.
Dá para refazer o sorteio e chegar ao mesmo resultado?
Sim. O cálculo é determinístico: com a mesma lista, as mesmas regras, o mesmo número público e a mesma versão do algoritmo, o resultado é sempre o mesmo.
Glossário: termos usados nesta página
Definições curtas dos termos técnicos do método.
- Sorteio verificável
- Sorteio em que qualquer pessoa, depois do fato, consegue refazer o cálculo e chegar ao mesmo resultado, e comprovar que a lista foi fixada antes de a fonte de aleatoriedade existir.
- Hash
- Resultado de uma função que transforma qualquer conjunto de dados em um código curto de tamanho fixo. Funciona como uma impressão digital: mudar um único caractere dos dados muda completamente o hash.
- SHA-256
- Função de hash amplamente usada e considerada segura, que produz um código de 256 bits. É a usada pelo método do Sorteio Verificável.
- Compromisso (commit)
- Registro, feito antes de um evento, de dados que não poderão mais ser alterados. No sorteio, o compromisso reúne os hashes da lista e das regras e a rodada escolhida da rede de aleatoriedade.
- Carimbo do tempo
- Prova emitida por uma autoridade independente de que determinados dados existiam em um momento específico e não foram alterados desde então. O padrão técnico mais usado é o RFC 3161.
- RFC 3161
- Padrão da internet para serviços de carimbo do tempo. Uma autoridade de carimbo assina digitalmente o hash dos dados junto com a data e a hora.
- drand
- Rede pública e distribuída que publica números aleatórios verificáveis a cada poucos segundos, operada por várias organizações independentes. Cada número vem com uma assinatura que qualquer pessoa pode conferir.
- Rodada
- Cada número aleatório publicado pelo drand corresponde a uma rodada numerada. O sorteio usa uma rodada futura, que ainda não existia quando a lista foi fixada.
- Semente (seed)
- Valor inicial a partir do qual o algoritmo calcula o resultado de forma determinística. Mesma semente e mesma lista produzem sempre o mesmo resultado.
- Embaralhamento de Fisher-Yates
- Algoritmo clássico para embaralhar uma lista de modo que todas as ordens possíveis sejam igualmente prováveis, quando alimentado por números aleatórios sem viés.
- Amostragem por rejeição
- Técnica que descarta valores aleatórios que causariam viés ao converter um número grande em uma posição da lista (viés de módulo), garantindo que todas as posições tenham a mesma chance.
- Verificador independente
- Programa de código aberto que refaz o cálculo do sorteio e confere hashes, assinaturas e carimbos sem depender da plataforma que realizou o sorteio.
- Ata
- Documento que registra formalmente o que ocorreu em uma reunião ou assembleia. O certificado de um sorteio pode ser anexado à ata como prova de apoio, mas não a substitui.
Para aplicar o método em situações reais, veja os guias.