JSON✯Atomic — o átomo criptográfico do Paper II: canonicalização rigorosa (Same Semantics = Same Bytes = Same Hash), CID BLAKE3, e DV25-Seal (Ed25519) para Signed Facts imutáveis e verificáveis.
Projeto irmão:
logline-core— o átomo conceitual (Paper I). Aqui, qualquer valorSerializevira bytes canônicos, que viram CID e então um selo Ed25519.
[dependencies]
json_atomic = "0.1.0"
# Integração opcional (recomendada)
logline-core = { version = "0.1.0", features = ["serde"] }std(default): experiência completa para dev (tests/examples/benches).alloc: habilita build no_std com alocação.unicode: normalização NFC (aloc-only). Recomendado para confluência semântica de strings.
use ed25519_dalek::{SigningKey, Signer};
use json_atomic::{seal_value, verify_seal, SignedFact};
use serde::Serialize;
#[derive(Serialize)]
struct Note { title: String, done: bool }
fn main() {
// chave de demo — em produção, derive de seed/keystore
let sk = SigningKey::generate(&mut rand::rngs::OsRng);
let n = Note { title: "Hello, Canon!".into(), done: false };
// 1) Canonize + hash + seal → SignedFact
let fact: SignedFact = seal_value(&n, &sk).expect("sealed");
// 2) Verificar
verify_seal(&fact).expect("valid");
// 3) CID hex (BLAKE3)
println!("cid={}", fact.cid_hex());
}use ed25519_dalek::SigningKey;
use json_atomic::{seal_logline, verify_seal};
use logline_core::{LogLine, Verb, Payload};
fn seal_entire_logline(line: &LogLine, sk: &SigningKey) {
let fact = seal_logline(line, sk).expect("sealed");
verify_seal(&fact).expect("valid");
}- Objetos → chaves ordenadas lexicograficamente (ordem estável).
- Strings → Unicode NFC (se
feature = "unicode"). - Números → inteiros em forma mínima (sem
+, sem zeros à esquerda).float→ erro. - Boolean / null → preservados.
- Arrays → ordem preservada (sem reordenação).
- Whitespace → nenhum fora de strings; encoding estável.
- Cycle of Truth →
canonize(value)→CID := BLAKE3(bytes)→seal := Ed25519.sign(CID). - Verify → recalcula canônico + CID e verifica a assinatura estrita.
- Headers mínimos em
SignedFact:canon_ver = "1",format_id = "json-atomic/1"hash_alg = "blake3",sig_alg = "ed25519"
Objetivo: Same Semantics = Same Bytes = Same Hash. Qualquer representação JSON semanticamente igual deve resultar na mesma sequência de bytes canônicos e, portanto, no mesmo CID.
📖 Especificação completa: docs/paper-ii-json-atomic.md (mantenha versionado; excluído do publish)
fn canonize<T: serde::Serialize>(value: &T) -> Result<Vec<u8>, CanonicalError>;
fn seal_value<T: serde::Serialize>(value: &T, sk: &SigningKey) -> Result<SignedFact, SealError>;
fn verify_seal(fact: &SignedFact) -> Result<(), VerifyError>;
fn seal_logline(line: &logline_core::LogLine, sk: &SigningKey) -> Result<SignedFact, SealError>;pub struct SignedFact {
pub canonical: Vec<u8>, // bytes canônicos (JSON✯Atomic)
pub cid: [u8; 32], // BLAKE3(canonical)
pub signature: [u8; 64], // Ed25519.sign(CID)
pub public_key: [u8; 32], // Ed25519 pk
pub hash_alg: &'static str, // "blake3"
pub sig_alg: &'static str, // "ed25519"
pub canon_ver: &'static str, // "1"
pub format_id: &'static str, // "json-atomic/1"
}Build sem std, apenas com alloc:
cargo build --no-default-features --features alloc
cargo build --no-default-features --features "alloc,unicode"Observação:
tests/examples/benchesusamstd. Em CI, compilamos a lib no modoallocpara garantir compatibilidade.
- Assinatura Ed25519 é feita sobre o CID (BLAKE3 dos bytes canônicos), nunca sobre JSON bruto.
- Mude o
SigningKey/VerifyingKeyconforme sua HSM/keystore. - Persistir somente o SignedFact já garante recomputação independente e verificação de integridade.
cargo fmt --all && cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features
cargo bench --no-runInclui testes de canto:
- Strings em NFC (decomposed vs composed → iguais no canônico)
- Inteiros com zeros à esquerda (como string vs inteiro → diferentes)
- Objetos aninhados com chaves em ordem diferente (canônico → igual)
- Veja o CHANGELOG.md e a seção [Unreleased].
- Planejamento inclui: cabeçalhos canônicos estendidos (content-type + schema-hash), Merkle chunking para documentos grandes e vetores determinísticos
no_std.
MIT — veja LICENSE.
Parte do ecossistema LogLine / JSON✯Atomic — verifiable, privacy-first intelligence.