PAN-RAP Municipio v0.5

Sistem pemungutan suara anonim dengan integritas kriptografis untuk tata kelola sipil municipal. Blind Schnorr di atas secp256k1, eligibility modular HMAC, siklus hidup convocatoria, dan pembuatan minutes PDF yang terverifikasi.

Apa itu

PAN-RAP (Planet Assembly Network / Red Asamblearia Planetaria) adalah ekosistem tata kelola sipil terdesentralisasi yang dirancang untuk municipalitas ~25.000 penduduk. Repo ini adalah implementasi referensi modul pemungutan suara anonim.

Stack:

  • Backend: Python 3.12+ / FastAPI / coincurve (libsecp256k1)
  • Frontend: JavaScript ES modules / @noble/curves vendored (tanpa CDN)
  • Kripto: Blind Schnorr di atas secp256k1 (token 65-byte)
  • DB: SQLite (WITHOUT ROWID pada kotak suara)
  • Lisensi: AGPL-3.0-or-later

Apa yang Diserahkan (Fase 5.5 Selesai)

Fitur Status Detail
Mesin Blind Schnorr ✅ Penerbit (coincurve) + Kotak Suara (verifikasi fail-closed) + Frontend (@noble/curves)
Eligibility Modular ✅ 4 mode: sensus (HMAC), tatap muka (kode sekali pakai), endorsement (K endorsement), eid (placeholder)
Siklus Hidup Convocatoria ✅ Transisi tervalidasi: draft → dijadwalkan → emisi → pemungutan → ditutup → diperiksa → diarsipkan
Pemeriksaan Publik ✅ GET /convocatorias/{id}/escrutinio dengan perhitungan, partisipasi, hash kotak suara
Unduh Kotak Suara Lengkap ✅ GET /convocatorias/{id}/urna suara diurutkan by r_prima
Minutes PDF ✅ POST /convocatorias/{id}/acta dengan reportlab, hanya di state diperiksa
Verifikator Independen ✅ scripts/verificador_independiente.py mengaudit kotak suara lengkap
Tests ✅ 10 passed (3 eligibility + 7 siklus hidup)

Apa yang BELUM Dilakukan

Fase Status Tertunda
Fase 6 ⏳ Audit kriptografis eksternal (Cure53, Trail of Bits, dll.)
Fase 7 ⏳ Deployment pilot di municipalitas nyata
Persistensi state memori ⏳ Kode tatap muka dan endorsement hilang saat restart server
Endpoint daftar convocatorias ⏳ GET /convocatorias publik untuk discovery
Mode eid lengkap ⏳ Integrasi OIDC / identitas digital nasional

Catatan transparansi: Proyek dalam Fase 5.5. Test lolos (10/10), mesin kripto diaudit internal, tapi belum ada audit eksternal. Belum cocok untuk penggunaan mengikat hingga Fase 6 selesai.

Cara Mencobanya

# 1. Clone dan setup git clone https://github.com/amurlaniakea/pan-rap-municipio.git cd pan-rap-municipio python3.12 -m venv .venv && source .venv/bin/activate pip install -r requirements.txt # include reportlab untuk minutes PDF # 2. Jalankan test pytest tests/ -v # → 10 passed # 3. Jalankan server export PANRAP_EMISOR_KEY_HEX="$(openssl rand -hex 32)" fastapi dev main.py # 4. Alur cepat (contoh mode sensus) curl -X POST http://localhost:8000/convocatorias \ -H "Content-Type: application/json" \ -d '{"titulo":"Test","texto":"...","opciones":["a_favor","en_contra"],"modo_elegibilidad":"padron","nivel_garantia":"alta","emision_abre_en":"2026-11-01T00:00:00","voto_abre_en":"2026-11-02T00:00:00","cierra_en":"2026-11-03T00:00:00"}' # → {"id": "uuid", "estado": "borrador"} curl -X POST http://localhost:8000/convocatorias/{id}/censo \ -H "Content-Type: application/json" \ -d '{"identificadores": ["dni_123"]}' curl -X PATCH http://localhost:8000/convocatorias/{id}/estado \ -H "Content-Type: application/json" \ -d '{"estado": "programada"}' curl -X PATCH http://localhost:8000/convocatorias/{id}/estado \ -H "Content-Type: application/json" \ -d '{"estado": "emision"}' # 5. Verifikasi kotak suara dan generate minutes python scripts/verificador_independiente.py # → VERIFIKASI BERHASIL: X suara valid, 0 invalid 

Arsitektur Keamanan (ringkasan)

  • S1 Emisi sequential: threading.Lock() + TTL 10s
  • S4 Nol aritmetika int pada secrets: hanya coincurve
  • S5 k efemer per session: PrivateKey() baru setiap inicio()
  • S6 Validasi fail-closed: urna_schnorr.verificar() tangkap exception
  • S7 Kunci di luar git: .gitignore cover clave_emisor.hex
  • S8 Client vendored: frontend/lib/ dengan @noble/curves (tanpa CDN)
  • Eligibility: persona_ref = HMAC-SHA256(secreto_convocatoria, convocatoria:identifikasi) — berbeda per convocatoria, non-linkable
  • Secret persisten: tersimpan di convocatorias.secreto_hmac, tidak pernah exposed di response HTTP

Referensi

Penulis: Pedro Sordo Martínez

Lisensi: AGPL-3.0-or-later