A hello world example
在这个hello world示例中,我们将介绍一个简单的用例。
首先,客户机Alice将生成密钥并加密两个数字。
然后,云会做一些同态计算:在这里,它会计算这两个数字中的最小值。
最后,Alice将解密并打印云计算出的答案
这三个步骤中的每一个都将被编码为一个单独的二进制文件,应该在程序之间传输的数据将被保存并加载到文件中。
Alice操作
第一步:生成和保存参数和密钥
要使用这个库,首先需要生成一个密钥和一个云密钥。下面的C示例代码展示了如何做到这一点。密钥(这里是文件secret.key)必须保持私有,而其对应的云密钥(cloud.key)可以安全地发送到云端。
#include <tfhe/tfhe.h>
#include <tfhe/tfhe_io.h>
#include <stdio.h>
int main() {
//generate a keyset
const int minimum_lambda = 110; //安全级别
TFheGateBootstrappingParameterSet* params = new_default_gate_bootstrapping_parameters(minimum_lambda);
//generate a random key
uint32_t seed[] = { 314, 1592, 657 };
tfhe_random_generator_setSeed(seed,3);
TFheGateBootstrappingSecretKeySet* key = new_random_gate_bootstrapping_secret_keyset(params);
//export the secret key to file for later use
FILE* secret_key = fopen("secret.key","wb");
export_tfheGateBootstrappingSecretKeySet_toFile(secret_key, key);
fclose(secret_key);
//export the cloud key to a file (for the cloud)
FILE* cloud_key = fopen("cloud.key","wb");
export_tfheGateBootstrappingCloudKeySet_toFile(cloud_key, &key->cloud);
fclose(cloud_key);
//you can put additional instructions here!!
//...
//clean up all pointers
delete_gate_bootstrapping_secret_keyset(key);
delete_gate_bootstrapping_parameters(params);
}
加密数据,导出密文
密钥的所有者可以加密比特。下面的C代码展示了如何加密16位整数2017和42,并将密文导出到一个文件(这里是cloud.data)。例如,您可以将这段代码放在前一个文件中。
//generate encrypt the 16 bits of 2017
int16_t plaintext1 = 2017;
LweSample* ciphertext1 = new_gate_bootstrapping_ciphertext_array(16, params);
for (int i=0; i<16; i++) {
bootsSymEncrypt(&ciphertext1[i], (plaintext1>>i)&1, key);
}
//generate encrypt the 16 bits of 42
int16_t plaintext2 = 42;
LweSample* ciphertext2 = new_gate_bootstrapping_ciphertext_array(16, params);
for (int i=0; i<16; i++) {
bootsSymEncrypt(&ciphertext2[i], (plaintext2>>i)&1, key);
}
printf("Hi there! Today, I will ask the cloud what is the minimum between %d and %d\n",plaintext1, plaintext2);
//export the 2x16 ciphertexts to a file (for the cloud)
FILE* cloud_data = fopen("cloud.data","wb");
for (int i=0; i<16; i++)
export_gate_bootstrapping_ciphertext_toFile(cloud_data, &ciphertext1[i], params);
for (int i=0; i<16; i++)
export_gate_bootstrapping_ciphertext_toFile(cloud_data, &ciphertext2[i], params);
fclose(cloud_data);
//clean up all pointers
delete_gate_bootstrapping_ciphertext_array(16, ciphertext2);
delete_gate_bootstrapping_ciphertext_array(16, ciphertext1);
云端操作
第二步: 计算电路
云密钥的所有者可以在密文上评估布尔门。最简单的方法是分层构建你的全电路。下面的C代码展示了如何编写一个电路,使其在两个16位整数之间实现最小值
// elementary full comparator gate that is used to compare the i-th bit:
// input: ai and bi the i-th bit of a and b
// lsb_carry: the result of the comparison on the lowest bits
// algo: if (a==b) return lsb_carry else return b
void compare_bit(LweSample* result, const LweSample* a, const LweSample* b, const LweSample* lsb_carry, LweSample* tmp, const TFheGateBootstrappingCloudKeySet* bk) {
bootsXNOR(tmp, a, b, bk);
bootsMUX(result, tmp, lsb_carry, a, bk);
}
// this function compares two multibit words, and puts the max in result
void minimum(LweSample* result, const LweSample* a, const LweSample* b, const int nb_bits, const TFheGateBootstrappingCloudKeySet* bk) {
LweSample* tmps = new_gate_bootstrapping_ciphertext_array(2, bk->params);
//initialize the carry to 0
bootsCONSTANT(&tmps[0], 0, bk);
//run the elementary comparator gate n times
for (int i=0; i<nb_bits; i++) {
compare_bit(&tmps[0], &a[i], &b[i], &tmps[0], &tmps[1], bk);
}
//tmps[0] is the result of the comparaison: 0 if a is larger, 1 if b is larger
//select the max and copy it to the result
for (int i=0; i<nb_bits; i++) {
bootsMUX(&result[i], &tmps[0], &b[i], &a[i], bk);
}
delete_gate_bootstrapping_ciphertext_array(2, tmps);
}
导入密文,进行计算
现在我们有了一个电路,让我们把所有东西都放到一个程序中,首先导入coud密钥和加密的输入数据,调用同态电路,并将结果导出到一个文件中。
int main() {
//reads the cloud key from file
FILE* cloud_key = fopen("cloud.key","rb");
TFheGateBootstrappingCloudKeySet* bk = new_tfheGateBootstrappingCloudKeySet_fromFile(cloud_key);
fclose(cloud_key);
//if necessary, the params are inside the key
const TFheGateBootstrappingParameterSet* params = bk->params;
//read the 2x16 ciphertexts
LweSample* ciphertext1 = new_gate_bootstrapping_ciphertext_array(16, params);
LweSample* ciphertext2 = new_gate_bootstrapping_ciphertext_array(16, params);
//reads the 2x16 ciphertexts from the cloud file
FILE* cloud_data = fopen("cloud.data","rb");
for (int i=0; i<16; i++) import_gate_bootstrapping_ciphertext_fromFile(cloud_data, &ciphertext1[i], params);
for (int i=0; i<16; i++) import_gate_bootstrapping_ciphertext_fromFile(cloud_data, &ciphertext2[i], params);
fclose(cloud_data);
//do some operations on the ciphertexts: here, we will compute the
//minimum of the two
LweSample* result = new_gate_bootstrapping_ciphertext_array(16, params);
minimum(result, ciphertext1, ciphertext2, 16, bk);
//export the 32 ciphertexts to a file (for the cloud)
FILE* answer_data = fopen("answer.data","wb");
for (int i=0; i<16; i++) export_gate_bootstrapping_ciphertext_toFile(answer_data, &result[i], params);
fclose(answer_data);
//clean up all pointers
delete_gate_bootstrapping_ciphertext_array(16, result);
delete_gate_bootstrapping_ciphertext_array(16, ciphertext2);
delete_gate_bootstrapping_ciphertext_array(16, ciphertext1);
delete_gate_bootstrapping_cloud_keyset(bk);
}
第三步:
读取解密最终的结果
最后,密钥的所有者检索、解密并打印最终的答案,如下所示:
int main() {
//reads the cloud key from file
FILE* secret_key = fopen("secret.key","rb");
TFheGateBootstrappingSecretKeySet* key = new_tfheGateBootstrappingSecretKeySet_fromFile(secret_key);
fclose(secret_key);
//if necessary, the params are inside the key
const TFheGateBootstrappingParameterSet* params = key->params;
//read the 16 ciphertexts of the result
LweSample* answer = new_gate_bootstrapping_ciphertext_array(16, params);
//import the 32 ciphertexts from the answer file
FILE* answer_data = fopen("answer.data","rb");
for (int i=0; i<16; i++)
import_gate_bootstrapping_ciphertext_fromFile(answer_data, &answer[i], params);
fclose(answer_data);
//decrypt and rebuild the 16-bit plaintext answer
int16_t int_answer = 0;
for (int i=0; i<16; i++) {
int ai = bootsSymDecrypt(&answer[i], key);
int_answer |= (ai<<i);
}
printf("And the result is: %d\n",int_answer);
printf("I hope you remember what was the question!\n");
//clean up all pointers
delete_gate_bootstrapping_ciphertext_array(16, answer);
delete_gate_bootstrapping_secret_keyset(key);
}