Между прочим, показанное в ролике гораздо ближе к идеологии Industry 4.0, чем весь этот разводняк с 3D-принтерами.
Месяц: Июль 2020
Человечество отупело
Вот примерно каждый год с большим пафосом сообщают, что где-то в очередной раз с помощью «3D-печати» сумели построить дом — вот как-то так:
https://ru.euronews.com/2020/07/08/3d-printed-house-in-belgium
Комментаторы в интернете тут же предрекают революцию в строительстве и все такое — а мне что-то кажется, что все это в плане хайтека и рядом не стояло с индустриальным домостроением. Обычная панельная хрущевка, или, если вам милее одноэтажная Америка — Levitt house, в сравнении с любым таким напечатанным на 3D-принтере сарайчиком — технологический шедевр, причем во всех отношениях — от массового производства стандартных комплектующих до обеспечивающей все это логистики.
С другой стороны, похоже, что для интеллекта среднего интернетовского комментатора осознать это сложновато, а «символ прогресса» в виде 3D-печати доступен пониманию даже полуидиота.
О чем говорят мужчины
Форум с преимущественно мужским населением, тема про тиндер. Фотки блядей, малолеток и блядей-малолеток с претензией на интеллектуальность в подписях обсуждать надоело, ждущих принца РСП — тем более, так что разговор плавно сполз в обсуждение методов триангуляции, геодезии и даже систем управления огнем английских линкоров ПМВ — а все оттого, что двое почти одновременно увидели одну и ту же смешную фотку.
Бесит, сука
Вот посмотрел я на то, из чего состоит rawStoreBallotTx, передающийся на сервер и сохраняющийся в блокчейн при электронном голосовании в Москве. Разбираться с обширным кодом клиента Exonum на Javascript я не стал, а просто глянул на сами данные.
58 1c c8 b3 ed 95 97 f3 f4 ab c7 76 1d 17 c3 02 a3 d5 3e 59 c8 c7 6c 55 04 4b f0 d3 91 e7 fc c1 00 00 e9 03 06 00 0a 40 64 61 38 35 66 61 66 38 34 66 61 65 62 30 65 39 30 65 66 33 31 61 32 65 37 32 35 32 34 31 35 31 66 62 61 63 30 65 32 66 36 65 36 63 34 39 38 33 36 30 31 33 64 36 34 35 32 39 34 36 39 38 38 64 10 4d 1a 56 0a 14 bc ef fd 5e 5e a6 8a 6b b2 d9 04 31 dd 51 2e 11 5e 4c 44 e3 12 1a 0a 18 9b 37 cb a5 f0 26 25 ca 74 45 00 21 88 e1 59 ca 56 ee d5 24 dd 25 d3 26 1a 22 0a 20 57 1d b7 6c 24 f5 85 22 7e 75 4c ca e6 97 99 8f f6 22 6b 24 58 94 b9 0d 57 b0 f3 d5 9a 0c 16 01 9d c1 e2 eb 1d 8d 8a cf 12 60 27 3f f0 2e cc ba 5d 9f 61 e0 ba 51 a7 d2 26 78 82 d1 05 6d a5 92 93 75 7d 5a c5 23 e0 45 f7 f9 8d 6b ed 4f 33 fe d7 c2 e2 48 77 c6 61 9b 10 86 b3 c7 a7 73 3f 0d
Первые 32 байта — это некий идентификатор под названием accountAddressBlock; дальше начинается что-то непонятное — но резко выделяется довольно длинная последовательность из байт в диапазоне 30—39 и 60—66 — это цифры и буквы от a до f. Выпишем ее отдельно (справа — символы, которым эти байты соответствуют):
64 61 38 35 66 61 66 38 da85faf8
34 66 61 65 62 30 65 39 30 65 66 33 31 61 32 65 4faeb0e90ef31a2e
37 32 35 32 34 31 35 31 66 62 61 63 30 65 32 66 72524151fbac0e2f
36 65 36 63 34 39 38 33 36 30 31 33 64 36 34 35 6e6c49836013d645
32 39 34 36 39 38 38 64 2946988d
Что это? А это как раз voting id, идентификатор голосования — только зачем-то переданный в виде текста. Сразу же хочется обратить внимание на байт 40, стоящий непосредственно перед voting id — да и вообще на всю последовательность 00 00 e9 03 06 00 0a 40 — хочется считать ее неким заголовком, а 40 — длиной поля. По аналогии находим еще три подобных последовательности — «заголовок» 10 4d 1a 56 0a 14 (в кавычках, и я сейчас объясню, почему) предшествует 20 байтам
bc ef
fd 5e 5e a6 8a 6b b2 d9 04 31 dd 51 2e 11 5e 4c
44 e3
Заголовок 12 1a 0a 18 — последовательности из 24 байт:
9b 37 cb a5 f0 26 25 ca 74 45
00 21 88 e1 59 ca 56 ee d5 24 dd 25 d3 26
А заголовок 1a 22 0a 20 — 32 байтам:
57 1d b7 6c 24 f5 85 22 7e 75 4c ca e6 97
99 8f f6 22 6b 24 58 94 b9 0d 57 b0 f3 d5 9a 0c
16 01
Казалось бы, это вся информация для записи в блокчейн? Но нет — не хватает district id, номера «участка» (здесь он принимал логичные значения 77 и 52 для Москвы и Нижнего Новгорода соответственно). Где он мог потеряться? Оказывается, первый «заголовок» из 6 байт — это на самом деле еще и поле с номером участка, 10 4d (4d в шестнадцатиричной системе — это как раз 77).
В оставшихся 64 байтах я какой-то структуры уже не увидел, но в целом для расшифровки голоса они нам уже не нужны. Вспоминаем структуру данных для передачи — это должны быть зашифрованный голос, nonce и публичный ключ пользователя; в используемой для голосования библиотеке NaCl длина nonce и публичного ключа как раз составляет 24 и 32 байта соответственно, 20 байт — это длина сообщения. Кажется, мы нашли все необходимое? Проверяем несложной программой:
unsigned char message[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0xbc, 0xef, 0xfd, 0x5e, 0x5e, 0xa6, 0x8a, 0x6b,
0xb2, 0xd9, 0x04, 0x31, 0xdd, 0x51, 0x2e, 0x11,
0x5e, 0x4c, 0x44, 0xe3
}; // first 16 bytes must be 0
unsigned char nonce[] = {
0x9b, 0x37, 0xcb, 0xa5, 0xf0, 0x26, 0x25, 0xca,
0x74, 0x45, 0x00, 0x21, 0x88, 0xe1, 0x59, 0xca,
0x56, 0xee, 0xd5, 0x24, 0xdd, 0x25, 0xd3, 0x26
};
unsigned char public_key[] = {
0x57, 0x1d, 0xb7, 0x6c, 0x24, 0xf5, 0x85, 0x22,
0x7e, 0x75, 0x4c, 0xca, 0xe6, 0x97, 0x99, 0x8f,
0xf6, 0x22, 0x6b, 0x24, 0x58, 0x94, 0xb9, 0x0d,
0x57, 0xb0, 0xf3, 0xd5, 0x9a, 0x0c, 0x16, 0x01
};
unsigned char dit_private_key[] = {
0xdb, 0x77, 0xd6, 0x2f, 0xc8, 0x87, 0x26, 0xf1,
0xc5, 0xa6, 0xb7, 0x9b, 0x00, 0x3b, 0x3b, 0xca,
0x83, 0x34, 0x9e, 0x33, 0x43, 0x37, 0xde, 0x84,
0xbd, 0x17, 0x34, 0x4a, 0xb6, 0x01, 0xdb, 0x74
};
unsigned char buf[sizeof(message)] = { 0 };
int res, vote;
res = crypto_box_open(buf, message, sizeof(message), nonce, public_key, dit_private_key);
vote = *((int*)(buf + crypto_secretbox_ZEROBYTES));
printf("%x\r\n", vote);
И действительно — расшифрованное сообщение содержит 4 байта 1a d5 be 0d — голос «против» на этом голосовании.
Так вот, возвращаясь к тому, что бесит. Во-первых, бесят просранные талантливыми фронтендерами 32 байта — зачем засовывать voting id в виде строки? Во-вторых — бесит полное отсутствие описание формата передаваемых данных — вот я его разобрал довольно элементарным способом, но пока так и не знаю о назначении еще 64 байт в конце — похоже, что это как-то связано с блокчейном и криптографической подписью для него, но я не уверен.
Боженька, побей их всех по голове ЕСПД.
Iditi srati!
К какой-то музыкальной программе есть плагин стоимостью 499$, умеющий изображать пение хора — и в числе прочих функций, можно заставить хор петь разные слоги. К сожалению, набор вариантов довольно ограничен, и на русском языке удалось собрать только фразу «Идите срать!» — точнее, «I-di-tis-ra-ti». В видео — с 8:00:
Хор, старательно выводящий эту фразу, просто офигенен.
По мотивам очередного выступления
В эту субботу в очередной раз собрались обсуждать электронные выборы, и в этот раз ступора уже не было — то ли Шевяков не курил в камеру, то ли действительно надо привыкать к «публичным» выступлениям в Зуме :) Полную запись можно посмотреть на ютубе, а тут — перескажу свои основные тезисы.
Московская голосовалка — вопреки всем ожиданиям — отработала более-менее нормально, и это не может не радовать. О технических сбоях вроде остановки выгрузки данных и редких падениях сайта для наблюдения до меня уже сказали, я хочу добавить немного о проблемах скорее организационного характера.
Начну с того, что тайна голосования, которая волнует довольно многих избирателей и экспертов, действительно держалась на честном слове ДИТа. Это сложно назвать виной разработчиков и эксплуатантов системы – так уж получилось, что занимается этим ровно одно ведомство, а надо разделять систему как минимум на две части — чуть дальше станет понятно, почему, но Александр Исавнин действительно много раз задавал вопрос об этом, а ответов лучше, чем “поверьте нам на слово” техническая рабочая группа так и не получила. Опять же, отмечу, вслед за Олегом, что фактов нарушения тайны голосования пока никто не зафиксировал.
С другой стороны — некоторые технические меры для защиты тайны голосования были приняты. Да, при изучении кода системы заметно, что авторы попытались реализовать вариант хорошо известного «протокола двух агентств«, который защищает тайну голосования, и в принципе система позволяет разнести авторизацию пользователя и собственно голосование по разным ведомствам, что критично для этого семейства протоколов. Это в целом довольно положительно характеризует разработчиков системы — как минимум обращение к известным протоколам позволяет избавиться от всевозможных неожиданностей.
Чуть подробнее опишу протокол голосования — при этом постараюсь изложить это все максимально упрощенно. К сожалению, в Википедии описан похожий, но отличающийся протокол, а «Прикладная криптография» Шнайера есть под рукой далеко не у всех — хотя протокол, похожий на ДИТовский, там описан под названием «Голосование с двумя Центральными комиссиями». Основаны все эти протоколы на криптографии с открытым ключом — здесь знать о ней надо лишь то, что используется пара из открытого и закрытого ключа, таких, что сообщение, зашифрованное открытым ключом, можно расшифровать только с помощью закрытого, и наоборот — если сообщение зашифровано закрытым ключом, то оно расшифровывается открытым. Закрытый ключ обычно держится в секрете, а открытый доступен всем.
Итак, для начала — подготовка к голосованию, которая с точки зрения криптографии состоит в том, что создается пара из открытого и закрытого ключа. Закрытый ключ разделяется на части, которые передаются членам избирательной комиссии — а они, как и на обычных выборах, представляют самые разные политические силы — например, в этот раз одним из членов комиссии был Григорий Мелконянц из «Голоса«. Главное здесь это то, что закрытый ключ не будет известен никому вплоть до момента его «сборки» — а открытый ключ, наоборот, будет опубликован во время голосования. Происходит процедура генерации и разделения ключей в торжественной обстановке, с банкетом, фуршетом, журналистками с декольте — в общем, «сожалею, что не был при сей баталии хотя бы мичманом!»
Дальше происходит собственно голосование — пройдя авторизацию на «Госуслугах» или mos.ru, избиратель получает от сервера регистрации уникальный номер (GUID) и перенаправляется на сервер голосования, по адресу «$host/election/check/$guid» (строка 94 файла Ballot.php в приложении form, опубликованном в ДИТовском гитхабе).
Сервер голосования — это приложение ballot (обратите внимание, что работало оно на другом домене — авторизация происходила на 2020og.ru, а собственно голосование — на elec.moscow, можно считать это демонстрацией возможности разделения авторизации и голосования), и там нам очень интересно содержимое файла election.js — точнее, то, что начинается после 243 строки. Там происходит следующее: с помощью библиотеки NaCl создается пара из «пользовательского» открытого и закрытого ключа, случайным образом выбирается значение nonce, сообщение из выбора избирателя и nonce зашифровывается сначала с помощью закрытого ключа избирателя, а затем — с помощью открытого ключа системы голосования. Пара из зашифрованного таким образом сообщения и открытого ключа избирателя обладает следующим очень полезным свойством — зная закрытый ключ системы голосования, можно убедиться, что сообщение (голос) зашифровано именно закрытым ключом избирателя, и никаким другим; не зная закрытого ключа избирателя, невозможно «подменить» голос; не зная закрытого ключа системы голосования — нельзя сделать с этим сообщением вообще ничего.
Затем пара из GUID и зашифрованного голоса отправляется на сервер голосования, где GUID проверяется на достоверность — что он действительно был выдан сервером регистрации, и по нему еще не голосовали, а зашифрованный голос в случае успешной проверки сохраняется — в данном голосовании в блокчейн, но в принципе это может быть любая база данных или вообще файлик на диске. Списки проголосовавших избирателей доступен наблюдателям, список зашифрованных голосов — вообще всем (в ходе голосования на специальном сайте транслировались транзакции блокчейна, а раз в полчаса они выгружались в файлы csv).
По окончании голосования снова проводится банкет с присутствием журналисток, где собирается закрытый ключ системы голосования и голоса избирателей расшифровываются.
Попробуем теперь перечислить свойства такой системы.
- Получить GUID и проголосовать могут лишь зарегистрированные избиратели — это обеспечивается не только криптографией, но и тем, что авторизацией пользователей занимаются «Госуслуги»;
- Cервер голосования не может «вбрасывать» в хранилище голоса по своему усмотрению — их не может быть больше, чем на сервере авторизации было создано GUID’ов (список избирателей с отметками, кто голосовал, а кто нет, доступен для просмотра наблюдателям, как и на обычных «бумажных» выборах);
- В ходе голосования голос пользователя расшифровать нельзя (и, допустим, отклонить его под видом технической ошибки);
- После голосования голос пользователя нельзя изменить (так как никому, кроме самого пользователя, неизвестен закрытый ключ — и то для его сохранения надо предпринять некие усилия);
- Каждый голосовавший может найти свой голос в опубликованных результатах;
- Каждый может самостоятельно проверить правильность подсчета голосов;
- Если сервер авторизации не сохраняет выданные пользователям GUID’ы, а сервер голосования не сохраняет связку между GUID и голосом (тут придется поверить разработчикам и эксплуатантам на слово — но скорее всего, это так) — никто не может узнать, какой голос принадлежит какому пользователю. Кстати, обращу внимание, что для раскрытия тайны голосования требуются согласованные действия операторов сервера авторизации и голосования — собственно, поэтому этот протокол и называется «протоколом двух агентств».
Собственно, это то, что требуется от системы тайного электронного голосования — и хочу заметить, что нигде здесь не требуется блокчейн, можно было бы обойтись лишь выгрузкой списков избирателей и зашифрованных голосов с некоторым интервалом. В исходниках остались комментарии, из которых можно предположить, что в качестве ближайшего развития системы рассматривается реализация протокола Фудзиока-Окамото-Охта, где сделаны шаги, позволяющие частично защититься и от сговора операторов сервера авторизации и голосования — так что впечатление осталось скорее положительное.
Теперь перейду к плохому. Во-первых — зачем я полез смотреть код? Полез я туда именно для того, чтобы посмотреть, какой конкретно протокол голосования там реализован, и повторюсь, остался более-менее доволен увиденным — но хочу сказать, что программистом на PHP и Javascript я не являюсь, и гораздо проще было бы прочитать описание алгоритма голосования в более явном виде. Те же ГОСТы 34 серии предусматривают документ под названием «Описание алгоритма» — и может быть, я бы успокоился, увидев его и сравнив с реализацией. Кстати, еще две шпилечки в адрес ДИТа — во-первых, на вопрос «где же, все-таки, предусмотренная ГОСТами документация», был дан ответ в духе «ну мы систему запустили, документацию напишем потом». Хочу заметить, что у них на сайте выложен ГОСТ 34.201-89, а жить по нему они не хотят — там ясно сказано, что документ под названием «Описание алгоритма», например, пишется на этапе технического проекта, еще до разработки каких-либо программ, и уж точно — до ввода в эксплуатацию. Точно так же хотелось бы напомнить о существовании ГОСТ РД 50-34.698-90, где можно увидеть мои хотелки в плане описания криптографических протоколов в разделе 7.1.
Вообще, в плане открытости и прозрачности электронного голосования есть куда расти. Это вовсе не какие-то абстрактные соображения, информация о работе системы и том, как в ней все устроено, должна быть доступна для широкого круга заинтересованных лиц, а не избранных «экспертов» — с которыми еще и делились информацией крайне неохотно. В противном случае мы получаем, например, пресловутую публикацию «Медузы» о том, что оказывается, если знать ключи шифрования и случайное число (то самое nonce), выбранное браузером пользователя при подготовке зашифрованного бюллетеня к отправке, можно проверить, правильно ли учтен этот бюллетень в итоговом протоколе. Открытие это сродни торжественной констатации факта «вода — мокрая».
Вообще, во многих алгоритмах тайного голосования возможность проверить правильность учета своего бюллетеня, найдя его в итоговом протоколе, предусмотрена штатно (к ним относятся и вышеназванные) — хотя тот же Шнайер все же намекает, что такая возможность при неправильном ее использовании — прямой путь к организованной скупке голосов. Здесь же получилось так, что из-за некоторой скрытности авторов системы голосования возможность проверить правильность своего голоса журналисты объявили «уязвимостью».
Довольно странно была организована и публикация исходных кодов системы — опубликованы были лишь два обеспечивающих голосование веб-приложения и код смарт-контрактов блокчейна, причем некоторые особенно интересные с точки зрения стойкости шифрования и сохраняемой информации места в исходном коде были почищены. Примерно так же выглядела и переданная рабочей группе «документация», причем местами доходило до смешного — цитирую один из документов: «хеш длиной YYY кодируется в XXX для сохранения целостности». При этом узнать длину хеша и способ его кодирования можно было совершенно тривиальным образом — например, открыв отладчик страницы во время голосования или заглянув в опубликованные исходники. Стоит еще сказать, что местами исходный код производит впечатление полуготового прототипа, к примеру, в некоторых местах остались комментарии в духе «удалить после тестирования».
Кстати, к вопросу об отладчике — получить представление о работе системы голосования можно было бы во время тестирования. К сожалению, тестовое голосование было доступно лишь для избирателей, уже имеющих право голоса на реальном голосовании — то есть жители Московской области, желающие посмотреть, как что там устроено, оказались в пролете. К настоящему тестированию, с другой стороны, это не имело никакого отношения — возможность проголосовать давалась лишь один раз, так что сделать несколько попыток и посмотреть, «что будет, если» было невозможно.
Еще одно странное явление — это подключение некоей «системы антифрода» (по словам представителей ДИТ), которая изначально не была заявлена. Фактически на каждую веб-страницу голосования внедрялся посторонний код на Javascript, не выложенный в публичный доступ заранее.
Скажу еще немного о блокчейне. Довольно часто говорят, что именно благодаря блокчейну эта система голосования надежна и безопасна. Вот даже на ютубе в комментариях задали вопрос — «СМИ писали, что система надёжно защищена и использование блокчейна гарантирует от подмены голосов и деанонимизации, так ли это?» — на самом деле это не совсем так. Блокчейн обеспечивает хранение уже принятых голосов, и существенно затрудняет какие-либо изменения данных постфактум — но в «модели угроз» для электронного голосования это лишь один из многих рисков. О том, как система защищена от подмены голосов и деанонимизации я сказал выше, блокчейн как таковой для этого не нужен. Впрочем, если в этот раз блокчейн работал почти хорошо (за исключением его “падения” на несколько часов в первый день голосования) – то почему бы и нет? С другой стороны, представляется, что блокчейн в целом — это «узкое место» системы, Александр Щербаков высказывал свои соображения по этому поводу.
Наблюдение за выборами — еще один не до конца проработанный вопрос. Например, не опубликован исходный код веб-приложения для наблюдателей — но скорее всего, каких-либо попыток скрыть попадающую в блокчейн информацию не предпринималось, по трудозатратам это эквивалентно созданию еще одной, «параллельной» системы голосования. Был довольно длительный период, когда не работала выгрузка данных о голосовании — по причинам, которые были попросту не предусмотрены или забыты в момент разработки. В теории это могло бы стать основанием не доверять голосам, поданным в этот период — с другой стороны, каких-либо аномалий там обнаружено не было, наоборот, было два заметных скачка голосов «против».
Это все может показаться придирками — но не устану ссылаться на опыт Эстонии, где описания системы электронного голосования для любой аудитории — от обывателей до специалистов — совершенно официально опубликованы на сайте тамошнего избиркома, а полный — вплоть до возможности собрать свою работающую систему голосования, полностью повторяющую настоящую — комплект исходных кодов выложен на все тот же гитхаб. Это очень полезно с «исследовательской» точки зрения, а один из основных принципов современной криптографии состоит именно в открытости криптографических систем для изучения.
В целом, конечно, вопросы к разработчикам имеющейся системы голосования — скорее не технические, а организационные. Повторюсь, что с точки зрения используемых протоколов голосования система довольно адекватна, а с точки зрения реализации — к сожалению, пока приходится верить на слово, что используемая система голосования совпадает с тем, что было показано публике. В будущем, конечно, хотелось бы иметь возможность изучить систему голосования не только по кускам кода на Github, а еще и по более-менее нормальной документации, причем целиком, а не отдельными частями «тут покажем, тут не покажем».
Диалоги про демократию
А вот вам красивый график
Взял и от нечего делать разобрал файлик с выгрузкой данных по электронному голосованию:
http://observer2020.mos.ru/observer/downloads/ballots_decrypted_2020-07-01T19:47:00.csv
Получился такой вот забавный график (кликабельно):
Интересно было бы сопоставить явно видимые на графике «скачки» с разными событиями прошедшей недели — например, резкий прирост голосов «за» в Москве в 17:00 25 июня, или синхронные скачки «против» в Москве и Нижнем в 16:00 26 июня и в 14:00 29 июня.
Наговняканный за полчаса код прилагается:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct voteblock {
int time; // time in seconds since day start
int res[2][2];
};
voteblock votes[2300000]; // max. block number is about 2.27M
int gettime(char *token){
token[2] = '\0';
token[5] = '\0';
int hours = atoi(token);
int minutes = atoi(token + 3);
int seconds = atoi(token + 6);
return hours * 60 * 60 + minutes * 60 + seconds;
}
void process_vote(char *buf){
char *token;
int district, res;
token = strtok(buf, "\";"); // номер голоса
int n = atoi(token);
token = strtok(NULL, "\";"); // избир. округ
if (strcmp(token, "77") == 0){
district = 0;
} else if (strcmp(token, "52") == 0) {
district = 1;
} else {
fprintf(stderr, "Unknown district %s\r\n", token);
return;
}
strtok(NULL, "\";"); // адрес голоса в блокчейне
token = strtok(NULL, "\";#"); // блок голоса
int block = atoi(token);
token = strtok(NULL, "\";"); // время записи блока голоса
int time = gettime(token);
strtok(NULL, ";"); // зашифрованный голос
token = strtok(NULL, "\";"); // расшифрованный голос
if (strcmp(token, "2212294583") == 0){
res = 0;
} else if (strcmp(token, "450215437") == 0) {
res = 1;
} else {
fprintf(stderr, "Unknown vote result %s\r\n", token);
return;
}
strtok(NULL, "\";"); // блок расшифровки
strtok(NULL, "\";"); // время записи блока расшифровки
strtok(NULL, "\";"); // транзакция
votes[block].time = time;
votes[block].res[district][res]++;
}
void print_votes_table(){
int day = 0;
int starttime = 7 * 3600; // 10:00:00 MSK = 7:00:00 UTC
int delta = 10 * 60; // 10 minutes granularity
int allvotes[2][2] = { 0 };
// to put the last line
votes[sizeof(votes) / sizeof(voteblock) - 1].time = INT_MAX;
for (int i = 0; i < sizeof(votes) / sizeof(voteblock); i++){
if (votes[i].time >= 0){
if ((votes[i].time > starttime + delta) || (votes[i].time < starttime)) {
/* either end of current stats block or end of day*/
if (votes[i].time < starttime) {
starttime = 0;
day++;
} else {
starttime += delta;
}
// finalize this line
printf("%i\t%i\t%i\t%i\t%i\t%i\r\n", day, starttime, allvotes[0][0], allvotes[0][1], allvotes[1][0], allvotes[1][1]);
}
allvotes[0][0] += votes[i].res[0][0];
allvotes[0][1] += votes[i].res[0][1];
allvotes[1][0] += votes[i].res[1][0];
allvotes[1][1] += votes[i].res[1][1];
}
}
}
int main(void){
char buf[1024]; // should be enough
fgets(buf, sizeof(buf), stdin); // skip first line
while (!feof(stdin)){
fgets(buf, sizeof(buf), stdin);
process_vote(buf);
}
print_votes_table();
return 0;
}
Обожаю медузоньку
Вот чувачки пишут: «мы нашли уязвимость в электронном голосовании, не знаем, как этим воспользоваться, но нас всех наебут!!!!1111»:
Собственно, «уязвимость» состоит в том, что зная созданный в ходе процедуры голосования закрытый ключ и еще один параметр (nonce), можно самостоятельно повторить шифрование голоса и убедиться, что именно этот зашифрованный голос оказался в итоговом списке. Казалось бы, можно радоваться? Но нет, «если залезть на шкаф», эту возможность якобы можно использовать для нарушения тайны голосования. То, что злоумышленнику для этого понадобится слишком много сделать — как минимум, встроить свой нехороший код во все пользовательские браузеры — как-то вообще не рассматривается.
А вообще такие громкие заявления — от банальной недоступности информации, как это все работает. Можно взять пример хотя бы с Эстонии, систему электронного голосования которой разобрали вдоль и поперек:
https://arxiv.org/pdf/1606.08654.pdf
Хотите описания «для широкой аудитории»? Пожалуйста:
http://www.vvk.ee/public/dok/General_Description_E-Voting_2010.pdf
Хотите анализ уязвимостей? Никаких проблем:
http://www.vvk.ee/public/dok/E-voting_concept_security_analysis_and_measures_2010.pdf
Опубликован полный исходный код (а не как у ДИТ Москвы, с купюрами в самых интересных местах):
https://github.com/vvk-ehk/ivxv
Вот такой уровень открытости и не позволяет выдавать очевидное за невероятные находки.
Кстати, на злободневную тему
Проголосовал против. И вот почему: не имею вообще ничего против «политической» части поправок. Даже пресловутое «обнуление» — акция разовая, а сторонникам святости конституции тут хорошо бы порадоваться тому, что уже очень скоро (в историческом масштабе) так ненавистное им слово «подряд» наконец-то уберут.
Но простите, поправки в главу 3 — это что-то кошмарное. Местами — популизм, особенно некоторые формулировки, по сути повторяющие и так уже имеющиеся федеральные законы. Местами — плохой популизм, типа «отмены» приоритета международных договоров — его и так никогда не было. Кое-где текст впихнут просто по принципу «чтобы было» — поправкам в 75 статью было бы самое место в 37, например. Где-то по этому принципу получается просто сборная солянка вроде статьи 671. И как положено — все это написано совершенно чудовищно. И прежняя версия была не фонтан, но вот некоторые формулировки из новой — это просто шедевр косноязычия, с моей точки зрения. В общем, за это — незачет.
PS Не знаю, говорили об этом или нет, но вообще принять эти поправки можно было и без всякого голосования, по описанной в статье 136 процедуре, но это было бы куда дольше. В чем причина спешки — не знаю, скорее всего, хотели успеть до единого дня голосования осенью (поправки в статьи 77 и 78, например).
PS/2 Агитация как «за», так и «против» была совершенно омерзительна.

