同态加密之SEAL(一)

SEAL学习笔记(一)

SEAL(Simple Encrypted Arithmetic Library)是微软开源的基于C++的同态加密库,支持BFV、CKKS等多种同态加密算法,近期摆烂摆够了ORZ,想学一学。项目地址:SEAL: An easy-to-use and powerful homomorphic encryption library

BFV 同态加密基础

一、准备工作
1.设置参数
  • poly_modulus_degree:多项式模度,为2的幂次,值越大计算越慢,但可支持更复杂的加密运算。推荐值:1024, 2048, 4096, 8192, 16384, 32768。

  • coefficient modulus:(密文)系数模量,大整数,素数之积。其长度为其素因子长度之和。值越大,噪声预算越大,加密计算能力越强,但其上限由poly_modulus_degree决定,关系如下:

    +----------------------------------------------------+
    
    | poly_modulus_degree | max coeff_modulus bit-length |
    
    +---------------------+------------------------------+
    
    | 1024         | 27              |
    
    | 2048         | 54              |
    
    | 4096         | 109              | 36+36+37
    
    | 8192         | 218              |
    
    | 16384        | 438              |
    
    | 32768        | 881              |
    
    +---------------------+------------------------------+
    

    初学者可使用CoeffModulus::BFVDefault(poly_modulus_degree)来确定它的值,它会返回std::vector<Modulus>包含推荐的取值。

parms.set_coeff_modulus(CoeffModulus::BFVDefault(poly_modulus_degree));
  • plaintext modulus: 取值任意,这里取了2的模数。它决定了明文数据的规模以及乘法计算所消耗的噪声预算。因此,可以尽量取小值来保证效率。

    一个新加密的密文的噪声预算为:log_2(\frac{coeff\_modulus}{plain\_modulus})\ bits

    一次同态乘法所消耗的噪声预算为:log_2(plain\_moduls)\ +\ 其他项

    plaintext modulus为BFV独有,CKKS无法设置

2.创建 SEALcontext
SEALContext context(parms)

SEALcontext 对设置的参数进行验证

3.KeyGenerator class生成公私钥
    KeyGenerator keygen(context);
    SecretKey secret_key = keygen.secret_key();
    PublicKey public_key;
    keygen.create_public_key(public_key);
4.生成加密器encryptor、执行器evaluator和解密器decryptor

Encryptor只需公钥

Encryptor encryptor(context, public_key);

Computations on the ciphertexts are performed with the Evaluator class。密文计算由执行器执行,实际使用中,执行器不会由持有私钥的同一方创建

Evaluator evaluator(context);

解密器需要私钥

Decryptor decryptor(context, secret_key);

BFV的明文空间为多项式环Z_{T_{[X]}/(X^N+1)}, 所以明文多项式最高次数比N小1,N为poly_modulus_degree(多项式模度)

二、计算示例

明文元素我们使用一个构造函数,它将所需的多项式作为一个字符串,其系数表示为十六进制数。

uint64_t x = 6;   
Plaintext x_plain(uint64_to_hex_string(x));
# Express x = 6 as a plaintext polynomial 0x6.

#加密未输入公钥
Ciphertext x_encrypted;
encryptor.encrypt(x_plain, x_encrypted);

密文包含两个或者更多的多项式(系数模coefficient modulus),其数目称为”size“ ,可通过Ciphertext::size()函数获得。一个新加密的密文size=2。

cout << "    + size of freshly encrypted x: " << x_encrypted.size() << endl;
cout << "    + noise budget in freshly encrypted x: " << decryptor.invariant_noise_budget(x_encrypted) << " bits"
         << endl;

解密 并输出:

Plaintext x_decrypted;
    cout << "    + decryption of x_encrypted: ";
    decryptor.decrypt(x_encrypted, x_decrypted);
    cout << "0x" << x_decrypted.to_string() << " ...... Correct." << endl;

三、同态乘法的特性和基本函数

  • 最小化最长的连续乘法链,噪声消耗与乘法深度成正比,所以要尽可能减小加密乘法深度。例如,将左式转化为右式计算更高效:

4x^4 + 8x^3 + 8x^2 + 8x + 4 = 4(x + 1)^2 * (x^2 + 1)

左式最大乘法深度为4,右式为2
  • 一次同态乘法所消耗的噪声预算为:log_2(plain\_moduls)\ +\ 其他项

  • 代码:计算x^2 + 1

    evaluator.square(x_encrypted, x_sq_plus_one);

    evaluator.add_plain_inplace(x_sq_plus_one, plain_one);

Ciphertext x_sq_plus_one;
evaluator.square(x_encrypted, x_sq_plus_one);#结果保存在x_sq_plus_one
Plaintext plain_one("1");
evaluator.add_plain_inplace(x_sq_plus_one, plain_one);
  • size为M、N的两密文相乘,结果size为M+N-1

  • 输出损耗

    x_sq_plus_one.size() 3

    decryptor.invariant_noise_budget(x_sq_plus_one) 55-22=33bit

    cout << "    + size of x_sq_plus_one: " << x_sq_plus_one.size() << endl;
        cout << "    + noise budget in x_sq_plus_one: " << decryptor.invariant_noise_budget(x_sq_plus_one) << " bits"
             << endl;
    
  • 计算( x + 1)^2

    Ciphertext x_plus_one_sq;
    evaluator.add_plain(x_encrypted, plain_one, x_plus_one_sq);
    evaluator.square_inplace(x_plus_one_sq); #加了inplace不需新变量保存结果,而是新结果对原变量inplace,即保存在函数第一个参数当中,否则保存在最后一个变量里
    

    加了inplace:不需新变量保存结果,而是新结果对原变量inplace,即保存在函数第一个参数当中;

    不加inplace: 函数最后额外需要输入一个变量,结果保存在最后一个参数里

  • 计算(x^2 + 1) * (x + 1)^2 * 4

    Ciphertext encrypted_result;
    Plaintext plain_four("4");
    evaluator.multiply_plain_inplace(x_sq_plus_one, plain_four);
    evaluator.multiply(x_sq_plus_one, x_plus_one_sq, encrypted_result);
    

四、Relinearization

  • 相乘之后size变M+N-1,需要更多噪声预算

  • Relinearization:每次同态乘法之后,将密文结果size减小到初始值2,但会带来额外的计算开销。BFV和CKKS皆采用。

  • 需要relinearization keys,可以用KeyGenerator生成

  • 代码步骤

    • 生成keys :keygen.create_relin_keys(relin_keys)
    • 重线性化:evaluator.relinearize_inplace(x_squared, relin_keys)
  • 完整代码(计算x^2 + 1)

    Ciphertext x_squared;
    evaluator.square(x_encrypted, x_squared);
    evaluator.relinearize_inplace(x_squared, relin_keys);
    
    evaluator.add_plain(x_squared, plain_one, x_sq_plus_one);
    
    decryptor.decrypt(x_sq_plus_one, decrypted_result);
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,104评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,816评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,697评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,836评论 1 298
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,851评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,441评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,992评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,899评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,457评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,529评论 3 341
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,664评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,346评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,025评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,511评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,611评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,081评论 3 377
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,675评论 2 359

推荐阅读更多精彩内容