https://github.com/rinon/Simple-Homomorphic-Encryption
Tip revision: c3ec8edb1a6e60f6fde83bafa2bd0b86d1e29ffe authored by Stephen Crane on 28 November 2011, 01:19:41 UTC
Added readme text. Removed a few unused lines from fully_homomorphic.h
Added readme text. Removed a few unused lines from fully_homomorphic.h
Tip revision: c3ec8ed
demo_vote_counter.cpp
#include "demo_vote_counter.h"
void print_help() {
printf("Takes one parameter, the number of candidates in the election\n");
}
bool DemoVoteCounter::verify_vote(unsigned int vote_id) {
Gate* input_zero = new Gate(InputLiteral, false, sec);
Gate* input_one = new Gate(InputLiteral, true, sec);
Gate* input;
unsigned long int w_length = log2(num_candidates);
unsigned long int p_length = pow(2, w_length);
Gate* temp_and;
Gate*** p = new Gate**[num_candidates+1];
for (unsigned long int i = 0; i < num_candidates+1; i++) { //row
p[i] = new Gate*[p_length+1];
p[i][0] = input_one;
if (i > 0) {
input = new Gate(Input, vote_id*num_candidates + i-1, sec);
}
for (unsigned int j = 1; j < p_length+1; j++) { //col
if (i == 0) {
p[0][j] = input_zero;
} else {
temp_and = new Gate(And, p[i-1][j-1], input, sec);
p[i][j] = new Gate(Xor, temp_and, p[i-1][j], sec);
}
}
}
Gate* output;
std::vector<Gate*> output_gates;
for (unsigned long int i = p_length; i > 0; i >>= 1) {
output = new Gate(Output, p[num_candidates][i], sec);
output_gates.push_back(output);
}
CipherBit** encrypted_results = fh->evaluate(output_gates, votes, pk);
bool* decrypted_results = fh->decrypt_bit_vector(sk, encrypted_results, w_length+1);
for (unsigned int i = 0; i < w_length; i++) {
if (decrypted_results[i]) {
printf("%u\n", decrypted_results[i]);
return false;
}
}
return decrypted_results[w_length];
}
DemoVoteCounter::DemoVoteCounter(unsigned int num_candidates) : num_candidates(num_candidates) {
sec = new SecuritySettings(4);
fh = new FullyHomomorphic(sec);
fh->key_gen(sk, pk);
}
void DemoVoteCounter::get_votes() {
int scan_result;
unsigned int vote;
num_votes = 0;
char temp_char;
std::vector<CipherBit*> encrypted_votes_vector;
CipherBit* encrypted_bit;
while (true) {
printf("Please enter a vote (1-%u), or 0 to terminate: ", num_candidates);
scan_result = scanf("%u", &vote);
if (scan_result != 1 || vote > num_candidates) {
printf("Invalid vote, please try again...\n");
while ((temp_char = getchar()) != '\n');
continue;
}
if (vote == 0) {
break;
}
for (unsigned int i = 0; i < num_candidates; i++) {
encrypted_bit = new CipherBit;
fh->encrypt_bit(*encrypted_bit, pk, i == vote-1);
fh->print_cipher_bit(*encrypted_bit);
encrypted_votes_vector.push_back(encrypted_bit);
}
printf("\n");
num_votes++;
}
votes = new CipherBit*[encrypted_votes_vector.size()];
for (unsigned int i = 0; i < encrypted_votes_vector.size(); i++) {
votes[i] = encrypted_votes_vector[i];
}
}
void DemoVoteCounter::verify_votes() {
printf("Verifying votes\n");
bool failed = false;
for (unsigned int i = 0; i < num_votes; i++) {
if (!verify_vote(i)) {
printf("Vote %u failed to verify!\n", i+1);
failed = true;
}
}
if (!failed) {
printf("All votes verified\n");
}
}
void DemoVoteCounter::count_votes() {
printf("Counting votes\n");
Gate* input_zero = new Gate(InputLiteral, false, sec);
Gate* input_one = new Gate(InputLiteral, true, sec);
Gate* input;
unsigned long int w_length = log2(num_votes);
unsigned long int p_length = pow(2, w_length);
Gate* temp_and;
Gate*** candidate_total = new Gate**[num_candidates];
for (unsigned int candidate = 0; candidate < num_candidates; candidate++) {
Gate*** p = new Gate**[num_votes+1];
for (unsigned long int i = 0; i < num_votes+1; i++) { //row
p[i] = new Gate*[p_length+1];
p[i][0] = input_one;
if (i > 0) {
input = new Gate(Input, (i-1)*num_candidates + candidate, sec);
}
for (unsigned int j = 1; j < p_length+1; j++) { //col
if (i == 0) {
p[0][j] = input_zero;
} else {
temp_and = new Gate(And, p[i-1][j-1], input, sec);
p[i][j] = new Gate(Xor, temp_and, p[i-1][j], sec);
}
}
}
candidate_total[candidate] = new Gate*[w_length+1];
int cur_index = 0;
for (unsigned long int i = p_length; i > 0; i >>= 1) {
candidate_total[candidate][cur_index++] = p[num_votes][i];
}
}
Gate* output;
std::vector<Gate*> output_gates;
for (unsigned int candidate = 0; candidate < num_candidates; candidate++) {
for (unsigned long int i = 0; i < w_length+1; i++) {
output = new Gate(Output, candidate_total[candidate][i], sec);
output_gates.push_back(output);
}
}
CipherBit** encrypted_results = fh->evaluate(output_gates, votes, pk);
bool* decrypted_results = fh->decrypt_bit_vector(sk, encrypted_results, num_candidates*(w_length+1));
textcolor(BRIGHT, RED);
for (unsigned int candidate = 0; candidate < num_candidates; candidate++) {
for (unsigned int i = 0; i < w_length+1; i++) {
printf("%u ", decrypted_results[candidate*(w_length+1) + i]);
}
printf("\n");
}
resettextcolor();
}
int main(int argc, char** argv) {
if (argc != 2) {
print_help();
exit(1);
}
unsigned int num_candidates = atoi(argv[1]);
DemoVoteCounter demo(num_candidates);
demo.get_votes();
demo.verify_votes();
demo.count_votes();
}