Архив 2 июля 2020

А вот вам красивый график

Взял и от нечего делать разобрал файлик с выгрузкой данных по электронному голосованию:

http://observer2020.mos.ru/observer/downloads/ballots_decrypted_2020-07-01T19:47:00.csv

Получился такой вот забавный график (кликабельно):

e-voting

Интересно было бы сопоставить явно видимые на графике “скачки” с разными событиями прошедшей недели – например, резкий прирост голосов “за” в Москве в 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″:

https://meduza.io/feature/2020/07/01/meduza-nashla-uyazvimost-v-sisteme-internet-golosovaniya-chast-golosov-mozhno-rasshifrovat-esche-do-ofitsialnogo-podscheta

Собственно, “уязвимость” состоит в том, что зная созданный в ходе процедуры голосования закрытый ключ и еще один параметр (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 Агитация как “за”, так и “против” была совершенно омерзительна.