Vada al contenuto
Condorcet.vote Alpha
← Documentazione tecnica

Procedura di verifica

Due percorsi per controllare un’elezione senza fidarsi della piattaforma: il registro pubblicato basta a verificare le schede e il risultato; la blockchain vi aggiunge l’integrità e l’immutabilità di tale registro.

Il secondo percorso comprende il primo. Ogni controllo indica ciò che dimostra e rimanda alla specifica su cui si basa; gli strumenti sono standard o open source: CryptoVote, CondorcetPHP, sq, openssl, ots.

Protocollo v1

Percorso 1 · Solo registro

Le schede e il risultato, dal registro.

Il registro pubblico di un’elezione pubblica la sua definizione, i suoi anelli, le sue schede firmate e, alla chiusura, il suo registro delle presenze. Questi controlli li prendono così come sono serviti, sulla pagina del registro o nei file dei blocchi. I controlli di partecipazione attendono la chiusura: il registro delle presenze è pubblicato una sola volta, nel blocco closure.

  1. 1

    Ogni scheda è autentica.

    Per ogni scheda, eseguire verify_vote (operazione C di CryptoVote) sul payload così come pubblicato, l’identificativo dell’elezione, la firma, l’immagine di chiave e le chiavi pubbliche del suo anello. Ricalcolare anche l’impronta di ogni anello (ring_digest) dalle sue public_keys e confrontarla con quella pubblicata.

    Che cosa dimostra: Ogni scheda è stata firmata da una chiave del suo anello, su questi byte esatti: una scheda modificata, o firmata al di fuori dell’anello, non supera la verifica.

    Si basa su Scheda firmata

  2. 2

    Una sola volta per chiave.

    Tutte le immagini di chiave (ki_…) sono distinte all’interno dell’elezione. L’immagine di chiave è propria della coppia chiave segreta-elezione: due schede firmate con la stessa chiave portano la stessa immagine.

    Che cosa dimostra: Nessuna chiave è stata usata due volte: un simile doppio voto sarebbe pubblicamente evidente.

    Si basa su Scheda firmata

  3. 3

    Ogni anello corrisponde ai suoi elettori.

    Per ogni anello R, il numero di schede firmate contro R è uguale al numero di righe del registro delle presenze il cui anello votato (ring_id) è R. Il limite «schede ≤ chiavi dell’anello» discende dall’unicità delle immagini di chiave.

    Che cosa dimostra: Le schede di ogni anello si ricollegano a elettori registrati come votanti in quell’anello.

    Si basa su Registro pubblico

  4. 4

    Non più schede che elettori.

    Il numero totale di schede non supera il numero di righe has_voted del registro delle presenze. In un’elezione ponderata, il multiinsieme dei pesi firmati nelle schede è uguale al multiinsieme dei pesi delle righe has_voted.

    Che cosa dimostra: È il limite che impedisce il riempimento delle urne: la piattaforma non può pubblicare né più schede che elettori contrassegnati come votanti, né un peso che nessun elettore ha ricevuto, senza che alcuna scheda sia mai collegata a un elettore.

    Si basa su Registro pubblico

  5. 5

    Il risultato si ricalcola.

    Convertire ogni payload pubblicato in formato CEF, con il suo peso firmato in un’elezione ponderata, e sottoporlo a CondorcetPHP (o a qualsiasi implementazione conforme a CEF) con i vincoli derivati dalle regole di scheda della definizione. Il risultato pubblicato indica il metodo, la versione della libreria e quella del contratto di scrutinio; gli eletti sono i primi della classifica, tanti quanti i seggi.

    Che cosa dimostra: La classifica e i conteggi annunciati (espressi, bianchi, nulli) sono quelli che danno le schede pubblicate. Il cuore della garanzia resta l’elenco firmato delle schede: uno scarto tra implementazioni sarebbe un difetto di calcolo, non di verificabilità.

    Si basa su Scrutinio e riconteggio

  6. 6

    Ogni elettore ritrova la propria scheda.

    Con la propria ricevuta (.condorcet_receipt), l’elettore cerca la propria immagine di chiave sulla pagina del registro, che trova anche una scheda ricevuta ma non ancora pubblicata, e confronta la scheda pubblicata, byte per byte, con il payload firmato della ricevuta. Confronta inoltre il ring_digest della ricevuta, calcolato dal proprio browser, con quello pubblicato per l’anello, e controlla la propria riga del registro delle presenze tramite il proprio identificativo elettore.

    Che cosa dimostra: La sua scheda figura così come l’ha firmata, il suo anello è quello pubblicato per tutti, e nessuna attività è stata fabbricata sulla sua riga. Di sua sola iniziativa, può anche dimostrare a un terzo che una scheda pubblicata è la sua, il che rivela il suo voto.

    Si basa su File dell'elettore Prova di voto

Percorso 2 · Con la blockchain

Integrità e immutabilità, controllabili da chiunque.

Il registro è pubblicato anche in blocchi JSON concatenati, firmati dalla piattaforma e ancorati in Bitcoin. Sette controlli, a partire dai soli file pubblicati, stabiliscono che tale registro è autentico, completo e invariato; il sesto vi ripete il percorso 1. La piattaforma non fornisce alcun verificatore: un’autoverifica da parte di chi produce la catena non aggiungerebbe alcuna fiducia.

  1. 1

    Recuperare i file.

    L’insieme dei certificati della piattaforma su /.well-known/blockchain-signing-key, chiavi ritirate e scadenze comprese; il manifesto dell’elezione (/elections/{election}/chain); ogni blocco {n}.json, la sua firma {n}.json.sig e la sua prova {n}.json.ots.

    Che cosa dimostra: Che non serve alcun accesso privilegiato: sono file semplici, memorizzabili in cache e replicabili, denominati con l’identificativo dell’elezione; una copia staccata dal suo URL resta identificabile.

    Si basa su Chiavi della piattaforma Blockchain

  2. 2

    Verificare ogni firma.

    Un comando per blocco, con qualsiasi implementazione RFC 9580: sq verify, poiché GnuPG non verifica le firme OpenPGP v6. Le regole di validità standard rifiutano una firma datata al di fuori della finestra della sua chiave. In verifica rigorosa, richiedere la notazione domain@condorcet.vote = chain-block/v1 e una data di creazione uguale al signed_at del manifesto.

    Che cosa dimostra: L’autenticità: ogni blocco è stato prodotto dalla piattaforma e non è cambiato di un solo byte dalla sua firma. Non, da sola, l’immutabilità (si vedano i limiti).

    Si basa su Chiavi della piattaforma

  3. 3

    Controllare il concatenamento.

    Il blocco 0 è di tipo configuration, con previous_hash nullo; per ogni blocco k > 0, lo SHA3-512 del file k − 1 (openssl dgst -sha3-512) è uguale al previous_hash del blocco k; i block_number si susseguono da 0 a n; election_id è lo stesso su ogni blocco.

    Che cosa dimostra: L’ordine e la continuità della catena: nessun blocco può essere rimosso, inserito o modificato senza rompere il concatenamento di tutti i successivi.

    Si basa su Blockchain

  4. 4

    Controllare la chiusura.

    Esattamente un blocco closure, per ultimo, nulla dopo di esso. I suoi totals si confrontano con la catena: block_count con il numero di blocchi (chiusura compresa), ballot_count con le schede dei blocchi votes, ring_count con gli anelli dei blocchi rings, voted_count e voted_weight con le righe has_voted del suo registro delle presenze.

    Che cosa dimostra: La catena è completa: un blocco di chiusura firmato, al termine di un concatenamento ininterrotto, dimostra che non manca alcun blocco.

    Si basa su Blockchain

  5. 5

    Validare ogni blocco.

    Ogni blocco si valida contro lo schema JSON del suo tipo (/schemas/blockchain/block.{type}.schema.json), che rifiuta qualsiasi proprietà aggiuntiva; un blocco il cui JSON ripete una chiave è rifiutato.

    Che cosa dimostra: Tutti i verificatori leggono lo stesso contenuto: poiché i parser divergono sulle chiavi duplicate, un simile blocco potrebbe leggersi come due insiemi di schede diversi sotto lo stesso hash e la stessa firma.

    Si basa su Blockchain

  6. 6

    Ripetere il percorso 1 sulla catena.

    Sul contenuto dei blocchi: ogni firma ad anello contro le chiavi del suo anello, ogni ring_digest ricalcolato dalle sue public_keys, l’unicità delle immagini di chiave, i limiti per anello e globale contro il registro delle presenze del blocco closure, poi il riconteggio a partire dalle regole del blocco configuration e dai payload dei blocchi votes.

    Che cosa dimostra: Le garanzie del percorso 1, ora su un registro di cui sono stabiliti l’autenticità, l’ordine e la completezza.

    Si basa su Registro pubblico Scrutinio e riconteggio

  7. 7

    Verificare l’ancoraggio Bitcoin.

    Opzionalmente, ogni prova .ots contro il suo file di blocco, con gli strumenti OpenTimestamps standard (ots verify). L’impegno è lo SHA-256 semplice del file. Una prova in attesa porta per ora solo gli impegni dei calendari; una prova completata indica un blocco Bitcoin.

    Che cosa dimostra: L’anteriorità: il blocco esisteva, byte per byte, al più tardi al blocco Bitcoin attestato, indipendentemente dalle chiavi della piattaforma, che non può retrodatare un blocco Bitcoin.

    Si basa su Blockchain

Verifica · shell
# il portachiavi pubblicato, chiavi attive e ritirate
curl -s https://admin.stg.condorcet.vote/.well-known/blockchain-signing-key > signing-keys.pgp

# per ogni blocco n: la firma OpenPGP v6 (Sequoia: GnuPG non legge il v6)
sq verify --signer-file signing-keys.pgp --signature-file {n}.json.sig {n}.json

# il concatenamento: l'impronta deve essere uguale al previous_hash del blocco n + 1
openssl dgst -sha3-512 {n}.json

# opzionalmente, l'ancoraggio Bitcoin
ots verify -f {n}.json {n}.json.ots
Limiti

Ciò che questi percorsi non dimostrano.

Entrambi i percorsi verificano ciò che è stato pubblicato. Non sostituiscono la fiducia accordata alla piattaforma durante il voto.

  • Il percorso 1 prende il registro così come è servito. Non dice se tale registro sia completo né se sia stato riscritto: la pagina del registro non è immutabile. È il compito del percorso 2.
  • Una firma non è l’immutabilità. La piattaforma detiene la propria chiave e potrebbe firmare una catena riscritta coerente. Ciò che impedisce a una riscrittura di passare inosservata: le copie conservate da chiunque recuperi i blocchi man mano che vengono pubblicati, e l’ancoraggio OpenTimestamps, poiché un blocco riscritto non può essere ancorato prima della sua riscrittura.
  • Un terzo fidato al momento del voto. Nessun registro dimostra che la piattaforma non abbia osservato gli elettori durante lo scrutinio. La modalità «Porti la propria chiave» riduce ciò che occorre affidarle.
  • Una partecipazione fabbricata per un assente. La piattaforma potrebbe contrassegnare come votante un iscritto che non ha votato, e votare al suo posto entro i limiti pubblicati; solo tale elettore può rilevarlo, controllando la propria riga del registro delle presenze.
  • Chi ha firmato in un anello. Per costruzione, la firma ad anello non rivela quale dei membri abbia firmato. Un elettore può invece dimostrare il proprio voto: il protocollo non offre resistenza alla coercizione.