mirror of
https://github.com/data61/MP-SPDZ.git
synced 2026-01-07 20:53:55 -05:00
98 lines
2.5 KiB
C++
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);
|
|
}
|