mirror of
https://github.com/mii443/FINAL.git
synced 2025-08-22 15:05:36 +00:00
Merge pull request #1 from KULeuven-COSIC/xor_not_gates
Homomorphic XOR and NOT gates
This commit is contained in:
4
Makefile
4
Makefile
@ -5,7 +5,7 @@ DEPS = -lntl -lgmp -lfftw3 -lm
|
|||||||
all: clean test
|
all: clean test
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) test test.o lwehe.o ntruhe.o fft.o sampler.o keygen.o
|
$(RM) test test.o lwehe.o ntruhe.o fft.o sampler.o keygen.o libfinal.a
|
||||||
|
|
||||||
test: FINAL.h libfinal.a
|
test: FINAL.h libfinal.a
|
||||||
$(CCX) $(CCXFLAGS) -o test test.cpp libfinal.a $(DEPS)
|
$(CCX) $(CCXFLAGS) -o test test.cpp libfinal.a $(DEPS)
|
||||||
@ -26,4 +26,4 @@ fft.o: include/fft.h
|
|||||||
$(CCX) $(CCXFLAGS) -c src/fft.cpp
|
$(CCX) $(CCXFLAGS) -c src/fft.cpp
|
||||||
|
|
||||||
sampler.o: include/sampler.h include/params.h src/sampler.cpp
|
sampler.o: include/sampler.h include/params.h src/sampler.cpp
|
||||||
$(CCX) $(CCXFLAGS) -c src/sampler.cpp
|
$(CCX) $(CCXFLAGS) -c src/sampler.cpp
|
||||||
|
@ -130,7 +130,7 @@ class SchemeLWE
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the AND gate of two given ciphertexts ct1 and ct2
|
* Computes the AND gate of two given ciphertexts ct1 and ct2
|
||||||
* @param[out] ct_res encryptions of the outuput of the NAND gate
|
* @param[out] ct_res encryptions of the outuput of the AND gate
|
||||||
* @param[in] ct_1 encryption of the first input bit
|
* @param[in] ct_1 encryption of the first input bit
|
||||||
* @param[in] ct_2 encryption of the second input bit
|
* @param[in] ct_2 encryption of the second input bit
|
||||||
*/
|
*/
|
||||||
@ -138,15 +138,26 @@ class SchemeLWE
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the OR gate of two given ciphertexts ct1 and ct2
|
* Computes the OR gate of two given ciphertexts ct1 and ct2
|
||||||
* @param[out] ct_res encryptions of the outuput of the NAND gate
|
* @param[out] ct_res encryptions of the outuput of the OR gate
|
||||||
* @param[in] ct_1 encryption of the first input bit
|
* @param[in] ct_1 encryption of the first input bit
|
||||||
* @param[in] ct_2 encryption of the second input bit
|
* @param[in] ct_2 encryption of the second input bit
|
||||||
*/
|
*/
|
||||||
void or_gate(Ctxt_LWE& ct_res, const Ctxt_LWE& ct1, const Ctxt_LWE& ct2) const;
|
void or_gate(Ctxt_LWE& ct_res, const Ctxt_LWE& ct1, const Ctxt_LWE& ct2) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the XOR gate of two given ciphertexts ct1 and ct2
|
||||||
|
* @param[out] ct_res encryptions of the outuput of the XOR gate
|
||||||
|
* @param[in] ct_1 encryption of the first input bit
|
||||||
|
* @param[in] ct_2 encryption of the second input bit
|
||||||
|
*/
|
||||||
|
void xor_gate(Ctxt_LWE& ct_res, const Ctxt_LWE& ct1, const Ctxt_LWE& ct2) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the NOT gate of a given ciphertext ct
|
||||||
|
* @param[out] ct_res encryption of the outuput of the NOT gate
|
||||||
|
* @param[in] ct encryption of the input bit
|
||||||
|
*/
|
||||||
|
void not_gate(Ctxt_LWE& ct_res, const Ctxt_LWE& ct) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -74,6 +74,7 @@ class SchemeNTRU
|
|||||||
Ctxt_NTRU ct_nand_const;
|
Ctxt_NTRU ct_nand_const;
|
||||||
Ctxt_NTRU ct_and_const;
|
Ctxt_NTRU ct_and_const;
|
||||||
Ctxt_NTRU ct_or_const;
|
Ctxt_NTRU ct_or_const;
|
||||||
|
Ctxt_NTRU ct_not_const;
|
||||||
|
|
||||||
void mask_constant(Ctxt_NTRU& ct, int constant);
|
void mask_constant(Ctxt_NTRU& ct, int constant);
|
||||||
|
|
||||||
@ -98,6 +99,13 @@ class SchemeNTRU
|
|||||||
//cout << "Encryption of OR: " << float(clock()-start)/CLOCKS_PER_SEC << endl;
|
//cout << "Encryption of OR: " << float(clock()-start)/CLOCKS_PER_SEC << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void set_not_const()
|
||||||
|
{
|
||||||
|
encrypt(ct_not_const, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SchemeNTRU()
|
SchemeNTRU()
|
||||||
@ -112,6 +120,7 @@ class SchemeNTRU
|
|||||||
set_nand_const();
|
set_nand_const();
|
||||||
set_and_const();
|
set_and_const();
|
||||||
set_or_const();
|
set_or_const();
|
||||||
|
set_not_const();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Encrypts a bit using matrix NTRU.
|
* Encrypts a bit using matrix NTRU.
|
||||||
@ -151,7 +160,7 @@ class SchemeNTRU
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the AND gate of two given ciphertexts ct1 and ct2
|
* Computes the AND gate of two given ciphertexts ct1 and ct2
|
||||||
* @param[out] ct_res encryptions of the outuput of the NAND gate
|
* @param[out] ct_res encryptions of the outuput of the AND gate
|
||||||
* @param[in] ct_1 encryption of the first input bit
|
* @param[in] ct_1 encryption of the first input bit
|
||||||
* @param[in] ct_2 encryption of the second input bit
|
* @param[in] ct_2 encryption of the second input bit
|
||||||
*/
|
*/
|
||||||
@ -159,11 +168,27 @@ class SchemeNTRU
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the OR gate of two given ciphertexts ct1 and ct2
|
* Computes the OR gate of two given ciphertexts ct1 and ct2
|
||||||
* @param[out] ct_res encryptions of the outuput of the NAND gate
|
* @param[out] ct_res encryptions of the outuput of the OR gate
|
||||||
* @param[in] ct_1 encryption of the first input bit
|
* @param[in] ct_1 encryption of the first input bit
|
||||||
* @param[in] ct_2 encryption of the second input bit
|
* @param[in] ct_2 encryption of the second input bit
|
||||||
*/
|
*/
|
||||||
void or_gate(Ctxt_NTRU& ct_res, const Ctxt_NTRU& ct1, const Ctxt_NTRU& ct2) const;
|
void or_gate(Ctxt_NTRU& ct_res, const Ctxt_NTRU& ct1, const Ctxt_NTRU& ct2) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the XOR gate of two given ciphertexts ct1 and ct2
|
||||||
|
* @param[out] ct_res encryptions of the outuput of the XOR gate
|
||||||
|
* @param[in] ct_1 encryption of the first input bit
|
||||||
|
* @param[in] ct_2 encryption of the second input bit
|
||||||
|
*/
|
||||||
|
void xor_gate(Ctxt_NTRU& ct_res, const Ctxt_NTRU& ct1, const Ctxt_NTRU& ct2) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the NOT gate of a given ciphertext ct
|
||||||
|
* @param[out] ct_res encryption of the outuput of the NOT gate
|
||||||
|
* @param[in] ct encryption of the input bit
|
||||||
|
*/
|
||||||
|
void not_gate(Ctxt_NTRU& ct_res, const Ctxt_NTRU& ct) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -470,4 +470,25 @@ void SchemeLWE::or_gate(Ctxt_LWE& ct_res, const Ctxt_LWE& ct1, const Ctxt_LWE& c
|
|||||||
ct_res = parLWE.or_const - (ct1 + ct2);
|
ct_res = parLWE.or_const - (ct1 + ct2);
|
||||||
bootstrap(ct_res);
|
bootstrap(ct_res);
|
||||||
//cout << "OR: " << float(clock()-start)/CLOCKS_PER_SEC << endl;
|
//cout << "OR: " << float(clock()-start)/CLOCKS_PER_SEC << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SchemeLWE::xor_gate(Ctxt_LWE& ct_res, const Ctxt_LWE& ct1, const Ctxt_LWE& ct2) const
|
||||||
|
{
|
||||||
|
if (ct_res.a.size() != parLWE.n)
|
||||||
|
ct_res.a = vector<int>(parLWE.n);
|
||||||
|
|
||||||
|
ct_res = ct1 + ct2;
|
||||||
|
ct_res = ct_res + ct_res; // ct = 2*(ct1 + ct2)
|
||||||
|
|
||||||
|
bootstrap(ct_res);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SchemeLWE::not_gate(Ctxt_LWE& ct_res, const Ctxt_LWE& ct) const
|
||||||
|
{
|
||||||
|
if (ct_res.a.size() != parLWE.n)
|
||||||
|
ct_res.a = vector<int>(parLWE.n);
|
||||||
|
|
||||||
|
ct_res = parLWE.delta_base - ct;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -282,4 +282,21 @@ void SchemeNTRU::or_gate(Ctxt_NTRU& ct_res, const Ctxt_NTRU& ct1, const Ctxt_NTR
|
|||||||
ct_res = ct_or_const - ct1 - ct2;
|
ct_res = ct_or_const - ct1 - ct2;
|
||||||
bootstrap(ct_res);
|
bootstrap(ct_res);
|
||||||
//cout << "OR: " << float(clock()-start)/CLOCKS_PER_SEC << endl;
|
//cout << "OR: " << float(clock()-start)/CLOCKS_PER_SEC << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SchemeNTRU::xor_gate(Ctxt_NTRU& ct_res, const Ctxt_NTRU& ct1, const Ctxt_NTRU& ct2) const
|
||||||
|
{
|
||||||
|
if (ct_res.data.size() != parNTRU.n)
|
||||||
|
ct_res.data = vector<int>(parNTRU.n);
|
||||||
|
|
||||||
|
ct_res = ct1 + ct2;
|
||||||
|
ct_res = ct_res + ct_res; // ct_res = 2*(ct1 + ct2) % q
|
||||||
|
|
||||||
|
bootstrap(ct_res);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SchemeNTRU::not_gate(Ctxt_NTRU& ct_res, const Ctxt_NTRU& ct) const
|
||||||
|
{
|
||||||
|
ct_res = ct_not_const - ct;
|
||||||
|
}
|
||||||
|
|
||||||
|
210
test.cpp
210
test.cpp
@ -265,12 +265,13 @@ void test_sampler()
|
|||||||
cout << "SAMPLER IS OK" << endl;
|
cout << "SAMPLER IS OK" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum GateType {NAND, AND, OR};
|
enum GateType {NAND, AND, OR, XOR, NOT};
|
||||||
|
|
||||||
void test_ntruhe_gate_helper(int in1, int in2, const SchemeNTRU& s, GateType g)
|
void test_ntruhe_gate_helper(int in1, int in2, const SchemeNTRU& s, GateType g)
|
||||||
{
|
{
|
||||||
float avg_time = 0.0;
|
float avg_time = 0.0;
|
||||||
for (int i = 0; i < 100; i++)
|
int N_TESTS = (g == NOT ? 30 : 100);
|
||||||
|
for (int i = 0; i < N_TESTS; i++)
|
||||||
{
|
{
|
||||||
Ctxt_NTRU ct_res, ct1, ct2;
|
Ctxt_NTRU ct_res, ct1, ct2;
|
||||||
s.encrypt(ct1, in1);
|
s.encrypt(ct1, in1);
|
||||||
@ -307,47 +308,80 @@ void test_ntruhe_gate_helper(int in1, int in2, const SchemeNTRU& s, GateType g)
|
|||||||
//cout << "OR output: " << output << endl;
|
//cout << "OR output: " << output << endl;
|
||||||
assert(output == (in1 | in2));
|
assert(output == (in1 | in2));
|
||||||
}
|
}
|
||||||
|
else if (g == XOR) {
|
||||||
|
auto start = clock();
|
||||||
|
s.xor_gate(ct_res, ct1, ct2);
|
||||||
|
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
int output = s.decrypt(ct_res);
|
||||||
|
|
||||||
|
//cout << "XOR output: " << output << endl;
|
||||||
|
assert(output == (in1 ^ in2));
|
||||||
|
}
|
||||||
|
else if (g == NOT) {
|
||||||
|
auto start = clock();
|
||||||
|
s.not_gate(ct_res, ct1);
|
||||||
|
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
int output = s.decrypt(ct_res);
|
||||||
|
|
||||||
|
// cout << ".... NOT output: " << output << endl;
|
||||||
|
assert(output == (1 - in1));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
cout << "Avg. time: " << avg_time/100.0 << endl;
|
cout << "Avg. time: " << avg_time/N_TESTS << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_ntru_gate(GateType g)
|
void test_ntru_gate(SchemeNTRU& s, GateType g)
|
||||||
{
|
{
|
||||||
SchemeNTRU s;
|
|
||||||
|
|
||||||
test_ntruhe_gate_helper(0, 0, s, g);
|
test_ntruhe_gate_helper(0, 0, s, g);
|
||||||
test_ntruhe_gate_helper(0, 1, s, g);
|
test_ntruhe_gate_helper(0, 1, s, g);
|
||||||
test_ntruhe_gate_helper(1, 0, s, g);
|
test_ntruhe_gate_helper(1, 0, s, g);
|
||||||
test_ntruhe_gate_helper(1, 1, s, g);
|
test_ntruhe_gate_helper(1, 1, s, g);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_ntruhe_nand()
|
void test_ntruhe_nand(SchemeNTRU& s)
|
||||||
{
|
{
|
||||||
GateType g = NAND;
|
GateType g = NAND;
|
||||||
|
|
||||||
test_ntru_gate(g);
|
test_ntru_gate(s, g);
|
||||||
|
|
||||||
cout << "NAND IS OK" << endl;
|
cout << "NAND IS OK" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_ntruhe_and()
|
void test_ntruhe_and(SchemeNTRU& s)
|
||||||
{
|
{
|
||||||
GateType g = AND;
|
GateType g = AND;
|
||||||
|
test_ntru_gate(s, g);
|
||||||
test_ntru_gate(g);
|
|
||||||
|
|
||||||
cout << "AND IS OK" << endl;
|
cout << "AND IS OK" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_ntruhe_or()
|
void test_ntruhe_or(SchemeNTRU& s)
|
||||||
{
|
{
|
||||||
GateType g = OR;
|
GateType g = OR;
|
||||||
|
test_ntru_gate(s, g);
|
||||||
test_ntru_gate(g);
|
|
||||||
|
|
||||||
cout << "OR IS OK" << endl;
|
cout << "OR IS OK" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_ntruhe_xor(SchemeNTRU& s)
|
||||||
|
{
|
||||||
|
GateType g = XOR;
|
||||||
|
test_ntru_gate(s, g);
|
||||||
|
cout << "XOR IS OK" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_ntruhe_not(SchemeNTRU& s)
|
||||||
|
{
|
||||||
|
GateType g = NOT;
|
||||||
|
for(int i = 0; i < 5; i++){
|
||||||
|
int bit = binary_sampler(rand_engine);
|
||||||
|
test_ntruhe_gate_helper(bit, 0, s, g);
|
||||||
|
}
|
||||||
|
cout << "NOT GATE IS OK" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void test_ntruhe_gate_composition_helper(SchemeNTRU& s, GateType g)
|
void test_ntruhe_gate_composition_helper(SchemeNTRU& s, GateType g)
|
||||||
{
|
{
|
||||||
float avg_time = 0.0;
|
float avg_time = 0.0;
|
||||||
@ -369,33 +403,40 @@ void test_ntruhe_gate_composition_helper(SchemeNTRU& s, GateType g)
|
|||||||
s.nand_gate(ct_res, ct_res, ct);// ct_res should encrypt NAND(exp_out, in2)
|
s.nand_gate(ct_res, ct_res, ct);// ct_res should encrypt NAND(exp_out, in2)
|
||||||
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
||||||
exp_out = !(exp_out & in2); // exp_out = NAND(exp_out, in2)
|
exp_out = !(exp_out & in2); // exp_out = NAND(exp_out, in2)
|
||||||
|
|
||||||
//cout << "NAND output: " << output << endl;
|
|
||||||
}
|
}
|
||||||
else if (g == AND) {
|
else if (g == AND) {
|
||||||
auto start = clock();
|
auto start = clock();
|
||||||
s.and_gate(ct_res, ct_res, ct);
|
s.and_gate(ct_res, ct_res, ct);
|
||||||
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
||||||
exp_out = (exp_out & in2); // exp_out = AND(exp_out, in2)
|
exp_out = (exp_out & in2); // exp_out = AND(exp_out, in2)
|
||||||
//cout << "AND output: " << output << endl;
|
|
||||||
}
|
}
|
||||||
else if (g == OR) {
|
else if (g == OR) {
|
||||||
auto start = clock();
|
auto start = clock();
|
||||||
s.or_gate(ct_res, ct_res, ct);
|
s.or_gate(ct_res, ct_res, ct);
|
||||||
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
||||||
exp_out = (exp_out | in2); // exp_out = OR(exp_out, in2)
|
exp_out = (exp_out | in2); // exp_out = OR(exp_out, in2)
|
||||||
//cout << "OR output: " << output << endl;
|
|
||||||
}
|
}
|
||||||
|
else if (g == XOR) {
|
||||||
|
auto start = clock();
|
||||||
|
s.xor_gate(ct_res, ct_res, ct);
|
||||||
|
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
||||||
|
exp_out = (exp_out ^ in2); // exp_out = XOR(exp_out, in2)
|
||||||
|
}
|
||||||
|
else if (g == NOT) {
|
||||||
|
auto start = clock();
|
||||||
|
s.not_gate(ct_res, ct_res);
|
||||||
|
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
||||||
|
exp_out = (1 - exp_out); // exp_out = NOT(exp_out)
|
||||||
|
}
|
||||||
|
|
||||||
int output = s.decrypt(ct_res);
|
int output = s.decrypt(ct_res);
|
||||||
assert(output == exp_out);
|
assert(output == exp_out);
|
||||||
}
|
}
|
||||||
cout << "Avg. time: " << avg_time/N_TESTS << endl;
|
cout << "Avg. time: " << avg_time/N_TESTS << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_ntruhe_composition_of_gates()
|
void test_ntruhe_composition_of_gates(SchemeNTRU& s)
|
||||||
{
|
{
|
||||||
SchemeNTRU s;
|
|
||||||
|
|
||||||
test_ntruhe_gate_composition_helper(s, NAND);
|
test_ntruhe_gate_composition_helper(s, NAND);
|
||||||
cout << "COMPOSING NAND IS OK" << endl;
|
cout << "COMPOSING NAND IS OK" << endl;
|
||||||
|
|
||||||
@ -404,12 +445,15 @@ void test_ntruhe_composition_of_gates()
|
|||||||
|
|
||||||
test_ntruhe_gate_composition_helper(s, OR);
|
test_ntruhe_gate_composition_helper(s, OR);
|
||||||
cout << "COMPOSING OR IS OK" << endl;
|
cout << "COMPOSING OR IS OK" << endl;
|
||||||
|
|
||||||
|
test_ntruhe_gate_composition_helper(s, XOR);
|
||||||
|
cout << "COMPOSING XOR IS OK" << endl;
|
||||||
|
|
||||||
|
test_ntruhe_gate_composition_helper(s, NOT);
|
||||||
|
cout << "COMPOSING NOT GATE IS OK" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- LWE tests
|
// ----- LWE tests
|
||||||
|
|
||||||
void test_lwehe_gate_helper(int in1, int in2, SchemeLWE& s, GateType g)
|
void test_lwehe_gate_helper(int in1, int in2, SchemeLWE& s, GateType g)
|
||||||
@ -452,51 +496,85 @@ void test_lwehe_gate_helper(int in1, int in2, SchemeLWE& s, GateType g)
|
|||||||
//cout << "OR output: " << output << endl;
|
//cout << "OR output: " << output << endl;
|
||||||
assert(output == (in1 | in2));
|
assert(output == (in1 | in2));
|
||||||
}
|
}
|
||||||
|
else if (g == XOR) {
|
||||||
|
auto start = clock();
|
||||||
|
s.xor_gate(ct_res, ct1, ct2);
|
||||||
|
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
int output = s.decrypt(ct_res);
|
||||||
|
|
||||||
|
//cout << "OR output: " << output << endl;
|
||||||
|
assert(output == (in1 ^ in2));
|
||||||
|
}
|
||||||
|
else if (g == NOT) {
|
||||||
|
auto start = clock();
|
||||||
|
s.not_gate(ct_res, ct1);
|
||||||
|
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
int output = s.decrypt(ct_res);
|
||||||
|
|
||||||
|
// cout << "NOT output: " << output << endl;
|
||||||
|
assert(output == (1 - in1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
cout << "Avg. time: " << avg_time/100.0 << endl;
|
cout << "Avg. time: " << avg_time/100.0 << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_lwe_gate(GateType g)
|
void test_lwe_gate(SchemeLWE& s, GateType g)
|
||||||
{
|
{
|
||||||
SchemeLWE s;
|
|
||||||
|
|
||||||
test_lwehe_gate_helper(0, 0, s, g);
|
test_lwehe_gate_helper(0, 0, s, g);
|
||||||
test_lwehe_gate_helper(0, 1, s, g);
|
test_lwehe_gate_helper(0, 1, s, g);
|
||||||
test_lwehe_gate_helper(1, 0, s, g);
|
test_lwehe_gate_helper(1, 0, s, g);
|
||||||
test_lwehe_gate_helper(1, 1, s, g);
|
test_lwehe_gate_helper(1, 1, s, g);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_lwehe_nand()
|
void test_lwehe_nand(SchemeLWE& s)
|
||||||
{
|
{
|
||||||
GateType g = NAND;
|
GateType g = NAND;
|
||||||
|
test_lwe_gate(s, g);
|
||||||
test_lwe_gate(g);
|
|
||||||
|
|
||||||
cout << "NAND IS OK" << endl;
|
cout << "NAND IS OK" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_lwehe_and()
|
void test_lwehe_and(SchemeLWE& s)
|
||||||
{
|
{
|
||||||
GateType g = AND;
|
GateType g = AND;
|
||||||
|
test_lwe_gate(s, g);
|
||||||
test_lwe_gate(g);
|
|
||||||
|
|
||||||
cout << "AND IS OK" << endl;
|
cout << "AND IS OK" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_lwehe_or()
|
void test_lwehe_or(SchemeLWE& s)
|
||||||
{
|
{
|
||||||
GateType g = OR;
|
GateType g = OR;
|
||||||
|
test_lwe_gate(s, g);
|
||||||
test_lwe_gate(g);
|
|
||||||
|
|
||||||
cout << "OR IS OK" << endl;
|
cout << "OR IS OK" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_lwehe_xor(SchemeLWE& s)
|
||||||
|
{
|
||||||
|
GateType g = XOR;
|
||||||
|
test_lwe_gate(s, g);
|
||||||
|
cout << "XOR IS OK" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_lwehe_not(SchemeLWE& s)
|
||||||
|
{
|
||||||
|
GateType g = NOT;
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
int bit = binary_sampler(rand_engine);
|
||||||
|
test_lwehe_gate_helper(bit, 0, s, g);
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "NOT GATE IS OK" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void test_lwehe_gate_composition_helper(SchemeLWE& s, GateType g)
|
void test_lwehe_gate_composition_helper(SchemeLWE& s, GateType g)
|
||||||
{
|
{
|
||||||
float avg_time = 0.0;
|
float avg_time = 0.0;
|
||||||
int N_TESTS = 100;
|
int N_TESTS = 110;
|
||||||
|
|
||||||
int in1, in2, exp_out;
|
int in1, in2, exp_out;
|
||||||
in1 = binary_sampler(rand_engine);
|
in1 = binary_sampler(rand_engine);
|
||||||
@ -514,7 +592,6 @@ void test_lwehe_gate_composition_helper(SchemeLWE& s, GateType g)
|
|||||||
s.nand_gate(ct_res, ct_res, ct);// ct_res should encrypt NAND(exp_out, in2)
|
s.nand_gate(ct_res, ct_res, ct);// ct_res should encrypt NAND(exp_out, in2)
|
||||||
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
||||||
exp_out = !(exp_out & in2); // exp_out = NAND(exp_out, in2)
|
exp_out = !(exp_out & in2); // exp_out = NAND(exp_out, in2)
|
||||||
|
|
||||||
//cout << "NAND output: " << output << endl;
|
//cout << "NAND output: " << output << endl;
|
||||||
}
|
}
|
||||||
else if (g == AND) {
|
else if (g == AND) {
|
||||||
@ -531,16 +608,28 @@ void test_lwehe_gate_composition_helper(SchemeLWE& s, GateType g)
|
|||||||
exp_out = (exp_out | in2); // exp_out = OR(exp_out, in2)
|
exp_out = (exp_out | in2); // exp_out = OR(exp_out, in2)
|
||||||
//cout << "OR output: " << output << endl;
|
//cout << "OR output: " << output << endl;
|
||||||
}
|
}
|
||||||
|
else if (g == XOR) {
|
||||||
|
auto start = clock();
|
||||||
|
s.xor_gate(ct_res, ct_res, ct);
|
||||||
|
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
||||||
|
exp_out = (exp_out ^ in2); // exp_out = XOR(exp_out, in2)
|
||||||
|
//cout << "XOR output: " << output << endl;
|
||||||
|
}
|
||||||
|
else if (g == NOT) {
|
||||||
|
auto start = clock();
|
||||||
|
s.not_gate(ct_res, ct_res);
|
||||||
|
avg_time += float(clock()-start)/CLOCKS_PER_SEC;
|
||||||
|
exp_out = (1 - exp_out); // exp_out = NOT(exp_out)
|
||||||
|
}
|
||||||
|
|
||||||
int output = s.decrypt(ct_res);
|
int output = s.decrypt(ct_res);
|
||||||
assert(output == exp_out);
|
assert(output == exp_out);
|
||||||
}
|
}
|
||||||
cout << "Avg. time: " << avg_time/N_TESTS << endl;
|
cout << "Avg. time: " << avg_time/N_TESTS << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_lwehe_composition_of_gates()
|
void test_lwehe_composition_of_gates(SchemeLWE& s)
|
||||||
{
|
{
|
||||||
SchemeLWE s;
|
|
||||||
|
|
||||||
test_lwehe_gate_composition_helper(s, NAND);
|
test_lwehe_gate_composition_helper(s, NAND);
|
||||||
cout << "COMPOSING NAND IS OK" << endl;
|
cout << "COMPOSING NAND IS OK" << endl;
|
||||||
|
|
||||||
@ -549,6 +638,12 @@ void test_lwehe_composition_of_gates()
|
|||||||
|
|
||||||
test_lwehe_gate_composition_helper(s, OR);
|
test_lwehe_gate_composition_helper(s, OR);
|
||||||
cout << "COMPOSING OR IS OK" << endl;
|
cout << "COMPOSING OR IS OK" << endl;
|
||||||
|
|
||||||
|
test_lwehe_gate_composition_helper(s, XOR);
|
||||||
|
cout << "COMPOSING XOR IS OK" << endl;
|
||||||
|
|
||||||
|
test_lwehe_gate_composition_helper(s, NOT);
|
||||||
|
cout << "COMPOSING NOT GATE IS OK" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -561,19 +656,26 @@ int main()
|
|||||||
cout << endl;
|
cout << endl;
|
||||||
cout << "-------------------------" << endl;
|
cout << "-------------------------" << endl;
|
||||||
cout << "NTRU tests" << endl;
|
cout << "NTRU tests" << endl;
|
||||||
test_ntruhe_nand();
|
SchemeNTRU s_ntru;
|
||||||
test_ntruhe_and();
|
test_ntruhe_nand(s_ntru);
|
||||||
test_ntruhe_or();
|
test_ntruhe_and(s_ntru);
|
||||||
test_ntruhe_composition_of_gates();
|
test_ntruhe_or(s_ntru);
|
||||||
|
test_ntruhe_xor(s_ntru);
|
||||||
|
test_ntruhe_not(s_ntru);
|
||||||
|
test_ntruhe_composition_of_gates(s_ntru);
|
||||||
cout << "NTRU tests PASSED" << endl;
|
cout << "NTRU tests PASSED" << endl;
|
||||||
|
|
||||||
cout << endl;
|
cout << endl;
|
||||||
cout << "-------------------------" << endl;
|
cout << "-------------------------" << endl;
|
||||||
cout << "LWE tests" << endl;
|
cout << "LWE tests" << endl;
|
||||||
test_lwehe_nand();
|
SchemeLWE s_lwe;
|
||||||
test_lwehe_and();
|
test_lwehe_not(s_lwe);
|
||||||
test_lwehe_or();
|
test_lwehe_nand(s_lwe);
|
||||||
test_lwehe_composition_of_gates();
|
test_lwehe_and(s_lwe);
|
||||||
|
test_lwehe_or(s_lwe);
|
||||||
|
test_lwehe_xor(s_lwe);
|
||||||
|
test_lwehe_not(s_lwe);
|
||||||
|
test_lwehe_composition_of_gates(s_lwe);
|
||||||
cout << "LWE tests PASSED" << endl;
|
cout << "LWE tests PASSED" << endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user