Registro pubblico
Ciò che ogni elezione rende pubblico, qualunque sia il mezzo che lo trasporta, e che cosa chiunque può verificarne senza fidarsi della piattaforma.
Il registro è la traccia verificabile dell’elezione. La piattaforma è una terza parte fidata al momento del voto; tutto ciò che ha fatto è poi controllabile dal solo registro pubblicato. Questa pagina ne descrive il contenuto, indipendentemente dal trasporto: la blockchain è solo uno dei modi di distribuirlo, quello che ne rende integrità e immutabilità controllabili da chiunque.
Protocollo v1
Cinque elementi, due lati non collegabili.
Una definizione e degli anelli, comuni a tutta l’elezione, poi due registri deliberatamente separati: il registro delle presenze dice chi ha partecipato, il registro delle schede dice che cosa è stato votato, con la sua prova crittografica e senza traccia di chi né di quando. Il risultato ne discende.
-
Contesto
Definizione dell’elezione
Titolo, organizzatore, tipo, seggi, candidati, regole della scheda e opzioni di privacy, congelati prima della prima scheda.
All’apertura · blocco configuration
-
Contesto
Anelli
L’elenco completo delle chiavi pubbliche autorizzate a firmare, anello per anello, con l’impronta di ciascun anello.
All’apertura, poi per anello di emergenza · blocchi rings
-
Lato presenze
Registro delle presenze
Una riga per elettore, sotto un identificativo casuale: ha votato o no, in quale anello, quante chiavi ricevute, quale peso. Pseudonimo per impostazione predefinita.
Alla chiusura, in un’unica istantanea · blocco closure
-
Lato schede
Schede firmate
Ogni scheda così come firmata, byte per byte, con la sua firma ad anello e la sua immagine di chiave, senza identità né timestamp.
Durante il voto, a lotti di almeno 600 · blocchi votes
-
Calcolo
Risultato pubblicato
La graduatoria ufficiale, con il metodo e le versioni di calcolo registrati, e le schede in formato CEF. Non è mai un blocco: si ricalcola.
Alla pubblicazione da parte dell’organizzatore · pagina dei risultati
-
Fuori dal registro
Mai pubblicato
I timestamp, l’ordine di arrivo, la corrispondenza tra identificativo e identità (salvo opzione nominativa), la presentazione estetica: logo, foto, messaggio di ringraziamento.
Né sulla pagina, né in un blocco
Ciò che è congelato prima della prima scheda.
La definizione è fissata al lancio dell’elezione; ogni anello lo è alla sua creazione. Né l’una né gli altri cambiano in seguito: ogni scheda si verifica rispetto alla definizione e all’anello pubblicati.
Definizione dell’elezione
-
protocol_versionintero - La versione del protocollo, oggi 1, legata all’elezione per sempre.
-
election_idUUID v4 - L’identificativo dell’elezione, ripreso in ogni scheda firmata e in ogni verifica di firma.
-
title, description?, organizer_namestringhe - Contesto informativo pubblicato in chiaro, mai un dato in ingresso dello scrutinio.
-
election_type, seatspreferential | fptp, intero ≥ 1 - Graduatoria o scelta unica; numero di seggi, quindi di candidati eletti in testa alla graduatoria.
-
candidates[].labelarray - Le etichette dei candidati, unico identificativo, ordinate per etichetta.
-
ballot_rulesoggetto - I parametri della scheda (parità, graduatoria parziale, scheda bianca, graduatoria completa), da cui i vincoli di scrutinio derivano secondo una regola documentata.
-
non_anonymous_voting, nominative_participation, weighted_votingbooleani - Le opzioni di privacy e di ponderazione, disattivate per impostazione predefinita. Il voto non anonimo impone il registro delle presenze nominativo.
-
max_ring_size, initial_electoral_roll_sizeinteri - Il tetto della dimensione degli anelli (oggi 600) e la dimensione della lista elettorale all’apertura.
Il dettaglio campo per campo, con voter_access_mode ed enrolment_mandatory, si trova nella specifica della blockchain. Il metodo Condorcet non fa parte della definizione: è pubblicato con il risultato.
Anelli
-
ring_idUUID - L’anello rispetto al quale una scheda è firmata; ogni scheda lo indica.
-
public_keys[]pk_<64 hex>_<8 hex> - Tutte le chiavi pubbliche dell’anello, uniche, ordinate in modo crescente, al massimo max_ring_size.
-
ring_digestring_<64 hex>_<8 hex> - L’impronta canonica dell’insieme dei membri, indipendente dall’ordine, ricalcolabile dalle chiavi.
L’anonimato di una scheda è esattamente l’anello sotto cui è firmata: una piattaforma che servisse a un elettore un anello diverso anche di un solo membro potrebbe riconoscerne la scheda. La pagina di voto calcola l’impronta dall’anello ricevuto (non la riceve mai dalla piattaforma), la mostra prima della firma e la scrive nella ricevuta; l’elettore la confronta con il valore pubblicato qui per tutti. È un rilevamento, non una prevenzione.
Un anello di emergenza, creato durante il voto se la lista cresce, è pubblicato alla sua creazione. Ogni anello si scarica in JSON dalla pagina del registro, con la sua impronta e le sue chiavi nello stesso ordine del suo blocco.
Chi ha partecipato, pubblicato una sola volta.
Il registro delle presenze è pubblicato in un’unica istantanea, nel blocco di chiusura, quando la lista è definitiva. Durante il voto la pagina del registro non ne mostra nulla: nessuna riga di partecipazione condivide una finestra di pubblicazione con una scheda.
Una riga per elettore
-
voter_idUUID v4 casuale - L’unico identificativo della riga; righe ordinate per voter_id. Identico in tutte le elezioni di uno stesso gruppo.
-
key_provisioning_modeserver_generated | organizer_imported | voter_enrolled - L’origine della chiave: generata dalla piattaforma, importata dall’organizzatore o portata dall’elettore.
-
has_votedbooleano - Ha votato o no.
-
ring_idUUID o null - L’anello in cui l’elettore ha votato, null se non ha votato: il legame elettore → anello del controllo per anello.
-
distribution_countintero ≥ 0 - Il numero di chiavi di voto distribuite: al massimo 3 per impostazione predefinita, di più solo se l’organizzatore le concede, il che resta visibile. Le singole distribuzioni non sono dettagliate.
-
weightintero ≥ 1 - Il peso (millesimi), sempre presente, 1 senza voto ponderato: il valore rispetto al quale si verifica il peso firmato nella scheda.
La lista di chiusura comprende gli elettori aggiunti durante il voto: la sua dimensione meno initial_electoral_roll_size ne dà il numero, mai quali. Il blocco di chiusura porta anche i totali: blocchi, schede, anelli, votanti, peso espresso.
Presenze nominative: un’opzione
Disattivata per impostazione predefinita, l’organizzatore può attivarla al lancio, informandone gli elettori; il voto non anonimo la impone. Solo le righe degli elettori che hanno votato ricevono allora due campi in più.
-
voter_namestringa - Il nome in chiaro, così come fornito dall’organizzatore all’importazione.
-
email_digest64 caratteri hex - SHA3-256(election_id ‖ indirizzo e-mail normalizzato), hex minuscolo: un’impronta propria dell’elezione.
- Gli astenuti non sono mai nominati. La loro riga resta pseudonima: l’opzione rivela chi ha votato, mai chi si è astenuto.
- Una divulgazione della partecipazione, non della scheda. Da sola collega un nome al fatto di aver votato, mai a una scheda. Con il voto non anonimo, che inserisce l’identificativo dell’elettore nella scheda firmata, il legame diventa scheda → identificativo → nome.
- Un’impronta debole, per scelta. Il sale (election_id) è pubblico e un indirizzo e-mail si può indovinare: chi detiene un indirizzo può confermare la partecipazione del titolare e collegarla da un’elezione all’altra. È uno strumento di controllo della lista, non una protezione; resta un dato personale.
Che cosa è stato votato, senza chi né quando.
Un record per scheda, ordinato per immagine di chiave: un ordine deterministico, ricavato dal contenuto, senza rapporto con l’ordine di arrivo.
Un record per scheda
-
ring_idUUID - L’anello le cui chiavi verificano la firma.
-
payloadstringa JSON - Il payload firmato, verbatim, byte per byte: versione, elezione, espressione della scheda, peso, e l’identificativo dell’elettore nel voto non anonimo.
-
signatureblsag_… - La firma ad anello (bLSAG) sul payload.
-
key_imageki_… - L’immagine di chiave: una stessa chiave dà sempre la stessa immagine in un’elezione, senza rivelare quale delle chiavi dell’anello abbia firmato.
- Pubblicazione a lotti. Le schede sono pubblicate a lotti di almeno 600, secondo una finestra temporale casuale; un lotto troppo piccolo attende il successivo. Tutto è pubblicato alla chiusura, e l’ultimo lotto può contare meno di 600 schede: un’elezione con meno di 600 elettori pubblica quindi le sue schede alla chiusura.
- Una sola regola per la pagina e la catena. La pagina del registro e la blockchain leggono lo stesso indicatore, is_chain_published: mostrano sempre esattamente lo stesso insieme di schede. Durante il voto la pagina indica il numero di schede ricevute in attesa di pubblicazione, senza il loro contenuto.
- Ritrovare la propria scheda prima della pubblicazione. La ricerca per immagine di chiave (invio POST, con limite di frequenza) trova anche una scheda ricevuta ma non ancora pubblicata. Un’immagine di chiave non si indovina: solo il detentore della ricevuta può inviarla. L’elenco pubblico mostra invece solo le schede pubblicate.
- Una pagina per scheda pubblicata. Payload, firma, immagine di chiave e impronta del suo anello. L’identificativo di scheda mostrato dalla pagina è un UUID v4 casuale; non compare nei blocchi.
Quando compare ogni elemento.
Nulla è pubblico prima dell’apertura del voto. In seguito il registro non fa che crescere, fino alla chiusura che lo termina.
Secondo lo stato dell’elezione
-
Draft, Enrolment, OpeningPreparazione - Nulla di pubblico. In Opening la definizione e gli anelli di lancio sono congelati e sigillati.
-
OpenVoto aperto - La pagina del registro è online: definizione, anelli, schede pubblicate a lotti, numero di schede in attesa, ricerca per immagine di chiave. Un anello di emergenza compare alla sua creazione. Nessun registro delle presenze.
-
ClosedVoto chiuso - L’ultimo lotto di schede, poi il blocco di chiusura: registro delle presenze completo e totali. Nessun blocco può seguirlo.
-
PublishedRisultato pubblicato - L’organizzatore pubblica il risultato: pagina dei risultati e download CEF.
-
ArchivedArchiviata - Il registro resta consultabile in sola lettura; il risultato non è più mostrato pubblicamente.
-
CancelledAnnullata - Tutte le viste pubbliche sono ritirate e la pagina del registro lo indica. Non viene emesso alcun blocco di chiusura: i blocchi già pubblicati restano validi, la catena si interrompe.
Il risultato pubblicato
- Mai un blocco. Il risultato si ricalcola dalla definizione e dalle schede pubblicate; non è un dato della catena.
- Metodo e versioni registrati. Il risultato registra il metodo usato, la versione della libreria CondorcetPHP e la versione del contratto di scrutinio, affinché un riconteggio riproduca esattamente la stessa semantica. La pagina dei risultati mostra il metodo e la versione della libreria.
- Le schede in formato CEF. Scaricabili dalla pagina dei risultati: una comodità, ricostruibile dal solo registro, che un verificatore può rigenerare per confrontarla.
- Gli eletti. Le prime seats posizioni della graduatoria ricalcolata, nulla di più.
Gli stessi dati, due letture.
La pagina del registro è la vista principale, paginata e consultabile, dei dati pubblicati; non è immutabile. La blockchain è un modo di distribuire quegli stessi dati: file JSON concatenati per hash e firmati dalla piattaforma, che chiunque può scaricare e conservare. La pagina la integra come sottosezione.
Indirizzi pubblici per elezione
- /elections/{election}/register
- La pagina del registro: stato dell’elezione, contatori, registro delle presenze, anelli, ricerca, schede, blockchain.
- POST /elections/{election}/register/lookup
- La ricerca di una scheda per immagine di chiave, con limite di frequenza; l’immagine di chiave non compare mai in un URL.
- /elections/{election}/register/ballots/{ballot}
- Il dettaglio di una scheda pubblicata.
- /elections/{election}/register/rings/{ring}/keys
- Un anello in JSON: election_id, ring_id, ring_number, ring_digest, public_keys.
- /elections/{election}/results
- Il risultato, solo nello stato Published.
- /elections/{election}/results/ballots.cef
- Le schede in formato CEF, alla stessa condizione.
- /elections/{election}/chain
- Il manifesto della blockchain, che rimanda a ogni blocco e ai suoi file accessori.
Questi indirizzi non hanno prefisso di lingua e non sono indicizzati dai motori di ricerca. Esistono finché l’elezione ha un registro pubblico, da Open ad Archived.
Che cosa aggiunge la blockchain
- Gli stessi dati. Quattro tipi di blocco (configuration, rings, votes, closure) che portano esattamente il contenuto descritto in questa pagina.
- L’integrità. Ogni blocco porta l’hash SHA3-512 del precedente e una firma staccata della piattaforma: una modifica retroattiva spezza la catena per ogni osservatore successivo.
- L’immutabilità, da verificare. La firma prova l’origine, non l’immutabilità: la piattaforma detiene la propria chiave. Sono le copie conservate da terzi, e l’ancoraggio in Bitcoin tramite OpenTimestamps che data i byte di ogni blocco, a rendere rilevabile una riscrittura.
- Nessuna API. File statici, memorizzabili in cache, archiviabili, che chiunque può replicare.
Ciò che chiunque può controllare, dal solo registro.
Senza fidarsi della piattaforma, con i soli dati pubblicati.
- 1 Ogni scheda è firmata da un membro del suo anello. Ripetere la verifica della firma ad anello su (payload, identificativo dell’elezione, firma, immagine di chiave, anello) per ogni scheda.
- 2 Una chiave, una scheda. Tutte le immagini di chiave dell’elezione sono distinte: nessuna chiave è stata usata due volte. Poiché un elettore può aver ricevuto più chiavi, è insieme ai controlli 3 e 4 che ciò dà una scheda per elettore.
- 3 Nessuna scheda aggiunta in un anello. Per ogni anello, il numero di schede è uguale al numero di righe di presenza il cui anello di voto è quello.
- 4 Non più schede che votanti. Il totale delle schede non supera il numero di righe has_voted: è il limite che conta contro il riempimento delle urne. Nel voto ponderato, i pesi firmati e i pesi delle righe di presenza formano lo stesso multinsieme, di somma voted_weight.
- 5 Il riconteggio. Serializzare i payload in CEF e scrutinarli con CondorcetPHP o qualsiasi implementazione CEF, con i vincoli derivati dalle regole della scheda pubblicate: si ritrovano la graduatoria e i conteggi di schede espresse, bianche e nulle.
- 6 Gli eletti. Leggere le prime seats posizioni della graduatoria ricalcolata.
Ciò che ogni elettore può controllare in più
- La propria riga di presenza. Tramite il proprio identificativo: ha votato o no, numero di chiavi ricevute. Un’attività inventata a suo nome si vede.
- Il proprio anello. L’impronta dell’anello nella ricevuta, calcolata dal proprio browser, deve essere uguale a quella pubblicata dal registro.
- La propria scheda. Con l’immagine di chiave della ricevuta ritrova la propria scheda e ne verifica il contenuto byte per byte, anche prima della pubblicazione.
La garanzia centrale è l’elenco fisso delle schede firmate: controlli da 1 a 4, più l’integrità della catena. Il riconteggio è un controllo incrociato; uno scarto di risultato tra implementazioni sarebbe un difetto di un programma di calcolo, non un difetto di verificabilità.
Procedura di verificaCiò che il registro non dice.
Ciò che tace per costruzione, e ciò che non può provare o lascia trasparire.
Ciò che non rivela
- Nessun timestamp. Nessun record pubblicato porta una data; le date tecniche restano nel database.
- Nessun ordine di arrivo. Schede ordinate per immagine di chiave, registro delle presenze per identificativo dell’elettore: due chiavi di ordinamento diverse, senza rapporto con la cronologia.
- Nessun legame tra elettore e scheda. Il registro delle presenze è pubblicato solo alla chiusura, mai per finestra: le sue righe non possono essere allineate nel tempo con le schede. Solo il voto non anonimo crea quel legame, per scelta dell’organizzatore.
- Nessuna identità, per impostazione predefinita. Senza l’opzione nominativa il registro non contiene dati personali; la corrispondenza tra identificativo e identità è nota solo alla piattaforma e all’organizzatore.
- Nessuna presentazione estetica. Logo, foto dei candidati, messaggio di ringraziamento: né pubblicati, né hashati.
Ciò che non può provare, o lascia trasparire
- Il momento del voto. Che il server non abbia osservato un elettore mentre votava: la piattaforma è una terza parte fidata in quel momento.
- Una partecipazione inventata. Che una riga «ha votato» non sia stata fabbricata per un assente: solo quell’elettore può accorgersene.
- Chi ha firmato nell’anello. Per costruzione.
- Un ordine approssimativo. I blocchi di voti si susseguono: ogni scheda di un blocco è stata espressa prima della sigillatura del successivo, alla granularità di almeno 600 schede. Un anello di emergenza, pubblicato più tardi, indica allo stesso modo che le sue schede sono più tardive.
- Anelli scarsi e pesi rari. In un anello in cui ha votato un solo elettore, il suo identificativo è collegato alla sua scheda, e il suo nome con l’opzione nominativa. L’organizzatore, che conosce il nome dietro ogni identificativo, può fare questo collegamento qualunque sia la modalità delle chiavi. Nel voto ponderato anonimo, un peso quasi unico designa il suo elettore.
- Gli iscritti senza chiave. In un’elezione in cui gli elettori devono portare la propria chiave, un iscritto che non ne ha depositata alcuna non può votare e oggi non compare nel registro delle presenze pubblicato.
- L’immutabilità della pagina. La pagina del registro può cambiare; l’immutabilità si verifica sulla blockchain, nella misura in cui terzi ne hanno conservato copie.
Vedi anche
- Scheda firmata La scheda così come l'elettore la firma: payload firmato, firma ad anello, immagine di chiave, digest dell'anello.
- Blockchain Il sovra-protocollo che sigilla il registro: busta, quattro tipi di blocco, serializzazione, concatenamento, firma, marcatura temporale.
- Procedura di verifica Verificare un'elezione da cima a fondo: dal solo registro, oppure con la blockchain.