- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我对密文和最后的正方形进行了一系列计算。问题是,即使有足够的噪声预算来执行平方和重新线性化(在操作之前和之后),当我解密它时,我也会得到不正确的结果。
奇怪的是,如果我解密和解码,然后在新的密文中再次编码和加密,在平方之前的数字,计算是正确执行的。
我不明白问题出在哪里,因为如果设置的参数有误,无论如何我都会得到不正确的结果。
我指定我使用分数编码器,整数部分的多项式系数为 64,小数部分的精度为 32 位(基数为 3),并且我在平方前的所有计算都在密文和明文之间执行。
这是我的意思的一个例子:
#include <vector>
#include "seal/seal.h"
using namespace std;
using namespace seal;
int main(int argc, char const *argv[])
{
//Set parameters
EncryptionParameters parms;
parms.set_poly_modulus("1x^4096 + 1");
parms.set_coeff_modulus(coeff_modulus_128(4096));
parms.set_plain_modulus(1<<20);
SEALContext context(parms);
KeyGenerator keygen(context);
PublicKey public_key = keygen.public_key();
SecretKey secret_key = keygen.secret_key();
EvaluationKeys ev_keys16;
keygen.generate_evaluation_keys(16, ev_keys16);
Encryptor encryptor(context, public_key);
Evaluator evaluator(context);
Decryptor decryptor(context, secret_key);
FractionalEncoder fraencoder(context.plain_modulus(), context.poly_modulus(), 64, 32, 3);
float data=0.5;
float weight= 1.5;
//encrypt data and encode weight
Ciphertext encrypted_data;
encryptor.encrypt(fraencoder.encode(data),encrypted_data);
cout<<"Noise budget in a freshly encrypted: "<<decryptor.invariant_noise_budget(encrypted_data)<<endl;
Plaintext encoded_weight=fraencoder.encode(weight);
//Operation: (0.5*1.5)*5=3.75
vector<Ciphertext> mul_vector(5);
for(int i=0;i<5;i++){
evaluator.multiply_plain(encrypted_data,encoded_weight,mul_vector[i]);
}
evaluator.add_many(mul_vector,encrypted_data);
cout<<"Noise budget after 5 plain multiplications and 4 additions: "<<decryptor.invariant_noise_budget(encrypted_data)<<endl;
//Operation: 3.75*4=15
vector<Ciphertext> add_vector(4);
for(int i=0;i<4;i++){
add_vector[i]= Ciphertext(encrypted_data);
}
evaluator.add_many(add_vector,encrypted_data);
cout<<"Noise budget after 4 additions: "<<decryptor.invariant_noise_budget(encrypted_data)<<endl;
//Operation: (15-1.5)*1.5=20.25
evaluator.sub_plain(encrypted_data,encoded_weight);
evaluator.multiply_plain(encrypted_data,encoded_weight);
cout<<"Noise budget after 1 plain sub and 1 plain multiplication: "<<decryptor.invariant_noise_budget(encrypted_data)<<endl;
//Operation: (20.25*1.5)*6=182.25
vector<Ciphertext> mul_vector2(6);
for(int i=0;i<6;i++){
evaluator.multiply_plain(encrypted_data,encoded_weight,mul_vector2[i]);
}
evaluator.add_many(mul_vector2,encrypted_data);
cout<<"Noise budget after 6 plain multiplications and 5 additions: "<<decryptor.invariant_noise_budget(encrypted_data)<<endl;
// here I decrypt, decode and encrypt again, to obtain the right result
Plaintext tmp;
float res;
//If I remove the following 4 lines the final result is incorrect
decryptor.decrypt(encrypted_data,tmp);
res = fraencoder.decode(tmp);
cout<<"Decrypted result before square: "<<res<<endl;
encryptor.encrypt(fraencoder.encode(res),encrypted_data);
//182.25^2=33215.1
evaluator.square(encrypted_data);
evaluator.relinearize(encrypted_data,ev_keys16);
cout<<"Noise budget after square and relianearization: "<<decryptor.invariant_noise_budget(encrypted_data)<<endl;
decryptor.decrypt(encrypted_data,tmp);
res= fraencoder.decode(tmp);
cout<<res<<endl;
return 0;
}
我错过了什么?
最佳答案
问题是你的 plain_modulus
对于这个计算来说太小了。
如果你打印出tmp
最后(tmp.to_string()
)你会看到它有非常大的系数。请注意,这些系数是模 plain_modulus
所以他们中的许多人预计看起来很大。尽管如此,res
的无穷范数作为一个整数(即,如果您使用足够大的 plain_modulus
)是 266441508,刚好低于 229。由于您的 plain_modulus
只有 220,你最终会得到不正确的结果。您的重新编码有所帮助,因为在最后一次计算之前,系数仍然不太大,并且重新编码多项式会将系数降低回无穷范数 1(在您的情况下,基数 = 3)。
解决方法是增加plain_modulus
到至少 229。当然,这会导致更多的噪音增长,并且您已经非常接近噪音溢出,但它仍然有效。
关于c++ - SEAL:平方运算后解密不正确,即使密文的噪声预算大于零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52059476/
我的 SEAL v2.3.1 中有这些 SEAL 设置: seal::EncryptionParameters parms; parms.set_poly_modulus("1x^2048 + 1")
我有一些使用 Perl 的 Crypt::CBC 加密的密文我希望在其他地方解密的模块。 密文是使用 Crypt::CBC 的“简单”版本生成的。构造函数,即: use Crypt::CBC; $ci
我在使用 CryptoPP 时遇到问题。我正在使用 AES,并且想通过将其编码为 base64 来表示二进制密文。 我的问题是我在运行以下代码时随机出现断言错误: std::string encode
据我所知,RSA 加密的输出将等于 key 模数的长度(在本例中为 128 字节)。我的 RSA 加密代码是: public byte [] RSAEncrypter () throws Except
情况: 我正在尝试从我的谷歌云存储桶中下载和解密一些数据。 对于加密和解密,我使用: https://cloud.google.com/kms/docs/quickstart#decrypt_data
我使用此 openssl 命令创建了一条加密消息: openssl enc -aes-256-cbc -salt -in plaintext.txt -out cipher.enc 我尝试过 Cryp
我正在尝试将 AES 加密的 Java 代码复制到 Golang 中。但是我在 golang 中没有得到相同的输出 我试过下面的代码: Java 代码: package EncryptionTest;
我通过 java 、 BouncyCaSTLe Provider 实现这个使用 block 模式 = ECB 和填充模式 = PKCS7Padding 我注意到,如果我加密32字节长度的数据(例如61
我看过类似的主题,但我找不到与我正在努力实现的目标完全相符的解决方案。 我有一个密文,需要根据每个字母在文本中出现的频率进行简单的字母替换。我已经有一个规范化文本的功能(小写,没有非字母字符,没有,计
我是一名优秀的程序员,十分优秀!