Contents

Further Clarifications to Specification

The client must create its inputstream before it creates its outputstream.


If a class/program requires the path to the election object then this 'path' this defined to be the location of the object as opposed to the location and filename. For example: /election-base/


If either or both of the servers go down during the election then we would advise the people running the election to restart it from scratch. The servers are not designed to automatically recover their states and continue after a crash. This could however be a improvement that could be made in future if this project were to be continued by others.

Further Modifications to Specification

We have added a method in the election class that will perform checking to ensure that the people running the election/ the setup program has setup necessary things such as created output directories


The extensions of the serialized CountControlForms and CandidateRecordForms will be in lowercase rather than uppercase, this is just for consistency with the general naming of files under UNIX. Furthermore, since there could possibly be a large number of these files, they will now be saved in the /election-base/formdata/ directory. The OutputResults program has been modified to look for these files in this directory. This and all other such directories (such as the public_html for the election results) will be created by the running GenerateElectionData.


Some additional modifications were also made during the testing phase. See the next section.

Testing

Details of the class isolation testing that took place earlier is available in the form of javadoc comments to the test class. See: http://www.thor.cam.ac.uk/group/CST1b/juliet/javadoc/

We decided to proceed directly from Phase One Testing to Phase Three Testing. This decision was not taken lightly, and it was not taken as a means to take time. Instead it was taken after reassessing the practicality of testing the system. Testing the system as a whole would not be particularly different from testing it in clusters because the system naturally divides into three clusters and these three clusters do maintain some degree of separation when the system is used wholly anyway. What follows is a description of our activities when testing the system, the problems that we encountered and how we proceeded.

We started the Setup GUI and entered the details for a small election:

Five voters
One position, "President", with one space/seat
Four candidates for the position: Bill, Tony, Mikael, Tak

Rules URL: http://www.cam.ac.uk/

Severs both set to: hammer.cam.ac.uk/
Voting URL: http://www.thor.cam.ac.uk/~ijc25/
Election base: /home/ijc5/test-election

pollOpen: 22/02/1999 11:00
pollClose: 22/02/1999 18:00

We saved the election object, exited the setup GUI and restarted it. We reloaded the elation object. All the data was reloaded. All though this was not an extensive test of the GUI, at this point we concluded that their were not any major problems with the Setup GUI. We were fairly sure of this beforehand because of the testing that had already taken place.

Next we ran GenerateElectionData. We received a null pointer exception. This was solved quite simply by making a small change to CST1b.juliet.setup.ElectionDeserializer

After successfully re-running GenerateElectionData we ran PrintPollCards. This program completed successfully. We inspected the letters that it had generated and noted some errors in the text of the letter:

Most of these changes were trivial.

Next we started the submission server and authentication server. There were no problems on startup but we did note that some difference in the arguments taken. Some coders had interpreted 'path' to mean the directory location and filename, while others had interpreted it as just meaning the directory location. We decided to make all the programs consistent, and that only the location was needed in the 'path' the filename of the election object was fixed as 'election' in the specification.

We started the client and were able to login, but we noted that there were problems in the repainting of the applet, that required the browser window to be resized before the applet repainted. During correcting this problem we also decided it might be an idea to change the login from a panel to a dialog box.

The client seemed to accept votes fine itself, but didn't actually seem to connect to the authentication server. Further inspection of the code found that this was because the line of code to actually make the connection was missing! This was fixed, but the client was still trying to connect to 'null' rather than the specified authentication sever location. To solve this we modified CST1b.juliet.client.VoteCaster to use sockets rather than URLs as URLs in Java did not support port numbers.

There were also problems in the authentication protocol. We had changed the protocol from sending character streams to String objects. This mean that we no longer required newlines at the end of a string, we modified the authentication server accordingly, and also made some forgotten modifications in CST1b.juliet.client.VoteCaster The authentication server also seemed to be sending a spurious "Votes saved" response which was not in the specification. This was removed and an "OK" response was added after the Retrieve stage, as in the spec.

While making these modifications the class CST1b.juliet.client.UserAuthenticator was merged into CST1b.juliet.client.VoteCaster Also, the class CST1b.juliet.ElectionGrabber was modified so that it no longer cached the election object. This was not necessary.

We tried to use the client again. This time it succeeded in connecting the Authentication Server, and the server sent signed sets of votes back to the client.

The client was unable to correctly unBlind the signature because of header information in the serialised object. We were resigned to stop using serialisation in this respect and make many changes. A new interface CST1b.juliet.security.Signable was created. CST1b.juliet.security.SignedObject, CST1b.juliet.security.BlindObject and CST1b.juliet.election.Vote were modified to make use of this interface. More tests were devised and carried out for SignedObject. Small changes were made to the implementation of the algorithms in CST1b.juliet.security.BlindObject and CST1b.juliet.security.SignedObject. CST1b.juliet.client.VoteCaster was modified to reflect the new handling of the BlindSignature. Also it was discovered that the VoteCaster was inserting the real vote in one set of votes rather than in each set of votes. This was fixed.

Initially the authentication server had been written so that it only coped with votes for one position. While we were modifying the server so that it coped with multiple positions, we noted that our protocol did not allow the client to specify which position's votes it wanted to retrieve. Accordingly we modified the protocol. After the client bents the "RETRIEVE" message it will send another string object containing the Position ID of the position whose votes it want to retrieve.

The single position election that we originally attempted to carry out was rerun (with amended poll dates) and was carried out successfully. We did note that the it was slightly difficult to read off the elected candidates from the generated HTML files because of all the other information in the count control form, and decided that we should also generate a simple elected candidates list at the top of each of the results pages. Also we decided that OutputResults should automatically generate a StyleSheet if none had been placed in the public_html directory.

We next decided to carry out a larger election, similar to that which we had described in our Phase 3 Testing Description. The details of the election that we set up were:

Election Title: ElectionName-Test
Rules URL: http://www.cam.ac.uk/election/Rules
Votes URL: http://www.thor.cam.ac.uk/~srs29/juliet/Client.html
Election Base: /home/srs29/election
pollOpen: 25/02/2000 13:00
pollClose: 25/02/2000 18:00
Submission Server: thor.cam.ac.uk
Authentication Server: thor.cam.ac.uk

Position Name: President
Position ID: Pres
Spaces 1
Candidate Names: Bill Clinton, Chairman Mao, PiKachu
Candidate URLS: http://www.cam.ac.uk/election/Bill, http://www.cam.ac.uk/election/Mao, http://www.cam.ac.uk/election/PiKachu

Position Name: Lackeys
Position ID: Lack
Spaces 3
Candidate Names: Puff Daddy, Wolverine, Blanka, Sammo Law, Britney Spears, Paul Gascoigne
Candidate URLS: http://www.cam.ac.uk/election/Puffy, http://www.cam.ac.uk/election/Wolfy, http://www.cam.ac.uk/election/Blanky, http://www.cam.ac.uk/election/Sam, http://www.cam.ac.uk/election/Spears, http://www.cam.ac.uk/election/Gazza

We used the following voterfile of ten voters and selected all ten to take part in the election:

Ian Bunning, IanB, Trinity Hall\nCambridge
Ian Campbell, IanC, Churchill College\nCambridge
Tak Fung, Tak, Girton College\nCambridge
Ritchie Hughes, Ritchie, Pembroke College\nCambridge
Sagar Shah, Sags, Sidney Sussex College\nCambridge
Will Smith, WillSmith, USA
Spiderman, Spiderman, America
King Tut, KingTut, Eygpt
Akira, Akira, Japan
Ronaldo, Ronaldo, Brazil

After using the Setup GUI to set all these parameters we ran GenerateElectionData. It did not appear to be creating directories for each position (named by the positionID) under the election/signed_votes directory. We found that it was attempting to create these directories before the actually loading the election object. This was fixed trivially.

We re-ran GenerateElectionData and then proceeded to run PrintPollCards. On inspecting the generated poll cards we discovered that the voter's address was still not being printed. We inspected the PrintPollCards class and found nothing wrong or missing. We traced the problem back to the Setup GUI, it was not correctly reading the voters' addresses from the comma separated voterlist file. We corrected this (again only a tiny change to the code) and reran the Setup, GenerateElectionData and PrintPollCards.

We printed the PollCards to screen (they could have also easily been printed to paper) and noted the PAKs for each voter.

Next we exported a Client.html file (within which the client applet will run) to a public_html directory and also copied over the classes that the applet would use.

We started the two Servers and loaded the Applet into a web browser. As we started to use the client we noticed that it did not display the ballot paper of the second position when we clicked on the appropriate button. We investigated this problem in the VotingBoothPanel class. After doing lots of checking and tracing trying to find the problem we concluded that the adding/removing or showing/hiding of ballot papers from button clicks would not do what we wished. We modified the class to use a CardLayout and then used the methods in the java.awt.CardLayout class to switch between the various BallotPapers as and when required.

After correcting the client we proceeded to use it to make votes. All went as it should. The communication with the servers was now fine, the votes were authenticated by the authentication server and accepted by the submission server. We also tried to enter some invalid votes, using incorrect userIDs and PAKs, these were rejected as they should have been. We also tried to vote more than once under some userIDs. The system did not allow this, just as it shouldn't.

After all the votes had been cast we stopped the servers, and started the STV class. There were no apparent problems here. We next ran the OutputResults class and inspected the generated Results file. The results for the position "President" were identical to our manual run of the election that we had carried out before starting the computer one. The results for the position "Lackey" were not. We noted that the generated results file showed that there was only one space for Lackey when there should have been three (as we entered in the Setup GUI). We did not notice this problem with the previous smaller election that we had run because this only included one space anyway.

After checking and convincing ourselves that there was nothing wrong with the STV classes and OutputResults we traced the problem all the way back to the SetupGUI itself. The Setup GUI was designed so that if it could not correctly parse an integer from the string (representing the text in the textbox) then it would automatically set the spaces variable to 1 for that particular position. Although an error message was sent out to the console there was a lot of debugging information so it wasn't noticed earlier. We found that the Setup GUI was calling the getText method on the wrong textbox when it was initialising the string for startspaces. This is why the parseInt failed.

We fixed the Setup GUI and got the STV module to use the corrected election object with the previously cast votes. We inspected the output generated by OutputResults. This time the results for both positions matched the manual election that had been carried out.

Next we deleted all details of that election and re-ran it from Setup to OutputResults. We experienced no problems along the way

We also decided that it was necessary to do some Load/Stress Testing. The analyst (IanC) wrote a StressTest class which creates an election with a configurable number of positions, candidates and spaces with a configurable number of voters. It then submits votes for all of those voters and runs the tallying phase. We ran a test of 2500 voters, with 32 positions. Each position having a varying number of candidates and spaces (with no.spaces<no.candidates).

From the stress tests we did discover that the java implementation was not cleaning up threads properly, and so we would recommend that people start the servers passing the -green option to java.

Final Summary

Our acceptance criteria for this project were:

We believe that our project has been successful and that we have met the acceptance criteria:

The group did not miss any of its deadlines and kept fairly close to its project plan. This plan might be regarded as slightly vague but was appropriate to the context under which this project was being carried out. Group members had other commitments such as lectures and supervisions and so tightly binding people to carry out specific amounts of work on specific days was not regarded as being a sensible idea. A flexible management strategy proved quite effective.

Summary of Work Undertaken by Group Members

Sagar R. Shah

Original Role: Manager and Chief Documenter
Work Undertaken:

Tak L. Fung

Original Role: Vice-Manager + Programmer + Tester
Work Undertaken:

Ian J. Campbell

Original Role: Analyst + Code Librarian
Work Undertaken:

Ritchie N. Hughes

Original Role: Programmer + Documenter + Webmaster + Minutes Taker
Work Undertaken:

Ian J. Bunning

Original Role: Programmer + Tester
Work Undertaken: Further details of work undertaken by group members are available in the form of summaries of our daily project logs. These are are at http://www.thor.cam.ac.uk/group/CST1b/juliet/sagar/prlogs.html

Classes Authorship

Package CST1b.juliet

Class Name Author
GenerateElectionData Ritchie
OutputResults Tak
PrintPollCards Ritchie
Setup Ritchie
STV Tak
SubmissionServer IanC
AuthenticationServer IanB

Package CST1b.juliet.authserver

Class Name Author
AuthThread IanB
UserData IanB

Package CST1b.juliet.client

Class Name Author
BallotPaper Ritchie
BallotPaperSpoiltException Ritchie
Client Ritchie
ElectionGrabber Ritchie
ElectionNotGrabbedException Ritchie
LoginPanel Ritchie
UserAuthenticationException Ritchie
VoteCaster Ritchie
VoteNotCastException Ritchie
VoteNotSignedException Ritchie
VotingBoothPanel Ritchie

Package CST1b.juliet.election

Class Name Author
Candidate IanC
Election IanB & IanC
ElectionDataGenerator Ritchie
IDNotUniqueException IanC
NoMorePreferencesException IanC
Position IanC
Vote IanC
Voter IanB

Package CST1b.juliet.security

Class Name Author
BlindFactorTooSmallException IanC
BlindObject IanB & IanC
EncryptedInputFilter IanB
EncryptedOutputFilter IanB
Key IanB
KeyPair IanB
PrivateKey IanB
PublicKey IanB
SecureRandom IanB
Signable [interface not class] IanC
SignedObject IanB & IanC

Package CST1b.juliet.setup

Class Name Author
ElectionDeserializer Ritchie
ElectionSerializer Ritchie
KeySerializer Ritchie
VotersDeserializer Ritchie
VotersSerializer Ritchie

Package CST1b.juliet.submission

Class Name Author
Server IanC

Package CST1b.juliet.tally

Class Name Author
CandVoteRec Tak
CountControlForm Tak
IDNotFoundException Tak
STVModule Tak

Testing Classes

To facilitate testing, the following classes have been written by IanC:

These classes reside in the package CST1b.juliet.testharness. All major classes have an associated [ClassName]Test.java Class that will be used by the Testharness in performing tests.

The exception classes are trivial and did not require testing above checking that they compiled correctly. The test classes for exceptions and other untestable classes subclass Untestable Test.

Documentation

Technical Documentation

The vast majority of the technical documentation consists of Javadoc output available on the web at http://www.thor.cam.ac.uk/group/CST1b/juliet/javadoc/. For completeness we also include here a documentation of the communications protocol between the client and servers, and also details of the STV Counting Regulations that our system implements.

Communications Protocol

See This Word Document

Details of the STV Counting Regulations Used By This System

The following is a comprehensive account of how counting of the votes occur within this computer system. It is based upon Points 5 to 17 of the Single Transferable Vote Regulations in the University of Cambridge Statutes and Ordinances, pages 121 to 124. This account has been designed firstly to take into account the differences between counting votes on a computer and counting by hand, and secondly to present the rules of counting in a clearer form of English.

1. The First Stage

1.1 Count all the voting papers to determine the total number of votes cast(=total valid vote).


1.2 Check the sorting, and put the papers for each candidate into bundles (i.e. group them up).
1.3 Check the counting. Enter on each candidate’s vote record form the total number of first preference votes.
1.4 Calculate the quota:

  Quota = (Total Valid Votes) / (number of VACANCIES to be filled+1)

  if (quota>100) quota=ceiling(quota);
  else quota=(quota round UP in the second d.p.)

1.5 Considering each candidate in turn in DESCENDING order of their votes, deem elected any candidate whose vote equals or exceeds the quota, up to the number of places to be filled, subject to NOTES (*).
1.6 That completes the first stage of the count.

2. Subsequent Stages

2.1 Each subsequent stage will involve EITHER:
Transfer Surplus or
Exclusion of candidate(s)
2.2 The surplus or surpluses is deferred and reconsidered at the next stage, if the total of such surpluses does not exceed either:
(a) The difference between the votes of the two candidates who have the fewest votes, or
(b) The difference between the total of the votes of two or more candidates with the fewest votes and the vote of the candidate next above.
2.3 If one or more candidates have surpluses which have not been deferred, transfer the largest surplus. If the surpluses of two or more candidates are equal, and they have the largest surplus, transfer the surplus of the candidate who had the greatest vote at the first stage or at the earliest point in the count, after the transfer of a batch of papers, where they had unequal votes. If the votes of such candidates have been equal at all such points, the computer shall randomly decide which surplus to transfer.
2.4 The transfer of a surplus constitutes a stage in the count. Details of how to do this are in section 3. If, after completing the transfer, there are still any untransferred surpluses, and not all the places have been filled, proceed as in paragraph 2.2 (a program loop)
2.5 If, after all surpluses have been transferred or deferred, one or more places remain to be filled, the candidate or candidates with the fewest votes must be excluded. Exclude as many candidates together as possible, provided that:
(a) Sufficient candidates remain to fill all the remaining places
(b) The total votes of these candidates, together with the total of any deferred surpluses, does not exceed the vote of the candidate next above. [Note: the base case is exclusion of the candidate with least votes].
If the votes of two or more candidates are equal, and those candidates have the fewest votes, exclude the candidate who had the fewest votes at the first stage or at the earliest point in the count, after the transfer of a batch of papers, where they had unequal votes. If the votes of such candidates have been equal at all such points the computer shall randomly decide which candidate to exclude.
2.6 Details of how to exclude a candidate are given in section 4.
2.7 Exclusion of one or more candidates constitutes a stage in the count. If, after completing this, there are any surpluses to transfer, and not all the places have been filled, proceed as in paragraph 2.2. Otherwise proceed to exclude further candidates as in paragraph 2.5. (more program loops)

3. Transfer of a Surplus

3.1 If a surplus arises at the first stage, select for examination all the papers which the candidate has received.
3.2 If a surplus arises at a later stage, because of the transfer of another surplus or the exclusion of a candidate or candidates, select only the last received batch of papers, which gave rise to the surplus. (Easy by looking at the latest entry in the appropriate forms)
3.3 Examine the selected voting papers and sort them into their next available preferences for continuing candidates. Set aside as non-transferable papers any on which no next available preference is expressed.
3.4 Check the sorting, count and bundle the papers now being transferred to each candidate, also any non-transferable papers.
3.5 Count the number of transferable papers and enter the number for each candidate on the vote record forms.
3.6 Calculate the total value of the transferable papers. If this exceeds the surplus, determine the transfer value of each paper by dividing the surplus by the number of transferable papers, to two decimal places, ignoring any remainder. If the total value does not exceed the surplus, the transfer value of each paper is its present value.
3.7 Calculate the value to be credited to each candidate by multiplying the transfer value by the number of papers.
3.8 Add these values to the previous votes for each candidate, and add the non-transferable difference to the previous total of non-transferable votes, entering the figures onto the vote record forms.
3.9 Considering each continuing candidate in turn in DESCENDING order of their votes, deem elected any candidate whose vote now equals or exceeds the quota, up to the number of places remaining to be filled, subject to NOTES (*)

4. Exclusion

4.1 Take together all the bundles of papers which are currently credited to the candidate or candidates to be excluded, and arrange them in batches in descending order of transfer value. (i.e. each paper will have a transfer value, simply sort the papers with respect to their transfer values).
4.2 First, take the batch of papers with the highest transfer value. Sort them according to the next available preferences for continuing candidates, and set aside as non-transferable papers any on which no next available preference is expressed.
4.3 Check the counting and enter the number of papers for each candidate and the number of non-transferable papers on the vote record forms.
4.4 Considering each continuing candidate in turn in DESCENDING order of their votes, deem elected any candidate whose vote now equals or exceeds the quota, up to the number of places remaining to be filled, subject to NOTES (*)
4.5 Ensure that no further papers are given to candidates who are no longer continuing candidates. Instead the next preference (if-any) on the papers must be examined. A continuing candidate is a candidate who has not already been deemed elected and who has not been excluded.
4.6 Repeat from 4.2, sort and transfer each batch of papers in turn in descending order of transfer value, and deem candidates to be elected as appropriate.

5. Completion of the Count

5.1 If an exclusion leads to (number of candidates left == remaining places to be filled) then finish.
5.2 If, at any point in the count, the number of candidates deemed to be elected is equal to the number of places to be filled, no further transfers of papers are made, and the remaining continuing candidate(s) are formally excluded.
5.3 The count is now completed. Declare elected all those candidates previously deemed to be elected.
5.4 Print all forms. These contain ALL intermediate stage results, and thus satisfy Regulation 13 in the University Statutes & Ordinances (p124), and also facilitate 5.5 of these regulations.
5.5 Any questions or serious disputes not settled will lead to a recount by hand.
5.6 If any question shall arise in relation to any transfer of the votes, the result of the computer program is final [this is a direct analogy from Ordinances, page 124, point 15]

NOTES

(*)If, when candidates should be deemed elected under sections 1.5, 3.9 or 4.4, there are not sufficient places left for them all, then none of them shall be deemed elected at that stage.

Admin/Server Guide

See This Word Document

User/Client Guide

See This Word Document

A4 'Dummies' Voting Booth Guide

See This Word Document