# Verificadores da Stickybit

Dois programas pequenos para conferir, na sua máquina, o que a Stickybit afirma sobre um dado.
Nenhum deles precisa de rede, conta ou chave secreta. Você não precisa confiar na gente: precisa
ler cerca de 900 linhas de código e rodar.

| Programa | Confere | Linguagem |
|---|---|---|
| `tube/` → `tube-verifica` | que um pacote TUBE comprimido é íntegro, que o índice embarcado não mente e que cada valor está a no máximo ε do original | Go, sem dependências |
| `girder/verifica.py` | que um razão GIRDER é uma cadeia assinada sem buracos, que o checkpoint assina exatamente aquele histórico e que um arquivo qualquer foi selado nele | Python + `cryptography` |

## Rodar tudo em um comando

```sh
pip install cryptography          # só para o razão
./verifica-tudo.sh --site         # Go ≥ 1.22
```

O script confere o corpus contra `SHA256SUMS`, regenera os dados sintéticos bit a bit, roda as
três provas em cada pacote e, com `--site`, baixa o razão público de
<https://stickybit.com.br/static/registro/> e confere que os cinco manifests do corpus estão
selados nele, com a chave fixada no próprio script.

## tube-verifica

```sh
cd tube && go build -trimpath -o ../tube-verifica . && cd ..
./tube-verifica corpus/sintetico-degrau-eps0.5.manifest.json corpus/sintetico-degrau.csv
```

Três provas, nesta ordem:

1. **Integridade.** O SHA-256 do fluxo e do índice bate com o manifest.
2. **Índice honesto.** O verificador decodifica o fluxo, reconstrói do zero o índice de mínimos
   e máximos por bloco e compara com o índice embarcado, byte a byte. Um índice que mente faria
   uma consulta como "houve valor acima de 430?" responder errado sem abrir o fluxo.
3. **Tolerância cumprida.** Com os originais em mãos, `max|original − reconstruído| ≤ ε`.
   Sem os originais, essa prova fica de fora e o programa diz isso.

Saída 0 é `VERIFICADO`, ou `VERIFICADO SÓ COERÊNCIA` quando faltaram os originais; 1 é
`FALHOU`, com a prova que falhou. "Só coerência" quer dizer que o pacote bate com o próprio
manifest, e nada além disso: nesse caso, confira o manifest no razão (abaixo).

## girder/verifica.py

```sh
python3 girder/verifica.py PASTA --chave e49648c5f81df74928259a016d5459dd2ca9bd07c1196ece89ab01fecebaa3a8 \
        --manifesto corpus/*.manifest.json
```

`PASTA` tem `ledger.jsonl`, `girder.pub` e `checkpoint.note`. O programa confere:

1. cada entrada: numeração contínua, encadeada na anterior, hash do conteúdo canônico e assinatura Ed25519;
2. cada manifesto diário em `PASTA/dias/`, se houver, contra o hash selado;
3. o checkpoint: raiz de Merkle (RFC 9162) sobre as entradas e assinatura no formato C2SP signed-note;
4. com `--manifesto`, que o SHA-256 de cada arquivo dado está selado numa entrada coberta pelo checkpoint.
5. com `--testemunha VKEY` e `--quorum K`, que pelo menos K testemunhas cossinaram o checkpoint
   (c2sp.org/tlog-cosignature, Ed25519). Uma cossignatura diz que a testemunha viu essa cabeça
   consistente com tudo o que já tinha visto do log, e é o que tira o razão da classe G1.

É uma reimplementação independente, em outra linguagem, do que o GIRDER (Go, fechado) grava.

## O que um VERIFICADO não prova

Medido neste repositório, não suposto:

- **Sem originais e sem âncora, o pacote só prova coerência consigo mesmo.** Trocamos um bit
  aleatório do fluxo 3.000 vezes e reescrevemos o manifest para o hash bater. Em 4,1% dos casos
  a série muda e o índice continua igual, e o pacote passa nas provas 1 e 2. Quem fecha essa
  porta é o `--manifesto` no razão: o manifest forjado não está selado.
- **A codificação é maleável.** Em 0,5% das trocas, bytes diferentes decodificam a mesma série,
  idêntica. A identidade do pacote é o SHA-256, não o conteúdo.
- **O verificador TUBE não é independente do codificador.** Ele é o decodificador da própria
  Stickybit, extraído. Um erro compartilhado pelos dois passaria nos dois. O de razão é
  independente; o de TUBE ainda não tem segunda implementação.
- **A chave vem de algum lugar.** Sem `--chave`, ela é lida da mesma pasta que se confere, e quem
  troca a pasta troca a chave. Pegue a chave por outro canal: ela está aqui, no script e na
  página do registro.
- **O razão hoje é G1.** Ele é assinado pelo próprio autor e ainda não tem testemunha externa.
  O GIRDER já fala o protocolo de testemunha da rede pública (c2sp.org/tlog-witness); falta uma
  testemunha de terceiros aceitar o log.
  Os checkpoints são carimbados no Bitcoin via OpenTimestamps (arquivos `.ots` no registro),
  o que data o histórico mas não impede o autor de manter dois.
- **ε é o que o manifest declara.** O verificador confere que a tolerância foi cumprida, não que
  ela é a certa para a sua norma. Essa pergunta é sua.

## Entrada hostil

O decodificador roda sob limites: nenhum laço sem teto, nenhuma leitura além do bloco,
número de amostras limitado pelo tamanho do fluxo. Qualquer byte forjado vira `FALHOU` com motivo,
nunca trava ou pânico. Coberto por `go test` (3.000 adulterações) e por um alvo de fuzzing:

```sh
cd tube && go test . && go test -run X -fuzz FuzzDecodifica -fuzztime 60s .
```

## Corpus

| Arquivo | Origem | Amostras |
|---|---|---|
| `noaa-co2-mlo-horario.csv` | CO₂ horário in situ de Mauna Loa, NOAA GML, horas válidas (valor > 0), domínio público | 412.519 |
| `sintetico-seno-ruido.csv` | seno + ruído gaussiano, semente 20261013 | 20.000 |
| `sintetico-degrau.csv` | degraus com ruído alternado | 18.000 |
| `sintetico-constante.csv` | constante 42 | 6.000 |

`corpus/gera.py` regenera os sintéticos e, com `--noaa`, baixa a série atual da NOAA e diz se o
retrato daqui é prefixo exato dela (era, em 2026-10-12).

Os pacotes foram gerados com o codificador fechado da Stickybit. Os cinco manifests estão selados
nas entradas 2 a 6 do razão público, checkpoint 7.

## Versões

Cada versão publicada tem o SHA-256 do tarball selado no razão público.

| Versão | Entrada no razão | Mudança |
|---|---|---|
| v1 | 7 | primeira publicação |
| v1.1 | 8 | sem originais, o veredito passa a dizer "só coerência" e aponta a âncora; a linha de falha da tolerância mostra `>` em vez de `≤` |
| v1.2 | 9 | o verificador do razão aceita a origem de rede `stickybit.com.br/registro` e confere cossignaturas de testemunhas (`--testemunha VKEY --quorum K`, Ed25519 cosignature/v1) |

## Licença

MIT. Veja `LICENSE`.
