Abraxas
ÚltimoDecreto N° 1.104 · híbrido AND · alcaldia → secretaria

Oráculo ZK · IdViva · groth16 / BN128 · 269 R1CS

Probar sin mostrar el expediente.

El testigo (RUN, nacimiento, cédula, comuna) queda en el dispositivo. El libro solo recibe π, el merkle root del padrón, el nullifier y ok=1. Groth16 real: e(A,B) = e(α,β) · e(IC,γ) · e(C,δ). Un predicado falso no produce prueba: el circuito es insatisfactible.

Persona natural identificada, mayor de edad, cédula al día. DAF, DOM e IdentityRegistry.

Testigo privado

Visible solo en esta sesión de prueba. Epoch 2026-08-24.

Nacimiento
1994-03-12
Cédula expira
2030-08-14
Comuna
05899 Las Encinas
Defunción
0

Constraints

269 constraints
  • Pertenencia
    MerkleVerify(Poseidon(run, sk), root)
    —
  • Con vida
    deathDate == 0
    —
  • Mayor de edad
    epoch - dob >= 18 años
    —
  • Cédula vigente
    cedulaExp >= epoch
    —
Artefacto π · groth16 bn254

IdVivaYVigente

16.***.***-4 · did:abraxas:encinas:9f3c2a

pairing ok
π.A
0x9d0b9088581e…adff
π.C
0x4b57f633ad74…ba32
nullifier
d9e55c998c14…8f9c
merkleRoot
d5249c37d30d…8ebf

Señales públicas: ok=1 · epoch=2026-08-24 · vk=vk:bn128:idviva:e6bfc8e4 · didCommit 4d011190…1716

Circuito

pragma circom 2.1.6;
include "poseidon.circom";

template IdViva() {
  signal input alive;
  signal input adult;
  signal input cedula;
  signal input membership;
  signal input sk;
  signal input stmt;
  signal input ok;
  signal output nullifier;

  alive * (alive - 1) === 0;
  adult * (adult - 1) === 0;
  cedula * (cedula - 1) === 0;
  membership * (membership - 1) === 0;
  ok * (ok - 1) === 0;

  signal a <== alive * adult;
  signal b <== cedula * membership;
  a * b === ok;

  component h = Poseidon(3);
  h.inputs[0] <== sk;
  h.inputs[1] <== stmt;
  h.inputs[2] <== ok;
  nullifier <== h.out;
}

component main {public [stmt, ok]} = IdViva();

Padrón root d5249c37d3…8ebf · 269 R1CS · wasm IdViva

Groth16

CRS de dos fases (powers of tau n=10 + zkey de Secretaría). El prover calcula A ∈ G₁, B ∈ G₂, C ∈ G₁. El verificador no ve el testigo: comprueba el pairing.

e(A,B) = e(α,β) · e(IC,γ) · e(C,δ)

  1. El dispositivo extrae bits del credencial SRCeI. El RUN no es input.
  2. Circom fuerza booleanos y AND. Poseidon(sk, stmt, ok) → nullifier.
  3. ok y stmt son públicos. Si AND ≠ ok, Assert Failed: no hay π.
  4. verifyGroth16 lee la vk. Replay: el nullifier se gasta en el epoch.

Hechos ZK en el libro

Sin RUN, sin nombre, sin certificado.

  • ProofVerified DefuncionInscrita
    regcivil → aseo · ok=1. Habilita cupo de cementerio. Certificado off-chain.
    zk
  • ProofVerified ConductorHabilitado
    regcivil → transito · CirculationOracle recibe ok=1. Sin cédula ni RUN en claro.
    zk
  • ProofVerified IdVivaYVigente
    regcivil → ciudadano · ok=1 · groth16 bn254. Nullifier gastado. RUN no viaja.
    zk