

Every half hour during the online voting period, Moscow’s Information Technology Department posted aggregated, anonymized voting data, including encrypted votes, on a special website. For each vote, that data identified the following information:

Once voting had concluded and a final CSV file containing data about 9,810 votes had been published, Moscow officials reconstructed a private key to decrypt those votes. The key had to be pieced together from fragments that had been entrusted to seven different officials in advance. Unexpectedly, the reconstructed key was entered into the voting experiment’s public blockchain. Meduza was able to find the block that contained it and the transaction itself through the web interface for online voting observers before access to the blockchain was shut down.
We don’t know whether this was an inadvertent mistake or not. However, if the officials running the online voting experiment had intended to give observers access to the private key, it’s not clear why they shut down access to the blockchain’s web interface a few hours later.
To decrypt the transactions in the blockchain, which had been encrypted using the ElGamal system, we needed more than the private key. We also had to find one component of the public key that had been used to encrypt the data in the first place: its modulo.
To find the public key’s modulo, we turned to our science editor, Alexander Ershov. He had voted online on September 8, and he agreed to give us a look at the HTML page for his ballot. That page contained the public key and the modulo we needed.

If you try to decrypt the votes yourself, remember that every candidate in the online election was assigned a number. Just before the encryption process took place in any given user’s browser, that number was squared, meaning that you’ll have to take the square root of the decrypted figure to find the original candidate number.
Our science editor, Alexander Ershov, recorded the online voting process in a HAR file. That file type allows users to save all incoming and outgoing traffic as they visit a web site or use a web app. Within that archive, we found Alexander’s encrypted vote. From there, figuring out who he voted for was a piece of cake.

Recording your own online voting isn’t a complicated process at all. You don’t even have to install any special programs to do it. Browsers like Google Chrome, Mozilla Firefox, Safari, and even Microsoft Edge have built-in tools to record web traffic in HAR files.
If election officials knew in advance that they were going to publish the private key to the blockchain temporarily, then in theory, other government officials who forced their subordinates to vote a certain way could have used that opportunity to determine how their employees really voted.
The election commissions for Precincts Number 5001, 5002, and 5003 all made their election results public, and those results match up perfectly with the decrypted voting data we obtained. That said, without direct access to the voting blockchain, we can’t determine how many electronic ballots were initially distributed to voters.
However, you don’t even have to decrypt anything to notice that something was off in these races. All you have to do is split the voting period into five-minute chunks and group together the online voting blocks that were recorded during each of those chunks.

The rate of incoming votes during the 12-hour voting period was uneven. There was a stretch of three hours during which almost no votes at all were added to the blockchain, and half of all the blocks recorded were added during a single hour (though each of those blocks contained only 1 – 3 votes). In the middle of the voting period, there was even a five-minute stretch when almost 1,400 votes were added to the blockchain. That’s about 14 percent of the total number of votes.
Here’s where we do need those decrypted votes. Let’s look at the distribution of votes among three competitors in a single district: The independent candidate Roman Yuneman, the pro-regime candidate Margarita Rusetskaya, and Vladislav Zhukovsky, a Communist Party candidate who was listed in opposition politician Alexey Navalny’s Smart Vote program. The bursts of votes did not favor any single candidate to a degree that looks suspicious on its face.



In all three districts that used online voting, voters who chose pro-regime candidates submitted their ballots in the morning (that is, in the hour and a half before the first major technical glitch) at noticeably higher rates than voters who chose independent candidates.

We don’t know whether or not this data could make it possible to identify the scale and nature of any forced voting in these races.
This was possible because a blockchain was used to record votes. We know for sure that every vote recorded in a given block could only have been cast before the moment that block was added to the blockchain. The developers who created Moscow’s online voting system said it would generate random pauses between the completion of every ballot and the time that ballot was added to the blockchain. However, it’s possible that those pauses only tend to shuffle votes within individual blocks: Alexander Ershov’s vote landed in the very first block that was formed after he submitted his ballot.
To get a sense of how precisely Moscow’s online voting can be reconstructed, take a look at the contest between Roman Yuneman and Margarita Rusetskaya. The video below tracks the difference between the two candidates’ vote totals by taking the final results of paper voting as a given from the start and then progressively adding online ballots as they were recorded over the 12-hour voting period. The result shows how Yuneman’s 581-vote lead over Rusetskaya in paper voting gradually crumbles into an overall 84-vote loss due to online voting.

You can download:
Don’t forget to write to us if you find anything interesting in this data.
Update: Following the publication of this report in Russian, Moscow IT Department Deputy Chair Artyom Kostyrko told the state-owned wire service TASS that the private key was published intentionally as a necessary step toward decrypting the voting blockchain. No government official has yet explained why the key was temporarily made public and subsequently taken down.
Text by Denis Dmitriev and Sultan Suleimanov
Translation by Hilah Kohen