ДЭГ-шоу
Как могло быть сфальсифицировано электронное голосование в Москве: расследование программиста Петра Жижина.
Юлия Латынина, обозреватель «Новой»
Программист Петр Жижин выгрузил с сайта observer.mos.ru весь дамп с результатами электронного голосования, написал программу для его расшифровки, расшифровал, проанализировал и в среду поделился результатами своего анализа в посте на «Хабре». Юлия Латынина поговорила с Петром Жижиным о том, что он нашел, а также о вещах, которые стали известны после его поста. В принципе, это рассказ о том, как могло быть фальсифицировано ДЭГ в Москве. Поэтапный.
— Петр, несколько слов о вас. Вы кто?
— Я работаю программистом в «Яндексе» и занимаюсь распознаванием речи. Анализом ДЭГ я занялся случайно. Анализировать данные — это то, что я люблю. Я бы хотел подчеркнуть, что анализ ДЭГ — это не то, чем «Яндекс» занимается. Это не имеет отношения к моей работе. Это мое свободное время, моя личная инициатива.
— На каком этапе вы включились в выборы?
— Меня возмутила ситуация. Я решил, что надо проанализировать то, что случилось.
— То есть вы не состоите ни в чьем штабе?
— Я являюсь сторонником Анастасии Брюхановой и Петра Карманова (кандидаты Каца в Госдуму и Мосгордуму. — Ю. Л.). Помогал им, волонтерил, перечислял им деньги.
— То есть вы волонтер Брюхановой?
— Да.
Петр Жижин. Фото из соцсетей
— До конца выборов как вы относились к электронному голосованию?
— Я не доверял системе, но пока они не начали фальсифицировать, я не интересовался этим. Было что-то вроде чувства: «Ну, похоже, они пока нормально работают, может быть, к президентским подключат». И я понимал, что система настолько непрозрачная, что нужны специальные технические знания, чтобы понимать, как она функционирует. Вы, наверное, на себе почувствовали, как это сложно было все проанализировать.
— Я говорила с Виктором Толстогузовым. Он не просто программист, а разработчик систем электронного голосования. Он был одним из немногих моих собеседников, который считал, что электронное голосование должно быть запрещено, и был его яростным критиком. Его после этой критики по требованию Венедиктова включили в экспертный совет по ДЭГ. Я начала нашу беседу со слов: «Я в этом ничего не понимаю», и он ответил: «Да, и это нарушение ваших прав как избирателя. Вы же понимаете, как устроена обычная урна? А тут понимают единицы. Значит, права избирателя нарушены».
— Да. У меня тоже такое чувство, что привычная система была заменена на волшебное слово «блокчейн», люди где-то его слышали, знали, что это криптовалюта, что это надежно, а что такое блокчейн — сколько знает?
— А вот, кстати, объясните, что такое блокчейн, публике.
— Дисклеймер: я не специалист по блокчейну, но для анализа данных этого и не нужно знать. Там очень большой массив данных, которые можно анализировать, вовсе не зная, что такое блокчейн. Но, в принципе, блокчейн — это система записей, которая криптографически устроена так, что в систему можно добавить новую запись, а вот чтобы удалить старую, нужно привлечь очень много ресурсов. Но если вы зайдете на сайт observer.mos.ru, вы можете просто скачать SQL-базу, распаковать и увидеть три таблицы: blocks, decrypted ballots и transactions. Перед нами — просто база данных, которую можно анализировать, ничего о блокчейне не зная. Просто когда у вас есть обычная база данных или таблица в экселе, у вас нет никакой гарантии, что в какой-то момент злоумышленник не придет и не подменит ее. Блокчейн — это способ удостовериться, что эта таблица никогда не была подменена.
— Как я понимаю, для того чтобы таблица не была подменена, все эти транзакции должны храниться на разных независимых серверах. Чтобы если у какого-то блока изменился хеш, то все другие серверы сказали бы: «Стоп! У нас другое записано».
— Да. И в Москве этого нет. Там все эти ноды — серверы — все равно контролируются кодом, который собрал ДИТ Москвы из своих исходников. Были эксперты, которые приходили и просили подключить независимые компании как отдельную ноду. Но этого нет, есть только сайт observer.mos.ru, куда транзакции выгружаются каждые 30 минут. Разработчики говорят независимым наблюдателям: «Вы можете зайти туда и скачать».
— Виктор Толстогузов сказал мне одну очень огорчительную вещь. Он сказал, что, поскольку все ноды контролируются ДИТом, то, в принципе, в эти полчаса можно откатить блокчейн и заменить реальные транзакции нарисованными.
Он мне объяснял (извините, тут я для читателей объясню то, что мне самой только что объяснили), что любой блок в блокчейне включает в себя саму запись о транзакции плюс хеш — уникальный набор символов, который ее характеризует. Следующий блок включает в себя запись о новой транзакции и новый уникальный хеш, который получается из предыдущего блока.
При этом существует технология отката блокчейна, она совершенно легальна и необходима, когда, например, на каком-то из серверов возникла ошибка: один сервер, скажем, считает, что биткоин принадлежит Пете, а другой — что он принадлежит Мише. И тогда откатывают всю цепочку и смотрят, где произошла ошибка. Но это происходит открыто, об этом знают все серверы. А если все серверы стоят в ДИТе, то так каждые полчаса в промежутках между дампами можно откатывать всю цепочку и записывать совершенно фиктивные выборы, и никто вообще никогда ничего не узнает.
Виктор Толстогузов. Фото из соцсетей
— Еще раз: я не эксперт по блокчейну. Но я легко могу представить, что когда у нас немного нод, мы за полчаса все можем перезаписать. У меня, к сожалению, возникли проблемы, когда я писал пост, найти людей, которые состояние блокчейна записывали не после конца выборов, а во время. Я скачал базу первый раз, когда итоги выборов уже подвели.
— Когда именно вы базу скачали?
— Ночью. Около трех часов ночи. Я ее скачал и увидел, что там не расшифровано 700 тыс. голосов. Тогда я попросил своего знакомого настроить скачку каждые полчаса, чтобы проследить за процессом дорасшифровки. Но после подведения итогов этот дамп не менялся. И эти 700 тыс. голосов еще нерасшифрованы. Расшифрованы только 1 миллион 300 тыс. голосов. Если точнее, 1 319 943.
— Стоп! Вот отсюда — поподробней. Это как? Проголосовали два миллиона, транзакций с типом «прием бюллетеня» в базе два миллиона, расшифрованы миллион триста, а итоги подведены. Это как? Это что?!
— Вот! Это меня сильно возмутило, я надеялся, что ночью они базу обновят. Нет! И дальше у меня встал вопрос:
если расшифровано только 70 процентов голосов, то что в остальных 30? Может, они все за оппозицию?
Я скачал исходный код московского ДИТа с GitHub. Тут надо отметить, что ДИТ утверждает, что весь код открыт. Это действительно так, но то, как он лежит, — это издевательство над программистами. Обычно исходные коды публикуются в виде текстовых файлов в репозитории. С полной историей изменения кода и с комментариями разработчиков. Но ДИТ опубликовал в репозитории архивы, внутри которых лежит исходный код. Слушайте, я в 10-м классе научился работать не в виде архивов, а в виде репозитория. Сейчас 2021 год!
— Гм. Я очень плохо сейчас представляю себе, о чем вы говорите, и боюсь, что большинство читателей тоже. Давайте вернемся к тому, что, возмутившись, вы написали программу для расшифровки результатов голосования.
— Ну, это громко сказано — программу. Я просто вытащил кусок исходного кода, немного причесал его и выложил его в виде отдельной утилиты. Меня уже потом поправили эксперты по блокчейну, что все можно было сделать гораздо проще. Но я не знал, как с этим работать, и потратил почти весь понедельник. И еще код был написан на Rust, с которым я никогда не работал.
— Просто обхохочешься, как просто. Итак, вы вытащили кусок кода, сделали из него утилиту по расшифровке голосов, и…?
— И за полчаса он у меня все расшифровал.
— Все два миллиона?
— Да. Вы знаете, что теоретически избиратель может узнать, как он проголосовал?
— Мне объяснили, что все сделано так, чтобы это было очень трудно. Но если человек голосует и записывает при этом хеши голосования, то потом он может проверить, как учли его голос.
— Да. Я кинул клич: «Кто записал хеши?» — и мне отвечает один человек: «У меня есть хеш, я зашел на сайт, и мой голос до сих пор не расшифрован». Смешно, да? Меня избиратели спрашивают: «Проверьте, мой голос не расшифрован?» И мне приходится помогать избирателю понять, как система учла его голос. Учла его, кстати, правильно.
Фото: Евгений Одиноков / РИА Новости
— Стоп-стоп. Еще раз. Переведем то, что вы сказали, на понятный читателю пример с бумажным голосованием и урной. Есть участок. На нем проголосовали 2 миллиона избирателей. Их голоса лежат в урнах. Выборы кончились, начался подсчет. Миллион триста голосов вывалили из урн, посчитали. Потом сказали: «Стоп». И перестали считать. Так если они перестали считать, как они объявили результат?!
— Давайте тогда с самого начала. Действительно, представьте себе, что вы пришли наблюдать на участке электронного голосования, как если бы это был бумажный участок. Что первое делает наблюдатель? Он проверяет книги избирателей. И тут мы замечаем, что у нас на участке книги странные. Там нет фамилии-имени-отчества, а вместо него — уникальный идентификатор. Сайт госуслуг этого избирателя знает, а мы — нет. Вы видите в книге, что у вас в системе 2 млн избирателей. Но вы находитесь на участке 5003. И вы хотите знать не сколько их всего, а сколько их конкретно в этом округе и на этом участке. И этого нет. Там внутри транзакции «регистрация избирателей», внутри одной транзакции, до 100 регистраций разных voter ID. Но при этом в них не указан округ, где избиратель зарегистрирован.
Я считаю, это странный способ вести книгу избирателей.
— То есть наблюдатель не видит, сколько электронных избирателей в данном округе?
— Из книги электронных избирателей — не видит.
— Это мозг выносит. Максим Гонгальский от «Яблока», глава муниципального округа Раменки, который тоже в штабе Брюхановой, мне сказал удивительную вещь. Он сказал, что у них вообще не было списков избирателей, в которых был бы указан их адрес. И то же самое мне подтвердила потом Анна Лобонок, наблюдатель от КПРФ. Она сказала, что у них в списках избирателей не был указан их адрес. И что с участков у них была жалоба. Приходит человек голосовать и видит, что в его квартире прописаны еще два человека, и эти двое ему неизвестных выписаны на ДЭГ. У меня просто крышу снесло.
— Я не знаю, как устроена система живого наблюдения. Я могу однозначно сказать по сайту observer.mos.ru. В Транзакции с типом «регистрация избирателей» — в них не указано, по какому округу он голосует.
— А как же это понять?!
— Потом во время голосования выдавались бюллетени, и в транзакции на выдачу бюллетеня было написано: данный voter ID получил бюллетень по заданному округу. Если кто-то из ДИТа мне пояснит, как проверить, что избиратель не может проголосовать не по своему округу, я буду рад, потому что у меня не получилось этого сделать. Так же, как и не получилось найти в исходном коде защиту от того, чтобы данный voter ID не проголосовал не в своем округе, но опять же я буду рад, если кто-то из ДИТ пояснит.
— Стоп-стоп! Вы помните праймериз «Единой России»? Когда чуть ли не 10 млн человек отъединороссили электронно? Зашли в их записи на «Госуслугах», изменили место прописки и проголосовали за них на праймериз в «ЕР» в городе Усть-Заколдобинске N-cкой области?
— Я не в курсе. Меня это не интересовало, пока у моего кандидата не украли мандат.
— Итак, мы выяснили, что на нашем условном участке 5003 нет книги избирателей с адресами. Что открывает захватывающие перспективы для ботов.
— Пока выглядит так, да, но буду рад, если кто-то пояснит, может, это я и ошибаюсь. Итак, продолжим. Избирательная комиссия начинает выдавать бюллетени. За выдачу бюллетеней отвечает транзакция, которая так и называется: «выдача бюллетеня». Внутри нее написано, что данный voter ID голосует по такому-то округу и может проголосовать с таким-то ключом. Избиратель начинает голосовать. Он ставит галочку в бюллетене. И так как избиратель не хочет, чтобы кто-то раньше времени узнал, как он проголосовал, он цифровым образом эту галочку замазывает.
— Выданным ему личным ключом шифрования?
— Да, по нашей аналогии с обычным бумажным округом считайте, что это замазка. Но — и это очень важно, — когда я уже получил бюллетень, заполнил и замазал, я не имею уже привязки бюллетеня к идентификатору голосующего.
— Ну и что?
— А то, что на выборах в Москве была введена система переголосования. И по факту она устроена так. Если ты решил, что твой кандидат тебе не подходит, то ты через три часа можешь прийти на участок, вытащить из-за пазухи готовый бюллетень и опять замазать галочку.
То есть когда я получил бюллетень, мне его выдали. А если я пришел переголосовать, то я материализовал его из-под полы. У нас нет никакой публичной информации, как эти бюллетени связаны друг с другом.
Фото: Владимир Федоренко / РИА Новости
— Стоп! То есть они взяли сейф, положили туда два миллиона голосов, сказали: «Сейф надежный, блокчейн, все дела», а потом рядом повесили на гвоздь 300 тыс.?
— Пользуясь нашей аналогией с бумажным участком, я бы сказал так. В конце дня мы подводим итоги голосования. И я вижу, что в урне лежит 133 тыс. бюллетеней с замазанной галочкой. И мне говорят: «А посчитаем мы из них только вот эти 120 тыс.». И спрашиваю: «Как же так получилось? На каком основании?» И председатель ОИКа тогда говорит: «Ах, ну знаете, у нас тут в ДИТе был второй непубличный блокчейн, в нем-то и записано, что вот эти 13 тыс. мы считать не будем».
— И наблюдатель не может отличить, какой бюллетень был выдан, а какой — материализовался из-под полы?
— Да. Мне сначала казалось, что я тупой. Я смотрю на бюллетени и не понимаю, какие из них переголосованы. Я ищу по чатам: найдите того человека, который воспользовался инструкцией «Голоса», переголосовал и сохранил два своих хеша. Я нахожу такого человека и вижу, что в его двух транзакциях ничего общего нет. Нет идентификатора, который показал бы, что они пришли из одной группы.
Вообще никакой информации нет! И тут у меня, и не только у меня, возникает вопрос: а где эту информацию взять?
— И откуда?
— Мы начали читать исходный код. И стали подозревать, что должна быть какая-то параллельная система. Я такого словосочетания, как «закрытый блокчейн», не знал тогда. И как потом выяснилось, даже не все наблюдатели за ДЭГ знали о его существовании. Но я понимал, что такая система должна быть. И что в этом втором блокчейне лежит т. н. encrypted group ID. И когда происходит переголосование, этот второй блокчейн записывает у себя внутри, какой голос был позже. И вот когда начался скандал, то выяснилось, что да, существовал-таки второй блокчейн. Закрытый блокчейн. И это возмутительно.
— Закрытый блокчейн? Как это блокчейн может быть закрытым? Закрытый блокчейн — это как секретный гимн. Они хоть его опубликуют?
— Я бы очень хотел, чтобы они его опубликовали. Или объяснили, как его содержимое можно получить по первому «публичному» блокчейну, который у нас есть.
— Итак, мы проголосовали. И начинаем подводить итоги.
— Чтобы подвести итоги, надо расшифровать все голоса.
Я точно заявляю, что никакими публичными системами все голоса не расшифровывались.
Расшифровка голосов — это когда к нам приходит член избирательной комиссии и приносит специальный инструмент, которым мы стираем замазку, которой была замазана галочка. Электронный ластик. Этот ластик — ключ, куски которого были у семи человек, и вот после восьми вечера они собрались вместе.
У нас лежит стопка из 2 млн бюллетеней. Комиссия ластиком начинает стирать замазку. И останавливается на миллионе трехстах тысячах. И председатель уходит. Ты спрашиваешь: «Что происходит? У нас 700 тыс. не расшифрованы. Мы итоги подвести не можем». Тут приходит председатель и приносит готовый протокол.
Ситуационный центр Общественной палаты РФ по мониторингу соблюдения избирательных прав граждан в единый день голосования. Фото: Евгений Биятов / РИА Новости
— И эта расшифровка — стирание замазки — у вас на лэптопе заняла полчаса?
— Ну, у меня все-таки не лэптоп. У меня 12-ядерный компьютер, 24 потока.
— Лэптоп, восемь ядер.
— Ну, у вас заняла бы 45 минут. И то если не оптимизировать код. Я же сказал, у меня был не оптимальный код.
— В переводе на здравый смысл, что случилось, почему они остановили подсчет и потом считали всю ночь на машинах, которые явно мощнее вашей? Они ужаснулись результатам? Как-то по-другому это можно объяснить?
— Ну, чисто теоретически там один голос не удается расшифровать. Там битые данные. Может быть, там программа взяла, увидела этот голос и свалилась.
— Но ваша программа не остановилась?
— Нет, моя все расшифровала.
— В вашем посте меня вот что поразило. Функция переголосования была введена для защиты от административного давления. К примеру, человека на работе попросили проголосовать за власть, за Хованскую, он проголосовал, пришел домой и переголосовал за Брюханову. Вы расшифровали все бюллетени, и вы не имели возможности определить, какие из них были переголосованы, а какие нет. И вот когда вы сравнили свои результаты с официальными, то оказалось, что у вас за «ЕдРо» меньше, чем официально. Ненамного — на 1%, но меньше. Мне это показалось математическим доказательством того, что переголосование использовалось для вбросов. Потому что из вашего результата получается, что люди, которые переголосовывали, они переголосовывали именно за «ЕдРо».
— Теоретически тот же результат мог бы получиться, если бы оппозиция, зная о возможности переголосования, переголосовывала бы несколько раз за своего кандидата. Игралась. Но вот сценарий, который предлагал Венедиктов: «Меня заставили на работе проголосовать за Хованскую, я пришел домой и проголосовал за Брюханову», — это не так, как система использовалась. По крайней мере, если мы доверяем результатам в ГАС «Выборы».
— Максим Гонгальский опубликовал у себя на фейсбуке график вбросов, которые команде Каца удалось построить. Они доказали, что это были банальные вбросы, а не какой-то хитрый откат блокчейна, как опасался Толстогузов, и пр. И там четко прослеживалось два этапа вмешательства: «медленная фаза», с пятницы по субботу, когда вбрасывали не очень много, «быстрая фаза» в воскресенье с 8:00 до 14:00, когда вбрасывали очень много, причем с «перерывом на обед». Была и «свободная фаза» с 14:30, когда вбросов практически не было: в этот момент было видно, что настоящее онлайн-голосование даже чуть-чуть больше, чем офлайн, склонялось к оппозиции. Вы можете соотнести эти фазы на графике с тем, что вам удалось обнаружить? С типами вбросов?
— Я могу только спекулировать. Честно: я такой же график по 198-му округу получил сам в понедельник утром, но не смог правильно на него посмотреть. Потому что это колоссальная техническая дополнительная работа. Снимаю шляпу.
— Так как фазы на графике соотносятся с обнаруженными вами дырами?
— Смотрите. У нас осталась за скобочками история с заявками на электронное голосование. Я писал, что у нас заявок на электронное голосование было больше, чем зарегистрировано в системе на mos.ru. Там еще 455 тыс. заявлений пришло из системы госуслуг, и у нас нет по ней информации. Уже после публикации мне показали, что да, эта информация в ГАС есть. Заявки сходятся. Надо проверить, реальные ли это вообще люди. Брюханова сегодня утром говорила, что на mos.ru есть несуществующие дома. Потенциально фейковые избиратели, которые могли быть как-то включены.
— Как мне сказал один приятель: «Ты пойми, что у каждого градоначальника всегда есть резерв из 5% умерших».
— Да, это первый вектор — взять умерших людей, купить учетные записи и зарегистрировать их на электронное голосование. Второй вектор — переголосование.
— Вам не кажется, что эти два вектора соответствуют «медленной» и «быстрой» фазе?
— Я видел, что это обсуждается в чатах. Но однозначно сказать нельзя.
— О, это радует. Потому что у меня очень быстро возникло впечатление, что вбрасывали разными способами, как и на настоящем участке, а не каким-то одним. И вот это очевидно напрашивалось, что «медленная фаза» — это боты, «быстрая» — переголосование. Но я же филолог и полный лох. Я подумала, это обобщение полного дилетанта. Знаете, увидел дилетант что-то знакомое и сразу связал между собой.
— У меня тоже до сих пор впечатление, что я где-то ошибся. Я очень переживал, что я опубликую пост и мне скажут: «Дурак, код прочитать не смог». И надеялся, что выйдет ДИТ и все объяснит. Но пока никто ошибок не нашел.
— Но из «медленной фазы» и «быстрой фазы» еще одна очень важная вещь следует. Если бы вбросы только ими ограничивались, то они бы не подводили итогов всю ночь, и не гоняли бы Сухорукова от ноды наблюдателя. Они бы через полчаса все посчитали. Они бы не остановили подсчет. Весь аврал, который был ночью, значит, что они стали считать уже после вбросов и остались недовольны.
— Да, они бы расшифровали 2 млн голосов. Вполне возможно, что они повесили амбарный замок на ноду и сели перебирать закрытый блокчейн, чтобы как-то подобрать группировки по переголосам, чтобы цифры за «ЕР» сходились.
— А «перерыв на обед» — это что такое?
— Не знаю. Может быть, это был действительно перерыв на обед, если голосовали люди. А может, они повбрасывали и согласовывали: хватит — не хватит.
— Вбросы — это боты или люди голосовали?
— Не знаю. Но если боты, это будет абсолютно возмутительно. Представляете? Сидят разработчики в ДИТ Москвы или где-то еще, не знаю где, и пишут скрипты, чтобы вбрасывать голоса.
Рис. Пётр Саруханов («Новая газета»)