Skip to content

Latest commit

 

History

History
142 lines (100 loc) · 7.06 KB

File metadata and controls

142 lines (100 loc) · 7.06 KB

The AuditRecord

last changed 08/17/2026

Rlauxe uses the following directory layout.

The auditrecord directory contains the publically available data, for use by verifiers. It should be published to a seperate bulletin board or web server. Files not in auditrecord are internal with formats that may change. Files in the private directory are typically only used in testing and must not be made public.

$topdir/
    countyData.csv        // optional - county contests only
    countyContestData.csv // optional - county contests only
    sortedCards.proto     // optional? - same as sortedCards.csv in kotlin protobuf format
    fastSampling.bin      // optional? - (prn, styleId) in binary, used for fast sampling

    auditrecord/
    
        // election record - output of createElectionRecord
        cardManifest.csv      // AuditableCardCsv, may be zipped
        contests.json         // ContestsUnderAuditJson
        electionInfo.json     // ElectionInfoJson 
        cardPools.csv         // optional - CardPoolCsv
        cardStyles.json       // optional - CardStylesJson  
        countyCardPools.csv   // optional - CountyCardPoolCsv, when pools are from county totals
        countyCvrPools.csv    // optional - CountyCardPoolCsv, compare countyCardPools to generated cvrs, used by viewer (TODO remove from audit record?)

        // auditRecord - output of createAuditRecord, after the seed has been chosen
        auditCreationConfig.json  // AuditCreationConfigJson 
        auditRoundConfig.json     // auditRoundConfigJson ; prototype for auditRoundConfigX
        sortedCards.csv           // AuditableCardCsv, sorted by prn, may be zipped

        roundX/
            // output of runAuditRound
            auditEstX.json       // AuditRoundJson,  an audit state with estimation, ready for auditing
            auditRoundConfigX.json  // auditRoundConfigJson, configuration for this round
            auditStateX.json     // AuditRoundJson,  the results of the audit for this round
            sampleCardsX.csv     // AuditableCardCsv, complete sorted cards used for this round; matches samplePrnsX.csv
            sampleMvrsX.csv      // AuditableCardCsv, complete sorted mvrs used for this round; matches samplePrnsX.csv
            samplePrnsX.json     // SamplePrnsJson, complete sorted sample prns for this round

    private/                  (test only - not part of the public record)
        sortedMvrs.csv      // AuditableCardCsv, sorted by prn, matches sortedCards.csv, may be zipped
        unsortedMvrs.csv    // AuditableCardCsv (optional)
        <county>.csv        // optional - AuditableCardCsv for specific county
        
    sortedChunks/
        sorted-cards-part-X // optional - used for external sort of cardManifest.csv
            

Also see core/src/main/kotlin/org/cryptobiotic/rlauxe/persist/Publisher.kt.

Commitment Sequence

1. CreateElectionRecord

The election information is contained in the following files. The EA (Election Authority) can modify these until satisfied that they are correct. Before the seed is chosen in step 2, they are digitally signed and published publically (aka committed to the Audit Record), and then may not be changed.

    cardManifest.csv      // AuditableCardCsv, may be zipped
    contests.json         // ContestsUnderAuditJson
    electionInfo.json     // ElectionInfoJson 
    cardPools.csv         // optional - CardPoolCsv
    cardStyles.json       // optional - CardStylesJson  
    countyCardPools.csv   // optional - CountyCardPoolCsv, when pools are from county totals

2. CreateAuditRecord : PRNG seed chosen, cards assigned PRNs

The PRNG seed is chosen, and all the cards in the card manifest are assigned a PRN in sequence by the PRNG. The cards are then sorted by PRN and written to sortedCards.csv. These are commited to the Audit Record. The PRNG seed can only be chosen once and the cards must be immediately committed.

    auditCreationConfig.json  // AuditCreationConfigJson 
    auditRoundConfig.json     // auditRoundConfigJson ; prototype for auditRoundConfigX
    sortedCards.csv           // AuditableCardCsv, sorted by prn, may be zipped

3. Audit Round X Sample Estimation

The EA decides which contests are in the audit, and what the configuration parameters are for the round. The EA can calculate estimated sample sizes, and modify contest sample sizes and AuditRoundConfig parameters as often as they want. The EA cannot hand pick which ballots to sample, only modify how many samples for each contest are used in the round. This preserves the canonical ordering of each contest, see Deterministic sampling order for each Contest for more explanation.

Once the EA is satisfied with sample sizes and auditing parameters, the following files are committed to the Audit Record:

    roundX/
        auditRoundConfigX.json  // the configuration parameters for round X
        auditEstX.json          // the estimation of sample sizes of the contests in this round
        samplePrnsX.json        // the chosen sample cards' prns for this round

4. Audit Round X gather MVRs

The physical ballots/cards are found that match samplePrnsX.json. These are hand-audited and their MVRs are written to sampleMvrsX.csv. The matching cards from the CardManifest are written to sampleCardsX.csv, for completeness and security. Before the audit is run, these are committed to the Audit Record:

    roundX/
        sampleMvrsX.csv      // complete mvrs used for this round; matches samplePrnsX.csv
        sampleCardsX.csv     // complete cards used for this round; matches samplePrnsX.csv

5. Run Audit Round X

The audit is run for round X, and the following file is committed to the Audit Record:

    roundX/
        auditStateX.json     // the results of the audit for this round

If not all contests are complete at the end of each round, then a new round begins and steps 3,4,5 are repeated.

Composite AuditRecord

This is an experimental feature for Belgium elections. Each componment is a single contest.

$compositedir/
    $component1/
       audit/
    $component2/
       audit/      
    ...  

Use AuditRecord.readFrom($compositedir). Each $component/audit is an AuditRecord. The contests from all components are put into the CompositeRecord. You can view and read, but not run audits on the CompositeRecord. Run audits independently on the individual components.

SingleRoundAudit vs Auditing with rounds

For simulation and testing, its convenient to do the audit in a single round, with all MVRs available, skipping the estimation steps, and keeping everything in memory (no persistence).

AuditWorkflow and its subclasses (esp PersistedWorkflow) implement auditing with rounds.

For real-world workflow examples, see createSfElection(), createBoulderElection(), createBelgiumClca(), and createColoradoElection() in the cases module.

Auditing with rounds workflow

Running an audit round is done through the RunRlaRoundCli, or from the viewer.