https://github.com/rinon/Simple-Homomorphic-Encryption
Raw File
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
Tip revision: c3ec8ed
test_suite.cpp
#include "fully_homomorphic.h"
#include "utilities.h"
#include "circuit.h"
#include "security_settings.h"

bool OUTPUT = true;

void test_encrypt_bit(FullyHomomorphic &fh, const PublicKey &pk, const PrivateKey &sk) {
  if (OUTPUT) {
	printf("----- TESTING ENCRYPTION OF A SINGLE BIT -----\n");
	printf("--- ENCRYPTING FALSE ---\n");
  }
  CipherBit c;
  bool result;
  for (int i = 0; i < 100; i++) {
	fh.encrypt_bit(c, pk, false);
	result = fh.decrypt_bit(c, sk);
	if (OUTPUT) {
	  printf("%u", result);
	  fflush(NULL);
	}
	fh.clear_cipher_bit(c);
  }
  if (OUTPUT) {
	printf("\n");
	printf("--- ENCRYPTING TRUE ---\n");
  }
  for (int i = 0; i < 100; i++) {
	fh.encrypt_bit(c, pk, true);
	result = fh.decrypt_bit(c, sk);
	if (OUTPUT) {
	  printf("%u", result);
	  fflush(NULL);
	}
	fh.clear_cipher_bit(c);
  }
  if (OUTPUT) {
	printf("\n");
  }
}

void test_encrypt_bit_vector(FullyHomomorphic &fh, const PublicKey &pk, const PrivateKey &sk) {
  printf("----- TESTING ENCRYPTION OF A BIT VECTOR -----\n");
  printf("--- ENCRYPTING ALTERNATING FALSE AND TRUE ---\n");
  bool* m = new bool[100];
  for (int i = 0; i < 100; i++) {
	m[i] = new bool;
	if (i%2 == 0)
	  m[i] = false;
	else
	  m[i] = true;
  }
  CipherBit** e = fh.encrypt_bit_vector(pk, m, 100);
  bool* d = fh.decrypt_bit_vector(sk, e, 100);
  for (int i = 0; i < 100; i++) {
	printf("%u", d[i]);
  }
  printf("\n");
}

void test_gates(FullyHomomorphic &fh, const PublicKey &pk, const PrivateKey &sk, SecuritySettings *sec) {
  printf("----- TESTING EVALUATION OF GATES -----\n");
  printf("--- AND GATE ---\n");
  bool domain[2];
  domain[0] = false;
  domain[1] = true;
  CipherBit** inputs = new CipherBit*[2];
  inputs[0] = new CipherBit;
  inputs[1] = new CipherBit;
  fh.encrypt_bit(*(inputs[0]), pk, false);
  fh.encrypt_bit(*(inputs[1]), pk, true);
  Gate* input_a;
  Gate* input_b;
  Gate* operation;
  Gate* output;
  std::vector<Gate*> output_vector;
  CipherBit** encrypted_eval_output;
  bool* decrypted_eval_output;
  for (unsigned long int a_index = 0; a_index < 2; a_index++) {
	for (unsigned long int b_index = 0; b_index < 2; b_index++) {
	  input_a = new Gate(Input, a_index, sec);
	  input_b = new Gate(Input, b_index, sec);
	  operation = new Gate(And, input_a, input_b, sec);
	  // input_a->add_output(operation);
	  // input_b->add_output(operation);
	  output = new Gate(Output, operation, sec);
	  // operation->add_output(output);
	  output_vector.push_back(output);
	  encrypted_eval_output = fh.evaluate(output_vector, inputs, pk);
	  decrypted_eval_output = fh.decrypt_bit_vector(sk, encrypted_eval_output, 1);
	  printf("%u x %u = %u\n", domain[a_index], domain[b_index], decrypted_eval_output[0]);
	  output_vector.clear();
	}
  }
  
  printf("--- XOR GATE ---\n");
  for (unsigned long int a_index = 0; a_index < 2; a_index++) {
	for (unsigned long int b_index = 0; b_index < 2; b_index++) {
	  input_a = new Gate(Input, a_index, sec);
	  input_b = new Gate(Input, b_index, sec);
	  operation = new Gate(Xor, input_a, input_b, sec);
	  // input_a->add_output(operation);
	  // input_b->add_output(operation);
	  output = new Gate(Output, operation, sec);
	  // operation->add_output(output);
	  output_vector.push_back(output);
	  encrypted_eval_output = fh.evaluate(output_vector, inputs, pk);
	  decrypted_eval_output = fh.decrypt_bit_vector(sk, encrypted_eval_output, 1);
	  printf("%u + %u = %u\n", domain[a_index], domain[b_index], decrypted_eval_output[0]);
	  output_vector.clear();
	}
  }
}

void test_circuits(FullyHomomorphic &fh, const PublicKey &pk, const PrivateKey &sk, SecuritySettings *sec) {
  printf("----- TESTING EVALUATION OF MORE COMPLEX CIRCUITS -----\n");
  printf("--- CIRCUIT 1 ---\n");
  int INPUT_LENGTH = 6;
  CipherBit** inputs = new CipherBit*[INPUT_LENGTH];
  for (int i = 0; i < INPUT_LENGTH; i++) {
	inputs[i] = new CipherBit;
  }
  fh.encrypt_bit(*(inputs[0]), pk, false);
  fh.encrypt_bit(*(inputs[1]), pk, true);
  fh.encrypt_bit(*(inputs[2]), pk, true);
  fh.encrypt_bit(*(inputs[3]), pk, true);
  fh.encrypt_bit(*(inputs[4]), pk, true);
  fh.encrypt_bit(*(inputs[5]), pk, true);

  Gate* input_a;
  Gate* input_b;
  Gate* input_c;
  Gate* operation1;
  Gate* operation2;
  Gate* operation3;
  Gate* operation4;
  Gate* operation5;
  Gate* output;
  std::vector<Gate*> output_vector;
  CipherBit** encrypted_eval_output;
  bool* decrypted_eval_output;
  input_a = new Gate(Input, (unsigned long int)1, sec);
  input_b = new Gate(InputLiteral, false, sec);
  operation1 = new Gate(And, input_a, input_b, sec);
  // input_a->add_output(operation1);
  // input_b->add_output(operation1);
  operation2 = new Gate(And, operation1, input_a, sec);
  // operation1->add_output(operation2);
  // input_a->add_output(operation2);
  output = new Gate(Output, operation2, sec);
  // operation2->add_output(output);
  output_vector.push_back(output);
  encrypted_eval_output = fh.evaluate(output_vector, inputs, pk);
  decrypted_eval_output = fh.decrypt_bit_vector(sk, encrypted_eval_output, 1);
  printf("1 x 0l x 1 = %u\n", decrypted_eval_output[0]);
  output_vector.clear();

  printf("--- CIRCUIT 2 ---\n");
  input_a = new Gate(Input, (unsigned long int)1, sec);
  input_b = new Gate(Input, (unsigned long int)2, sec);
  input_c = new Gate(Input, (unsigned long int)3, sec);
  operation1 = new Gate(And, input_a, input_b, sec);
  // input_a->add_output(operation1);
  // input_b->add_output(operation1);
  operation2 = new Gate(And, operation1, input_c, sec);
  // operation1->add_output(operation2);
  // input_c->add_output(operation2);
  output = new Gate(Output, operation2, sec);
  // operation2->add_output(output);
  output_vector.push_back(output);
  encrypted_eval_output = fh.evaluate(output_vector, inputs, pk);
  decrypted_eval_output = fh.decrypt_bit_vector(sk, encrypted_eval_output, 1);
  printf("1 x 1 x 1 = %u\n", decrypted_eval_output[0]);
  output_vector.clear();

  printf("--- CIRCUIT 3 ---\n");
  input_a = new Gate(Input, (unsigned long int)1, sec);
  input_b = new Gate(Input, (unsigned long int)1, sec);
  input_c = new Gate(Input, (unsigned long int)0, sec);
  operation1 = new Gate(And, input_a, input_b, sec);
  operation2 = new Gate(And, input_a, input_c, sec);
  operation3 = new Gate(And, input_b, input_c, sec);
  operation4 = new Gate(Xor, operation1, operation2, sec);
  operation5 = new Gate(Xor, operation4, operation3, sec);
  output = new Gate(Output, operation5, sec);
  output_vector.push_back(output);
  fh.is_allowed_circuit(output_vector);
  encrypted_eval_output = fh.evaluate(output_vector, inputs, pk);
  decrypted_eval_output = fh.decrypt_bit_vector(sk, encrypted_eval_output, 1);
  printf("%u\n", decrypted_eval_output[0]);
  output_vector.clear();
}

void benchmark(FullyHomomorphic &fh, PublicKey &pk, PrivateKey &sk, SecuritySettings *sec) {
  OUTPUT = false;
  clock_t start_time = clock();
  fh.key_gen(sk, pk);
  clock_t key_gen_finished = clock();
  printf("Key Generation: %f\n", (double)(key_gen_finished - start_time)/CLOCKS_PER_SEC);
  test_encrypt_bit_vector(fh, pk, sk);
  clock_t test_encrypt_bit_vector_finished = clock();
  printf("Encrypting and decrypting 100 bit vector: %f\n", (double)(test_encrypt_bit_vector_finished - key_gen_finished)/CLOCKS_PER_SEC);
  test_encrypt_bit(fh, pk, sk);
  clock_t test_encrypt_bit_finished = clock();
  printf("Encrypting and decrypting 200 bits: %f\n", (double)(test_encrypt_bit_finished - test_encrypt_bit_vector_finished)/CLOCKS_PER_SEC);
}

int main(int argc, char** argv) {
  CryptoPP::AutoSeededRandomPool rng;
  SecuritySettings *security_settings = new SecuritySettings(atoi(argv[1]));
  FullyHomomorphic fh(security_settings);
  PrivateKey sk;
  PublicKey pk;
  fh.key_gen(sk, pk);

  for (int i = 2; i < argc; i++) {
	if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--all") == 0) {
	  fh.key_gen(sk, pk);
	  test_encrypt_bit(fh, pk, sk);
	  test_encrypt_bit_vector(fh, pk, sk);
	  //fh.test_decryption_circuit(pk, sk);
	  test_gates(fh, pk, sk, security_settings);
	  test_circuits(fh, pk, sk, security_settings);
	}
	if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--single-bit") == 0) {
	  fh.key_gen(sk, pk);
	  test_encrypt_bit(fh, pk, sk);
	}
	if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--bit-vector") == 0) {
	  fh.key_gen(sk, pk);
	  test_encrypt_bit_vector(fh, pk, sk);
	}
	if (strcmp(argv[i], "-dc") == 0 || strcmp(argv[i], "--decryption-circuit") == 0) {
	  fh.key_gen(sk, pk);
	  fh.test_decryption_circuit(pk, sk);
	}
	if (strcmp(argv[i], "-g") == 0 || strcmp(argv[i], "--gates") == 0) {
	  fh.key_gen(sk, pk);
	  test_gates(fh, pk, sk, security_settings);
	}
	if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--circuits") == 0) {
	  fh.key_gen(sk, pk);
	  test_circuits(fh, pk, sk, security_settings);
	}
	if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--timing") == 0) {
	  benchmark(fh, pk, sk, security_settings);
	}
  }
}
back to top