₱17.99 Billion, and We Can't See How It Counts
The counting machine does two things. It reads the marks on a piece of paper, and it sends the total somewhere else. That is the entire job.
It does not check whether you are allowed to vote. That is the Electoral Board, working from a printed list and a bottle of indelible ink. The machine never learns your name. It doesn’t know what a senator is, or which race is close, or that the country is waiting. It looks at ovals, decides which ones are dark enough to count, adds them up, prints the total, and transmits.
We leased 110,620 of them for ₱17.99 billion, ₱149,000 a unit, for one day in May 2025. And the code that does the adding has never been put where you or I can read it.
What “open to the public” turned out to mean
In March 2024, Comelec announced that for the first time in PH election history it would open the counting machine source code to the public, and that Miru Systems had agreed to it. Chairman George Garcia said the code would go up on the Comelec website so anyone could access it and test it for vulnerabilities. That was reported, fairly, as a breakthrough.
What actually ran was the Local Source Code Review. It launched in Makati on 11 October 2024 and opened for reading on the 14th. To get in you had to be a registered political party or coalition, a Comelec-accredited organisation, or an IT group, university, or citizen watchdog endorsed by the DICT or the DOST. You filled out a form on the Comelec website. You went to the building. You read code in a room, during office hours.
None of that is open source. It is a reading room with a guest list. What did go up on the Comelec website was a review report and a list of hashes, the digital fingerprints of the files. Useful, but a fingerprint isn’t the recipe.
Then there’s the version. The review was supposed to close in December, and Comelec extended it into January because, in the words of its own LSCR committee chief, the code being reviewed was “not yet the secured versions of the systems intended for the final trusted build.” The certification committee accredited version 3.4. The machines ran 3.5. Comelec said 3.4 passed a third-party audit and was relabelled 3.5, the certifier later said it had reviewed 3.5, and Rappler’s fact-check found the published hashes matched. I’ll take that at face value. A matching hash only proves the machine ran the same file Comelec certified, though. It can’t tell you what that file does. For that you need the code.
The recipe
Open source means publishing the recipe.
Not “you may visit my kitchen.” Not “an accredited panel tasted it and signed a form.” The recipe, written out, in public, where anyone can read it: the ingredients, the amounts, the order, the temperature.
If the recipe says two tablespoons of salt where it should say sugar, somebody spots it. A pastry chef spots it. A hobbyist spots it. Somebody’s tita spots it. They spot it before you bake for 68 million people, not after.
Closed source is: trust me, it’s delicious. You can come to my kitchen in Makati between nine and five if you’re accredited. On the day, I’ll hand you a sealed box and a receipt that says it’s the same cake.
Fifteen percent
Somewhere in that code is a number that decides how dark a mark has to be before it counts as a vote. For 2025, Comelec set it at 15%, down from 25% in 2022.
That one number is the difference between a smudge and a vote, and between a stray ink mark and a whole contest voided as an overvote. ACM errors turned out to be the most reported problem of the 2025 midterms: 798 verified reports, 50.09% of all verified violations, mostly smudging, oversensitive scanners, and overvotes. PPCRV recommended going back to 25%. Chairman George Erwin Garcia said the poll body fully agrees.
So we changed the most consequential constant in the system, discovered it was wrong by holding a national election with it, and agreed to fix it afterwards. With the code public, that argument happens the previous October, in the open, with the actual thresholds on the table, instead of in May with 798 complaints and a shrug.
Your cashier’s machine is harder to build
The point-of-sale terminal at the counter of any convenience store does more, under more rules, than the machine that counts your vote.
It computes VAT. It applies senior citizen and PWD discounts under law. It takes cash, card, GCash, a gift certificate, and any split between them. It speaks EMV to the chip in your card and lives inside PCI DSS. It voids, refunds, and processes returns. It moves inventory. It runs the loyalty account. It prints a receipt with a sequential invoice number, on a machine the BIR has to accredit before the store can switch it on, and it keeps an audit log the BIR can walk in and inspect. It does all of that a few thousand times a day, every day, for years, and the cashier is on minimum wage.
The counting machine reads dark spots on paper and adds them up. Once every three years. For one day.
The whole count
This is roughly all the counting a counting machine does, written out.
tally = {}
for ballot in scan(ballot_box): # one ballot at a time
for contest in ballot.contests: # president, senator, mayor
chosen = [oval.candidate for oval in contest.ovals
if oval.darkness >= THRESHOLD] # <- this is the 15%
if len(chosen) > contest.seats: # overvote, the contest is void
continue
for candidate in chosen:
tally[candidate] = tally.get(candidate, 0) + 1
record = sign(tally, precinct_private_key) # so nobody can alter it in transit
print_election_return(record) # the paper copy
transmit(record, recipients) # to the servers
Twelve lines. That is the arithmetic of a Philippine election. The hard parts of the real system sit around this, not inside it: reading a smudged oval reliably on 110,620 machines, managing the signing keys, surviving a hot day in a school gym. Those are engineering problems and they are real. The counting is not one of them, and the counting is the part the public never got to read.
”But the vendor owns the code”
Los Angeles County owns its voting system outright. VSAP Tally 1.0 was certified by the California Secretary of State in August 2018 as the first publicly owned, open-source election tally system certified under that state’s standards. Swiss Post publishes its e-voting source code, its specifications, and its documentation on GitLab, with the verification software under a licence broad enough that a competitor could take it, improve it, and sell it. Estonia put its internet voting code on GitHub.
None of those governments were compelled. They wrote it into what they were buying. Vendor intellectual property is a clause in a contract, and a contract is a thing you draft before you sign it.
”But publishing the code makes it easier to attack”
This is the objection that sounds most serious, and it is the one that was answered longest ago. Auguste Kerckhoffs set it out in 1883: a system must remain secure even when everything about it except the key is public.
The encryption protecting your bank transfer, your Viber messages, and every secure page you have ever loaded runs on algorithms anyone can read. Most of the servers on the internet run Linux, source published. We don’t keep any of it safe by hiding it. We keep it safe because millions of people can look, and the ones who find holes get credit for saying so out loud.
A system that is only secure while nobody can see it isn’t secure. It is unexamined. And we already know what unexamined looks like here: in March 2016, the Comelec website was breached and roughly 55 million voters’ records went public, fingerprints and passport numbers included.
The objection that is actually good
Publishing the code does not prove the machine ran that code. That one is true, and it is the argument worth having.
The answer is reproducible builds: publish the source, publish the build instructions, and let any stranger compile it and get a binary whose hash matches the one that shipped. We already perform most of that ceremony. There is a final trusted build. There is a hash, and Comelec published it. Comelec deposited the final software with the Bangko Sentral in March 2025, in a vault, on camera, as a demonstration of transparency. We do every step except the one that would let someone outside the room verify any of it.
On election night in 2016, a Smartmatic engineer changed a script on the transparency server to fix a “ñ” that was rendering as a question mark in candidates’ names. Comelec said it changed nothing in the results. The DOJ found probable cause and indicted Smartmatic and Comelec personnel under the Cybercrime Prevention Act for making the change without authorisation from the en banc. A decade later people still argue about it, and no argument will ever settle it, because there is no public artefact for anyone to compare. Open source would not have proven anybody’s intent. It would have made the change checkable in an afternoon, by anyone, instead of a permanent national grievance.
The window is open right now
Comelec is drafting the terms of reference for the Online Voting and Counting System and the Secure Electronic Transmission Services for 2028. Overseas registration has been running since December 2025 and closes September 2027; Comelec wants 2 million registered voters abroad, up from about 990,000. Online voting for 2028 starts 9 April.
The ask is small, and it is a procurement decision rather than a new law:
- The full source of any counting, canvassing, or transmission system is published to a public repository under an open licence, at contract award, and on every change after.
- Build instructions that let anyone compile the source and match the hash of the binary that shipped.
- No accreditation, no endorsement letter, no room in Makati.
RA 9369 already orders the Commission to “promptly make the source code of that technology available and open to any interested political party or groups.” That was written in 2007, before “open” got redefined to mean a reading room with a sign-up sheet. Publishing it on the internet is not a stretch of that law. It is the plain reading of it.
We are going to spend billions on this again. The counting logic fits on a page. Print the page.






