An Algorithmic Failure Beneath the Secret Ballot

Authored by Max Springer

The secret ballot is one of the load-bearing walls of democracy. In Georgia, as in most states, this allows you to know whether your neighbor voted, but never who they voted for. This simple guarantee allows for transparent elections while deterring voter intimidation. Yet, in multiple states including Georgia, that guarantee is actively at risk. To keep the published record anonymous, ballot scanners shuffle the electronic records randomly before releasing them. But a security vulnerability disclosed back in 2022 shows the shuffle can be reversed, and some states have not applied the software update that resolves it. Undo the randomness, pair it with a record of when a person voted, and anonymous ballots reveal themselves.

I am not a security researcher, and I have never been to Georgia. Yet within a few hours, using AI tools and nothing but public records, I was able to reconstruct the order in which 1.5 million ballots were cast in Georgia’s May 2026 primary–98.9% of the in-person ballots. From this order and the state’s public logs, I can target specific counties and ask the AI to exactly identify how any person voted. In some of Georgia’s counties, I can determine the exact ballot cast by every voter at the vote centers–ballot secrecy is entirely lost.

The Exploit.

In October 2022, a team of researchers published a report showing that certain ballot scanning machines used throughout the US had a critical privacy failure in how they anonymized ballots. Specifically, the machines would assign a seemingly random number to each electronic ballot record at the time of scanning to label each ballot for later auditing. However, the algorithm by which the machines generate this random number is actually deterministic and can be exactly reversed to identify the sequence in which ballots were cast.

To illustrate, if I were to shuffle a deck of cards by sequentially taking the card on top and moving it to the middle, and then I proceeded to loudly proclaim this was how I shuffle, you might have an easy time against me in a game of blackjack. The shuffle meant to provide anonymity has exactly the opposite effect.

Naturally, knowing the order ballots were cast is just one piece of the puzzle. But, when paired with publicly available records on the order in which voters cast their ballots (such as logbooks or poll watchers), a simple procedure exists to reconstruct the mapping from ballots back to voters.

AI Tools.

Through the history of computer security, there has usually been a moat of expertise separating a vulnerability from its exploitation. The process of reading a research paper on a vulnerability and then turning it into working code on the right dataset would take a trained programmer weeks to months. That gap was, in practice, a form of protection. Large Language Models (LLMs), the systems behind chatbots like ChatGPT, are building bridges across that moat. Given the ability to write code, run it, see what breaks, and try again, models are now capable of programming until a goal is achieved. One can describe this goal in plain language, and the LLM carries out the work that used to require a specialist. An LLM set loose in this way on a programming task is what I’ll call a “coding agent” (or more simply “agent”).

For just $20, I accessed the most powerful coding agents and easily pointed them at this specific, real, and unpatched flaw in American election equipment. I did not develop a new attack or discover a new exploit. All I did was point an agent to the paper on the vulnerability and ask whether it was possible to use it in the state of Georgia. Within a couple of hours, I had a pipeline to analyze and identify secret ballots across the state of Georgia and the agent told me exactly what further information it would need to identify real voter’s ballots. At no point did the agent refuse to comply or raise concerns over implementing the exploit.

The Results.

Nearly four years since the original vulnerability was disclosed, I was still able to use it to analyze voter behavior in Georgia (one of the 21 states that uses affected scanners) in the recent May 2026 primary.

Notably, I never touched a voting machine, exploited a network, examined source code, or accessed anything non-public.

After pointing a coding agent to the original vulnerability paper, I supplied it with two data sources highlighted in the paper: the early-voting list for each county, and the “CVR” (cast-vote record) file, containing every ballot and its selections (but not the voters’ names or other identifying information). The CVR file is available upon request, precisely because a public, ballot-level record is what makes election results independently verifiable.

Independently, these public files do not break the secret ballot. However, the AI agent was able to combine them by deshuffling the ballots using the published exploit, identifying the date each ballot was cast, and subsequently creating buckets of ballots and potential voters. For example, in a primary election if three Democrats arrived to vote at a certain precinct on the same morning, the model could readily point to the three ballots that must belong to those three voters, even if it could not yet say which ballot was whose. It is easy to see that for small rural counties in Georgia where, say, only one Democrat arrived to vote on a given primary-election early voting day, the model would already have enough information to identify that person’s ballot with complete certainty.

With just those two public files, I found that in 114 of the 139 counties I examined, the in-person cast order of ballots can be recovered. This amounts to 1.52 million ballots, or 98.9% of in-person ballots in those counties. 

To dive deeper, it helps to separate two tiers of certainty. Uniquely identified means a forced match: the person was the only voter of their party, in their precinct, of a certain ballot type, on a given day and thus there is exactly one ballot to match. From the public files alone, this amounts to about 1% of all early in-person voters analyzed. 

timeline of how anonymized ballot can be traced back to the voter

Tied to a specific ballot is the stronger claim and requires one additional public record. In instances where we need to disentangle a bucket of possible ballots (say, which of those three Democrats cast each ballot), I obtained the scanner’s public audit log and check-in records for individual voting locations, which precisely give the order and timestamps for voters checking in. In Heard County, one of Georgia’s smallest, the agent was able to match the majority of the 650 early in-person voters to a specific ballot, and the rest to within a single swap. The same result persisted when I examined Ball Ground, a particularly busy vote center in Cherokee County, across all 1,860 early voters.

Implications.

The above two counties are not remarkable in the sense that I could repeat this process of matching voters to ballots in any affected county. Given even a coarse record of the order in which voters scanned their ballots, the AI system can match their ballots. And that record is often trivial to obtain. In the small towns of Georgia, where many voters know each other, simple CCTV footage or even stationed poll watchers can directly monitor when individuals cast their ballot; feed that to a coding agent as above, and it returns their ballots. 

In fact, most precinct scanners show a public running count of how many ballots have been submitted at a given location. If I note my own number, and know my spouse is directly behind me, then their secret ballot protection is immediately lost.

ballot box digital screen showing which number is being cast

To reiterate, the secret ballot is not a courtesy, but is the protection that makes voter coercion pointless, as a vote that cannot be proven cannot be sold or compelled. If we allow this to be stripped away, then these failures are within reach. Your employer, your neighbor, or even your spouse can extract your sensitive information.

What is being done to fix this?

Less than you would hope. A corrected version of the software was developed and certified in March 2023, yet the data I analyzed here is from May 2026. Disclosure, and even a direct fix, have not resolved the issue due to slow uptake of the solution by election officials. While previously I may have conceded that this exploit was unlikely to be used at scale, the emergence of AI coding tools has fundamentally changed the stakes. For this vulnerability, and many others which were previously perceived as too technically sophisticated to bother fixing immediately, we are at the eleventh hour.

Recommendations.

AI coding tools have lowered the technical barrier to the point where officials must patch systems with far more urgency, and where we, as researchers, must reconsider how we handle the responsible disclosure of security vulnerabilities. The clock on remediation now runs at an entirely different speed and anyone can target a vulnerability with little to no technical knowledge.

Concretely, for this vulnerability, jurisdictions using Dominion scanners should install version 5.17 (or newer) of the software. Affected scanners should be corrected before the next election, not after the next headline. Maintaining publicly available election data is essential to a healthy, auditable democracy, and none of the results produced by these machines are in question. However, such data cannot be maintained if we improperly deploy privacy algorithms and put voters at risk by the sheer act of voting. It is exactly this civic duty that we have failed to protect, and it is well past time we did.


Max Springer is a postdoctoral research fellow in Princeton’s Center for Information Technology Policy, and holds a PhD in Applied Mathematics from the University of Maryland. His work explores how to make algorithms and AI systems more reliable and trustworthy, both in theory and practice. In addition to his scientific work, he works as a freelance science communicator and collaborates with policymakers to ensure technical systems are understood and deployed responsibly.


Comments

8 responses to “An Algorithmic Failure Beneath the Secret Ballot”

  1. Here is some c# source code that I use to decypher the ballot ID numbers.

    public class DvsOrderService : IDvsOrderService
    {
    public Dictionary DvsNumbers { get; set; }

    public DvsOrderService()
    {
    DvsNumbers = [];

    var value = 0;

    for (var index = 0; index < 1_000_000; index++)
    {
    var text = Cypher(value.ToString("D6"));

    DvsNumbers.Add(text, index);

    value = (value + 864_803) % 1_000_000;
    }
    }

    public int GetICP(string obfuscatedIcp)
    {
    var unobfuscated = ReverseICP(obfuscatedIcp);

    var dvsNumber = DvsNumbers[unobfuscated];

    return dvsNumber;
    }

    public int GetICE(string obfuscatedIcp)
    {
    var unobfuscated = ReverseICE(obfuscatedIcp);

    var dvsNumber = DvsNumbers[unobfuscated];

    return dvsNumber;
    }

    public string ObfuscateICP(string text)
    {
    return $"{text[1]}{text[5]}{text[0]}{text[4]}{text[2]}{text[3]}";
    }

    public string ReverseICP(string text)
    {
    return $"{text[2]}{text[0]}{text[4]}{text[5]}{text[3]}{text[1]}";
    }

    public string ObfuscateICE(string text)
    {
    return $"{text[2]}{text[3]}{text[1]}{text[5]}{text[0]}{text[4]}";
    }

    public string ReverseICE(string text)
    {
    return $"{text[4]}{text[2]}{text[0]}{text[1]}{text[5]}{text[3]}";
    }

    ///
    /// The output is then obfuscated by a simple substitution cipher in which
    ///
    ///
    /// The digits [0,1,2,3,4,5,6,7,8,9] are replaced by [5,0,8,3,2,6,1,9,4,7].
    ///
    ///
    ///

    static readonly int[] _cypher = [5, 0, 8, 3, 2, 6, 1, 9, 4, 7];

    static string Cypher(string text)
    {
    return string.Concat(text.Select(digit => _cypher[digit – ‘0’]));
    }
    }

  2. David Jefferson

    Storing ballots in randomized order is not actually necessary to protect vote privacy.

    Much better would be to store the ballots in some canonical lexicographic sorted order. That would perfectly destroy all information regarding the order in which the ballots were cast. Both the sorting algorithm and the sorted ballots could be made public. No reverse engineering, even with benefit of source code and AI aids, could recover the order the ballots were cast.

    I have wondered for 20 years why vendors don’t do this, and why we technologists don’t just call for this.

  3. Marilyn Marks

    David and Phillip,
    Thanks for your comments here on this important subject. But could you both dumb it down for some of us non-technical folks?

    Phillip, can you tell us what that code does and how you use it?
    David, can you explain those fancy words in your post?

    Thanks so much.

    1. David Jefferson

      Sorry of the confusion. What I mean is that from each voted ballot we should create some series of numbers representing its votes to be a sort key. For example, if there are 5 races on the ballot, and the voter voted for the 2nd candidate in race 1, and the 3rd in race 2, and the 10th in race 3, and did not vote in race 4, and voted a write-in in race 5, then the sort key might be (2,3,10,0,-1). All the ballots are then stored in a lexicographical order so that the first element of the key is most important, and the 2nd is the next most important, etc. Thus, if there are 8 ballots, and their sort strings in the order the ballots were cast are

      2,3,10,0,-1
      1,2,2,2,1
      1,2,7,4,2
      2,0,0,0,0
      1,2,2,2,1
      1,2,5,0,0
      1,0,5,1,0
      2,3,10,1,1

      Then as each ballot is cast it would be stored in its proper sorted place among those already cast, and at the end of the day the 8 ballots would be stored in this order:

      1,0,5,1,0
      1,2,2,2,1
      1,2,2,2,1
      1,2,5,0,0
      1,2,7,4,2
      2,0,0,0,0
      2,3,10,0,-1
      2,3,10,1,1

      There are many ways to create a sort key from the votes on a ballot, and it does not matter if some of the sort keys are identical, as happens in this example. All that matters is the ballots are stored in an order that is provably unrelated to the order in which they were cast. Those 8 ballots could have been cast in any order whatsoever, but they will be stored in this particular canonical sorted order.

      I hope that helps explain what I mean.

  4. This is a truly frightening finding – thanks to both Marilyn and Max for showing how easy it is for our votes to be uncovered in GA!

    And David – what a brilliant solution to the ordering problem!

    I truly hope this leads to the upgrading of Georgia’s election system.

  5. Kevin Moncla

    “I have wondered for 20 years why vendors don’t do this, and why we technologists don’t just call for this.”

    Mr. Jefferson,

    I believe the voting system manufacturer’s use of an algorithm to “scramble” the ballot record order as opposed to a pseudo-random generator strongly suggests that they intentionally wanted to preserve the ability to reverse the scrambling and return the ballot record order to the sequence in which the ballots were cast. The natural record order also serves as the addressing map of the paper ballots. Such a map would be a valuable metric if it were necessary to select specific ballots for a Risk Limiting Audit. Specific ballots could be selected to support any result.

  6. Melissa White

    I think there was a mistake in the article at the end..he states to use 5.16 or newer. He meant 5.17 correct? 5.17 is the Federally certified version via EAC. There is no “Federally” certified 5.16.

  7. Obviously, this is a severe problem that needs to be fixed. However, I believe you are over-claiming what you can actually do, and secondly, there are easy workarounds you did not mention that can be implemented immediately.

    1. You say that “I can determine the exact ballot cast by every voter at the vote centers–ballot secrecy is entirely lost.” — But you actually have no way to know if you actually can accurately do that. If you know the sequence that people signed-in, this is not necessarily the same as the order that they scanned their ballot. People vote at different rates. And even worse, if a voter were to sign-in and then leave without scanning their ballot (and this happens somewhat often) then you might try to predict all the remaining ballots by the sequence of entry, but they are all entirely off by a ballot, and therefore the correlation is unreliable and worthless.

    There is no way to actually test what you claim, and you can’t verify it either, unless you actually “out” a voter. And if you do that, please let me know so I can make a formal complaint myself that you are intimidating voters. Your claim is that AI thinks it can correlate them, but in this case that is a typical AI over estimation of its own capabilities. Happens all the time.

    In a way, this is similar to the story of hacking slot machine PRNG, allowing him to steal $20 million. https://www.youtube.com/watch?v=jyyZR4H8N6g

    The slot machine story is similar, but also extremely different. He could try his timing technique and verify it, over and over. You actually can’t verify your technique, other than perhaps a simulation, and it could not account for randomness of human behavior.

    This is a very fragile correspondence that can be upset by both a change in the order of the ballots scanned compared with the order of sign-in, and also whether a voter scans their ballot at all. You would need even more information to make this worth doing, such as a video of voters walking up and scanning their ballot.

    If you, or some other privacy breaker actually “outs” a voter, then the voter could just deny it, as you can’t really prove it and you should not try. If the fear is that just the existence of this vulnerability could cause voters to balk, I can congratulate you at making this even worse. The easier you make it, the more privacy is lost.

    2. There are several very easy workarounds.

    A. CENTRAL SCANNING

    The first is to simply not scan ballots in the polling places but rather to deposit the ballot into a big sealed bin where they flutter to the bottom and naturally reorder themselves, and then transport these sealed packages to the central office where they can be easily scanned by high speed scanners. This is the way they do it in San Diego County, indeed since the “top to bottom review” of Debra Bowen around 2006 or so in California.

    During early voting, ballots can be gathered each day and combined, and then scanned in the central scanning operation. On election day, they can be easily scanned in one night. That will completely avoid those simplistic polling-place scanners and actually make it much easier to monitor and observe by oversight observers. Further, this obfuscates the “single Dem voter who voted today” issue because by combing ballots in the central office, you will dilute the likelihood of such a instance, although it is still not impossible.

    B. SHUFFLE BOX

    Now, if there is some extreme urgency to use the laptop-size scanners in polling places, then they might want to use a “shuffle box” where ballots are placed in security folders, then added at random to a small filing box, and a different ballot removed and scanned. This makes it impossible to link the ballot to the voter, except that the “Single Dem” issue is not improved. Although you linked the single Dem issue to the DVS Order vulnerability, it has actually nothing to do with it, as that would exist even if the numbers were impossible to order.

    Timestamps are not allowed in voting system scanners. If they have them, then they are set to the election day only. But also, e poll books should not timestamp records either. That would also make your hack harder to implement.

    Even if we do find a way to fully obfuscate the sequence, it may still be feasible to figure it out if the digital media (flash memory) is obtained. ES&S Reorders their ballots by hash value and places them in 4096 folders based on the first 12 bits. That shuffles them in the storage system, but actually not. You see, the flash drive deterministically records each record in memory even if it looks like they are shuffled. It isn’t an absolute that this vulnerability exists, but don’t be fooled by what looks like a shuffle when you are only shuffling the directory.

    Laws against voter intimidation is another guard we can use. Please don’t out voters, even if you think you are the white knight.

Leave a Reply

Your email address will not be published. Required fields are marked *