1 EVM 2003 Homepage

2 The Standard Ballot System

2.1 Ballot Sample

Alan Dechert's Ballot Sample should be taken fairly seriously in the sense that we want to look *exactly* like that for the demo. I have some reservations on the checkbox/radiobutton/deselect design, but not to rule out this design as an initial target.


Reduced version of the Standard Ballot

Large version of Standard Ballot

The resolution of the touchscreen hardware will be exactly 1280x1024.

2.2 Software libraries chosen

The standard ballot system will utilize the following software libraries:

what else?

2.3 Model-View-Controller paradigm

A common way of dividing and conceptualizing an user-interface application or component is with a MVC (Model-View-Controller) paradigm. One portion of the application controls the underlying data (the Model); another controls the visual presentation (the View); a final one controls the user interaction (the Controller). For example, see:


The Standard Ballot System can be thought of in MVC terms. The Controller involved is the wxPython GUI application. Python code utilizing the wxPython library handles things like accepting mouse clicks and drawing widgets on the screen.

The View and the Model, on the other hand, will be represented in XML documents. The XML document ballot-election.xml will contain information on the actual races, candidates, and so on. This is the Model. Two other XML documents will constitute the View: ballot-placements.xml and ballot-style.xml.

2.3.1 The Controller

Non-selected items should not be modified at all after a voter selection is made in a race. That is bad interface design. Rather, only the selected item(s) (one or several, depending on the type of contest) should be highlighted. This highlight should be prominent, probably combining a larger font, surrounding box, and a color change.

It may also make sense to mark elections in which a vote (or an adequate number of votes) have been properly cast in some manner. For example, perhaps after a vote is selected and the candidate highlighted, the entire race will be surrounded with a colored border that marks the fact that the race has been voted in.

2.3.2 The Model

A proper DTD for a ballot modle has not yet been created. But the following provides a rough conceptual outline:

<!-- ballot-election.xml -->
<ballot election_date="2004-11-04" state="MA" county="Franklin">
      Electors for President and Vice-President (a vote for the
      candidate will actually be a vote for their electors
    <candidate party="Republican">Abraham Lincoln</candidate>
    <candidate party="Democrat">Harry Truman</candidate>
    <candidate party="Green">Rachel Carson</candidate>

Incidentally, this provides a good example to show new developers how gnosis.xml.objectify API access to XML works, e.g.:

from gnosis.xml.objectify import make_instance
ballot = make_instance('ballot.xml')
date = ballot.election_date
state = ballot.state
county = ballot.county
for slot, election in enumerate(ballot.election):
    wx_in_position_display(slot, election.desciption.PCDATA)
    for candidate in election.candidate:
        wx_next_candidate(slot, candidate.PCDATA, party=candidate.party)

We will presumably need an additional ballot-election-lang.xml file for each additional language provided. For the large type option, we will need to define a new set of all the data files.

2.3.3 The View (style)

The XML file ballot-style.xml defines a set of visual appearances for elements such as fonts, line styles, colors, etc. For the demo, we will define EXACTLY ONE ballot style. Anand Pillai has created these working copies of the XML and its DTD

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ballot_style SYSTEM "ballot-style.dtd">
<!--- Created by Anand Pillai -->
<ballot_style name="Alan Dechert's ballot style">
  <main_frame resolution="1280x1024" view="default" />
  <frame_top_bottom style="solid-line" thickness="10px" />
  <frame_left_right style="solid-line" thickness="5px" />
  <instruction_box style="solid-line" thickness="5px" />
  <ballot_print_box style="solid-line" thickness="10px" />
  <choice_radio_button style="double-line" thickness="2px" />
  <column_separator style="double-line" thickness="2px" />
  <box_separator style="solid-line" thickness="2px" />
  <candidate_separator style="thin-line" spacing="10px" />
  <choice_separator style="thin-line" />
  <fonts script="Western">
  <generic_font size="10" face="Helvetica" style="regular" />
  <header1_font size="26" face="Helvetica" style="bold"
  underline="yes" />
  <header2_font size="20" face="Helvetica" style="bold" />
  <office_font size="12" face="Helvetica" style="bold" />
  <instructions_font size="10" face="Helvetica" style="regular" />
  <candidate_font size="14" face="Helvetica" style="regular" />
  <party_font size="12" face="Helvetica" style="bold" />
  <box_content_font size="12" face="Helvetica" style="bold" />
  <large_type_font size="20" face="Helvetica" style="bold" />
  <ballot_print_box_font size="26" face="Helvetica" style="bold" />

The (preliminary) DTD for this XML is:

<?xml version="1.0" encoding="utf-8"?>
<!--- Document type definition for EVM 2003 ballot style, version 2.0 -->
<!--- Created by Anand Pillai -->
<!ELEMENT ballot_style
    (main_frame, border_lines, separator_lines, fonts, colors)>
<!ELEMENT main_frame (EMPTY)>
<!ELEMENT border_lines
    (frame_top_bottom, frame_left_right, instruction_box,
     ballot_print_box, choice_radio_button)>
<!ELEMENT frame_top_bottom (EMPTY)>
<!ELEMENT frame_left_right (EMPTY)>
<!ELEMENT instruction_box (EMPTY)>
<!ELEMENT ballot_print_box (EMPTY)>
<!ELEMENT choice_radio_button (EMPTY)>
<!ELEMENT separator_lines
    (column_separator, box_separator, candidate_separator,
<!ELEMENT column_separator (EMPTY)>
<!ELEMENT box_separator (EMPTY)>
<!ELEMENT candidate_separator (EMPTY)>
<!ELEMENT choice_separator (EMPTY)>
<!ELEMENT fonts
    (generic_font, header1_font, header2_font, office_font,
     instructions_font, candidate_font, party_font, box_content_font,
     large_type_font, ballot_print_box_font)>
<!ELEMENT generic_font (EMPTY)>
<!ELEMENT header1_font (EMPTY)>
<!ELEMENT header2_font (EMPTY)>
<!ELEMENT office_font (EMPTY)>
<!ELEMENT instructions_font (EMPTY)>
<!ELEMENT candidate_font (EMPTY)>
<!ELEMENT party_font (EMPTY)>
<!ELEMENT box_content_font (EMPTY)>
<!ELEMENT large_type_font (EMPTY)>
<!ELEMENT ballot_print_box_font (EMPTY)>
<!ELEMENT colors
    (frame_bg_color, box_fill_color, generic_font_color,
<!ELEMENT box_fill_color (#PCDATA)>
<!ELEMENT generic_font_color (#PCDATA)>
<!ELEMENT generic_border_color (#PCDATA)>
<!ATTLIST ballot_style name CDATA "Alan Dechert's ballot style">
<!ATTLIST main_frame resolution CDATA "1280x1024">
<!ATTLIST main_frame view CDATA "default">
<!ATTLIST frame_top_bottom style
    (solid-line|thin-line|double-line|dotted-line) "solid-line">
<!ATTLIST frame_top_bottom thickness CDATA "10px">
<!ATTLIST frame_left_right style
    (solid-line|thin-line|double-line|dotted-line) "solid-line">
<!ATTLIST frame_left_right thickness CDATA "5px">
<!ATTLIST instruction_box style
    (solid-line|thin-line|double-line|dotted-line) "solid-line">
<!ATTLIST instruction_box thickness CDATA "5px">
<!ATTLIST ballot_print_box style
    (solid-line|thin-line|double-line|dotted-line) "solid-line">
<!ATTLIST ballot_print_box thickness CDATA "10px">
<!ATTLIST choice_radio_button style
    (solid-line|thin-line|double-line|dotted-line) "double-line">
<!ATTLIST choice_radio_button thickness CDATA "2px">
<!ATTLIST column_separator style
    (solid-line|thin-line|double-line|dotted-line) "double-line">
<!ATTLIST column_separator thickness CDATA "2px">
<!ATTLIST box_separator style
    (solid-line|thin-line|double-line|dotted-line) "solid-line">
<!ATTLIST box_separator thickness CDATA "2px">
<!ATTLIST candidate_separator style
    (solid-line|thin-line|double-line|dotted-line) "thin-line">
<!ATTLIST candidate_separator thickness CDATA #IMPLIED>
<!ATTLIST candidate_separator spacing CDATA "10px">
<!ATTLIST choice_separator style
    (solid-line|thin-line|double-line|dotted-line) "thin-line">
<!ATTLIST column_separator thickness CDATA #IMPLIED>
<!ATTLIST fonts script CDATA "Western">
<!ATTLIST generic_font size CDATA "10">
<!ATTLIST generic_font face CDATA "Helvetica">
<!ATTLIST generic_font style CDATA "regular">
<!ATTLIST generic_font underline CDATA #IMPLIED>
<!ATTLIST header1_font size CDATA "26">
<!ATTLIST header1_font face CDATA "Helvetica">
<!ATTLIST header1_font style CDATA "bold">
<!ATTLIST header1_font underline CDATA  "yes">
<!ATTLIST header2_font size CDATA "20">
<!ATTLIST header2_font face CDATA "Helvetica">
<!ATTLIST header2_font style CDATA "bold">
<!ATTLIST header2_font underline CDATA #IMPLIED>
<!ATTLIST office_font size CDATA "12">
<!ATTLIST office_font face CDATA "Helvetica">
<!ATTLIST office_font style CDATA "bold">
<!ATTLIST office_font underline CDATA #IMPLIED>
<!ATTLIST part_font size CDATA "12">
<!ATTLIST party_font face CDATA "Helvetica">
<!ATTLIST party_font style CDATA "bold">
<!ATTLIST party_font underline CDATA #IMPLIED>
<!ATTLIST box_content_font size CDATA "12">
<!ATTLIST box_content_font face CDATA "Helvetica">
<!ATTLIST box_content_font style CDATA "bold">
<!ATTLIST box_content_font underline CDATA #IMPLIED>
<!ATTLIST large_type_font size CDATA "20">
<!ATTLIST large_type_font face CDATA "Helvetica">
<!ATTLIST large_type_font style CDATA "bold">
<!ATTLIST large_type_font underline CDATA #IMPLIED>
<!ATTLIST ballot_print_box_font size CDATA "26">
<!ATTLIST ballot_print_box_font face CDATA "Helvetica">
<!ATTLIST ballot_print_box_font style CDATA "bold">
<!ATTLIST ballot_print_box_font underline CDATA #IMPLIED>

2.3.4 The View (placement)

The ballot placement will indicate where on the page each race appears. The rules about where columns may break and the like is complicated, and depends on jurisdiction (e.g. when can a candidate list go to next column). However, for our purposes, we should be able to manually set the positions to match our known-OK sample. Perhaps post-demo, we can automatically generate ballot-placement.xml based on ballot-election.xml and a set of election rules. The data file might look like:

<ballot-placement>    <!-- measured from top/left -->
  <summary x="165" y="20"/>       <!-- General election ... -->
  <usage x="80" y="65"/>          <!-- To vote ... -->
  <instructions x="60" y="88"/>
  <slot x="60" y="430"/>          <!-- president race -->
  <slot x=... y=.../>             <!-- congressional -->

Again, we're only looking to determine one set of values for the demo, but in principle, this is how a different ballot layout could be defined. We can demonstrate this configuration technique to election officials or to others.

2.4 Validation of XML

During development, we can manually validate sample files as samples and DTDs are modified. By the time the demo goes out, gnosis.xml.objectify will grow a new switch to add validation (a one line change to the code).

3 The Blind-Accessible Ballot System

The Blind-Accessible Ballot System will use the same ballot-election.xml and ballot-election-lang.xml data files (the Model) as the Standard Ballot system. However, the style and placement XML data (the View) is presumably not relevant. Presumably also, the Controller will be completely different for vocal (or braille) presentation.

Ballot result output files (and ultimately printed ballots), however, should be identical in form to those produced by the Standard Ballot System.

What else goes here?

4 The Ballot Printing System

4.1 The barcode system/font

We will use the barcode Code128 for the demo. The reasons for this choice are:

For the production system, a two-dimensional bar code, such as PDF417, may be used. This has a much more sophisticated level of error correction, see for example:


4.2 The encoding of cast votes

Information on the digit representation of votes

4.2.1 Visual obfuscation of exposed barcodes

To protect vote anonymity, it is required that poll workers not be able to visually identify recurring patterns on exposed barcodes. Since under a simple encoding, the vote for e.g. President may be represented consistently at or near the beginning of a barcode, an identifiable "Jones for President" pattern might occur.

A number of obfuscation schemes are possible. For example, if we later add compression of vote selections, that may provide sufficient obfuscation in itself. For the demo, we will XOR vote selections against repetitions of the unique ballot-id.

A ballot-id is composed of a publically know machine-id and a random session-id. The machine-id might be printed on the physical machine, for example; it will probably be a one-digit number. The session-id will be a number unique to each ballot cast on that machine; it must not be correlatable with the time of voting--sequential numbers, for example, would partially compromise anonymity. To avoid birthday paradox collisions, the voting machine will probably generate and retain a randomized list of session-id's at initialization. In Python, this can be generated with:

session_ids = range(1000)
random.shuffle(session_ids) XOR of vote selections

Most likely, a ballot-id will be a four digit number. We can convert this number to a "key" to a binary string in various ways. For our demo, we will encode each decimal digit as 4-bit binary, producing a 16-bit "key." In Python:

bits = {'0':(0,0,0,0),'1':(0,0,0,1),'2':(0,0,1,0),'3':(0,0,1,1),
def bit_tuple(num):
    tup = ()
    for c in str(num):
        tup += bits[c]
    return tup

Of course, the distribution of bits is not uniform; but the point is obfuscation, not encryption, so this is a non-issue.

A person who recognizes Code 128 can read the ballot-id at the beginning of a barcode, but this is not secret information. I believe it is outside the capability of a person to both read the remainder of the barcode and perform a rapid mental XOR against the ballot-id based key. Obviously, this is possible with some time, and pencil-and-paper; but generally anyone with sufficient degree of access can also obtained access to the human-readable ballot itself.

Quick XOR example:

vote bitstream = 10011001011101011001110
machine-id = 7
session-id = 843
XOR key = 0111100001000011

 1001100101110101 1001110......... | vote bits
 0111100001000011 0111100001000011 | repeated key
 --------------------------------- |
 1110000000110110 1110011......... | result

Obviously, the point is that XOR'ing the result against the same key produces the original vote bits. Padding bar code

It may become necessary to also pad the bar code if selection of write-in candidates or other identifiable types of votes produce a longer vote representation. However, we will not initially do so. Here is an illustration of padding.

Suppose the digit-ization of voting results is encoded in 36 digits of information. We will pad that within the size of the ballot to 60 or 70 digits. The first two digits will simply indicate the offset to get to the real data. So, for example, is the ballot data is:


Two different voters who vote identically will have on their ballot distinct encoded strings, such as:




(or rather, the barcode version of these).

Where the ds are random decimal digits. I am confident that that is sufficient to prevent elections workers who see numerous exposed edges during a day from beginning to recognize vote patterns.

4.3 The human-readable ballot

Printed ballots will look like the following samples:




Reduced printed ballot sample

5 The Barcode Vocalization System

What goes here?