Files
MP-SPDZ/Utils/he-example.cpp
2022-05-27 14:20:31 +02:00

98 lines
2.5 KiB
C++

/*
* he-example.cpp
*
*/
#include "FHE/FHE_Params.h"
#include "FHE/NTL-Subs.h"
#include "FHE/FHE_Keys.h"
#include "FHE/Plaintext.h"
void first_phase(string filename, int n_mults, int circuit_sec);
void second_phase(string filename);
int main()
{
for (int n_mults = 0; n_mults < 2; n_mults++)
for (int sec = 0; sec <= 120; sec += 40)
{
string filename = "mp-spdz-he";
first_phase(filename, n_mults, sec);
second_phase(filename);
}
}
void first_phase(string filename, int n_mults, int circuit_sec)
{
// specify number of multiplications (at most one) and function privacy parameter
// increase the latter to accommodate more operations
FHE_Params params(n_mults, circuit_sec);
// generate parameters for computation modulo a 32-bit prime
params.basic_generation_mod_prime(32);
// find computation modulus (depends on parameter generation)
cout << "computation modulo " << params.get_plaintext_modulus() << endl;
// generate key pair
FHE_KeyPair pair(params);
pair.generate();
Plaintext_mod_prime plaintext(params);
// set first two plaintext slots
plaintext.set_element(0, 4);
plaintext.set_element(1, -1);
// encrypt
Ciphertext ciphertext = pair.pk.encrypt(plaintext);
// store for second phase
octetStream os;
params.pack(os);
pair.pk.pack(os);
ciphertext.pack(os);
plaintext.pack(os);
pair.sk.pack(os);
ofstream out(filename);
os.output(out);
}
void second_phase(string filename)
{
// read from file
ifstream in(filename);
octetStream os;
os.input(in);
FHE_Params params;
FHE_PK pk(params);
FHE_SK sk(params);
Plaintext_mod_prime plaintext(params);
Ciphertext ciphertext(params);
// parameter must be set correctly first
params.unpack(os);
pk.unpack(os);
ciphertext.unpack(os);
plaintext.unpack(os);
if (params.n_mults() == 0)
// public-private multiplication is always available
ciphertext *= plaintext;
else
// private-private multiplication only with matching parameters
ciphertext = ciphertext.mul(pk, ciphertext);
// re-randomize for circuit privacy
ciphertext.rerandomize(pk);
// read secret key and decrypt
sk.unpack(os);
plaintext = sk.decrypt(ciphertext);
cout << "should be 16: " << plaintext.element(0) << endl;
cout << "should be 1: " << plaintext.element(1) << endl;
assert(plaintext.element(0) == 16);
assert(plaintext.element(1) == 1);
}