{"id":946,"date":"2019-07-09T16:15:43","date_gmt":"2019-07-09T14:15:43","guid":{"rendered":"https:\/\/blogs.gentoo.org\/mgorny\/?p=946"},"modified":"2019-07-10T19:17:29","modified_gmt":"2019-07-10T17:17:29","slug":"verifying-gentoo-election-results-via-votrify","status":"publish","type":"post","link":"https:\/\/blogs.gentoo.org\/mgorny\/2019\/07\/09\/verifying-gentoo-election-results-via-votrify\/","title":{"rendered":"Verifying Gentoo election results via Votrify"},"content":{"rendered":"<p>Gentoo elections are conducted using a&nbsp;custom software called votify.  During the&nbsp;voting period, the&nbsp;developers place their votes in&nbsp;their respective home directories on&nbsp;one of&nbsp;the&nbsp;Gentoo servers.  Afterwards, the&nbsp;election officials collect the&nbsp;votes, count them, compare their results and&nbsp;finally announce them.<\/p>\n<p>The&nbsp;simplified description stated above suggests two weak points.  Firstly, we rely on&nbsp;honesty of&nbsp;election officials.  If they chose to conspire, they could fake the&nbsp;result.  Secondly, we rely on&nbsp;honesty of&nbsp;all Infrastructure members, as&nbsp;they could use root access to&nbsp;manipulate the&nbsp;votes (or&nbsp;the&nbsp;collection process).<\/p>\n<p>To&nbsp;protect against possible fraud, we make the&nbsp;elections transparent (but&nbsp;pseudonymous).  This means that all votes cast are public, so everyone can count them and&nbsp;verify the&nbsp;result.  Furthermore, developers can verify whether their personal vote has been included.  Ideally, all developers would do that and&nbsp;therefore confirm that no votes were manipulated.<\/p>\n<p>Currently, we are pretty much implicitly relying on&nbsp;developers doing that, and&nbsp;assuming that no&nbsp;protest implies successful verification.  However, this is not&nbsp;really reliable, and&nbsp;given the&nbsp;unfriendly nature of&nbsp;our scripts I have reasons to doubt that the&nbsp;majority of&nbsp;developers actually verify the&nbsp;election results.  In&nbsp;this post, I&nbsp;would like to shortly explain how Gentoo elections work, how they could be&nbsp;manipulated and introduce <a rel=\"external\" href=\"https:\/\/github.com\/mgorny\/votrify\">Votrify<\/a> \u2014 a&nbsp;tool to&nbsp;explicitly verify election results.<\/p>\n<p><!--more--><\/p>\n<h2>Gentoo voting process in&nbsp;detail<\/h2>\n<p>Once the&nbsp;nomination period is&nbsp;over, an&nbsp;election official sets the&nbsp;voting process up by&nbsp;creating control files for&nbsp;the&nbsp;voting scripts.  Those control files include election name, voting period, ballot (containing all vote choices) and&nbsp;list of&nbsp;eligible voters.<\/p>\n<p>There are no&nbsp;explicit events corresponding to&nbsp;the&nbsp;beginning or&nbsp;the&nbsp;end of&nbsp;voting period.  The&nbsp;votify script used by&nbsp;developers reads election data on&nbsp;each execution, and&nbsp;uses it to determine whether the&nbsp;voting period is open.  During the&nbsp;voting period, it permits the&nbsp;developer to&nbsp;edit the&nbsp;vote, and&nbsp;finally to&nbsp;\u2018submit\u2019 it.  Both draft and&nbsp;submitted vote are stored as&nbsp;appropriate files in&nbsp;the&nbsp;developer&#8217;s home directory, \u2018submitted\u2019 votes are not&nbsp;collected automatically.  This means that the&nbsp;developer can still manually manipulate the&nbsp;vote once voting period concludes, and&nbsp;before the&nbsp;votes are manually collected.<\/p>\n<p>Votes are collected explicitly by&nbsp;an&nbsp;election official.  When run, the&nbsp;countify script collects all vote files from developers&#8217; home directories.  An&nbsp;unique \u2018confirmation ID\u2019 is generated for&nbsp;each voting developer.  All votes along with their confirmation IDs are placed in&nbsp;so-called \u2018master ballot\u2019, while mapping from developer names to&nbsp;confirmation IDs is stored separately.  The&nbsp;latter is used to send developers their respective confirmation IDs, and&nbsp;can be discarded afterwards.<\/p>\n<p>Each of&nbsp;the&nbsp;election officials uses the&nbsp;master ballot to&nbsp;count the&nbsp;votes.  Afterwards, they compare their results and&nbsp;if they match, they announce the&nbsp;election results.  The&nbsp;master ballot is attached to the&nbsp;announcement mail, so that everyone can verify the&nbsp;results.<\/p>\n<h2>Possible manipulations<\/h2>\n<p>The&nbsp;three methods of&nbsp;manipulating the&nbsp;vote that I can think of are:<\/p>\n<ol>\n<li><em>Announcing fake results.<\/em>  An&nbsp;election result may be presented that does not&nbsp;match the&nbsp;votes cast.  This is actively prevented by&nbsp;having multiple election officials, and&nbsp;by&nbsp;making the&nbsp;votes transparent so that everyone can count them.<\/li>\n<li><em>Manipulating votes cast by&nbsp;developers.<\/em>  The&nbsp;result could be&nbsp;manipulated by modifying the&nbsp;votes cast by&nbsp;individual developers.  This is prevented by&nbsp;including pseudonymous vote attribution in&nbsp;the&nbsp;master ballot.  Every developer can therefore check whether his\/her&nbsp;vote has been reproduced correctly.  However, this presumes that the&nbsp;developer is&nbsp;active.<\/li>\n<li><em>Adding fake votes to the&nbsp;master ballot.<\/em>  The&nbsp;result could be&nbsp;manipulated by adding votes that were not cast by&nbsp;any of&nbsp;the&nbsp;existing developers.  This is a&nbsp;major problem, and&nbsp;such manipulation is entirely plausible if&nbsp;the&nbsp;turnout is low enough, and&nbsp;developers who did not vote fail to&nbsp;check whether they have not been added to&nbsp;the&nbsp;casting voter list.<\/li>\n<\/ol>\n<p>Furthermore, the&nbsp;efficiency of&nbsp;the&nbsp;last method can be improved if&nbsp;the&nbsp;attacker is able to restrict communication between voters and\/or&nbsp;reliably deliver different versions of&nbsp;the&nbsp;master ballot to&nbsp;different voters, i.e. convince the&nbsp;voters that their own vote was included correctly while manipulating the&nbsp;remaining votes to&nbsp;achieve the&nbsp;desired result.  The&nbsp;former is rather unlikely but the&nbsp;latter is generally feasible.<\/p>\n<p>Finally, the&nbsp;results could be&nbsp;manipulated via&nbsp;manipulating the&nbsp;voting software.  This can be counteracted through verifying the&nbsp;implementation against the&nbsp;algorithm specification or, to&nbsp;some degree, via&nbsp;comparing the&nbsp;results a&nbsp;third party tool.  Robin H. Johnson and&nbsp;myself were historically working on&nbsp;this (or&nbsp;more specifically, on&nbsp;verifying whether the&nbsp;Gentoo implementation of&nbsp;Schulze method is correct) but neither of&nbsp;us was able to finish the&nbsp;work.  If&nbsp;you&#8217;re interested in&nbsp;the&nbsp;topic, you can look at&nbsp;my <a rel=\"external\" href=\"https:\/\/github.com\/mgorny\/election-compare\">election-compare<\/a> repository.  For the&nbsp;purpose of&nbsp;this post, I&#8217;m going to consider this possibility out of&nbsp;scope.<\/p>\n<h2>Verifying election results using Votrify<\/h2>\n<p>Votrify uses a&nbsp;two-stage verification model.  It consists of&nbsp;<em>individual verification<\/em> which is performed by&nbsp;each voter separately and&nbsp;produces <em>signed confirmations<\/em>, and&nbsp;<em>community verification<\/em> that uses the&nbsp;aforementioned files to&nbsp;provide final verified election result.<\/p>\n<p>The&nbsp;individual verification part involves:<\/p>\n<ol>\n<li><em>Verifying that the&nbsp;developer&#8217;s vote has been recorded correctly.<\/em>  This takes part in&nbsp;detecting whether any votes have been manipulated.  The&nbsp;positive result of&nbsp;this verification is implied by&nbsp;the&nbsp;fact that a&nbsp;confirmation is produced.  Additionally, developers who did not&nbsp;cast a&nbsp;vote also need to&nbsp;produce confirmations, in&nbsp;order to&nbsp;detect any extraneous votes.<\/li>\n<li><em>Counting the&nbsp;votes and&nbsp;producing the&nbsp;election result.<\/em>  This produces the&nbsp;election results as&nbsp;seen from the&nbsp;developer&#8217;s perspective, and&nbsp;therefore prevents manipulation via&nbsp;announcing fake results.  Furthermore, comparing the&nbsp;results between different developers helps finding implementation bugs.<\/li>\n<li><em>Hashing the&nbsp;master ballot.<\/em>  The&nbsp;hash of&nbsp;master ballot file is&nbsp;included, and&nbsp;comparing it between different results confirms that all voters received the&nbsp;same master ballot.<\/li>\n<\/ol>\n<p>If&nbsp;the&nbsp;verification is&nbsp;positive, a&nbsp;confirmation is produced and&nbsp;signed using developer&#8217;s OpenPGP key.  I&nbsp;would like to&nbsp;note that no&nbsp;private data is&nbsp;leaked in&nbsp;the&nbsp;process.  It does not even indicate whether the&nbsp;dev in&nbsp;question has actually voted \u2014 only that he\/she participates in&nbsp;the&nbsp;verification process.<\/p>\n<p>Afterwards, confirmations from&nbsp;different voters are collected.  They are used to&nbsp;perform community verification which involves:<\/p>\n<ol>\n<li><em>Verifying the&nbsp;OpenPGP signature.<\/em>  This is&nbsp;necessary to&nbsp;confirm the&nbsp;authenticity of&nbsp;the&nbsp;signed confirmation.  The&nbsp;check also involves verifying that the&nbsp;key owner was an&nbsp;eligible voter and&nbsp;that each voter produced only one confirmation.  Therefore, it prevents attempts to~fake the&nbsp;verification results.<\/li>\n<li><em>Comparing the&nbsp;results and&nbsp;master ballot hashes.<\/em>  This confirms that everyone participating received the&nbsp;same master ballot, and&nbsp;produced the&nbsp;same results.<\/li>\n<\/ol>\n<p>If&nbsp;the&nbsp;verification for&nbsp;all confirmations is&nbsp;positive, the&nbsp;election results are repeated, along with explicit quantification of&nbsp;how trustworthy they are.  The&nbsp;number indicates how many confirmations were used, and&nbsp;therefore how many of&nbsp;the&nbsp;votes (or&nbsp;non-votes) in&nbsp;master ballot were confirmed.  The&nbsp;difference between the&nbsp;number of&nbsp;eligible voters and&nbsp;the&nbsp;number of&nbsp;confirmations indicates how many votes may have been altered, planted or&nbsp;deleted.  Ideally, if&nbsp;all eligible voters produced signed confirmations, the&nbsp;election would be 100%&nbsp;confirmed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Gentoo elections are conducted using a&nbsp;custom software called votify. During the&nbsp;voting period, the&nbsp;developers place their votes in&nbsp;their respective home directories on&nbsp;one of&nbsp;the&nbsp;Gentoo servers. Afterwards, the&nbsp;election officials collect the&nbsp;votes, count them, compare their results and&nbsp;finally announce them. The&nbsp;simplified description stated above suggests two weak points. Firstly, we rely on&nbsp;honesty of&nbsp;election officials. If they chose to conspire, &hellip; <a href=\"https:\/\/blogs.gentoo.org\/mgorny\/2019\/07\/09\/verifying-gentoo-election-results-via-votrify\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Verifying Gentoo election results via Votrify&#8221;<\/span><\/a><\/p>\n","protected":false},"author":137,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[3],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/946"}],"collection":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/users\/137"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/comments?post=946"}],"version-history":[{"count":30,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/946\/revisions"}],"predecessor-version":[{"id":976,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/946\/revisions\/976"}],"wp:attachment":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/media?parent=946"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/categories?post=946"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/tags?post=946"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}