Skip to content

Commit 0ed6008

Browse files
authored
Merge pull request #5 from wfus/jpg
Jpg
2 parents 4d77e84 + 16136d8 commit 0ed6008

File tree

5 files changed

+206
-58
lines changed

5 files changed

+206
-58
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"files.associations": {
33
"algorithm": "cpp",
4-
"random": "cpp"
4+
"random": "cpp",
5+
"ios": "cpp"
56
}
67
}

homo/Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LDFLAGS=-g
77

88
.PHONY : all clean
99

10-
all : raymond dct encode test sender
10+
all : raymond dct encode test sender reciever
1111

1212

1313
raymond : raymond.cpp
@@ -29,6 +29,10 @@ sender: test.cpp
2929
@-mkdir -p $(dir $@)
3030
$(CXX) $(CXXFLAGS) $(LDFLAGS) sender.cpp $(addprefix -I,$(INCLUDE_DIR)) $(addprefix -L,$(LIB_DIR)) -lseal -o $(BIN_DIR)/sender
3131

32+
reciever: test.cpp
33+
@-mkdir -p $(dir $@)
34+
$(CXX) $(CXXFLAGS) $(LDFLAGS) reciever.cpp $(addprefix -I,$(INCLUDE_DIR)) $(addprefix -L,$(LIB_DIR)) -lseal -o $(BIN_DIR)/reciever
35+
3236

3337
clean :
3438
@-rm -f ../bin/*

homo/fhe_image.h

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ using namespace seal;
2121

2222

2323
const int BLOCK_SIZE = 8;
24-
std::vector<std::vector<double>> split_image_eight_block(std::vector<double> im, int w, int h) {
25-
std::vector<std::vector<double>> lst;
24+
template <class T>
25+
std::vector<std::vector<T>> split_image_eight_block(std::vector<T> &im, int w, int h) {
26+
std::vector<std::vector<T>> lst;
2627
for (int i = 0; i < w; i += BLOCK_SIZE) {
2728
for (int j = 0; j < h; j += BLOCK_SIZE) {
28-
std::vector<double> new_lst;
29+
std::vector<T> new_lst;
2930
for (int k = 0; k < BLOCK_SIZE; k++)
3031
for (int l = 0; l < BLOCK_SIZE; l++) {
3132
int index = (j+k)*w + i + l;
@@ -45,16 +46,17 @@ void print_image(uint8_t *im, int w, int h) {
4546
}
4647
}
4748

48-
void print_image(std::vector<double> &im, int w, int h) {
49+
template <class T>
50+
void print_image(std::vector<T> &im, int w, int h) {
4951
std::cout << "Printing Image dim: (" << w << "," << h << ")" << std::endl;
5052
for (int i = 0; i < im.size(); i++) {
5153
std::cout << std::setw(11) << im[i] << " ";
5254
if ((i + 1) % w == 0) std::cout << std::endl;
5355
}
5456
}
5557

56-
57-
void print_blocks(std::vector<std::vector<double>> &blocks) {
58+
template <class T>
59+
void print_blocks(std::vector<std::vector<T>> &blocks) {
5860
for (int a = 0; a < blocks.size(); a++) {
5961
std::cout << "Printing block " << a << std::endl;
6062
for (int i = 0; i < blocks[a].size(); i++) {
@@ -212,9 +214,6 @@ inline void quantize_fhe(std::vector<Ciphertext> &data,
212214
}
213215

214216

215-
216-
217-
218217
// Forward DCT, regular no encryption
219218
inline void dct(double *data) {
220219
double z1, z2, z3, z4, z5, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp10, tmp11, tmp12, tmp13, *data_ptr;

homo/reciever.cpp

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#include "seal/seal.h"
2+
#include "fhe_image.h"
3+
#include "jpge.h"
4+
#include "stb_image.c"
5+
6+
using namespace seal;
7+
8+
auto start = std::chrono::steady_clock::now();
9+
void fhe_jpg(std::vector<Ciphertext> &raw_data,
10+
int width,
11+
int height,
12+
Evaluator &evaluator,
13+
FractionalEncoder &encoder,
14+
Encryptor &encryptor);
15+
16+
const std::vector<double> S_STD_LUM_QUANT = { 16,11,12,14,12,10,16,14,13,14,18,17,16,19,24,40,26,24,22,22,24,49,35,37,29,40,58,51,61,60,57,51,56,55,64,72,92,78,64,68,87,69,55,56,80,109,81,87,95,98,103,104,103,62,77,113,121,112,100,120,92,101,103,99 };
17+
const std::vector<double> S_STD_CROMA_QUANT = { 17,18,18,24,21,24,47,26,26,47,99,66,56,66,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99 };
18+
19+
int main(int argc, char** argv) {
20+
21+
// Read encryption parameters from file
22+
int WIDTH = 0, HEIGHT = 0;
23+
std::ifstream paramfile;
24+
paramfile.open("../keys/params.txt");
25+
paramfile >> WIDTH;
26+
paramfile >> HEIGHT;
27+
std::cout << WIDTH << " " << HEIGHT << std::endl;
28+
paramfile.close();
29+
30+
31+
// Encryption Parameters
32+
EncryptionParameters params;
33+
params.set_poly_modulus("1x^8192 + 1");
34+
params.set_coeff_modulus(coeff_modulus_128(2048));
35+
params.set_plain_modulus(1 << 14);
36+
SEALContext context(params);
37+
print_parameters(context);
38+
39+
40+
// Generate keys
41+
std::ifstream pkfile, skfile;
42+
pkfile.open("../keys/pubkey.txt");
43+
skfile.open("../keys/seckey.txt");
44+
start = std::chrono::steady_clock::now();
45+
PublicKey public_key;
46+
SecretKey secret_key;
47+
public_key.load(pkfile);
48+
secret_key.load(skfile);
49+
auto diff = std::chrono::steady_clock::now() - start;
50+
std::cout << "Key Load Time: ";
51+
std::cout << chrono::duration<double, milli>(diff).count() << " ms" << std::endl;
52+
pkfile.close(); skfile.close();
53+
54+
55+
// Encrytor and decryptor setup
56+
Encryptor encryptor(context, public_key);
57+
Evaluator evaluator(context);
58+
59+
// FOR DEBUGGING ONLY!
60+
Decryptor decryptor(context, secret_key);
61+
62+
// Base + Number of coefficients used for encoding past the decimal point (both pos and neg)
63+
// Example: if poly_base = 11, and N_FRACTIONAL_COEFFS=3, then we will have
64+
// a1 * 11^-1 + a2 * 11^-2 + a3 * 11^-3
65+
const int POLY_BASE = 11;
66+
const int N_FRACTIONAL_COEFFS = 3;
67+
const int N_NUMBER_COEFFS = 10;
68+
69+
FractionalEncoder encoder(context.plain_modulus(), context.poly_modulus(), N_NUMBER_COEFFS, N_FRACTIONAL_COEFFS, POLY_BASE);
70+
71+
std::ifstream myfile;
72+
myfile.open("../image/nothingpersonnel.txt");
73+
start = std::chrono::steady_clock::now();
74+
std::vector<Ciphertext> nothingpersonnel;
75+
for (int i = 0; i < HEIGHT; i++) {
76+
for (int j = 0; j < WIDTH; j++) {
77+
Ciphertext c;
78+
c.load(myfile);
79+
nothingpersonnel.push_back(c);
80+
}
81+
}
82+
myfile.close();
83+
diff = std::chrono::steady_clock::now() - start;
84+
std::cout << "Ciphertext load time: ";
85+
std::cout << chrono::duration<double, milli>(diff).count() << " ms" << std::endl;
86+
87+
/*
88+
for (int i = 0; i < nothingpersonnel.size(); i++) {
89+
Plaintext p;
90+
decryptor.decrypt(nothingpersonnel[i], p);
91+
std::cout << encoder.decode(p) << " ";
92+
if ((i+1) % WIDTH == 0) std::cout << std::endl;
93+
}
94+
*/
95+
96+
// Actually run the FHE calculations necessary...
97+
start = std::chrono::steady_clock::now();
98+
fhe_jpg(nothingpersonnel, WIDTH, HEIGHT, evaluator, encoder, encryptor);
99+
diff = std::chrono::steady_clock::now() - start;
100+
std::cout << "DCT/QUANT calculation time: ";
101+
std::cout << chrono::duration<double, milli>(diff).count() << " ms" << std::endl;
102+
103+
104+
return 0;
105+
}
106+
107+
void fhe_jpg(std::vector<Ciphertext> &raw_data,
108+
int width,
109+
int height,
110+
Evaluator &evaluator,
111+
FractionalEncoder &encoder,
112+
Encryptor &encryptor) {
113+
std::cout << "Got here" << std::endl;
114+
std::vector<std::vector<Ciphertext>> blocks = split_image_eight_block(raw_data, width, height);
115+
std::cout << "Got here" << std::endl;
116+
for (int i = 0; i < blocks.size(); i++) {
117+
encrypted_dct(blocks[i], evaluator, encoder, encryptor);
118+
quantize_fhe(blocks[i], S_STD_LUM_QUANT, evaluator, encoder, encryptor);
119+
}
120+
}

homo/sender.cpp

Lines changed: 71 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -11,60 +11,84 @@ const bool VERBOSE = true;
1111

1212
std::vector<double> read_image(std::string fname);
1313

14-
int main()
15-
{
16-
const char* test_filename = "../image/kung.jpg";
17-
const int requested_composition = 3;
18-
int width = 0, height = 0, actual_composition = 0;
19-
uint8_t *image_data = stbi_load(test_filename, &width, &height, &actual_composition, requested_composition);
20-
std::cout << width << " x " << height << std::endl;
21-
print_image(image_data, width, height);
14+
int main(int argc, char** argv) {
15+
bool sending = true;
16+
if (argc >= 2) {
17+
sending = false;
18+
}
19+
if (sending) {
20+
const char* test_filename = "../image/kung.jpg";
21+
const int requested_composition = 3;
22+
int width = 0, height = 0, actual_composition = 0;
23+
uint8_t *image_data = stbi_load(test_filename, &width, &height, &actual_composition, requested_composition);
24+
std::cout << width << " x " << height << std::endl;
25+
print_image(image_data, width, height);
2226

27+
// Encryption Parameters
28+
EncryptionParameters params;
29+
params.set_poly_modulus("1x^8192 + 1");
30+
params.set_coeff_modulus(coeff_modulus_128(2048));
31+
params.set_plain_modulus(1 << 14);
32+
SEALContext context(params);
33+
print_parameters(context);
2334

24-
// Encryption Parameters
25-
EncryptionParameters params;
26-
params.set_poly_modulus("1x^32768 + 1");
27-
params.set_coeff_modulus(coeff_modulus_128(2048));
28-
params.set_plain_modulus(1 << 14);
29-
SEALContext context(params);
30-
print_parameters(context);
35+
std::ofstream paramfile;
36+
paramfile.open("../keys/params.txt");
37+
paramfile << width << " ";
38+
paramfile << height << " ";
39+
paramfile << (1 << 14) << std::endl;
40+
paramfile.close();
3141

3242

33-
// Generate keys
34-
start = std::chrono::steady_clock::now();
35-
KeyGenerator keygen(context);
36-
auto public_key = keygen.public_key();
37-
auto secret_key = keygen.secret_key();
38-
auto diff = std::chrono::steady_clock::now() - start;
39-
std::cout << "KeyGen: ";
40-
std::cout << chrono::duration<double, milli>(diff).count() << " ms" << std::endl;
41-
42-
// Encrytor and decryptor setup
43-
Encryptor encryptor(context, public_key);
44-
Evaluator evaluator(context);
45-
Decryptor decryptor(context, secret_key);
43+
// Generate keys
44+
std::ofstream pkfile, skfile;
45+
pkfile.open("../keys/pubkey.txt");
46+
skfile.open("../keys/seckey.txt");
47+
start = std::chrono::steady_clock::now();
48+
KeyGenerator keygen(context);
49+
auto public_key = keygen.public_key();
50+
auto secret_key = keygen.secret_key();
51+
public_key.save(pkfile);
52+
secret_key.save(skfile);
53+
auto diff = std::chrono::steady_clock::now() - start;
54+
std::cout << "KeyGen: ";
55+
std::cout << chrono::duration<double, milli>(diff).count() << " ms" << std::endl;
56+
pkfile.close(); skfile.close();
4657

47-
// Base + Number of coefficients used for encoding past the decimal point (both pos and neg)
48-
// Example: if poly_base = 11, and N_FRACTIONAL_COEFFS=3, then we will have
49-
// a1 * 11^-1 + a2 * 11^-2 + a3 * 11^-3
50-
const int POLY_BASE = 11;
51-
const int N_FRACTIONAL_COEFFS = 3;
52-
const int N_NUMBER_COEFFS = 10;
5358

54-
FractionalEncoder encoder(context.plain_modulus(), context.poly_modulus(), N_NUMBER_COEFFS, N_FRACTIONAL_COEFFS, POLY_BASE);
55-
56-
std::ofstream myfile;
57-
myfile.open("../image/nothingpersonnel.txt");
58-
start = std::chrono::steady_clock::now();
59-
for (int i = 0; i < width * height; i++) {
60-
Ciphertext c;
61-
double conv = (double)(image_data[i]);
62-
std::cout<< conv <<std::endl;
63-
encryptor.encrypt(encoder.encode(conv), c);
64-
c.save(myfile);
65-
}
59+
// Encrytor and decryptor setup
60+
Encryptor encryptor(context, public_key);
61+
Evaluator evaluator(context);
62+
Decryptor decryptor(context, secret_key);
63+
64+
// Base + Number of coefficients used for encoding past the decimal point (both pos and neg)
65+
// Example: if poly_base = 11, and N_FRACTIONAL_COEFFS=3, then we will have
66+
// a1 * 11^-1 + a2 * 11^-2 + a3 * 11^-3
67+
const int POLY_BASE = 11;
68+
const int N_FRACTIONAL_COEFFS = 3;
69+
const int N_NUMBER_COEFFS = 10;
6670

71+
FractionalEncoder encoder(context.plain_modulus(), context.poly_modulus(), N_NUMBER_COEFFS, N_FRACTIONAL_COEFFS, POLY_BASE);
72+
73+
std::ofstream myfile;
74+
myfile.open("../image/nothingpersonnel.txt");
75+
std::cout << width << " " << height << std::endl;
76+
start = std::chrono::steady_clock::now();
77+
for (int i = 0; i < width * height; i++) {
78+
Ciphertext c;
79+
double conv = (double)(image_data[i]);
80+
encryptor.encrypt(encoder.encode(conv), c);
81+
c.save(myfile);
82+
if (i % 100 == 0) std::cout << i << std::endl;
83+
}
84+
myfile.close();
85+
}
86+
else
87+
{
88+
// We are recieving the results and then doing the actual compression
89+
// Note that it is impossible to do compression with purely FHE,
90+
// it is possible to do decompression though.
91+
}
6792

68-
myfile.close();
6993
return 0;
7094
}

0 commit comments

Comments
 (0)