diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/Paillier-Packing.iml b/.idea/Paillier-Packing.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/Paillier-Packing.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..06bb031 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d56657a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..0ad8537 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 6f11745..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,74 +0,0 @@ -cmake_minimum_required(VERSION 3.0.0) -project(Coding) - - -enable_testing() - -add_subdirectory(coding) #add sub directory -add_subdirectory(paillier) #add sub directory - - -add_executable(main main.cpp) - - - - -# GMP -find_path(GMP_INCLUDE_DIR NAMES gmp.h) -find_library(GMP_LIBRARIES NAMES gmp libgmp) -find_library(GMPXX_LIBRARIES NAMES gmpxx libgmpxx) - - - - - -# If not called from root CMakeLists.txt -if(NOT DEFINED SEAL_BUILD_EXAMPLES) - set(SEAL_BUILD_EXAMPLES ON) - - # Import Microsoft SEAL - find_package(SEAL 4.0.0 EXACT REQUIRED) - - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) -endif() - -if(SEAL_BUILD_EXAMPLES) - - - if(TARGET SEAL::seal) - target_link_libraries(main PRIVATE SEAL::seal gmp gmpxx coding paillier ) - elseif(TARGET SEAL::seal_shared) - target_link_libraries(main PRIVATE SEAL::seal_shared gmp gmpxx coding paillier ) - else() - message(FATAL_ERROR "Cannot find target SEAL::seal or SEAL::seal_shared") - endif() -endif() - - -add_executable(lsic lsic_test.cpp) -if(SEAL_BUILD_EXAMPLES) - - - if(TARGET SEAL::seal) - target_link_libraries(lsic PRIVATE SEAL::seal gmp gmpxx coding paillier ) - elseif(TARGET SEAL::seal_shared) - target_link_libraries(lsic PRIVATE SEAL::seal_shared gmp gmpxx coding paillier) - else() - message(FATAL_ERROR "Cannot find target SEAL::seal or SEAL::seal_shared") - endif() -endif() - - - - - - - - - - - - - - - diff --git a/Coding.py b/Coding.py new file mode 100644 index 0000000..c5cc703 --- /dev/null +++ b/Coding.py @@ -0,0 +1,36 @@ + +# value为插入值数组,n是value的位数,block为间隔大小 +# 插值编码函数 +def testEncoding(value, n, block): + value_max = pow(2, n) - 1 + # print("保证每个value <=", value_max) + m = "" + num = len(value) + for i in range(0, num): + if value[i] > value_max: + print("数值超出设定范围,无法编码") + return 0 + m = m + "0" * block + bin(value[i])[2:].zfill(n) + # print("合并结果为" + m) + # 转换成十进制 + m = int(m, 2) + return m + + +# 对完成同态计算后的值进行解码,输出为其结果数组 +# w为一个十进制数,n为value的位数,block间隔大小,num为值个数 +def testDecoding(w, n, block, num): + # 规范二进制数,length为规定的二进制数的bit位数 + length = (n + block) * num + w = bin(w)[2:].zfill(length) + # print(w) + # 含有的value的个数 + num = int(length / (block + n)) + # 获得二进制的结果数组 + value_bin_list = [w[block * i + n * i - n - 1:i * (block + n)] for i in range(0, num + 1)] + # 转换为十进制的结果数组 + value_sum_list = [int(value_bin_list[i], 2) for i in range(1, num + 1)] + for value in value_sum_list: + print(value) + return value_sum_list + diff --git a/README.md b/README.md index 03fd91c..c279032 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,30 @@ - +# Paillier-Packing ## Introduction -Secure maximum(minimum) batching comparison scheme based on Paillier and BFV - -* The maximum value comparison scheme is referred to [Machine Learning Classification over Encrypted Data](https://eprint.iacr.org/2014/331.pdf) -* Implementation of Paillier: https://github.com/camillevuillaume/Paillier-GMP -* Implementation of BFV: https://github.com/microsoft/SEAL - -The scheme realizes batching process through FHE and Paillier on the basis of secure maximum comparison protocol. We can carry out parallel comparison of multiple groups of values. - -This is a complete beta version, and the performance test and optimization are still in progress...... - -## Project Structure - -- CMakeLists.txt - -- coding: Realize encoding and decoding function - -- paillier: Implementation of Paillier encryption system and the basic maximum comparison in that paper - -- seal-part: The tool of seal library - -- seal_lsic.cpp - -- batching_encrypted_comparing.cpp - -- lsic_test.cpp - -- main.cpp +Through this program, we try to understand Paillier cryptosystem and complete the operation of batching in this encryption. - +To ensure security, the plaintext space in this scheme has a fixed size (such as 3072 bits). When the plaintext to be encrypted belongs to a smaller space (such as 16bits), we make full use of the plaintext space and package multiple plaintexts into one for encryption and decryption. -## Preparation +Compared with the original encryption of one plaintext at a time, this batching operation can greatly improve performance. -> Some knowledge used in this project +## Scheme -* GMP Labrary -* SEAL -* Cmake -* FHE -* Paillier -* Cmake +* Packing: concatenate a series of values -## Use +* Encryption: encrypt $m$ using Paillier algorithm to obtain ciphertext $c$ +* Homomorphic operation: Use the homomorphic property to do some calculation and get a sum ciphertext $c'$ +* Decryption: decrypt ciphertext $c'$ using Paillier decryption, obtain plaintext $m'$ +* Unpacking: split $m'$ after decryption -``` -mkdir build; -cd build; -cmake .. -make -./main -``` +## Demo -## For Example +![20220916011143](https://pic-1306483575.cos.ap-nanjing.myqcloud.com/images/20220916011143.png) -``` -INPUT: -{3, 18, 20, 8, 10} -{13, 20, 29, 7, 13} -{14, 25, 27, 6, 5} -{14, 22, 23, 12,19} -OUTPUT: -MAX: -{14,25,29,12,19} +## Dependency -``` +[Partially Homomorphic Encryption library for Python](https://github.com/data61/python-paillier) -![image-20221024214938346](https://pic-1306483575.cos.ap-nanjing.myqcloud.com/images/image-20221024214938346.png) +## Reference -![image-20221024215031338](https://pic-1306483575.cos.ap-nanjing.myqcloud.com/images/image-20221024215031338.png) +[Answering Aggregation Queries in a Secure System Model](http://cs.brown.edu/research/db/publications/vldb07_ge.pdf) diff --git a/Test.py b/Test.py new file mode 100644 index 0000000..c34e3c6 --- /dev/null +++ b/Test.py @@ -0,0 +1,30 @@ +import Coding +from phe import paillier + +# 设定value的位数n,设定值与值之间的间隔数, +n = 9 +block = 5 + +val1 = [1, 8, 10, 5] +val2 = [25, 6, 9, 8] + + +public_key, private_key = paillier.generate_paillier_keypair() + +# 添加测试数据 + +m1 = Coding.testEncoding(val1, n, block) +m2 = Coding.testEncoding(val2, n, block) + +message_list = [m1, m2] +# 加密操作 +encrypted_message_list = [public_key.encrypt(m) for m in message_list] + +# 同态运算 +x, y = encrypted_message_list +z = x + y + +# 解密操作 +q = private_key.decrypt(z) +Coding.testDecoding(q, n, block, len(val1)) + diff --git a/batching_encrypted_comparing.cpp b/batching_encrypted_comparing.cpp deleted file mode 100644 index 25cdd90..0000000 --- a/batching_encrypted_comparing.cpp +++ /dev/null @@ -1,306 +0,0 @@ -#include "seal-part/examples.h" -#include -#include -#include - - - -#include "seal_lsic.cpp" - -using namespace std; -using namespace seal; - -int EncodingLSIC(vector result,int row_size,int n, int block,int num, mpz_t t) { - - - /* - - - 1 2 1 2 3 1 2 3 4 5 6 7 8 9 10 - - 3 4 4 5 6 11 12 13 14 15 16 17 18 19 20 - - - */ - - int encoding_row= (num+1)/2; - - int base=pow(2, n); - string m,s; - char c = '0'; - - for (int i = 0; i < encoding_row; i++) { - string q = toBinary(result[i], n); - - q.insert(0, block, c); - - // cout << "Adding value expressed by binary in t :" << q << endl; - - - m = m + q; - - } - for (int i = 0; i < num-encoding_row; i++) { - string q = toBinary(result[row_size+i], n); - - q.insert(0, block, c); - - //cout << "Adding value expressed by binary in t :" << q << endl; - - - m = m + q; - - } - - // cout << "The value t packed :" << m << endl; - // printf("%s", "so, the packing value t is "); - trans(m, t); - // printf("\n"); - - - return 0; -} - -int EncodingZ(mpz_t z,int n, int block,int num, mpz_t zl,mpz_t d) { - - - - - - int base=pow(2, n); - string m,s; - char c = '0'; - int *value=testDecoding(z, n, block, num); - for (int i = 0; i < num; i++) { - string q = toBinary(value[i]%base, n); - string p = toBinary(value[i]/base, n); - q.insert(0, block, c); - p.insert(0, block, c); - cout << "Adding value expressed by binary in d :" << q << endl; - // cout << "Adding value expressed by binary in zl:" << p << endl; - - - m = m + q; - s = s + p; - - } - - cout << "The value d packed :" << m << endl; - //cout << "The value zl packed:" << s << endl; - //printf("%s", "so, the packing value d is "); - trans(m, d); - //printf("%s", "so, the packing value zl is "); - trans(s, zl); - // printf("\n"); - - - return 0; -} - -int EncodingRandom(int n, int block,int lambda,int num, mpz_t result,mpz_t rl,mpz_t cc) { - - mpz_t r,base; - - unsigned long seed = time(NULL); - - mpz_init(result); - mpz_init(r); - mpz_init(rl); - mpz_init(base); - mpz_init(cc); - gmp_randstate_t state; - gmp_randinit_default(state); - gmp_randseed_ui(state, seed); - - - - mpz_set_si(base, pow(2, n)); - string m,s,t; - char c = '0'; - for (int i = 0; i < num; i++) { - mpz_urandomb(r,state,n+lambda); - - mpz_fdiv_q(rl,r,base); - mpz_mod (cc, r, base); - string p = toBinary(mpz_get_ui(rl), n); - string q = toBinary(mpz_get_ui(r), n+lambda); - string h = toBinary(mpz_get_ui(cc), n); - q.insert(0, block-lambda, c); - p.insert(0, block, c); - h.insert(0, block, c); - // cout << "Adding value expressed by binary in rl:" << p << endl; - // cout << "Adding value expressed by binary in r :" << q << endl; - cout << "Adding value expressed by binary in c :" << h << endl; - - m = m + q; - s = s + p; - t = t + h; - - } - - //cout << "The value r packed :" << m << endl; - //cout << "The value rl packed:" << s << endl; - cout << "The value c packed :" << t << endl; - //printf("%s", "so, the packing value r is "); - trans(m, result); - // printf("%s", "so, the packing value rl is "); - trans(s, rl); - //printf("%s", "so, the packing value c is "); - trans(t, cc); - //printf("\n"); - - - mpz_clear(r); - mpz_clear(base); - return 0; -} - - -int EncodingSame(int n, int block, int num, mpz_t result) { - - mpz_init(result); - - int valuemax = pow(2, n) - 1; - string m; - char c = '0'; - for (int i = 0; i < num; i++) { - - - string q = toBinary(pow(2, n), n); - q.insert(0, block-1, c); - //cout << "Adding value expressed by binary:" << q << endl; - m = m + q; - - } - - // cout << "The value packed:" << m << endl; - //printf("%s", "so, the packing value is "); - trans(m, result); - return 0; -} - - - - - -int batching_encrypted_comparing(mpz_t ca, mpz_t cb,paillier_public_key pub, paillier_private_key priv,int l,int block,int n,int lambda,mpz_t res) -{ - cout<<"\n"<<"\n"<<"batching_encrypted_comparing:......."< matrix_c(n, 0ULL); - matrix_c=seal_lsic(d, c,n,block,l); - EncodingLSIC(matrix_c,8192,l,block,n, t); - // gmp_printf ("t:%Zd\n",t); - //-------------------------------------------------------------------------- - /*batching the front x row_size*/ - - //t - - // gmp_printf ("t:%Zd\n",t); - paillier_encrypt(ct,t,&pub); - - - - //z_l-t-r_l - paillier_homomorphic_multc(cm,ct,negone,&pub); - paillier_homomorphic_multc(cn,crl,negone,&pub); - - paillier_homomorphic_add(cres,czl,cn,&pub); - paillier_decrypt(res,cres,&priv); - //gmp_printf ("res:%Zd\n",res); - testDecoding(res, l, block, n); - - paillier_homomorphic_add(cres,cres,cm,&pub); - paillier_decrypt(res,cres,&priv); - //gmp_printf ("res:%Zd\n",res); - testDecoding(res, l, block, n); - - - - - mpz_clear(a); - mpz_clear(b); - mpz_clear(q); - mpz_clear(base); - mpz_clear(change); - mpz_clear(two); - mpz_clear(x); - mpz_clear(cx); - mpz_clear(cq); - mpz_clear(negone); - mpz_clear(r); - mpz_clear(cr); - mpz_clear(z); - mpz_clear(cz); - mpz_clear(rl); - mpz_clear(c); - mpz_clear(d); - mpz_clear(zl); - mpz_clear(t); - mpz_clear(ct); - mpz_clear(crl); - mpz_clear(czl); - mpz_clear(cm); - mpz_clear(cn); - mpz_clear(cres); - return 0; - - - -} diff --git a/coding/CMakeLists.txt b/coding/CMakeLists.txt deleted file mode 100644 index 3b0d7a9..0000000 --- a/coding/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -aux_source_directory(. DIR_LIB_SRCS) - -add_library(coding ${DIR_LIB_SRCS}) - - -# GMP -find_path(GMP_INCLUDE_DIR NAMES gmp.h) -find_library(GMP_LIBRARIES NAMES gmp libgmp) -find_library(GMPXX_LIBRARIES NAMES gmpxx libgmpxx) - - -target_link_libraries(coding gmp gmpxx) diff --git a/coding/decoding.cpp b/coding/decoding.cpp deleted file mode 100644 index a7d43eb..0000000 --- a/coding/decoding.cpp +++ /dev/null @@ -1,119 +0,0 @@ - - - -#include -#include -#include -#include -#include -#include -#include -#include -#include "decoding.h" - -using namespace std; - - - - -/*trans 010101(string)-->little num*/ -long long translittle(string s) { - long long res = 0; - for (int i = 0; i < s.length(); i++) { - // printf("%d", s[i] - 48); - - - res = res + (s[i] - 48) * pow(2, s.length() - 1 - i); - - - } - //printf("--------The value by decimal %lld\n", res); - return res; - -} - - -/* -Decoding a big big number which has been transformed to plaintext after the homomorphic operations -*/ -int *testDecoding(mpz_t w, int n, int block, int num) { - - - int length = (n + block) * num; - char *str = new char[100000]; - string b; - char c = '0'; - - mpz_get_str(str, 2, w); - b = str; - - - if (b.length() < length) { - b.insert(0, length - b.length(), c); - } - //cout << "The packing result can use binary to express: " << b << endl; - - - int *value = new int[num]; - string val; - for (int i = 0; i < num; i++) { - int a = (n + block) * i; - int c = block + n; - val = b.substr(a, c); - value[i] = translittle(val); - - } - return value; - -} - - -int decoding(int block,int n,int num, char *input,char *output) { - - - - mpz_t result; - - mpz_init(result); - - - FILE *fp1 = fopen(input, "r"); - - mpz_inp_str(result, fp1, 16); - - fclose(fp1); - - /* - - Start to decoding : - - - - Start to decoding and write the output into the output.txt - - - - */ - - int *res; - - res = testDecoding(result, n, block, num); - - FILE *fp2 = fopen(output, "w"); - - char blockflag = ' '; - - for (int i = 0; i < num; i++) { - int value = *(res + i); - - fprintf(fp2, "%d", value); - fputc(blockflag, fp2); - - } - fclose(fp2); - return 0; -} - - - - diff --git a/coding/decoding.h b/coding/decoding.h deleted file mode 100644 index 9c89410..0000000 --- a/coding/decoding.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef DECODING_H__ -#define DECODING_H__ - #include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - -long long translittle(string s); -int *testDecoding(mpz_t w, int n, int block, int num); -int decoding(int block,int n,int num, char *intput,char *output); - -#endif diff --git a/coding/encoding.cpp b/coding/encoding.cpp deleted file mode 100644 index c166770..0000000 --- a/coding/encoding.cpp +++ /dev/null @@ -1,177 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "encoding.h" - -using namespace std; - -/*a decimal number will be transformed to the binary one with the fix length*/ -string toBinary(long long n, int length) { - string r; - char c = '0'; - while (n != 0) { - r += (n % 2 == 0 ? "0" : "1"); - n /= 2; - } - reverse(r.begin(), r.end()); - if (r.length() < length) { - r.insert(0, length - r.length(), c); - } - return r; -} - - -/*trans 010101(string)-->gmp_num*/ -void trans(string s, mpz_t result) { - - mpz_t base, b; - mpz_init(base); - mpz_init(b); - mpz_set_si(base, 2); - - mpz_init(result); - unsigned long int exponent; - unsigned long int midvalue; - long long res = 0; - for (int i = 0; i < s.length(); i++) { - midvalue = s[i] - 48; - exponent = s.length() - 1 - i; - mpz_pow_ui(b, base, exponent); - mpz_mul_ui(b, b, midvalue); - mpz_add(result, b, result); - - } - //gmp_printf("%Zd", result); - printf("\n"); - mpz_clear(base); - mpz_clear(b); - -} - - -/*encoding these data and generate a gmp_num*/ -int testEncoding(int value[], int n, int block, int num, mpz_t result) { - - mpz_init(result); - - int valuemax = pow(2, n) - 1; - string m; - char c = '0'; - for (int i = 0; i < num; i++) { - if (value[i] > valuemax) { - printf("Too large!"); - return 0; - } - - string q = toBinary(value[i], n); - q.insert(0, block, c); - cout << "Adding value expressed by binary:" << q << endl; - m = m + q; - - } - - cout << "The value packed:" << m << endl; - printf("%s", "so, the packing value is "); - trans(m, result); - return 0; -} - - -int encoding(int block, int n,char *input,char *output,mpz_t result) { - - - - - - /* - Reading data: - - - Read a series of data in data.txt - - */ - - int a; - - int val[100]; - - - FILE *fp1 = fopen(input, "r"); - - char c = ' '; - - if (fp1 == NULL) { - puts("CAN NOT OPEN THE TXT!"); - return 0; - } - - int m; - - int num = 0; - - fseek(fp1, 0, 2); - - m = ftell(fp1); - - rewind(fp1); - - while (ftell(fp1) != m - 1) { - fscanf(fp1, "%d", &a); - - val[num] = a; - - //printf("%d\n",val[num]); - - num++; - - - } - - - fclose(fp1); - - /* - - Start to encoding : - - - - try to packing all values into one coded number - - - */ - - FILE *fp2 = fopen(output, "w"); - - - - mpz_init(result); - - testEncoding(val, n, block, num, result); - - mpz_out_str(fp2, 16, result); - fclose(fp2); - return 0; - -} - - - - - - - - - - - - - - - diff --git a/coding/encoding.h b/coding/encoding.h deleted file mode 100644 index 10a95f9..0000000 --- a/coding/encoding.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef MATH_ADD_H__ -#define MATH_ADD_H__ - #include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - -string toBinary(long long n, int length); -void trans(string s, mpz_t result); -int testEncoding(int value[], int n, int block, int num, mpz_t result); -int encoding(int block, int n,char *input,char *output,mpz_t result); - -#endif diff --git a/lsic_test.cpp b/lsic_test.cpp deleted file mode 100644 index e78ae91..0000000 --- a/lsic_test.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "seal_lsic.cpp" -#include "seal-part/examples.h" -#include -#include -#include -#include -#include -#include -#include -#include "coding/encoding.cpp" - - - -using namespace std; - -int main(){ - -int n=5; -int block=5; -int l=10; -mpz_t a,b; -mpz_inits(a,b,NULL); -int valuea[]={2,31,6,31,9}; -int valueb[]={20,30,16,5,19}; - -testEncoding(valuea, l, block, n, a); -testEncoding(valueb, l, block, n, b); - -clock_t start,end; -start = clock(); -seal_lsic(a, b,n,block,l); -end = clock(); -cout<<"time = "< -#include -#include -#include -#include -#include -#include - - -#include "batching_encrypted_comparing.cpp" - -using namespace std; -using namespace seal; - - - - - - - - - - -vector decodingMPZ2Vec(int num,int l,int block,int row_size,int slot_count,mpz_t w){ - vector matrix_bi(slot_count, 0ULL); - int encoding_row=(num+1)/2; - int length = (l + block) * num; - char *str = new char[100000]; - string b; - char c = '0'; - - mpz_get_str(str, 2, w); - b = str; - - - if (b.length() < length) { - b.insert(0, length - b.length(), c); - } - //cout << "The packing result can use binary to express: " << b << endl; - - - string val; - for (int i = 0; i < encoding_row; i++) { - int a = (l + block) * i; - int c = block + l; - val = b.substr(a, c); - matrix_bi[i] = translittle(val); - - } - for (int i = encoding_row; i < num; i++) { - int a = (l + block) * i; - int c = block + l; - val = b.substr(a, c); - matrix_bi[row_size+i-encoding_row] = translittle(val); - - } - return matrix_bi; - - -} - - - -int encodingVec(int n,int l,int block,int row_size, vector max_result, mpz_t result){ - mpz_init(result); - vector value(n, 0ULL); - int encoding_row=(n+1)/2; - - for(int j=0;jqualifiers(); - cout << "Batching enabled: " << boolalpha << qualifiers.using_batching << endl; - -/* KeyGenerate */ - KeyGenerator keygen(context); - - SecretKey secret_key = keygen.secret_key(); - - PublicKey public_key; - - RelinKeys relin_keys; - keygen.create_relin_keys(relin_keys); - - keygen.create_public_key(public_key); - - Encryptor encryptor(context, public_key); - - Evaluator evaluator(context); - - Decryptor decryptor(context, secret_key); - - - - //generate keys - int len=2048; - paillier_public_key pub; - paillier_private_key priv; - - paillier_public_init(&pub); - paillier_private_init(&priv); - paillier_keygen(&pub, &priv, len); - - - // Data - - Plaintext plain_result; - vector pod_result; - - int k=4; - int n=5; - int nums=k; - int block=6; - int l=7; - int lambda=3; - - int value[4][5] = { - {3, 18, 20, 8, 10} , - {13, 20, 29, 7, 13} , - {14, 25, 27, 6, 5} , - {14, 22, 23, 12,19 } - }; - - srand((unsigned)time(NULL)); - int q=(int)pow(2,l+lambda); - - - - - - - //mpz_t - mpz_t max,cmax,cpii,pii,bi,cbi; - mpz_inits(max,cmax,cpii,pii,bi,cbi,NULL); - - BatchEncoder batch_encoder(context); - size_t slot_count = batch_encoder.slot_count(); - size_t row_size = slot_count / 2; - cout << "Plaintext matrix row size: " << row_size << endl; - - vector> matrix; - int encoding_row=(n+1)/2; - for(int i=0;i matrix_a(slot_count, 0ULL); - for(int j=0; j matrix_one(slot_count, 0ULL); - for(int i=0; i max_result; - max_result=matrix[0]; - print_matrix(max_result, row_size); - - Ciphertext max_encrypted; - encryptor.encrypt(plain_matrix_max, max_encrypted); - for(int i=1; i matrix_bi(slot_count, 0ULL); - matrix_bi=decodingMPZ2Vec(n,l,block,row_size,slot_count,bi); - cout << "matrix_bi:" << endl; - print_matrix(matrix_bi, row_size); - - - - Plaintext bi_plain; - batch_encoder.encode(matrix_bi, bi_plain); - Ciphertext bi_encrypted; - encryptor.encrypt(bi_plain, bi_encrypted); - - //1-bi - Ciphertext one_sub_bi_encrypted; - evaluator.sub(one_encrypted,bi_encrypted,one_sub_bi_encrypted); - decryptor.decrypt(one_sub_bi_encrypted, plain_result); - - batch_encoder.decode(plain_result, pod_result); - cout << "1-bi:" << endl; - print_matrix(pod_result, row_size); - - // - //------------------------------------------------------------------------------------------- - //ri,si - - vector matrix_ri(slot_count, 0ULL); - for(int j=0; j matrix_si(slot_count, 0ULL); - for(int j=0; jB\n"); - else printf("A<=B\n"); - - - - - - mpz_clear(d); - - mpz_clear(tau); - mpz_clear(ct); - mpz_clear(negone); - mpz_clear(x); - mpz_clear(cx); - mpz_clear(q); - mpz_clear(cq); - mpz_clear(r); - mpz_clear(cr); - mpz_clear(z); - mpz_clear(cz); - mpz_clear(c); - mpz_clear(czl); - mpz_clear(crl); - mpz_clear(cm); - mpz_clear(cn); - mpz_clear(t); - mpz_clear(base); - mpz_clear(cres); - mpz_clear(zl); - mpz_clear(rl); - - return 0; - - - -} diff --git a/paillier/encrypted_comparing.h b/paillier/encrypted_comparing.h deleted file mode 100644 index 86a1cf8..0000000 --- a/paillier/encrypted_comparing.h +++ /dev/null @@ -1,32 +0,0 @@ - - -#ifndef ENCRYPTED_COMPARING_H_ -#define ENCRYPTED_COMPARING_H_ - - -#include -#include -#include "paillier.h" -#include "lsic.h" - - - - - - - -#ifdef PAILLIER_DEBUG -/** Print debug message - * - * @ingroup Tools - */ -#define DEBUG_MSG(str) fputs(str, stderr) -#else -#define DEBUG_MSG(str) -#endif -int encrypted_comparing(mpz_t res,mpz_t ca,mpz_t cb,int l,paillier_public_key pub,paillier_private_key priv); - - - - -#endif diff --git a/paillier/lsic.c b/paillier/lsic.c deleted file mode 100644 index 8f6848c..0000000 --- a/paillier/lsic.c +++ /dev/null @@ -1,184 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "lsic.h" - - -#include "paillier.h" - - - - - /* - - LSIC:Lightweight Secure Integer Comparison - - */ - -int test(mpz_t ctest,paillier_private_key priv){ - mpz_t test; - mpz_init(test); - - paillier_decrypt(test,ctest,&priv); - - //gmp_printf ("The result of this comparison:%Zd \n",test); - //printf("\n"); - - mpz_clear(test); - - return 0; - -} - - -int binarybit(mpz_t r,mpz_t val,int n){ - mpz_t q, d; - mpz_init(q); - mpz_init(r); - mpz_init(d); - mpz_set_si(d, 2); - - for(int i=0;i=b\n"); - - //gmp_printf ("Proof:The inputA=%Zd, inputB=%Zd\n",a,b); - - - - - - - - - mpz_clear(a0); - mpz_clear(b0); - mpz_clear(cb0); - mpz_clear(zero); - mpz_clear(czero); - mpz_clear(one); - mpz_clear(cone); - mpz_clear(negativeone); - mpz_clear(ctau); - mpz_clear(ai); - mpz_clear(bi); - mpz_clear(tb); - mpz_clear(ctb); - mpz_clear(cbi); - mpz_clear(t); - - - - return 0; -} diff --git a/paillier/lsic.h b/paillier/lsic.h deleted file mode 100644 index 584d3ec..0000000 --- a/paillier/lsic.h +++ /dev/null @@ -1,34 +0,0 @@ - - -#ifndef LSIC_H_ -#define LSIC_H_ - - -#include -#include -#include "paillier.h" - - - - - - - - -#ifdef PAILLIER_DEBUG -/** Print debug message - * - * @ingroup Tools - */ -#define DEBUG_MSG(str) fputs(str, stderr) -#else -#define DEBUG_MSG(str) -#endif -int test(mpz_t ctest,paillier_private_key priv); -int binarybit(mpz_t r,mpz_t val,int n); -int LSIC(mpz_t a,mpz_t b, int l,mpz_t ct,paillier_public_key pub,paillier_private_key priv); - - - - -#endif diff --git a/paillier/paillier.c b/paillier/paillier.c deleted file mode 100644 index db9778e..0000000 --- a/paillier/paillier.c +++ /dev/null @@ -1,268 +0,0 @@ -/** - * @file paillier.c - * - * @date Created on: Aug 25, 2012 - * @author Camille Vuillaume - * @copyright Camille Vuillaume, 2012 - * - * This file is part of Paillier-GMP. - * - * Paillier-GMP is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * - * Paillier-GMP is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Paillier-GMP. If not, see . - * - */ - -#include -#include "paillier.h" -#include "tools.h" - -/** Function L(u)=(u-1)/n - * - * @ingroup Paillier - * @param[out] result output result (u-1)/n - * @param[in] input u - * @param[in] ninv input n^{-1} mod 2^len - * @param[in] len input bit length - * @return 0 if no error - * - * The function L is evaluated using the pre-computed value n^{-1} mod 2^len. - * The calculation a/n is computed as a*n^{-1} mod 2^len - * - First a non-modular multiplication with n^{-1} mod 2^len is calculated. - * - Then the result is reduced by masking higher bits. - */ -int paillier_ell(mpz_t result, mpz_t input, mpz_t ninv, mp_bitcnt_t len) { - mpz_t mask; - - mpz_init(mask); - - mpz_sub_ui(result, input, 1); - mpz_mul(result, result, ninv); - mpz_setbit(mask, len); - mpz_sub_ui(mask, mask, 1); - mpz_and(result, result, mask); - - mpz_clear(mask); - return 0; -} - -/** - * The function does the following. - * - It generates two (probable) primes p and q having bits/2 bits. - * - It computes the modulus n=p*q and sets the basis g to 1+n. - * - It pre-computes n^{-1} mod 2^len. - * - It pre-computes the CRT paramter p^{-2} mod q^2. - * - It calculates lambda = lcm((p-1)*(q-1)) - * - It calculates mu = L(g^lambda mod n^2)^{-1} mod n using the CRT. - * . - * Since /dev/random is one of the sources of randomness in prime generation, the program may block. - * In that case, you have to wait or move your mouse to feed /dev/random with fresh randomness. - */ -int paillier_keygen(paillier_public_key *pub, paillier_private_key *priv, mp_bitcnt_t len) { - mpz_t p, q, n2, temp, mask, g; - - mpz_init(p); - mpz_init(q); - mpz_init(n2); - mpz_init(temp); - mpz_init(mask); - mpz_init(g); - - //write bit lengths - priv->len = len; - pub->len = len; - - //generate p and q - DEBUG_MSG("generating prime p\n"); - gen_prime(p, len/2); - DEBUG_MSG("generating prime q\n"); - gen_prime(q, len/2); - - //calculate modulus n=p*q - DEBUG_MSG("calculating modulus n=p*q\n"); - mpz_mul(pub->n, p, q); - mpz_mul(priv->n, p, q); - - //set g = 1+n - DEBUG_MSG("calculating basis g=1+n\n"); - mpz_add_ui(g, pub->n, 1); - - //compute n^{-1} mod 2^{len} - DEBUG_MSG("computing modular inverse n^{-1} mod 2^{len}\n"); - mpz_setbit(temp, len); - if(!mpz_invert(priv->ninv, pub->n, temp)) { - fputs("Inverse does not exist!\n", stderr); - mpz_clear(p); - mpz_clear(q); - mpz_clear(n2); - mpz_clear(temp); - mpz_clear(mask); - mpz_clear(g); - exit(1); - } - - //compute p^2 and q^2 - mpz_mul(priv->p2, p, p); - mpz_mul(priv->q2, q, q); - - //generate CRT parameter - DEBUG_MSG("calculating CRT parameter p^{-2} mod q^2\n"); - mpz_invert(priv->p2invq2, priv->p2, priv->q2); - - //calculate lambda = lcm(p-1,q-1) - DEBUG_MSG("calculating lambda=lcm((p-1)*(q-1))\n"); - mpz_clrbit(p, 0); - mpz_clrbit(q, 0); - mpz_lcm(priv->lambda, p, q); - - //calculate n^2 - mpz_mul(n2, pub->n, pub->n); - - //calculate mu - DEBUG_MSG("calculating mu\n"); - crt_exponentiation(temp, g, priv->lambda, priv->lambda, priv->p2invq2, priv->p2, priv->q2); - - paillier_ell(temp, temp, priv->ninv, len); - - if(!mpz_invert(priv->mu, temp, pub->n)) { - fputs("Inverse does not exist!\n", stderr); - mpz_clear(p); - mpz_clear(q); - mpz_clear(n2); - mpz_clear(temp); - mpz_clear(mask); - mpz_clear(g); - exit(1); - } - - //free memory and exit - DEBUG_MSG("freeing memory\n"); - mpz_clear(p); - mpz_clear(q); - mpz_clear(n2); - mpz_clear(temp); - mpz_clear(mask); - mpz_clear(g); - DEBUG_MSG("exiting\n"); - return 0; -} - -/** - * The function calculates c=g^m*r^n mod n^2 with r random number. - * Encryption benefits from the fact that g=1+n, because (1+n)^m = 1+n*m mod n^2. - */ -int paillier_encrypt(mpz_t ciphertext, mpz_t plaintext, paillier_public_key *pub) { - mpz_t n2, r; - - if(mpz_cmp(pub->n, plaintext)) { - mpz_init(n2); - mpz_init(r); - - //re-compute n^2 - mpz_mul(n2, pub->n, pub->n); - - DEBUG_MSG("generating random number\n"); - //generate random r and reduce modulo n - gen_random_new(r, pub->len); -// gen_pseudorandom(r, pub->len); - mpz_mod(r, r, pub->n); - if(mpz_cmp_ui(r, 0) == 0) { - fputs("random number is zero!\n", stderr); - mpz_clear(n2); - mpz_clear(r); - exit(1); - } - - DEBUG_MSG("computing ciphertext\n"); - //compute r^n mod n2 - mpz_powm(ciphertext, r, pub->n, n2); - - //compute (1+m*n) - mpz_mul(r, plaintext, pub->n); - mpz_add_ui(r, r, 1); - - //multiply with (1+m*n) - mpz_mul(ciphertext, ciphertext, r); - mpz_mod(ciphertext, ciphertext, n2); - - DEBUG_MSG("freeing memory\n"); - mpz_clear(n2); - mpz_clear(r); - } - DEBUG_MSG("exiting\n"); - return 0; -} - -/** - * The decryption function computes m = L(c^lambda mod n^2)*mu mod n. - * The exponentiation is calculated using the CRT, and exponentiations mod p^2 and q^2 run in their own thread. - * - */ -int paillier_decrypt(mpz_t plaintext, mpz_t ciphertext, paillier_private_key *priv) { - DEBUG_MSG("computing plaintext\n"); - //compute exponentiation c^lambda mod n^2 - crt_exponentiation(plaintext, ciphertext, priv->lambda, priv->lambda, priv->p2invq2, priv->p2, priv->q2); - - //compute L(c^lambda mod n^2) - paillier_ell(plaintext, plaintext, priv->ninv, priv->len); - - //compute L(c^lambda mod n^2)*mu mod n - mpz_mul(plaintext, plaintext, priv->mu); - mpz_mod(plaintext, plaintext, priv->n); - - DEBUG_MSG("exiting\n"); - return 0; -} - -/** - * "Add" two plaintexts homomorphically by multiplying ciphertexts modulo n^2. - * For example, given the ciphertexts c1 and c2, encryptions of plaintexts m1 and m2, - * the value c3=c1*c2 mod n^2 is a ciphertext that decrypts to m1+m2 mod n. - */ -int paillier_homomorphic_add(mpz_t ciphertext3, mpz_t ciphertext1, mpz_t ciphertext2, paillier_public_key *pub) { - mpz_t n2; - - mpz_init(n2); - DEBUG_MSG("compute n^2"); - mpz_mul(n2, pub->n, pub->n); - - DEBUG_MSG("homomorphic add plaintexts"); - mpz_mul(ciphertext3, ciphertext1, ciphertext2); - mpz_mod(ciphertext3, ciphertext3, n2); - - DEBUG_MSG("freeing memory\n"); - mpz_clear(n2); - DEBUG_MSG("exiting\n"); - return 0; -} - -/** - * "Multiplies" a plaintext with a constant homomorphically by exponentiating the ciphertext modulo n^2 with the constant as exponent. - * For example, given the ciphertext c, encryptions of plaintext m, and the constant 5, - * the value c3=c^5 n^2 is a ciphertext that decrypts to 5*m mod n. - */ -int paillier_homomorphic_multc(mpz_t ciphertext2, mpz_t ciphertext1, mpz_t constant, paillier_public_key *pub) { - mpz_t n2; - - mpz_init(n2); - DEBUG_MSG("compute n^2"); - mpz_mul(n2, pub->n, pub->n); - - DEBUG_MSG("homomorphic multiplies plaintext with constant"); - mpz_powm(ciphertext2, ciphertext1, constant, n2); - - DEBUG_MSG("freeing memory\n"); - mpz_clear(n2); - DEBUG_MSG("exiting\n"); - return 0; -} diff --git a/paillier/paillier.h b/paillier/paillier.h deleted file mode 100644 index 725021d..0000000 --- a/paillier/paillier.h +++ /dev/null @@ -1,274 +0,0 @@ -/** - * @file paillier.h - * - * @date Created on: Aug 25, 2012 - * @author Camille Vuillaume - * @copyright Camille Vuillaume, 2012 - * @defgroup Paillier Paillier cryptosystem - * - * This file is part of Paillier-GMP. - * - * Paillier-GMP is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * - * Paillier-GMP is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Paillier-GMP. If not, see . - */ - -#ifndef PAILLIER_H_ -#define PAILLIER_H_ - -#ifdef __cplusplus -extern "C" { -#endif - - -#include -#include - -/** Private key - * - * @ingroup Paillier - * - * In addition to the usual private key elements, the structure contains: - * - CRT parameters for accelerating exponentiations during decryption - * - The modular inverse n^{-1} mod 2^len for accelerating the calculation of L - */ -typedef struct { - mp_bitcnt_t len; /**< bit length of n */ - mpz_t lambda; /**< least common multiple of p and q */ - mpz_t mu; /**< Modular inverse */ - mpz_t p2; /**< square of prime number p */ - mpz_t q2; /**< square of prime number q */ - mpz_t p2invq2; /**< CRT parameter p^{-2} mod q^2 */ - mpz_t ninv; /**< modular inverse n^{-1} mod 2^len */ - mpz_t n; /**< n=p*q */ -} paillier_private_key; - -/** Public key - * - * @ingroup Paillier - * - * The generator is 1+n. This is fine in view of security because Class[g,n] is random self-reducible over g, - * therefore the security of the cryptosystem does not depend on the choice of g. - */ -typedef struct { - mp_bitcnt_t len; /**< bit length of n */ - mpz_t n; /**< modulus n */ -} paillier_public_key; - -/** Memory allocation for public key - * - * @ingroup Paillier - * @param[in] pub input public key - */ -void paillier_public_init(paillier_public_key *pub); - -/** Memory allocation for private key - * - * @ingroup Paillier - * @param[in] priv input private key - */ -void paillier_private_init(paillier_private_key *priv); - -/** Free memory for public key - * - * @ingroup Paillier - * @param[in] pub input public key - */ -void paillier_public_clear(paillier_public_key *pub); - -/** Free memory for private key - * - * @ingroup Paillier - * @param[in] priv input private key - */ -void paillier_private_clear(paillier_private_key *priv); - - -/** Output public key to stdio stream - * - * @ingroup Paillier - * @param[out] fp output stream - * @param[in] pub input public key - */ -int paillier_public_out_str(FILE *fp, paillier_public_key *pub); - -/** Output private key to stdio stream - * - * @ingroup Paillier - * @param[out] fp output stream - * @param[in] priv input private key - */ -int paillier_private_out_str(FILE *fp, paillier_private_key *priv); - -/** Input public key from stdio stream - * - * @ingroup Paillier - * @param[out] pub output public key - * @param[in] fp input stream - */ -int paillier_public_in_str(paillier_public_key *pub, FILE *fp); - -/** Input private key from stdio stream - * - * @ingroup Paillier - * @param[out] priv output private key - * @param[in] fp input stream - */ -int paillier_private_in_str(paillier_private_key *priv, FILE *fp); - -/** Key generation - * - * @ingroup Paillier - * @param[out] pub output public key - * @param[out] priv output private key - * @param[in] len input bit length of public modulus - * @return 0 if no error - */ -int paillier_keygen( - paillier_public_key *pub, - paillier_private_key *priv, - mp_bitcnt_t len); - - -/** Key generation to stdio stream - * - * @ingroup Paillier - * @param[out] public_key output stream for public key - * @param[out] private_key output stream for private key - * @param[in] len input bit length of public modulus - * @return 0 if no error - */ -int paillier_keygen_str( - FILE *public_key, - FILE *private_key, - int len); - -/** Encrypt - * - * @ingroup Paillier - * @param[out] ciphertext output ciphertext c=g^m*r^n mod n^2 - * @param[in] plaintext input plaintext m - * @param[in] pub input public key - * @return 0 if no error - */ -int paillier_encrypt( - mpz_t ciphertext, - mpz_t plaintext, - paillier_public_key *pub); - -/** Encrypt from stdio stream - * - * @ingroup Paillier - * @param[out] ciphertext output stream for ciphertext c=g^m*r^n mod n^2 - * @param[in] plaintext input stream for plaintext m - * @param[in] public_key input stream for public key - * @return 0 if no error - */ -int paillier_encrypt_str( - FILE *ciphertext, - FILE *plaintext, - FILE *public_key); - - -/** Decrypt - * - * @ingroup Paillier - * @param[out] plaintext output plaintext m - * @param[in] ciphertext input ciphertext - * @param[in] priv input private key - * @return 0 if no error - */ -int paillier_decrypt( - mpz_t plaintext, - mpz_t ciphertext, - paillier_private_key *priv); - -/** Decrypt from stdio stream - * - * @ingroup Paillier - * @param[out] plaintext output stream for plaintext m - * @param[in] ciphertext input stream for ciphertext c - * @param[in] private_key input stream for private key - * @return 0 if no error - */ -int paillier_decrypt_str( - FILE *ciphertext, - FILE *plaintext, - FILE *private_key); - -/** Homomorphically add two plaintexts - * - * @ingroup Paillier - * @param[out] ciphertext3 output ciphertext corresponding to the homomorphic addition of the two plaintexts - * @param[in] ciphertext1 input first ciphertext corresponding to a plaintext to be homomorphically added - * @param[in] ciphertext2 input second ciphertext corresponding to a plaintext to be homomorphically added - * @param[in] pub input public key - * @return 0 if no error - */ -int paillier_homomorphic_add( - mpz_t ciphertext3, - mpz_t ciphertext1, - mpz_t ciphertext2, - paillier_public_key *pub); - -/** Homomorphically add two plaintexts from stdio stream - * - * @ingroup Paillier - * @param[out] ciphertext3 output stream for result of homomorphic addition - * @param[in] ciphertext1 input stream for first ciphertext c1 - * @param[in] ciphertext2 input stream for second ciphertext c2 - * @param[in] public_key input stream for public key - * @return 0 if no error - */ -int paillier_homomorphic_add_str( - FILE *ciphertext3, - FILE *ciphertext1, - FILE *ciphertext2, - FILE *public_key); - -/** Homomorphically multiply a plaintext with a constant - * - * @ingroup Paillier - * @param[out] ciphertext2 output ciphertext corresponding to the homomorphic multiplication of the plaintext with the constant - * @param[in] ciphertext1 input ciphertext corresponding to a plaintext to be homomorphically multiplied - * @param[in] constant input constant to be homomorphically multiplied - * @param[in] pub input public key - * @return 0 if no error - */ -int paillier_homomorphic_multc( - mpz_t ciphertext2, - mpz_t ciphertext1, - mpz_t constant, - paillier_public_key *pub); - - -/** Homomorphically multiply a plaintext with a constant from stdio stream - * - * @ingroup Paillier - * @param[out] ciphertext2 output stream for result of homomorphic multiplication - * @param[in] ciphertext1 input stream for ciphertext c - * @param[in] constant input stream for constant k - * @param[in] public_key input stream for public key - * @return 0 if no error - */ -int paillier_homomorphic_multc_str( - FILE *ciphertext2, - FILE *ciphertext1, - FILE *plaintext, - FILE *public_key); - -#ifdef __cplusplus -} -#endif - -#endif /* PAILLIER_H_ */ diff --git a/paillier/paillier_io.c b/paillier/paillier_io.c deleted file mode 100644 index deec833..0000000 --- a/paillier/paillier_io.c +++ /dev/null @@ -1,243 +0,0 @@ -/** - * @file paillier_io.c - * - * @date Created on: Sep 06, 2012 - * @author Camille Vuillaume - * @copyright Camille Vuillaume, 2012 - * - * This file is part of Paillier-GMP. - * - * Paillier-GMP is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * - * Paillier-GMP is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Paillier-GMP. If not, see . - * - */ - -#include "tools.h" -#include "paillier.h" - -/** - * Wrapper to the key generation function using stdio streams as inputs and output. - * @see paillier_keygen - */ -int paillier_keygen_str(FILE *public_key, FILE *private_key, int len) { - int result; - paillier_public_key pub; - paillier_private_key priv; - - paillier_public_init(&pub); - paillier_private_init(&priv); - - //generate keys - result = paillier_keygen(&pub, &priv, len); - - //export public key - DEBUG_MSG("export public key: \n"); - result |= paillier_public_out_str(public_key, &pub); - - //export private key - DEBUG_MSG("export private key: \n"); - result |= paillier_private_out_str(private_key, &priv); - - DEBUG_MSG("freeing memory\n"); - paillier_public_clear(&pub); - paillier_private_clear(&priv); - - DEBUG_MSG("exiting\n"); - return result; -} - -/** - * Wrapper to the encryption function using stdio streams as inputs and output. - * @see paillier_encrypt - */ -int paillier_encrypt_str(FILE *ciphertext, FILE *plaintext, FILE *public_key) { - mpz_t c, m; - int result; - paillier_public_key pub; - - mpz_init(c); - mpz_init(m); - paillier_public_init(&pub); - - //import public key - DEBUG_MSG("importing public key: \n"); - paillier_public_in_str(&pub, public_key); - - //convert plaintext from stream - DEBUG_MSG("importing plaintext: \n"); - gmp_fscanf(plaintext, "%Zx\n", m); - if(mpz_cmp(m, pub.n) >= 0) { - fputs("Warning, plaintext is larger than modulus n!\n", stderr); - } - - //calculate encryption - result = paillier_encrypt(c, m, &pub); - - //convert ciphertext to stream - DEBUG_MSG("exporting ciphertext: \n"); - gmp_fprintf(ciphertext, "%Zx\n", c); - - DEBUG_MSG("freeing memory\n"); - mpz_clear(c); - mpz_clear(m); - paillier_public_clear(&pub); - - DEBUG_MSG("exiting\n"); - return result; -} - -/** - * Wrapper to the decryption function using stdio streams as inputs and output. - * @see paillier_decrypt - */ -int paillier_decrypt_str(FILE *plaintext, FILE *ciphertext, FILE *private_key) { - mpz_t c, m, n2; - paillier_private_key priv; - int result; - - mpz_init(c); - mpz_init(m); - mpz_init(n2); - paillier_private_init(&priv); - - //import private key - DEBUG_MSG("importing private key: \n"); - paillier_private_in_str(&priv, private_key); - - //compute n^2 - mpz_mul(n2, priv.n, priv.n); - - //convert ciphertext from stream - DEBUG_MSG("importing ciphertext: \n"); - gmp_fscanf(ciphertext, "%Zx\n", c); - if(mpz_cmp(c, n2) >= 0) { - fputs("Warning, ciphertext is larger than modulus n^2!\n", stderr); - } - //calculate decryption - result = paillier_decrypt(m, c, &priv); - - //convert plaintext to stream - DEBUG_MSG("exporting plaintext: \n"); - gmp_fprintf(plaintext, "%Zx\n", m); - - DEBUG_MSG("freeing memory\n"); - mpz_clear(c); - mpz_clear(m); - mpz_clear(n2); - paillier_private_clear(&priv); - - DEBUG_MSG("exiting\n"); - return result; -} - -/** - * Wrapper to the homomorphic addition function using stdio streams as inputs and output. - * @see paillier_homomorphic_add - */ -int paillier_homomorphic_add_str(FILE *ciphertext3, FILE *ciphertext1, FILE *ciphertext2, FILE *public_key) { - mpz_t c3, c1, c2, n2; - paillier_public_key pub; - int result; - - mpz_init(c3); - mpz_init(c1); - mpz_init(c2); - mpz_init(n2); - paillier_public_init(&pub); - - //import public key - DEBUG_MSG("importing public key: \n"); - paillier_public_in_str(&pub, public_key); - - //compute n^2 - mpz_mul(n2, pub.n, pub.n); - - //convert ciphertexts from stream - DEBUG_MSG("importing ciphertexts: \n"); - gmp_fscanf(ciphertext1, "%Zx\n", c1); - if(mpz_cmp(c1, n2) >= 0) { - fputs("Warning, first ciphertext is larger than modulus n^2!\n", stderr); - } - gmp_fscanf(ciphertext2, "%Zx\n", c2); - if(mpz_cmp(c2, n2) >= 0) { - fputs("Warning, second ciphertext is larger than modulus n^2!\n", stderr); - } - //calculate decryption - result = paillier_homomorphic_add(c3, c1, c2, &pub); - - //convert result to stream - DEBUG_MSG("exporting result: \n"); - gmp_fprintf(ciphertext3, "%Zx\n", c3); - - DEBUG_MSG("freeing memory\n"); - mpz_clear(c3); - mpz_clear(c1); - mpz_clear(c2); - mpz_clear(n2); - paillier_public_clear(&pub); - - DEBUG_MSG("exiting\n"); - return result; -} - -/** - * Wrapper to the homomorphic multiplication function using stdio streams as inputs and output. - * @see paillier_homomorphic_add - */ -int paillier_homomorphic_multc_str(FILE *ciphertext2, FILE *ciphertext1, FILE *constant, FILE *public_key) { - mpz_t c2, c1, k, n2; - paillier_public_key pub; - int result; - - mpz_init(c2); - mpz_init(c1); - mpz_init(k); - mpz_init(n2); - paillier_public_init(&pub); - - //import public key - DEBUG_MSG("importing public key: \n"); - paillier_public_in_str(&pub, public_key); - - //compute n^2 - mpz_mul(n2, pub.n, pub.n); - - //convert ciphertext from stream - DEBUG_MSG("importing ciphertexts: \n"); - gmp_fscanf(ciphertext1, "%Zx\n", c1); - if(mpz_cmp(c1, n2) >= 0) { - fputs("Warning, first ciphertext is larger than modulus n^2!\n", stderr); - } - gmp_fscanf(constant, "%Zx\n", k); - if(mpz_cmp(k, pub.n) >= 0) { - fputs("Warning, constant is larger than modulus n!\n", stderr); - } - //calculate decryption - result = paillier_homomorphic_multc(c2, c1, k, &pub); - - //convert result to stream - DEBUG_MSG("exporting result: \n"); - gmp_fprintf(ciphertext2, "%Zx\n", c2); - - DEBUG_MSG("freeing memory\n"); - mpz_clear(c2); - mpz_clear(c1); - mpz_clear(k); - mpz_clear(n2); - paillier_public_clear(&pub); - - DEBUG_MSG("exiting\n"); - return result; -} - diff --git a/paillier/paillier_manage_keys.c b/paillier/paillier_manage_keys.c deleted file mode 100644 index 6657517..0000000 --- a/paillier/paillier_manage_keys.c +++ /dev/null @@ -1,156 +0,0 @@ -/** - * @file paillier_manage_keys.c - * - * @date Created on: Sep 06, 2012 - * @author Camille Vuillaume - * @copyright Camille Vuillaume, 2012 - * - * This file is part of Paillier-GMP. - * - * Paillier-GMP is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * - * Paillier-GMP is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Paillier-GMP. If not, see . - * - */ - -#include "paillier.h" -#include "tools.h" - -void paillier_public_init(paillier_public_key *pub) { - mpz_init(pub->n); -} - -void paillier_private_init(paillier_private_key *priv) { - mpz_init(priv->lambda); - mpz_init(priv->mu); - mpz_init(priv->p2); - mpz_init(priv->q2); - mpz_init(priv->p2invq2); - mpz_init(priv->ninv); - mpz_init(priv->n); -} - -void paillier_public_clear(paillier_public_key *pub) { - mpz_clear(pub->n); -} - -void paillier_private_clear(paillier_private_key *priv) { - mpz_clear(priv->lambda); - mpz_clear(priv->mu); - mpz_clear(priv->p2); - mpz_clear(priv->q2); - mpz_clear(priv->p2invq2); - mpz_clear(priv->ninv); - mpz_clear(priv->n); -} - -int paillier_public_out_str(FILE *fp, paillier_public_key *pub) { - int printf_ret, result = 0; - - printf_ret = gmp_fprintf(fp, "%d\n", pub->len); - if(printf_ret < 0) return printf_ret; - result += printf_ret; - DEBUG_MSG("output modulus n\n"); - printf_ret = gmp_fprintf(fp, "%Zx\n", pub->n); - if(printf_ret < 0) return printf_ret; - result += printf_ret; - - return result; -} - -int paillier_private_out_str(FILE *fp, paillier_private_key *priv) { - int printf_ret, result = 0; - - printf_ret = gmp_fprintf(fp, "%d\n", priv->len); - if(printf_ret < 0) return printf_ret; - result += printf_ret; - printf_ret = gmp_fprintf(fp, "%Zx\n", priv->lambda); - if(printf_ret < 0) return printf_ret; - result += printf_ret; - printf_ret = gmp_fprintf(fp, "%Zx\n", priv->mu); - if(printf_ret < 0) return printf_ret; - result += printf_ret; - printf_ret = gmp_fprintf(fp, "%Zx\n", priv->p2); - if(printf_ret < 0) return printf_ret; - result += printf_ret; - printf_ret = gmp_fprintf(fp, "%Zx\n", priv->q2); - if(printf_ret < 0) return printf_ret; - result += printf_ret; - printf_ret = gmp_fprintf(fp, "%Zx\n", priv->p2invq2); - if(printf_ret < 0) return printf_ret; - result += printf_ret; - printf_ret = gmp_fprintf(fp, "%Zx\n", priv->ninv); - if(printf_ret < 0) return printf_ret; - result += printf_ret; - printf_ret = gmp_fprintf(fp, "%Zx\n", priv->n); - if(printf_ret < 0) return printf_ret; - result += printf_ret; - - return result; -} - -int paillier_public_in_str(paillier_public_key *pub, FILE *fp) { - int scanf_ret, result = 0; - - DEBUG_MSG("importing bit length\n"); -// scanf_ret = gmp_fscanf(fp, "%d\n", &(pub->len)); - scanf_ret = fscanf(fp, "%ld\n",&(pub->len)); - if(scanf_ret < 0) return scanf_ret; - result += scanf_ret; - DEBUG_MSG("importing modulus\n"); - scanf_ret = gmp_fscanf(fp, "%Zx\n", pub->n); - if(scanf_ret < 0) return scanf_ret; - result += scanf_ret; - - return result; -} - -int paillier_private_in_str(paillier_private_key *priv, FILE *fp) { - int scanf_ret, result = 0; - - DEBUG_MSG("importing bit length\n"); -// scanf_ret = gmp_fscanf(fp, "%d\n", &(priv->len)); - scanf_ret = fscanf(fp, "%ld\n",&(priv->len)); - if(scanf_ret < 0) return scanf_ret; - result += scanf_ret; - DEBUG_MSG("importing lambda\n"); - scanf_ret = gmp_fscanf(fp, "%Zx\n", priv->lambda); - if(scanf_ret < 0) return scanf_ret; - result += scanf_ret; - DEBUG_MSG("importing mu\n"); - scanf_ret = gmp_fscanf(fp, "%Zx\n", priv->mu); - if(scanf_ret < 0) return scanf_ret; - result += scanf_ret; - DEBUG_MSG("importing p^2\n"); - scanf_ret = gmp_fscanf(fp, "%Zx\n", priv->p2); - if(scanf_ret < 0) return scanf_ret; - result += scanf_ret; - DEBUG_MSG("importing q^2\n"); - scanf_ret = gmp_fscanf(fp, "%Zx\n", priv->q2); - if(scanf_ret < 0) return scanf_ret; - result += scanf_ret; - DEBUG_MSG("importing p^-2 mod q^2\n"); - scanf_ret = gmp_fscanf(fp, "%Zx\n", priv->p2invq2); - if(scanf_ret < 0) return scanf_ret; - result += scanf_ret; - DEBUG_MSG("importing n^-1 mod 2^len\n"); - scanf_ret = gmp_fscanf(fp, "%Zx\n", priv->ninv); - if(scanf_ret < 0) return scanf_ret; - result += scanf_ret; - DEBUG_MSG("importing n\n"); - scanf_ret = gmp_fscanf(fp, "%Zx\n", priv->n); - if(scanf_ret < 0) return scanf_ret; - result += scanf_ret; - - return result; -} diff --git a/paillier/tools.c b/paillier/tools.c deleted file mode 100644 index 2823663..0000000 --- a/paillier/tools.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * @file tools.c - * - * @date Created on: Aug 25, 2012 - * @author Camille Vuillaume - * @copyright Camille Vuillaume, 2012 - * - * This file is part of Paillier-GMP. - * - * Paillier-GMP is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * - * Paillier-GMP is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Paillier-GMP. If not, see . - * - */ - -#include -#include -#include -#include -#include -#include "tools.h" - -/** - * Generate a random number using /dev/urandom. - * Random number generation does not block. - */ -int gen_pseudorandom(mpz_t rnd, mp_bitcnt_t len) { - FILE *dev_urandom; - int byte_count, byte_read; - char *seed; - - byte_count = BIT2BYTE(len); - - dev_urandom = fopen("/dev/urandom", "r"); - if (dev_urandom == NULL) { - fprintf(stderr, "cannot open random number device!\n"); - exit(1); - } - - seed = (char *) malloc(sizeof(char) * byte_count); - - byte_read = 0; - //generate the bytes with /dev/urandom - while (byte_read < byte_count) { - byte_read += fread(seed, sizeof(char), byte_count, dev_urandom); - } - fclose(dev_urandom); - - mpz_import(rnd, byte_count, 1, sizeof(seed[0]), 0, 0, seed); - free(seed); - return 0; -} - -/** - * Generate a random number using /dev/random for the first 128 bits and then /dev/urandom. - * This guarantees that there is enough entropy in the pool and that it is safe to use /dev/urandom. - * Since /dev/random is used, if entropy is insufficient the program will block. - * In that case, it is necessary to feed /dev/random with entropy, for example by moving the mouse. - */ -int gen_random(mpz_t rnd, mp_bitcnt_t len) { - FILE *dev_random, *dev_urandom; - int byte_count, byte_read; - char *seed; - - byte_count = BIT2BYTE(len); - - dev_random = fopen("/dev/random", "r"); - if (dev_random == NULL) { - fprintf(stderr, "cannot open random number device!\n"); - exit(1); - } - dev_urandom = fopen("/dev/urandom", "r"); - if (dev_urandom == NULL) { - fprintf(stderr, "cannot open random number device!\n"); - exit(1); - } - - seed = (char *) malloc(sizeof(char) * byte_count); - - byte_read = 0; - //generate the first 16 bytes with /dev/random - while (byte_read < 16 && byte_read < byte_count) { - byte_read += fread(seed, sizeof(char), byte_count, dev_random); - } - fclose(dev_random); - //generate the remaining bytes with /dev/urandom - while (byte_read < byte_count) { - byte_read += fread(seed, sizeof(char), byte_count, dev_urandom); - } - fclose(dev_urandom); - - mpz_import(rnd, byte_count, 1, sizeof(seed[0]), 0, 0, seed); - free(seed); - return 0; -} - -int gen_random_new(mpz_t rnd, mp_bitcnt_t len) { - time_t now = clock(); - gmp_randstate_t state; - gmp_randinit_mt(state); - gmp_randseed_ui(state, now); - mpz_urandomb(rnd, state, len); - gmp_randclear(state); - return 0; -} - -/** - * Generate a random prime number using /dev/random and /dev/urandom as a source of randomness. - * @see gen_random - */ -int gen_prime(mpz_t prime, mp_bitcnt_t len) { - mpz_t rnd; - - mpz_init(rnd); - -// gen_random(rnd, len); - gen_random_new(rnd, len); - //set most significant bit to 1 - mpz_setbit(rnd, len - 1); - //look for next prime - mpz_nextprime(prime, rnd); - mpz_clear(rnd); - - return 0; -} - -/** Threaded exponentiation - * @ingroup Tools - * - * This function reduces the input modulo the given modulus, and performs a modular exponentiation. - * It is intended to be run in a pthread. - * - * @param[in,out] args arguments for the exponentiation, a pointer to an exp_args, with - * - exp_args::result storing the result of the exponentiation - * - exp_args::basis storing the basis - * - exp_args::exponent storing the exponent - * - exp_args::modulus storing the modulus - * - */ -void *do_exponentiate(void *args) { - mpz_t basis_reduced; - exp_args *args_struct = (exp_args *) args; - - mpz_init(basis_reduced); - mpz_mod(basis_reduced, args_struct->basis, args_struct->modulus); - mpz_powm(args_struct->result, basis_reduced, args_struct->exponent, args_struct->modulus); - - mpz_clear(basis_reduced); - pthread_exit(NULL); -} - - -/** - * The exponentiation is computed using Garner's method for the CRT: - * - Exponentiation mod p: y_p = (x mod p)^{exp_p} mod p - * - Exponentiation mod q: y_q = (x mod q)^{exp_q} mod q - * - Recombination: y = y_p + p*(p^{-1} mod q)*(y_q-y_p) mod n - * . - * The exponentiations mod p and mod q run in their own thread. - */ -int crt_exponentiation(mpz_t result, mpz_t base, mpz_t exp_p, mpz_t exp_q, mpz_t pinvq, mpz_t p, mpz_t q) { - mpz_t pq; - exp_args *args_p, *args_q; - -#ifdef PAILLIER_THREAD - pthread_t thread1, thread2; -#endif - - mpz_init(pq); - - //prepare arguments for exponentiation mod p - args_p = (exp_args *) malloc(sizeof(exp_args)); - - mpz_init(args_p->result); - mpz_init(args_p->basis); - mpz_init(args_p->exponent); - mpz_init(args_p->modulus); - - mpz_set(args_p->basis, base); - mpz_set(args_p->exponent, exp_p); - mpz_set(args_p->modulus, p); - - //prepare arguments for exponentiation mod q - args_q = (exp_args *) malloc(sizeof(exp_args)); - - mpz_init(args_q->result); - mpz_init(args_q->basis); - mpz_init(args_q->exponent); - mpz_init(args_q->modulus); - - mpz_set(args_q->basis, base); - mpz_set(args_q->exponent, exp_q); - mpz_set(args_q->modulus, q); - -#ifdef PAILLIER_THREAD - //compute exponentiation modulo p - pthread_create(&thread1, NULL, do_exponentiate, (void *) args_p); - - //compute exponentiation modulo q - pthread_create(&thread2, NULL, do_exponentiate, (void *) args_q); - - pthread_join(thread1, NULL); - pthread_join(thread2, NULL); - -#else - //compute exponentiation modulo p - mpz_mod(args_p->result, base, p); - mpz_powm(args_p->result, args_p->result, exp_p, p); - - //compute exponentiation modulo q - mpz_mod(args_q->result, base, q); - mpz_powm(args_q->result, args_q->result, exp_q, q); -#endif - - //recombination - mpz_mul(pq, p, q); - mpz_sub(result, args_q->result, args_p->result); - mpz_mul(result, result, p); - mpz_mul(result, result, pinvq); - mpz_add(result, result, args_p->result); - mpz_mod(result, result, pq); - - mpz_clear(pq); - mpz_clear(args_p->result); - mpz_clear(args_p->basis); - mpz_clear(args_p->exponent); - mpz_clear(args_p->modulus); - mpz_clear(args_q->result); - mpz_clear(args_q->basis); - mpz_clear(args_q->exponent); - mpz_clear(args_q->modulus); - free(args_p); - free(args_q); - - return 0; -} diff --git a/paillier/tools.h b/paillier/tools.h deleted file mode 100644 index 8879be3..0000000 --- a/paillier/tools.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @file tools.h - * - * @date Created on: Aug 25, 2012 - * @author Camille Vuillaume - * @copyright Camille Vuillaume, 2012 - * @defgroup Tools Tools for Paillier-GMP - * - * This file is part of Paillier-GMP. - * - * Paillier-GMP is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * - * Paillier-GMP is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Paillier-GMP. If not, see . - * - */ - -#ifndef TOOLS_H_ -#define TOOLS_H_ - -#include -#include - -/** Convert bit length to byte length - * - * @ingroup Tools - */ -#define BIT2BYTE(a) (a+7)>>3 - -#ifdef PAILLIER_DEBUG -/** Print debug message - * - * @ingroup Tools - */ -#define DEBUG_MSG(str) fputs(str, stderr) -#else -#define DEBUG_MSG(str) -#endif - -/** Structure for threaded exponentiation - * - */ -typedef struct { - mpz_t result; /**< result of exponentiation */ - mpz_t basis; /**< basis of exponentiation */ - mpz_t exponent; /**< exponent of exponentiation */ - mpz_t modulus; /**< modulus of exponentiation */ -} exp_args; - -/** Generate a pseudo-random number - * - * @ingroup Tools - * @param[out] rnd output random number, randomness coming from /dev/urandom - * @param[in] len input bit length of the random number to generate - */ -int gen_pseudorandom( - mpz_t rnd, - mp_bitcnt_t len); - -/** Generate a random number - * - * @ingroup Tools - * @param[out] rnd output random number, randomness coming from /dev/random first and then /dev/urandom - * @param[in] len input bit length of the random number to generate - */ -int gen_random( - mpz_t rnd, - mp_bitcnt_t len); - -int gen_random_new(mpz_t rnd, mp_bitcnt_t len); - -/** Generate prime number - * - * @ingroup Tools - * @param[out] prime output prime number, randomness coming from /dev/random - * @param[in] len input bit length of prime number to generate - */ -int gen_prime( - mpz_t prime, - mp_bitcnt_t len); - -/** Exponentiation with Chinese Remainder Theorem - * - * @ingroup Tools - * @param[out] result output exponentiation result - * @param[in] base input basis of the exponentiation - * @param[in] exp_p input exponent for modulo p exponentiation - * @param[in] exp_q input exponent for modulo q exponentiation - * @param[in] pinvq input CRT parameter - * @param[in] p input modulus p - * @param[in] q input modulus q - */ -int crt_exponentiation( - mpz_t result, - mpz_t base, - mpz_t exp_p, - mpz_t exp_q, - mpz_t pinvq, - mpz_t p, - mpz_t q); - - -#endif /* TOOLS_H_ */ diff --git a/seal-part/examples.h b/seal-part/examples.h deleted file mode 100644 index e061f3c..0000000 --- a/seal-part/examples.h +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -#pragma once - -#include "seal/seal.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -/* -Helper function: Prints the name of the example in a fancy banner. -*/ -inline void print_example_banner(std::string title) -{ - if (!title.empty()) - { - std::size_t title_length = title.length(); - std::size_t banner_length = title_length + 2 * 10; - std::string banner_top = "+" + std::string(banner_length - 2, '-') + "+"; - std::string banner_middle = "|" + std::string(9, ' ') + title + std::string(9, ' ') + "|"; - - std::cout << std::endl << banner_top << std::endl << banner_middle << std::endl << banner_top << std::endl; - } -} - -/* -Helper function: Prints the parameters in a SEALContext. -*/ -inline void print_parameters(const seal::SEALContext &context) -{ - auto &context_data = *context.key_context_data(); - - /* - Which scheme are we using? - */ - std::string scheme_name; - switch (context_data.parms().scheme()) - { - case seal::scheme_type::bfv: - scheme_name = "BFV"; - break; - case seal::scheme_type::ckks: - scheme_name = "CKKS"; - break; - case seal::scheme_type::bgv: - scheme_name = "BGV"; - break; - default: - throw std::invalid_argument("unsupported scheme"); - } - std::cout << "/" << std::endl; - std::cout << "| Encryption parameters :" << std::endl; - std::cout << "| scheme: " << scheme_name << std::endl; - std::cout << "| poly_modulus_degree: " << context_data.parms().poly_modulus_degree() << std::endl; - - /* - Print the size of the true (product) coefficient modulus. - */ - std::cout << "| coeff_modulus size: "; - std::cout << context_data.total_coeff_modulus_bit_count() << " ("; - auto coeff_modulus = context_data.parms().coeff_modulus(); - std::size_t coeff_modulus_size = coeff_modulus.size(); - for (std::size_t i = 0; i < coeff_modulus_size - 1; i++) - { - std::cout << coeff_modulus[i].bit_count() << " + "; - } - std::cout << coeff_modulus.back().bit_count(); - std::cout << ") bits" << std::endl; - - /* - For the BFV scheme print the plain_modulus parameter. - */ - if (context_data.parms().scheme() == seal::scheme_type::bfv) - { - std::cout << "| plain_modulus: " << context_data.parms().plain_modulus().value() << std::endl; - } - - std::cout << "\\" << std::endl; -} - -/* -Helper function: Prints the `parms_id' to std::ostream. -*/ -inline std::ostream &operator<<(std::ostream &stream, seal::parms_id_type parms_id) -{ - /* - Save the formatting information for std::cout. - */ - std::ios old_fmt(nullptr); - old_fmt.copyfmt(std::cout); - - stream << std::hex << std::setfill('0') << std::setw(16) << parms_id[0] << " " << std::setw(16) << parms_id[1] - << " " << std::setw(16) << parms_id[2] << " " << std::setw(16) << parms_id[3] << " "; - - /* - Restore the old std::cout formatting. - */ - std::cout.copyfmt(old_fmt); - - return stream; -} - -/* -Helper function: Prints a vector of floating-point values. -*/ -template -inline void print_vector(std::vector vec, std::size_t print_size = 4, int prec = 3) -{ - /* - Save the formatting information for std::cout. - */ - std::ios old_fmt(nullptr); - old_fmt.copyfmt(std::cout); - - std::size_t slot_count = vec.size(); - - std::cout << std::fixed << std::setprecision(prec); - std::cout << std::endl; - if (slot_count <= 2 * print_size) - { - std::cout << " ["; - for (std::size_t i = 0; i < slot_count; i++) - { - std::cout << " " << vec[i] << ((i != slot_count - 1) ? "," : " ]\n"); - } - } - else - { - vec.resize(std::max(vec.size(), 2 * print_size)); - std::cout << " ["; - for (std::size_t i = 0; i < print_size; i++) - { - std::cout << " " << vec[i] << ","; - } - if (vec.size() > 2 * print_size) - { - std::cout << " ...,"; - } - for (std::size_t i = slot_count - print_size; i < slot_count; i++) - { - std::cout << " " << vec[i] << ((i != slot_count - 1) ? "," : " ]\n"); - } - } - std::cout << std::endl; - - /* - Restore the old std::cout formatting. - */ - std::cout.copyfmt(old_fmt); -} - -/* -Helper function: Prints a matrix of values. -*/ -template -inline void print_matrix(std::vector matrix, std::size_t row_size) -{ - /* - We're not going to print every column of the matrix (there are 2048). Instead - print this many slots from beginning and end of the matrix. - */ - std::size_t print_size = 5; - - std::cout << std::endl; - std::cout << " ["; - for (std::size_t i = 0; i < print_size; i++) - { - std::cout << std::setw(3) << std::right << matrix[i] << ","; - } - std::cout << std::setw(3) << " ...,"; - for (std::size_t i = row_size - print_size; i < row_size; i++) - { - std::cout << std::setw(3) << matrix[i] << ((i != row_size - 1) ? "," : " ]\n"); - } - std::cout << " ["; - for (std::size_t i = row_size; i < row_size + print_size; i++) - { - std::cout << std::setw(3) << matrix[i] << ","; - } - std::cout << std::setw(3) << " ...,"; - for (std::size_t i = 2 * row_size - print_size; i < 2 * row_size; i++) - { - std::cout << std::setw(3) << matrix[i] << ((i != 2 * row_size - 1) ? "," : " ]\n"); - } - std::cout << std::endl; -} - -/* -Helper function: Print line number. -*/ -inline void print_line(int line_number) -{ - std::cout << "Line " << std::setw(3) << line_number << " --> "; -} - -/* -Helper function: Convert a value into a hexadecimal string, e.g., uint64_t(17) --> "11". -*/ -inline std::string uint64_to_hex_string(std::uint64_t value) -{ - return seal::util::uint_to_hex_string(&value, std::size_t(1)); -} diff --git a/seal_lsic.cpp b/seal_lsic.cpp deleted file mode 100644 index bfaae88..0000000 --- a/seal_lsic.cpp +++ /dev/null @@ -1,388 +0,0 @@ -#include "seal-part/examples.h" -#include -#include -#include -#include "coding/encoding.h" -#include "coding/decoding.h" -#include "paillier/lsic.h" - -#include "paillier/paillier.h" - -#include "paillier/encrypted_comparing.h" -using namespace std; -using namespace seal; - - -int valueAtBit(int num, int bit) { - - return (num >> (bit -1)) & 1; - -} - -vector seal_lsic(mpz_t a, mpz_t b,int n,int block,int l) -{ - cout<<"------------------------LSIC------------------------"<<"\n"<qualifiers(); - //cout << "Batching enabled: " << boolalpha << qualifiers.using_batching << endl; - - - - /* KeyGenerate */ - KeyGenerator keygen(context); - - SecretKey secret_key = keygen.secret_key(); - - PublicKey public_key; - - RelinKeys relin_keys; - keygen.create_relin_keys(relin_keys); - - keygen.create_public_key(public_key); - - Encryptor encryptor(context, public_key); - - Evaluator evaluator(context); - - Decryptor decryptor(context, secret_key); - - - - - // Data - - - BatchEncoder batch_encoder(context); - size_t slot_count = batch_encoder.slot_count(); - size_t row_size = slot_count / 2; - //cout << "Plaintext matrix row size: " << row_size << endl; - - - int *value_a=testDecoding(a, l, block, n); - int *value_b=testDecoding(b, l, block, n); - int encoding_row=(n+1)/2; - - - vector matrix_a(slot_count, 0ULL); - - for(int i=0; i matrix_b(slot_count, 0ULL); - - for(int i=0; i matrix_a0(slot_count, 0ULL); - for(int i=0; i matrix_b0(slot_count, 0ULL); - for(int i=0; i matrix_one_sub_a0(slot_count, 0ULL); - for(int i=0; i matrix_one(slot_count, 0ULL); - for(int i=0; i matrix_zero(slot_count, 0ULL); - for(int i=0; i pod_result; - batch_encoder.decode(plain_result, pod_result); - //cout << "t:" << endl; - //print_matrix(pod_result, row_size); - - - for(int i=2;i matrix_c(slot_count, 0ULL); - for(int j=0; j matrix_one_sub_c(slot_count, 0ULL); - for(int j=0; j matrix_bi(slot_count, 0ULL); - for(int j=0; j matrix_ai(slot_count, 0ULL); - cout< matrix_one_sub_ai(slot_count, 0ULL); - for(int j=0; j