微软SEAL库的安装与CKKS示例

一、SEAL安装

1、准备工作

下载seal库的zip包并解压:https://github.com/microsoft/SEAL/tree/main

下载seal库

下载并安装VS studio:https://visualstudio.microsoft.com/zh-hans/vs/older-downloads/

下载VS studio
安装vs studio

2、安装seal库

在上一步中我们解压得到了一个名为SEAL-main-4.1.1的文件夹,记住该文件的位置。在这里插入图片描述
我们找到Developer Command Prompt For VS XXXX 终端,并以管理员身份运行,进入后我们先进入SEAL-main-4.1文件夹;
在这里插入图片描述
接着我们依次运行下面三句代码:
(安装时需要链接GitHub下载一些包,可能出现报错,多试几次就好了)

cmake -S . -B build -G "Visual Studio 17 2019" -A x64
 //"Visual Studio 17 2019" 这里的 17, 2019根据自己下载的VS studio版本填写
cmake --build build --config Release
 
cmake --install build

编译运行完成后,在SEAL文件夹下会出现build文件夹,其中有很多文件,同时会安装一个本地库在你的C:\Program Files\SEAL位置下。至此我们的seal库就安装完成了,接下来运行一个实例来使用seal库。

二、CKKS实例

2.1创建项目、配置项目属性

首先打开VS studio,创建一个新项目,按照下面图片提示一步一步操作就行:
在这里插入图片描述
在这里插入图片描述
找到自己的安装目录分别把三个目录的路径复制上去;
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述seal-4.1.lib在上一张图的D:\SEAL-main\build\lib\Release下可以找到,填对应的文件文件名就行。
在这里插入图片描述

2.2 编写代码

我这里编写了一个简单多用户的CKKS示例;首先设置参数,分别生成A用户和B用户的公私钥;接着实例化实例化A和B的加密器、解密器和计算器,其中A用户有两个加密器,encryptor_A用于加密对用户B可解密的密文,所以这里的第二个参数写的是B的公钥,encryptor_A1用于加密A的密文,方便A解密自己的密文;后面就是分别对A和B赋值,调用各自的加密器加密,最后使用B的计算器进行密文的计算,最后使用B的解密器解密出相加后的结果,A使用自己的解密器解密出原始数据。

#include <iostream>
#include <vector>
#include "seal/seal.h"

using namespace std;
using namespace seal;

int main() {
    
    
    // 选定参数
    EncryptionParameters params(scheme_type::ckks);
    size_t poly_modulus_degree = 8192;
    params.set_poly_modulus_degree(poly_modulus_degree);
    params.set_coeff_modulus(CoeffModulus::BFVDefault(poly_modulus_degree));
    double scale = pow(2.0, 40);
    SEALContext context(params);
    
    // 生成 A 用户的密钥
    KeyGenerator keygen_A(context);
    PublicKey public_key_A;
    keygen_A.create_public_key(public_key_A);
    auto secret_key_A = keygen_A.secret_key();
   

    // 生成 B 用户的密钥
    KeyGenerator keygen_B(context);
    PublicKey public_key_B;
    keygen_B.create_public_key(public_key_B);
    auto secret_key_B = keygen_B.secret_key();
    

    // 实例化加密器、解密器和计算器
    Encryptor encryptor_A(context, public_key_B);//这个加密器用于加密对用户B可解密的密文
    Encryptor encryptor_A1(context, public_key_A);//这个加密器用于加密用户A的密文
    Evaluator evaluator_A(context);
    Decryptor decryptor_A(context, secret_key_A);//这个解密器用于解密用户A加密后的密文
    Encryptor encryptor_B(context, public_key_B);
    Decryptor decryptor_B(context, secret_key_B);
    Evaluator evaluator_B(context);

    // 生成 A 用户的数据并加密
    vector<double> vec_A{
    
     1.0};
    CKKSEncoder encoder_A(context);
    size_t slot_count_A = encoder_A.slot_count();
    Plaintext plain_A;
    encoder_A.encode(vec_A, scale, plain_A);
    Ciphertext encrypted_A;
    encryptor_A.encrypt(plain_A, encrypted_A);
    //加密用户A的数据
    Ciphertext encrypted_A1;
    encryptor_A1.encrypt(plain_A, encrypted_A1);

    // 生成 B 用户的数据并加密
    vector<double> vec_B{
    
     9.0 };
    CKKSEncoder encoder_B(context);
    size_t slot_count_B = encoder_B.slot_count();
    Plaintext plain_B;
    encoder_B.encode(vec_B, scale, plain_B);
    Ciphertext encrypted_B;
    encryptor_B.encrypt(plain_B, encrypted_B);

    // 对两个加密数据进行加法
    Ciphertext encrypted_sum;
    evaluator_B.add(encrypted_A, encrypted_B, encrypted_sum);

    // 解密加法结果并解码
    Plaintext plain_sum;
    decryptor_B.decrypt(encrypted_sum, plain_sum);
    vector<double> vec_sum;
    encoder_B.decode(plain_sum, vec_sum);
    cout << "Decrypted result: " << vec_sum[0] << endl;
    //解密用户A的数据
    Plaintext plain_A1;
    decryptor_A.decrypt(encrypted_A1, plain_A1);
    vector<double> vec_A1;
    encoder_A.decode(plain_A1, vec_A1);
    cout << "Decrypted result: " << vec_A1[0] << endl;
    
    return 0;
}

运行结果如下:
在这里插入图片描述

三、感谢

最后感谢CSDN博主兽拳(https://blog.csdn.net/qq_41565526)提供的安装教程给予我莫大的帮助。

猜你喜欢

转载自blog.csdn.net/Lionxiaorw/article/details/130594951
今日推荐