University2024
Referendum, a secure voting app
Secure voting application in Java/JavaFX with ElGamal encryption, non-interactive Zero Knowledge Proof, AI chatbot (DeepSeek) and Scrum methodology over a full academic year.
- Duration
- Full second year of CS degree (Year-end project)
- Team
- Group of 4 students
- My role
- Product Owner & Cryptography Developer: ElGamal encryption, Zero Knowledge Proof, AI ChatBot and socket security

Context
Referendum is the final project of the second year of the Computer Science degree. It's the most structuring project of the program: it lasted the entire academic year and was conducted using Scrum methodology under conditions close to the professional world.
The case study was a fictional company that needed its employees to vote securely. Our mission was to design and develop a complete voting application, guaranteeing vote confidentiality, result integrity, and voter authentication.
We were a team of 4 students, and I held the role of Product Owner. In this capacity, I managed the product backlog, prioritized features, and served as the link between "client needs" (defined by instructors) and the development team. But I also had a major technical role: I was responsible for the entire cryptography part (ElGamal encryption, imposed by the professors), securing socket communications, implementing the non-interactive Zero Knowledge Proof for vote verification, and creating a FAQ chatbot powered by the DeepSeek API.
The project was divided into several phases: sprints with regular deliveries, then a new contract where we had to further improve the application, followed by more sprints. Each phase included oral presentations to a "client" (the instructors), technical documentation writing, and defenses.
Objectives
- 01Secure voting application: Develop a Java/JavaFX application allowing creation of polls, confidential voting, and secure result viewing.
- 02ElGamal encryption: Implement the ElGamal cryptographic protocol (imposed by professors) to guarantee vote confidentiality. This was my main part within the team.
- 03Non-interactive Zero Knowledge Proof: Ensure each vote is strictly 0 or 1 (yes or no) without revealing the actual vote value. The project integrates createZKProof (client-side proof creation) and verifyZKProof (server-side verification) functions to validate votes in a single exchange.
- 04FAQ ChatBot (DeepSeek API): Create a chatbot integrated into the application to answer frequently asked questions. The DeepSeek API is used solely to understand the user's question and provide the most relevant answer from pre-prepared responses related to the application.
- 05Socket security: Set up secure client-server communication via encrypted sockets, to prevent interception or manipulation of votes in transit.
- 06Scrum methodology: Work in sprints with regular deliveries, retrospectives, a prioritized backlog, and oral client presentations.
- 07Technical documentation: Write complete technical documents at each project phase (architecture, technical choices, UML diagrams, tests).
Technical approach
The project followed Scrum methodology throughout the year. As Product Owner, I organized sprint plannings, maintained the backlog, and presented demos to the "client" (instructors) at each sprint end. At the end of each cycle, we received a new contract with additional requirements, simulating the evolving needs of a real client.
On the technical side, the application is developed in Java with a JavaFX interface. My main technical role was ElGamal encryption, an asymmetric public-key cryptography system. The principle: each vote is encrypted with the poll's public key before being sent to the server. Only the private key holder can decrypt votes when the poll closes. This ensures that nobody, not even the server, can read an individual vote before the poll ends.
Non-interactive Zero Knowledge Proof: To guarantee vote integrity, the project integrates a Zero Knowledge Proof. The goal is to prove server-side that a client's vote is indeed "yes" or "no" (0 or 1), without revealing which one. If a user attempts to vote an invalid value (e.g., 10 or a negative number), the vote is rejected. The proof is non-interactive: a single exchange between client and server suffices, sending the proof along with the encrypted message. Client-side, the createZKProof function generates two proofs (one real, one simulated) via cryptographic commitments, a SHA-256 hash, and modular arithmetic. Server-side, verifyZKProof recalculates values and verifies that the sum of challenges matches the hash. If so, the proof is valid, the vote is indeed 0 or 1, without the server knowing which.
FAQ ChatBot (DeepSeek API): I implemented a FAQ chatbot integrated into the application to answer users' frequently asked questions. I integrated the DeepSeek API which serves solely to understand the user's question and provide the most relevant answer from specific pre-prepared responses, limited to questions related to the application.
I also secured socket communications between client and server. Exchanges are encrypted to prevent any interception (man-in-the-middle) or data manipulation in transit.
The rest of the team worked on the JavaFX interface, user management, database, and poll business logic. We conducted regular code reviews and used Git for source code management.
Architecture
Java client-server application with JavaFX interface:
- JavaFX Client: GUI for poll creation, voting, and result viewing.
- Java Server: Poll management, encrypted vote storage, decryption at poll closure.
- ElGamal Cryptography: Key generation (public/private), client-side vote encryption, server-side decryption at poll closure.
- Zero Knowledge Proof: createZKProof (client) and verifyZKProof (server) functions in the cryptographic library to validate that each vote is strictly 0 or 1 without revealing its value.
- FAQ ChatBot: Integrated chatbot using the DeepSeek API to understand user questions and provide pre-prepared answers related to the application.
- Secure Sockets: Encrypted client-server communication to protect data exchanges.
- Methodology: Scrum with sprints, backlog, retrospectives, client presentations, technical documents.
Screenshots
Skills developed
ElGamal cryptography
Complete implementation of the ElGamal protocol: asymmetric key generation, vote encryption and decryption. Understanding of mathematical foundations (discrete logarithm, modular arithmetic) and security challenges.
Non-interactive Zero Knowledge Proof
Cryptographic verification that each vote is strictly 0 or 1 without revealing its value. Non-interactive proof in a single exchange via cryptographic commitments, SHA-256 hash, and modular arithmetic (createZKProof and verifyZKProof functions).
AI ChatBot (DeepSeek API)
Implementation of a FAQ chatbot integrated into the application using the DeepSeek API to understand user questions and provide relevant pre-prepared answers, limited to the application context.
Socket Security
Implementation of encrypted client-server communications via Java sockets, protection against interception and data manipulation in transit.
Product Owner (Scrum)
Product backlog management, feature prioritization, sprint organization, oral client presentations, technical document writing. Interface between client needs and the development team.
Advanced Java & JavaFX
Development of a complete Java desktop application with JavaFX GUI, event handling, and client-server architecture.
Code highlights
1// Referendum - Chiffrement ElGamal en Java
2import java.math.BigInteger;
3import java.security.SecureRandom;
4
5public class ElGamalEncryption {
6 private BigInteger p; // Nombre premier grand
7 private BigInteger g; // Generateur
8 private BigInteger publicKey; // Cle publique (g^x mod p)
9 private BigInteger privateKey; // Cle privee (x)
10
11 public ElGamalEncryption(int bitLength) {
12 SecureRandom random = new SecureRandom();
13 // 1. Generer nombre premier p de taille bitLength
14 this.p = BigInteger.probablePrime(bitLength, random);
15 // 2. Trouver generateur g du groupe multiplicatif Z*p
16 this.g = findGenerator(p, random);
17 // 3. Generer cle privee x (aleatoire dans [1, p-2])
18 this.privateKey = new BigInteger(bitLength - 1, random);
19 // 4. Calculer cle publique: h = g^x mod p
20 this.publicKey = g.modPow(privateKey, p);
21 }
22
23 public ElGamalCiphertext encrypt(BigInteger message) {
24 SecureRandom random = new SecureRandom();
25 // 1. Generer k aleatoire (ephemere) dans [1, p-2]
26 BigInteger k = new BigInteger(p.bitLength() - 1, random);
27 // 2. Calculer c1 = g^k mod p
28 BigInteger c1 = g.modPow(k, p);
29 // 3. Calculer s = h^k mod p (secret partage)
30 BigInteger s = publicKey.modPow(k, p);
31 // 4. Calculer c2 = m * s mod p
32 BigInteger c2 = message.multiply(s).mod(p);
33 return new ElGamalCiphertext(c1, c2);
34 }
35
36 public BigInteger decrypt(ElGamalCiphertext ciphertext) {
37 BigInteger s = ciphertext.c1.modPow(privateKey, p);
38 BigInteger sInverse = s.modInverse(p);
39 return ciphertext.c2.multiply(sInverse).mod(p);
40 }
41}ElGamal asymmetric encryption implementation in Java with BigInteger for large numbers. Key generation uses a 512+ bit prime p, generator g, random private key x and public key h = g^x mod p. Encryption generates ephemeral k, computes c1 = g^k and c2 = m * h^k, ensuring security through discrete logarithm hardness.
1// Referendum - Controlleur JavaFX pour vote chiffre
2public class VoteController {
3 @FXML private ListView<String> candidateListView;
4 @FXML private TextArea encryptedVoteArea;
5 @FXML private Label statusLabel;
6 private ElGamalEncryption elGamal;
7
8 @FXML
9 private void handleVote() {
10 String selected = candidateListView.getSelectionModel().getSelectedItem();
11 if (selected == null) {
12 statusLabel.setText("Erreur: Selectionnez un candidat!");
13 return;
14 }
15
16 // 1. Convertir choix en BigInteger (A=1, B=2, C=3, Blanc=0)
17 int index = candidateListView.getItems().indexOf(selected);
18 BigInteger voteValue = BigInteger.valueOf(index);
19
20 // 2. Chiffrer le vote avec ElGamal
21 ElGamalCiphertext encrypted = elGamal.encrypt(voteValue);
22
23 // 3. Afficher vote chiffre en hexadecimal
24 encryptedVoteArea.setText(String.format(
25 "c1 = %s\nc2 = %s",
26 encrypted.c1.toString(16),
27 encrypted.c2.toString(16)
28 ));
29
30 // 4. Enregistrer et confirmer
31 database.saveEncryptedVote(encrypted);
32 statusLabel.setText("Vote enregistre! (Chiffre ElGamal)");
33 voteButton.setDisable(true);
34 }
35}This JavaFX controller manages the encrypted voting interface. User selects a candidate, vote is converted to BigInteger then encrypted with ElGamal. Ciphertext (c1, c2) is displayed in hexadecimal and stored in database. Only the administrator with the private key can decrypt results.
Results & outcomes
The Referendum project was successfully conducted throughout the academic year:
- Functional and secure voting application: Poll creation, confidential voting with ElGamal encryption, result viewing after closure, all through an intuitive JavaFX interface.
- Operational ElGamal cryptography: The asymmetric encryption system ensures votes are unreadable in transit and storage, and are only decrypted at poll closure.
- Functional Zero Knowledge Proof: Cryptographic verification that each vote is indeed 0 or 1 in a single exchange, without compromising vote confidentiality. Invalid votes are automatically rejected by the server.
- Operational FAQ ChatBot: Integrated chatbot using the DeepSeek API to answer users' frequently asked questions in a relevant and contextual manner.
- Secure communications: Client-server exchanges via sockets are encrypted, preventing any interception.
- Scrum methodology respected: Regular sprints, deliveries, continuous improvement through new contracts, oral presentations to the client, and complete technical documents at each phase.
- Structured teamwork: Effective collaboration of 4, with clear roles and good work distribution.
Reflection & learnings
The Referendum project taught me the most on a professional level during my studies:
- 01The Product Owner role taught me to see a project beyond the code. Managing a backlog, prioritizing features based on business value, and presenting a product to a client, these are skills I wouldn't have developed by staying purely a developer.
- 02ElGamal cryptography and Zero Knowledge Proof confronted me with a domain I knew nothing about. Understanding the mathematical foundations (discrete logarithm, modular arithmetic, SHA-256), implementing an asymmetric encryption protocol, and designing a non-interactive proof guaranteeing vote integrity without compromising confidentiality gave me a genuine sensitivity to cybersecurity and the rigor it demands.
- 03The AI chatbot with DeepSeek allowed me to explore integrating artificial intelligence APIs into a concrete application, limiting the AI to question understanding to provide relevant pre-prepared answers.
- 04The project duration (the full year) taught me long-term management: maintaining motivation, managing technical debt, and adapting to scope changes with each new contract. It's very different from a project lasting just a few weeks.
- 05Oral presentations and technical documents forced me to structure my thinking and explain complex concepts in an accessible way. It's an essential skill that code alone doesn't develop.