SEAL库的安装(Windows VS2019环境下3.5.9版本SEAL)

SEAL库的安装(Windows VS2019环境下)

笔者的话:关于SEAL的安装,在3.6版本发布后发生了一个重大的转变,自3.6版本开始,SEAL库不再提供Windows的Visual Studio解决方案文件,就是比前几个项目少了个SEAL.sln文件,这意味着,安装新版本的SEAL库就只能使用CMAKE了,老版本的SEAL库依然是可以用SEAL.sln文件来安装的,笔者按照官方文档尝试着按照了一下3.6版本的seal库,但是安装完成后无法正常通过VS调用该库(提示说是有一个关于gsl库的头文件无法正常调用,我尝试安装了完整的gsl库,但是也依然无法使用,猜测可能是SEAL库为该第三方库配置了新的内容文件,导致必须引用SEAL里带有的gsl,但是SEAL里的gsl又由于未知原因无法被编译器正常识别到),网上目前也未能找到VS相关的安装3.6版本SEAL库的说明,因此只能写一篇3.5.9版本的安装方法了。
SEAL库是一个用C++编写的,实现了全同态加密的CKKS方案和BFV方案的全同态加密库,由Microsoft在Github开源。你可以访问: https://github.com/microsoft/SEAL进入SEAL库的开源地址,更深入地了解SEAL库,本文只做简单的介绍。
SEAL库提供了密文的加减乘除等基本运算功能,还有私钥公钥的生成方法,简单而易于使用,同时,它没有其他依赖,你可以轻松地在Windows,Linux、macOS以及最新添加的Android和ios上安装并使用SEAL库。本文会对于SEAL库在Windows环境下,Visual Studio2019上的安装和配置展开详细的讲解。本文中的部分内容引用自SEAL库在github开源地址上提供的官方说明,以及微软在youtube上发布的SEAL库安装视频(从SEAL3.6.0版本开始,SEAL库取消了对于VS的sln支持文件,因此该视频提供的方案只能用于3.5版本及以前的SEAL安装),敬请见谅。
废话不多说了,下面开始正文的讲解:
  1. 首先,SEAL库是一个C++的库,您需要为您的VS安装好C++的编译运行环境,笔者选择安装的是如图的两项内容配置,可供您参考:
    编译器安装需求

  2. 前往SEAL在GitHub的开源地址下载库文件:
    点击左侧master选择以前的版本号:
    在这里插入图片描述

点击右侧绿色的Code按钮,再点击最下方的Download Zip即可。
SEAL下载
3. 下载完成后解压即可。笔者选择了解压到D盘。
需要注意的是,请务必将文件解压到SEAL文件夹下(自己新建一个叫SEAL的文件夹),否则下面的安装过程有可能报错。(我的文件夹里面有个demo文件是新建的一个测试项目,下面会讲到,不用管它没事)
在这里插入图片描述

  1. 进入你解压的文件夹中,打开seal.sln文件,这是vs专有的解决方案文件。
    在这里插入图片描述

  2. 右键SEAL设置SEAL为启动项目
    在这里插入图片描述
    在这里插入图片描述

  3. 设置上方为release和64位模式
    在这里插入图片描述然后点击右侧的绿色三角标志的按钮,运行项目。
    待运行完成,可以在输出中看到seal.lib文件的生成路径:
    D:\SEAL\SEAL-3.5.9\lib\x64\Release\seal.lib
    在这里插入图片描述

  4. 下面开始为项目配置SEAL库,新建一个C++的控制台项目:
    在这里插入图片描述

    右键项目,选择属性 C/C++、常规,添加附加包含目录: 目录为您的SEAL库的native文件夹下的src文件夹
    在这里插入图片描述
    而后选择链接器、常规,添加 附加库目录: 目录地址为您的SEAL文件夹下的lib文件夹,并在末尾加上后缀:

    \$(Platform)\$(Configuration)用来帮助编译器找到之前生成的.lib文件。
    在这里插入图片描述
    最后,在 链接器、输入 的 附加依赖项中添加 seal.lib ,别忘了加分号和其他的库文件名分隔开。

    在这里插入图片描述

  5. 之后,想要在该项目中调用seal库,只需要在程序中加上如下两句即可:

#include"seal/seal.h"
using namespace seal;

这里提供一个BFV方案的加密计算例子供您参考:

#include <cstddef>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <string>
#include <chrono>
#include <random>
#include <thread>
#include <mutex>
#include <memory>
#include <limits>
#include <algorithm>
#include <numeric>
#include "seal/seal.h"
#include <time.h>
#include <math.h>
#include <cstdlib>
#include <ctime>


using namespace std;
using namespace seal;

inline void print_parameters(std::shared_ptr<seal::SEALContext> context)
{
	// Verify parameters
	if (!context)
	{
		throw std::invalid_argument("context is not set");
	}
	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;
	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_mod_count = coeff_modulus.size();
	for (std::size_t i = 0; i < coeff_mod_count - 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;
}
/*计算5*6*8*120+500+300*/
int main()
{
	/* 首先设置加密方案的参数 poly_modulus 、coeff_modulus 、plain_modulus*/
	EncryptionParameters parms(scheme_type::BFV);
	size_t poly_modulus_degree = 4096;
	parms.set_poly_modulus_degree(poly_modulus_degree);
	parms.set_coeff_modulus(CoeffModulus::BFVDefault(poly_modulus_degree));
	parms.set_plain_modulus(1024);
	auto context = SEALContext::Create(parms);//产生context
	print_parameters(context);
	cout << endl;

	//产生密钥、加密、解密、evaluator
	KeyGenerator keygen(context);
	PublicKey public_key = keygen.public_key();
	SecretKey secret_key = keygen.secret_key();
	RelinKeys relin_keys = keygen.relin_keys_local();
	Encryptor encryptor(context, public_key);//加密机 
	Evaluator evaluator(context);// 评估机 
	Decryptor decryptor(context, secret_key);//解密机 
	IntegerEncoder encoder(context);//对整数编码

	//5*6
	int x5 = 5;
	int x6 = 6;
	Plaintext x5_plain;
	Plaintext x6_plain;
	encoder.encode(x5, x5_plain);//将整数编码
	encoder.encode(x6, x6_plain);
	Ciphertext x5_encrypted, x6_encrypted;//密文
	encryptor.encrypt(x5_plain, x5_encrypted);
	encryptor.encrypt(x6_plain, x6_encrypted);//明文加密为密文

	Ciphertext x5x6_encrypted;//5*6的密文结果
	evaluator.multiply(x5_encrypted, x6_encrypted, x5x6_encrypted);//密文5*6保存到x5x6-encrypted中
	evaluator.relinearize_inplace(x5x6_encrypted, relin_keys);
	cout << "Noise budget of x5x6_encrypted:" << decryptor.invariant_noise_budget(x5x6_encrypted) << "bits" << endl;
	//对密文结果再线性化并计算噪音大小

	//8*120
	int x8 = 8, x120 = 120;
	Plaintext x8_plain;
	Plaintext x120_plain;//明文 
	encoder.encode(x8, x8_plain);
	encoder.encode(x120, x120_plain);//转化为明文 
	Ciphertext x8_encrypted, x120_encrypted;//密文
	encryptor.encrypt(x8_plain, x8_encrypted);
	encryptor.encrypt(x120_plain, x120_encrypted);//转化为密文

	Ciphertext x8x120_encrypted;//8*120结果
	evaluator.multiply(x8_encrypted, x120_encrypted, x8x120_encrypted);//8*120
	evaluator.relinearize_inplace(x8x120_encrypted, relin_keys);//再线性化
	cout << "Noise budget of x8x120_encrypted:" << decryptor.invariant_noise_budget(x8x120_encrypted) << "bits" << endl;

	//计算(5*6)*(8*120)
	Ciphertext total_mul;
	evaluator.multiply(x5x6_encrypted, x8x120_encrypted, total_mul);
	evaluator.relinearize_inplace(total_mul, relin_keys);//再线性化
	cout << "Noise budget of total_mul:" << decryptor.invariant_noise_budget(total_mul) << "bits" << endl;

	//计算500+300
	int x500 = 500, x300 = 300;
	Plaintext x500_plain;
	Plaintext x300_plain;
	encoder.encode(x500, x500_plain);
	encoder.encode(x300, x300_plain);
	Ciphertext x500_encrypted, x300_encrypted;
	encryptor.encrypt(x500_plain, x500_encrypted);
	encryptor.encrypt(x300_plain, x300_encrypted);

	Ciphertext total_add;
	evaluator.add(x500_encrypted, x300_encrypted, total_add);//add函数相加

	//计算最终结果
	Ciphertext total;
	evaluator.add(total_mul, total_add, total);

	//解密
	Plaintext result;
	decryptor.decrypt(total, result);
	//运用decode_int32()函数解码
	cout << encoder.decode_int32(result) << endl;
}

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

  • 12
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 48
    评论
评论 48
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值