P
Petr Ploskikh
Guest
How HappyVote on Aztec approaches ballot privacy, one-person-one-vote, public verification, and the trust assumptions behind remote electronic voting.
Electronic voting has a difficult set of requirements that pull in opposite directions.
A voting system needs to establish that only eligible participants can vote and that nobody can vote twice. At the same time, it must prevent anyone from learning how a particular person voted. The tally must be verifiable, while a voter should not receive a receipt that can be shown to an employer, government official, teacher, or anyone else as proof of their choice.
And there is another question that is easy to miss:
Who has to be trusted for the system to produce the result it claims to produce?
This article looks at that question through two very different architectures.
In September 2020, Rostelecom published an overview on Habr of Russia’s remote electronic voting system (DEG), describing its cryptographic design and infrastructure. The system uses verified identity through ESIA/Gosuslugi, blind signatures, homomorphic ElGamal encryption, Pedersen distributed key generation, Shamir’s secret sharing, tally servers, and a permissioned blockchain.
The architecture is technically sophisticated.
But the 2020 Habr discussion focused on a different question: where does trust ultimately sit?
I built HappyVote on Aztec as an experiment in a different direction: a public voting platform where ballots can be private while the tally remains publicly readable on a programmable privacy network.
HappyVote uses Aztec private calls, nullifiers for one-vote-per-period enforcement, optional ZKPassport identity verification for high-stakes polls, and public contract state for tallying.
This is not a replacement for the Russian Central Election Commission, and it is not a proposal to put government elections on a blockchain. HappyVote is a public polling service, not an election commission.
The comparison is technical: two architectures make different trade-offs around privacy, identity, verification, operator trust, and public observability.
Rostelecom’s 2020 Habr article lists six requirements for a ballot box and remote electronic voting:
These requirements are individually understandable. The engineering difficulty comes from satisfying them simultaneously.
For example:
The interesting part is therefore not the word blockchain.
It is the trust boundary.
The 2020 Rostelecom description provides a useful real-world example.
Registration and authentication go through a verified ESIA/Gosuslugi account.
The voter roll is checked against GAS “Vybory” and loaded into the DEG hardware/software infrastructure. Unique identifiers are written to the blockchain.
Observers access the relevant information from a dedicated workstation in the commission’s room.
After authentication, the voter is sent to an “anonymous zone” on another domain and advised to enable a VPN.
A cryptographic blind signature is used to break the direct link between the voter and the ballot key: the system can attest that a participant has the right to vote without learning which key it signed.
The ballot is encrypted on the voter’s device using ElGamal.
The corresponding private key is distributed among multiple participants using Pedersen distributed key generation and Shamir’s secret sharing. Until the key is reconstructed, the encrypted ballots cannot be decrypted, including for intermediate results.
Encrypted ballots can be combined homomorphically.
The resulting ciphertext represents the sum of the votes, allowing the system to decrypt the aggregate without decrypting each individual ballot. Correctness is accompanied by zero-knowledge proofs.
In the Rostelecom description, the blockchain provides immutability of votes and smart contracts, stores identical copies, and exposes transactions from the opening of the vote through the recording of results.
Alongside the blockchain nodes are tally servers responsible for generating keys, checking ciphertexts, adding encrypted ballots, and participating in joint decryption.
This is a coherent cryptographic design.
The question is what happens when we remove the diagrams and ask:
Several roles remain trusted components of the system.
Blind signatures and ElGamal solve real cryptographic problems.
They do not, by themselves, eliminate trust in the operator controlling the identity system, permissioned nodes, key ceremony, tally infrastructure, or client software.
This distinction matters.
A cryptographic primitive can be mathematically sound while the overall system still depends on trusted infrastructure around it.
The comments under the original Habr article repeatedly returned to the same engineering concern: the relationship between the public result and the infrastructure that produces it.
Several recurring objections were raised.
One commenter pointed out that there were no independent observer nodes in the architecture. If one actor controls all of the nodes in a permissioned network, the trust model is fundamentally different from a public blockchain such as Bitcoin or Ethereum.
Other comments raised denial-of-service concerns around the identity system.
Another line of criticism asked what prevents the system from storing one set of votes while presenting another result.
The deeper question was:
Another commenter argued that trust remains limited until observers can independently inspect the same ledger rather than depending on access to the operator’s infrastructure.
A further objection concerned the fact that encrypted ballots remain hidden until the final decryption procedure.
That protects the secrecy of intermediate results, but it also means an independent observer cannot inspect the actual running tally.
Several commenters identified a classic voting-system problem:
If a voter can prove how they voted, someone else can demand that proof.
A manager can ask an employee to demonstrate their vote. A teacher can ask a student. A political organization can ask a supporter.
A mechanism designed to increase individual verifiability can therefore undermine ballot secrecy.
Another proposal in the discussion was to distribute anonymized ballots to independent observers or candidates’ infrastructure so that multiple parties could perform their own count.
The central idea is simple:
Do not require everyone to trust one tallying authority if independent parties can verify the same public data.
I built HappyVote by reversing several of those assumptions.
The goal is not to reproduce every property of a government election system.
The goal is to explore what becomes possible when the voting protocol itself runs on a public privacy-preserving blockchain.
The HappyVote contract runs on the Aztec Network.
Consensus and block proving are not controlled by the HappyVote operator.
The contract address, RPC endpoint, and explorer are public.
The operator can create, pause, and close polls according to the contract’s privileged operations, but cannot simply rewrite already included ballots and publish a different blockchain history.
An Aztec private call hides the sender of a private transaction.
Double voting is prevented through a nullifier mechanism (
Privacy here is therefore a protocol property, not a second domain plus a VPN.
HappyVote does not keep encrypted ballots waiting for a private-key ceremony.
A private ballot triggers an update to the public
There is no ElGamal ballot-decryption key shared between operators.
The public tally is part of the contract state.
Normal polls can use an Aztec account as the unit of participation.
For high-stakes polls, HappyVote uses ZKPassport.
The identity proof is generated on the user’s device. The platform receives predicates and a
High-stakes polls also use FaceMatch in
The identity claim is then bound to the poll on-chain.
The contract, tests, public UI, and public APIs are available in the repository:
https://github.com/pittpv/happy-vote-aztec
There is no hidden blockchain infrastructure that an observer must trust in order to understand the result.
The basic guest path does not require a wallet to inspect a poll.
The voter can see:
Casting a vote consists of several steps.
For a high-stakes poll:
On desktop, Azguard Wallet browser extension is preferred.
Browser Session for mobile devices also available.
On Testnet, the public Sponsored FPC covers the ballot fee.
The poll can permit:
The contract uses the same one-vote claim for both modes, so a voter cannot first vote privately and then vote again in open mode.
The private path can be simplified to:
The voter’s address is not published on the private path.
There is an important limitation, however:
Therefore, if a poll is not sealed, the public board can show which option’s counter moved.
Private voting hides the voter’s address from the public ballot record. It does not hide the option’s changing public tally.
This distinction is important enough to state explicitly.
HappyVote’s private mode does not promise universal anonymity.
It does not hide:
What Aztec privacy changes is the exposure of the sender at the protocol level.
That is a fundamentally different property from asking a user to change their IP address.
If the poll creator does not want the dynamics of voting to be visible, the poll can be created in sealed mode.
In sealed mode, view methods return zeros while the poll is open. After the poll closes, the counters become readable.
This should not be confused with homomorphic encryption or MPC.
It is an application-level presentation mode.
One of the hardest parts of remote voting is distinguishing an account from a person.
Without identity verification, HappyVote’s unit is an account.
A browser session can create a new address.
That is acceptable for lightweight polls such as Happy/Sad, but it is not sufficient for a high-stakes decision where “one account, one vote” is not the same as “one person, one vote.”
For those polls, HappyVote uses ZKPassport.
The flow is:
The resulting commitment is associated with the poll rather than exposing the user’s full identity on-chain.
The system therefore does not need a server-side passport database to enforce the identity constraint.
There is an important limitation:
one document is not necessarily one human forever.
If one living person has multiple valid identity documents, FaceMatch does not turn those documents into one universal civil identity.
The system is designed to address the specific classes of problems described here — such as a deceased person’s document or another person presenting a stolen document — not to replace a national population register.
The 2020 Habr discussion raised another issue that is easy to overlook in cryptographic voting systems: the voter registry itself can become part of the trust boundary.
If the system knows only that a registry row exists and an account was issued a ballot, cryptography cannot establish that a living person is actually operating the account.
HappyVote takes a different approach for high-stakes polls.
The relevant chain is:
A deceased person’s document cannot pass a live-face check.
A stolen document without its legitimate holder should not match the biometric image stored on the chip.
The platform does not receive the passport scan as the identity record.
Again, this does not create perfect remote-voting security. It addresses one specific trust boundary: whether the person presenting the document is the document holder.
It does not prove that the person is voting freely.
Remote voting cannot solve every problem with cryptography.
Suppose a voting system gives a voter a permanent receipt saying:
That receipt can be shown to someone else.
The same feature that makes individual verification stronger can make coercion easier.
HappyVote’s private mode deliberately does not create such a public receipt.
An observer can see that a transaction occurred.
They cannot look at the public chain and find:
The open mode explicitly provides that relationship when the poll allows it.
This is why open and private voting are separate modes.
And it is why cryptography cannot solve the problem of someone standing behind a voter’s monitor.
A privacy-preserving protocol can avoid creating a receipt.
It cannot prove that a person was not under pressure while using their device.
One of the architectural differences between the two systems is where an observer needs to go to inspect the result.
In the DEG architecture described by Rostelecom, observation is tied to dedicated infrastructure and an observer workstation.
In HappyVote, the relevant state is public blockchain state.
An observer can use:
The guest API is a convenience for the UI.
The contract is the source of truth.
For example, the catalog is bound to an on-chain
The goal is not to make the UI trustworthy because it says it is trustworthy.
The goal is to make it possible to inspect the underlying state independently.
The comparison can be summarized as follows.
The point is not that one table makes one system universally suitable.
The point is that the systems place trust in different places.
There are two important DEG properties that HappyVote does not copy one-to-one.
DEG is designed around the Russian electoral framework and therefore uses the national voter-registration infrastructure.
HappyVote does not participate in that electoral process and does not claim legal election status under Federal Law No. 67-FZ.
DEG’s architecture uses homomorphic encryption so that the encrypted ballots can be combined and the aggregate decrypted later.
HappyVote intentionally takes a different route.
A private ballot can update a public tally immediately.
If a use case requires the voting dynamics to remain hidden, the poll can be sealed until closing.
This is a different trade-off.
In a permissioned system, blockchain immutability still depends on who controls the permissioned infrastructure.
On Aztec, the HappyVote operator does not control the network’s consensus.
Once a transaction is included in the public network, rewriting it is no longer a matter of changing the application’s own database.
The trust boundary moves.
A private Aztec call removes the sender address from the public trace of the private ballot.
That is stronger than asking the user to visit another domain or enable a VPN.
It still does not provide network-layer anonymity.
HappyVote does not require a private ballot-decryption key to be split between multiple participants.
A private proof establishes that the account has a valid unused claim and that the ballot is valid.
The contract then updates the tally.
An observer does not need to trust that a group of key holders performed a decryption ceremony correctly.
The same public chain is available to anyone.
An observer does not need access to a commission workstation to inspect the relevant contract state.
For high-stakes polls, ZKPassport and FaceMatch allow the system to verify identity-related properties without turning the voting platform into a passport database.
The contract receives a commitment rather than a full identity document.
If the tally is public contract state, anyone can read and count it.
A candidate, journalist, researcher, or independent observer does not need a private feed from the voting operator.
The public state is the feed.
The important part is what is not in the diagram.
There is no central tally server.
There is no ballot-decryption key ceremony.
There is no private blockchain controlled by the application operator.
For high-stakes polls, there is also no passport file sent to the voting platform.
HappyVote currently runs on Aztec Testnet 5.1.0. The target is Alpha.
Contract:
This matters because the implementation should not be described as a production-grade election system.
The current system is a live public demonstration of the architecture.
Its limitations are part of the design discussion.
There is no voter register, election commission status, or legally binding election result.
The implementation runs on Aztec Testnet.
It should not be presented as having the final security or finality guarantees of a mature production network.
A sealed poll hides the counters until the configured closing time.
It is an application-level visibility rule.
It is not homomorphic encryption, MPC, or a cryptographic ballot box.
If a poll is not sealed, a private ballot can cause a visible change in the public counter.
The sender is private; the live tally is not.
Timing correlation remains possible.
Aztec privacy does not hide IP addresses, browser fingerprints, timing information, or the fact that someone used the application.
The operator can create, pause, and close polls.
Those privileges are visible in the contract.
They do not give the operator the ability to rewrite another user’s already recorded ballot.
Without ZKPassport, the system enforces one vote per account.
A new browser session can create a new account.
High-stakes polls therefore require an identity claim and strict FaceMatch.
FaceMatch addresses the case of someone presenting another person’s document and helps exclude deceased-document and stolen-document scenarios.
It does not transform multiple valid documents belonging to one person into one universal civil identity.
It proves that the person presenting the document matches the biometric identity.
It does not prove that nobody else is standing behind the monitor.
That limitation applies to remote voting generally.
The most useful way to think about HappyVote is not:
That is not what it is.
It is a different primitive for situations where a group needs to make a decision and wants some combination of:
Possible examples include community decisions, product decisions, internal referenda, personhood polls, DAO governance experiments, and other situations where identity or ballot privacy matters.
The privacy policy can be configured per poll:
The system therefore does not assume that every poll has the same requirements.
The easiest way to evaluate the architecture is not to trust this article.
Inspect the implementation.
Live application
https://aztec.happyvote.xyz
Poll catalog
https://aztec.happyvote.xyz/polls
Example polls
Contract
https://testnet.aztecscan.xyz/addre...9a62f570535966fb940bb10d18a0c146a36cac64713b6
Source code
https://github.com/pittpv/happy-vote-aztec
Aztec documentation
https://docs.aztec.network/
ZKPassport
https://zkpassport.id/
Guest tallies can be read without a wallet.
To vote on Testnet, connecting is sufficient; the network’s Sponsored FPC covers the ballot fee itself.
The interesting change introduced by privacy-preserving blockchains is not simply that votes can be encrypted.
The deeper change is that several trust assumptions can move from the application operator into the protocol.
In the architecture described by Rostelecom, cryptography protects the ballot while a number of institutional components remain part of the trust boundary:
HappyVote makes a different set of choices:
None of these choices makes remote voting magically secure.
They change what has to be trusted.
That is the architectural question worth asking whenever someone says that a voting system is “on blockchain.”
In 2020, the discussion around remote electronic voting on Habr repeatedly came back to a simple engineering demand:
Show me what the system actually knows, who controls it, and how I can independently verify the result.
Privacy-preserving blockchain infrastructure makes it possible to approach that demand differently.
A voter can submit a private ballot.
A nullifier can prevent a second vote.
A public smart contract can maintain the tally.
ZKPassport can establish identity-related properties without handing a passport file to the voting application.
An observer can inspect the same public contract state as everyone else.
And the implementation can be open source.
HappyVote is not a government election system and does not claim to solve the legal, social, or coercion problems of remote elections.
It is a working experiment in a narrower question:
On Aztec, the answer can be demonstrated rather than merely described.
The next step is to inspect the contract, inspect the transactions, run the polls, and challenge the assumptions.
That is the point of an open protocol.
**Peter Ploskikh \ X — https://x.com/pittpv
The problem is not just “put voting on a blockchain”
Electronic voting has a difficult set of requirements that pull in opposite directions.
A voting system needs to establish that only eligible participants can vote and that nobody can vote twice. At the same time, it must prevent anyone from learning how a particular person voted. The tally must be verifiable, while a voter should not receive a receipt that can be shown to an employer, government official, teacher, or anyone else as proof of their choice.
And there is another question that is easy to miss:
Who has to be trusted for the system to produce the result it claims to produce?
This article looks at that question through two very different architectures.
In September 2020, Rostelecom published an overview on Habr of Russia’s remote electronic voting system (DEG), describing its cryptographic design and infrastructure. The system uses verified identity through ESIA/Gosuslugi, blind signatures, homomorphic ElGamal encryption, Pedersen distributed key generation, Shamir’s secret sharing, tally servers, and a permissioned blockchain.
The architecture is technically sophisticated.
But the 2020 Habr discussion focused on a different question: where does trust ultimately sit?
I built HappyVote on Aztec as an experiment in a different direction: a public voting platform where ballots can be private while the tally remains publicly readable on a programmable privacy network.
HappyVote uses Aztec private calls, nullifiers for one-vote-per-period enforcement, optional ZKPassport identity verification for high-stakes polls, and public contract state for tallying.
This is not a replacement for the Russian Central Election Commission, and it is not a proposal to put government elections on a blockchain. HappyVote is a public polling service, not an election commission.
The comparison is technical: two architectures make different trade-offs around privacy, identity, verification, operator trust, and public observability.
1. What a Remote Voting System Has to Guarantee
Rostelecom’s 2020 Habr article lists six requirements for a ballot box and remote electronic voting:
- Secrecy of the vote.
- Only eligible people may cast a ballot.
- One voter, one vote.
- Openness and publicity for voters and observers.
- Immutability of a submitted ballot.
- No one should learn intermediate results before the vote closes.
These requirements are individually understandable. The engineering difficulty comes from satisfying them simultaneously.
For example:
- If you make every vote publicly visible, verification is easy but secrecy is lost.
- If you hide every ballot until the end, independent observers cannot inspect the running system.
- If you identify every voter directly, eligibility is easy to enforce but voter privacy becomes a trust problem.
- If a voter receives a cryptographic receipt proving their choice, that receipt can potentially be used for coercion.
- If a central operator controls the nodes and the tally infrastructure, “blockchain” does not automatically make that operator decentralized.
The interesting part is therefore not the word blockchain.
It is the trust boundary.
2. Where Trust Sits in Russia’s DEG Architecture
The 2020 Rostelecom description provides a useful real-world example.
Identity
Registration and authentication go through a verified ESIA/Gosuslugi account.
The voter roll is checked against GAS “Vybory” and loaded into the DEG hardware/software infrastructure. Unique identifiers are written to the blockchain.
Observers access the relevant information from a dedicated workstation in the commission’s room.
Anonymization
After authentication, the voter is sent to an “anonymous zone” on another domain and advised to enable a VPN.
A cryptographic blind signature is used to break the direct link between the voter and the ballot key: the system can attest that a participant has the right to vote without learning which key it signed.
Confidentiality until the vote closes
The ballot is encrypted on the voter’s device using ElGamal.
The corresponding private key is distributed among multiple participants using Pedersen distributed key generation and Shamir’s secret sharing. Until the key is reconstructed, the encrypted ballots cannot be decrypted, including for intermediate results.
Tallying
Encrypted ballots can be combined homomorphically.
The resulting ciphertext represents the sum of the votes, allowing the system to decrypt the aggregate without decrypting each individual ballot. Correctness is accompanied by zero-knowledge proofs.
Blockchain
In the Rostelecom description, the blockchain provides immutability of votes and smart contracts, stores identical copies, and exposes transactions from the opening of the vote through the recording of results.
Alongside the blockchain nodes are tally servers responsible for generating keys, checking ciphertexts, adding encrypted ballots, and participating in joint decryption.
This is a coherent cryptographic design.
The question is what happens when we remove the diagrams and ask:
Which parties must I trust for all of those cryptographic guarantees to correspond to the result I see?
3. The Trust Boundary Is More Important Than the Blockchain Label
Several roles remain trusted components of the system.
| Component | Trust assumption |
|---|---|
| ESIA / Gosuslugi | Determines who gets onto the voter list and who receives a ballot |
| Node operators | Determine the canonical chain in a permissioned network |
| Key-share holders | Participate in reconstructing the private key used to decrypt the result |
| Tally servers | Validate ciphertexts, aggregate them, and participate in decryption |
| Voting portal | Serves the JavaScript that constructs and encrypts the ballot |
Blind signatures and ElGamal solve real cryptographic problems.
They do not, by themselves, eliminate trust in the operator controlling the identity system, permissioned nodes, key ceremony, tally infrastructure, or client software.
This distinction matters.
A cryptographic primitive can be mathematically sound while the overall system still depends on trusted infrastructure around it.
4. What the 2020 Habr Discussion Focused On
The comments under the original Habr article repeatedly returned to the same engineering concern: the relationship between the public result and the infrastructure that produces it.
Several recurring objections were raised.
All nodes belong to one actor
One commenter pointed out that there were no independent observer nodes in the architecture. If one actor controls all of the nodes in a permissioned network, the trust model is fundamentally different from a public blockchain such as Bitcoin or Ethereum.
Other comments raised denial-of-service concerns around the identity system.
The count cannot be independently reproduced
Another line of criticism asked what prevents the system from storing one set of votes while presenting another result.
The deeper question was:
Can an independent observer verify, using public tools, that a particular ballot entered the system and contributed to the announced result?
The ledger is not independently controlled by the voter
Another commenter argued that trust remains limited until observers can independently inspect the same ledger rather than depending on access to the operator’s infrastructure.
The vote is not immediately visible
A further objection concerned the fact that encrypted ballots remain hidden until the final decryption procedure.
That protects the secrecy of intermediate results, but it also means an independent observer cannot inspect the actual running tally.
A receipt can become a coercion mechanism
Several commenters identified a classic voting-system problem:
If a voter can prove how they voted, someone else can demand that proof.
A manager can ask an employee to demonstrate their vote. A teacher can ask a student. A political organization can ask a supporter.
A mechanism designed to increase individual verifiability can therefore undermine ballot secrecy.
Independent parallel counting
Another proposal in the discussion was to distribute anonymized ballots to independent observers or candidates’ infrastructure so that multiple parties could perform their own count.
The central idea is simple:
Do not require everyone to trust one tallying authority if independent parties can verify the same public data.
5. HappyVote Starts With Different Assumptions
I built HappyVote by reversing several of those assumptions.
The goal is not to reproduce every property of a government election system.
The goal is to explore what becomes possible when the voting protocol itself runs on a public privacy-preserving blockchain.
A public network instead of an operator-controlled consortium
The HappyVote contract runs on the Aztec Network.
Consensus and block proving are not controlled by the HappyVote operator.
The contract address, RPC endpoint, and explorer are public.
The operator can create, pause, and close polls according to the contract’s privileged operations, but cannot simply rewrite already included ballots and publish a different blockchain history.
Privacy at the protocol level
An Aztec private call hides the sender of a private transaction.
Double voting is prevented through a nullifier mechanism (
SingleUseClaim) rather than a voter-list entry controlled by the voting operator.Privacy here is therefore a protocol property, not a second domain plus a VPN.
Public tally instead of a decryption ceremony
HappyVote does not keep encrypted ballots waiting for a private-key ceremony.
A private ballot triggers an update to the public
tally[option] state.There is no ElGamal ballot-decryption key shared between operators.
The public tally is part of the contract state.
Identity without storing a passport
Normal polls can use an Aztec account as the unit of participation.
For high-stakes polls, HappyVote uses ZKPassport.
The identity proof is generated on the user’s device. The platform receives predicates and a
uniqueIdentifier, rather than a passport scan.High-stakes polls also use FaceMatch in
strict mode: a live face is checked against the biometric photo stored on the chip, together with extended liveness checks.The identity claim is then bound to the poll on-chain.
Open source
The contract, tests, public UI, and public APIs are available in the repository:
https://github.com/pittpv/happy-vote-aztec
There is no hidden blockchain infrastructure that an observer must trust in order to understand the result.
6. How a HappyVote Ballot Works
The basic guest path does not require a wallet to inspect a poll.
The voter can see:
- the question;
- the available options;
- public totals, unless the poll is sealed.
Casting a vote consists of several steps.
Step 1: Optional identity verification
For a high-stakes poll:
- The user scans an NFC-enabled identity document.
- ZKPassport generates the identity proof.
- FaceMatch
strictmode compares a live face against the biometric image on the chip. - The server re-verifies the proof.
- The UI displays the verified state.
Step 2: Connect
On desktop, Azguard Wallet browser extension is preferred.
Browser Session for mobile devices also available.
On Testnet, the public Sponsored FPC covers the ballot fee.
Step 3: Select the voting mode
The poll can permit:
- Private — the default for private voting;
- Open — the voter explicitly publishes the address-to-choice relationship.
The contract uses the same one-vote claim for both modes, so a voter cannot first vote privately and then vote again in open mode.
The private path can be simplified to:
Code:
cast_vote_private
→ SingleUseClaim
→ enqueue add_to_tally_public
→ tally[option] += 1
→ total_votes += 1
The voter’s address is not published on the private path.
There is an important limitation, however:
option_id in the public enqueue is visible.Therefore, if a poll is not sealed, the public board can show which option’s counter moved.
Private voting hides the voter’s address from the public ballot record. It does not hide the option’s changing public tally.
7. Private Does Not Mean “Invisible to Everything”
This distinction is important enough to state explicitly.
HappyVote’s private mode does not promise universal anonymity.
It does not hide:
- IP addresses;
- browser/device information;
- transaction timing;
- the fact that someone accessed the service;
- timing correlations with a live public tally.
What Aztec privacy changes is the exposure of the sender at the protocol level.
That is a fundamentally different property from asking a user to change their IP address.
If the poll creator does not want the dynamics of voting to be visible, the poll can be created in sealed mode.
In sealed mode, view methods return zeros while the poll is open. After the poll closes, the counters become readable.
This should not be confused with homomorphic encryption or MPC.
It is an application-level presentation mode.
8. ZKPassport and One-Person-One-Vote
One of the hardest parts of remote voting is distinguishing an account from a person.
Without identity verification, HappyVote’s unit is an account.
A browser session can create a new address.
That is acceptable for lightweight polls such as Happy/Sad, but it is not sufficient for a high-stakes decision where “one account, one vote” is not the same as “one person, one vote.”
For those polls, HappyVote uses ZKPassport.
The flow is:
- An NFC identity document is read on the user’s phone.
- ZKPassport creates a proof without sending the passport file to HappyVote.
- FaceMatch
strictmode captures a live face and compares it with the biometric photo on the chip. - Extended liveness checks make a static photograph insufficient.
- HappyVote re-verifies the proof server-side.
- An on-chain identity commitment is derived from the ZKPassport
uniqueIdentifier. - The same identity cannot claim a second ballot for the poll.
The resulting commitment is associated with the poll rather than exposing the user’s full identity on-chain.
The system therefore does not need a server-side passport database to enforce the identity constraint.
There is an important limitation:
one document is not necessarily one human forever.
If one living person has multiple valid identity documents, FaceMatch does not turn those documents into one universal civil identity.
The system is designed to address the specific classes of problems described here — such as a deceased person’s document or another person presenting a stolen document — not to replace a national population register.
9. Dead Souls, Live Faces, and the Identity Problem
The 2020 Habr discussion raised another issue that is easy to overlook in cryptographic voting systems: the voter registry itself can become part of the trust boundary.
If the system knows only that a registry row exists and an account was issued a ballot, cryptography cannot establish that a living person is actually operating the account.
HappyVote takes a different approach for high-stakes polls.
The relevant chain is:
Code:
NFC document
↓
ZKPassport proof
↓
strict FaceMatch + liveness
↓
server-side verification
↓
identity commitment
↓
on-chain one-time claim
↓
ballot
A deceased person’s document cannot pass a live-face check.
A stolen document without its legitimate holder should not match the biometric image stored on the chip.
The platform does not receive the passport scan as the identity record.
Again, this does not create perfect remote-voting security. It addresses one specific trust boundary: whether the person presenting the document is the document holder.
It does not prove that the person is voting freely.
10. The Coercion Problem Does Not Disappear
Remote voting cannot solve every problem with cryptography.
Suppose a voting system gives a voter a permanent receipt saying:
Code:
Address X → Option Y
That receipt can be shown to someone else.
The same feature that makes individual verification stronger can make coercion easier.
HappyVote’s private mode deliberately does not create such a public receipt.
An observer can see that a transaction occurred.
They cannot look at the public chain and find:
Code:
Address X voted for Option Y
The open mode explicitly provides that relationship when the poll allows it.
This is why open and private voting are separate modes.
And it is why cryptography cannot solve the problem of someone standing behind a voter’s monitor.
A privacy-preserving protocol can avoid creating a receipt.
It cannot prove that a person was not under pressure while using their device.
11. Public Verification Without a Commission Workstation
One of the architectural differences between the two systems is where an observer needs to go to inspect the result.
In the DEG architecture described by Rostelecom, observation is tied to dedicated infrastructure and an observer workstation.
In HappyVote, the relevant state is public blockchain state.
An observer can use:
- the Aztec explorer;
- the public RPC;
- the HappyVote guest API;
- the published contract source.
The guest API is a convenience for the UI.
The contract is the source of truth.
For example, the catalog is bound to an on-chain
metadata_hash, which means that changing the poll wording after deployment would leave a detectable mismatch.The goal is not to make the UI trustworthy because it says it is trustworthy.
The goal is to make it possible to inspect the underlying state independently.
12. DEG vs. HappyVote: Different Trust Models
The comparison can be summarized as follows.
| Property | DEG architecture described by Rostelecom | HappyVote on Aztec |
|---|---|---|
| Network | Permissioned infrastructure | Public Aztec network |
| Node control | Nodes belong to the voting infrastructure | HappyVote does not validate Aztec blocks |
| Ballot privacy | Blind signatures + encrypted ballots | Aztec private calls |
| Double voting | Identity/ballot issuance infrastructure | SingleUseClaim nullifier |
| Tally | Homomorphic encrypted tally + joint decryption | Public tally contract state |
| Intermediate results | Hidden until decryption | Public by default, or sealed at the application layer |
| Identity | ESIA/Gosuslugi + voter registry | Account for ordinary polls; ZKPassport for high-stakes polls |
| Passport data | Part of the identity infrastructure | Passport data remains on the device; contract receives a commitment |
| Observer access | Dedicated observer infrastructure | Public explorer/RPC/contract state |
| Source | Described system includes operator-controlled infrastructure | Contract, tests, UI and APIs published on GitHub |
| Receipt | Verification architecture must balance secrecy and verifiability | Private mode does not expose address → option |
| Operator role | Identity, infrastructure, nodes, tally and key ceremony are trusted components | Operator retains contract privileges for creating/pausing/closing polls |
| Legal status | Government remote voting system | Public polling service; not an election commission |
The point is not that one table makes one system universally suitable.
The point is that the systems place trust in different places.
13. What HappyVote Deliberately Does Not Reproduce
There are two important DEG properties that HappyVote does not copy one-to-one.
Legal voter eligibility
DEG is designed around the Russian electoral framework and therefore uses the national voter-registration infrastructure.
HappyVote does not participate in that electoral process and does not claim legal election status under Federal Law No. 67-FZ.
Homomorphic encrypted tallying until the end
DEG’s architecture uses homomorphic encryption so that the encrypted ballots can be combined and the aggregate decrypted later.
HappyVote intentionally takes a different route.
A private ballot can update a public tally immediately.
If a use case requires the voting dynamics to remain hidden, the poll can be sealed until closing.
This is a different trade-off.
14. What This Architecture Changes
14.1 Immutability no longer depends on the voting operator
In a permissioned system, blockchain immutability still depends on who controls the permissioned infrastructure.
On Aztec, the HappyVote operator does not control the network’s consensus.
Once a transaction is included in the public network, rewriting it is no longer a matter of changing the application’s own database.
The trust boundary moves.
14.2 Privacy is implemented at the protocol level
A private Aztec call removes the sender address from the public trace of the private ballot.
That is stronger than asking the user to visit another domain or enable a VPN.
It still does not provide network-layer anonymity.
14.3 There is no ballot-decryption key ceremony
HappyVote does not require a private ballot-decryption key to be split between multiple participants.
A private proof establishes that the account has a valid unused claim and that the ballot is valid.
The contract then updates the tally.
An observer does not need to trust that a group of key holders performed a decryption ceremony correctly.
14.4 Observation does not require privileged infrastructure
The same public chain is available to anyone.
An observer does not need access to a commission workstation to inspect the relevant contract state.
14.5 Personhood can be verified without storing the passport
For high-stakes polls, ZKPassport and FaceMatch allow the system to verify identity-related properties without turning the voting platform into a passport database.
The contract receives a commitment rather than a full identity document.
14.6 Independent counting becomes straightforward
If the tally is public contract state, anyone can read and count it.
A candidate, journalist, researcher, or independent observer does not need a private feed from the voting operator.
The public state is the feed.
15. The Architecture in One Diagram
Code:
Voter
→ open poll on aztec.happyvote.xyz
→ site reads the public tally on Aztec
→ [high-stakes poll] NFC + FaceMatch strict in ZKPassport
→ server re-verifies proof
→ Connect + select option
→ generate proof + send transaction on Aztec Network
→ contract: validate nullifier + update tally
→ explorer link + results
The important part is what is not in the diagram.
There is no central tally server.
There is no ballot-decryption key ceremony.
There is no private blockchain controlled by the application operator.
For high-stakes polls, there is also no passport file sent to the voting platform.
16. What the Current Testnet Implementation Actually Does
HappyVote currently runs on Aztec Testnet 5.1.0. The target is Alpha.
Contract:
0x2e10858cf6750c003489a62f570535966fb940bb10d18a0c146a36cac64713b6This matters because the implementation should not be described as a production-grade election system.
The current system is a live public demonstration of the architecture.
Its limitations are part of the design discussion.
This is not a Russian election system
There is no voter register, election commission status, or legally binding election result.
This is Testnet
The implementation runs on Aztec Testnet.
It should not be presented as having the final security or finality guarantees of a mature production network.
Sealed mode is not MPC
A sealed poll hides the counters until the configured closing time.
It is an application-level visibility rule.
It is not homomorphic encryption, MPC, or a cryptographic ballot box.
Private does not hide the live option tally
If a poll is not sealed, a private ballot can cause a visible change in the public counter.
The sender is private; the live tally is not.
Timing correlation remains possible.
There is no channel anonymity
Aztec privacy does not hide IP addresses, browser fingerprints, timing information, or the fact that someone used the application.
The contract has privileged operations
The operator can create, pause, and close polls.
Those privileges are visible in the contract.
They do not give the operator the ability to rewrite another user’s already recorded ballot.
Account-based eligibility is not personhood
Without ZKPassport, the system enforces one vote per account.
A new browser session can create a new account.
High-stakes polls therefore require an identity claim and strict FaceMatch.
Multiple documents can still belong to one person
FaceMatch addresses the case of someone presenting another person’s document and helps exclude deceased-document and stolen-document scenarios.
It does not transform multiple valid documents belonging to one person into one universal civil identity.
FaceMatch does not prove absence of coercion
It proves that the person presenting the document matches the biometric identity.
It does not prove that nobody else is standing behind the monitor.
That limitation applies to remote voting generally.
17. Why This Is a Different Voting Primitive
The most useful way to think about HappyVote is not:
“A government election system, but on blockchain.”
That is not what it is.
It is a different primitive for situations where a group needs to make a decision and wants some combination of:
- private ballots;
- public tallying;
- one-vote-per-participant enforcement;
- optional personhood verification;
- independently readable state;
- open-source implementation;
- programmable voting rules.
Possible examples include community decisions, product decisions, internal referenda, personhood polls, DAO governance experiments, and other situations where identity or ballot privacy matters.
The privacy policy can be configured per poll:
- private only;
- open only;
- or voter choice.
The system therefore does not assume that every poll has the same requirements.
18. How to Inspect It Yourself
The easiest way to evaluate the architecture is not to trust this article.
Inspect the implementation.
Live application
https://aztec.happyvote.xyz
Poll catalog
https://aztec.happyvote.xyz/polls
Example polls
/p/1— Happy/Sad/p/2— single choice/p/3— ZKPassport personhood/p/4— sealed tally
Contract
https://testnet.aztecscan.xyz/addre...9a62f570535966fb940bb10d18a0c146a36cac64713b6
Source code
https://github.com/pittpv/happy-vote-aztec
Aztec documentation
https://docs.aztec.network/
ZKPassport
https://zkpassport.id/
Guest tallies can be read without a wallet.
To vote on Testnet, connecting is sufficient; the network’s Sponsored FPC covers the ballot fee itself.
19. The Broader Lesson
The interesting change introduced by privacy-preserving blockchains is not simply that votes can be encrypted.
The deeper change is that several trust assumptions can move from the application operator into the protocol.
In the architecture described by Rostelecom, cryptography protects the ballot while a number of institutional components remain part of the trust boundary:
- identity infrastructure;
- permissioned nodes;
- tally servers;
- key-share holders;
- client software;
- observer infrastructure.
HappyVote makes a different set of choices:
- a public network instead of an operator-controlled consortium;
- a protocol-level private call instead of an anonymous-zone workflow;
- a nullifier instead of a voter-list counter;
- public contract state instead of a final decryption ceremony;
- ZK identity proofs instead of uploading a passport;
- an open repository instead of asking observers to trust the deployed application.
None of these choices makes remote voting magically secure.
They change what has to be trusted.
That is the architectural question worth asking whenever someone says that a voting system is “on blockchain.”
20. Conclusion
In 2020, the discussion around remote electronic voting on Habr repeatedly came back to a simple engineering demand:
Show me what the system actually knows, who controls it, and how I can independently verify the result.
Privacy-preserving blockchain infrastructure makes it possible to approach that demand differently.
A voter can submit a private ballot.
A nullifier can prevent a second vote.
A public smart contract can maintain the tally.
ZKPassport can establish identity-related properties without handing a passport file to the voting application.
An observer can inspect the same public contract state as everyone else.
And the implementation can be open source.
HappyVote is not a government election system and does not claim to solve the legal, social, or coercion problems of remote elections.
It is a working experiment in a narrower question:
Can a voting system keep the ballot private while making the tally and the underlying protocol independently inspectable?
On Aztec, the answer can be demonstrated rather than merely described.
The next step is to inspect the contract, inspect the transactions, run the polls, and challenge the assumptions.
That is the point of an open protocol.
**Peter Ploskikh \ X — https://x.com/pittpv