Linux下使用SEAL同态加密

SEAL 全称Simple Encrypted Arithmetic Library,是微软研究院提出的一种同态加密算法的实现方案,其最终结果是一个C++库,在程序中调用相关API,完成同态加密的功能。因为毕设要用到相关的内容,所以做了些调研。

0 准备工作

下载链接 http://sealcrypto.codeplex.com/SourceControl/latest
Linux下使用SEAL同态加密_第1张图片

SEAL就是源码。

1 编译

同样还是config、make两兄弟,但是这里还是有很多坑。
因为官网只提供了源码,没有给文档,所以编译还是花了很多功夫。

1.1 configure

下载得到的文件没有直接可用的configure文件和makefile文件。
只有configure.acmakefile.in

所以要先执行autoconfconfigure.ac转换成普通的configure

之后进行 ./configure

1.2 make

SEAL需要gcc4.8的编译器,所以在make之前还需要先安装gcc-4.8

通过apt安装gcc-4.8g++-4.8

sudo apt-get install gcc-4.8 g++-4.8

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 60

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 40

sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.6 60

sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 40

sudo update-alternatives --config gcc

sudo update-alternatives --config g++

之后再进行make

1.3 结果

make之后,就可以看到SEAL的bin目录下,多了一个libseal.a的文件,就算大功告成了。

2 运行实例

编译得到库文件只是第一步,接下来就是使用了。

官方提供了一个SEALExamples的实例代码,可以让我们比较清晰的了解相关的API调用以及最终效果:
这里写图片描述

下载到SEALExample的代码之后,直接make一下就可以了:
这里写图片描述

make之后,会在seal的bin目录下看到一个可执行文件:
这里写图片描述

直接./sealexamples就可以运行了:
Linux下使用SEAL同态加密_第2张图片

3 API分析

看了大概的运行效果,要想集成到自己的系统里面,看API是必不可少的,不过官方一句话的文档都没给,也可能是我没找到?(>_<)

所以就从example里面分析了一下这个库是如何被调用的。

这个example向我们展示了SEAL库比较强大的同态加密运算能力:

  • 整数的取负、求和、求差、求积
  • 浮点数的取负、求和、求差、求积
  • 批量运算

3.1 运行机制

从我自己的分析看,SEAL的运行机制如下:

  • 将数字转换成多项式的形式
  • 在多项式的形式下加密
  • 对密文进行运算
  • 结果进行解密得到明文多项式
  • 将多项式转换成数字的形式

3.2 主要的几个类

因此SEAL库也相应的有如下几个类:

  • Encoder类 把数字和多项式相互转换
  • KeyGenerator类 生成公私钥
  • Encryptor类 加密多项式
  • Evaluator类 在密文多项式上进行运算
  • Decryptor类 解密多项式

3.3 具体分析

/** 初始化加密参数 
 *  选定多项式模数
 *  选定系数模数
 *  选定噪声模数
 * /
EncryptionParameters parms; 
parms.poly_modulus() = "1x^2048 + 1";
parms.coeff_modulus() = ChooserEvaluator::default_parameter_options().at(2048);
parms.plain_modulus() = 1 << 8;

/** 根据加密参数初始化编码器 
 *  将数字编码成多项式
 * /
IntegerEncoder encoder(parms.plain_modulus());
const int value1 = 5;
const int value2 = -7;
BigPoly encoded1 = encoder.encode(value1);
BigPoly encoded2 = encoder.encode(value2);
cout << "Encoded " << value1 << " as polynomial " << encoded1.to_string() << endl;
cout << "Encoded " << value2 << " as polynomial " << encoded2.to_string() << endl;

/** 根据加密参数初始化密钥生成器 
 *  生成公私钥对
 * /
cout << "Generating keys ..." << endl;
KeyGenerator generator(parms);
generator.generate();
cout << "... key generation complete" << endl;
BigPolyArray public_key = generator.public_key();
BigPoly secret_key = generator.secret_key();

/** 根据加密参数初始化加密器 
 *  将多项式加密
 * /
cout << "Encrypting values..." << endl;
Encryptor encryptor(parms, public_key);
BigPolyArray encrypted1 = encryptor.encrypt(encoded1);
BigPolyArray encrypted2 = encryptor.encrypt(encoded2);

/** 根据加密参数初始化运算器 
 *  在密文多项式上进行运算
 *  取负 - nagate
 *  求和 - add
 *  求差 - sub
 *  求积 - mutiply
 * /
cout << "Performing arithmetic on ecrypted numbers ..." << endl;
Evaluator evaluator(parms);
cout << "Performing homomorphic negation ..." << endl;
BigPolyArray encryptednegated1 = evaluator.negate(encrypted1);
cout << "Performing homomorphic addition ..." << endl;
BigPolyArray encryptedsum = evaluator.add(encrypted1, encrypted2);
cout << "Performing homomorphic subtraction ..." << endl;
BigPolyArray encrypteddiff = evaluator.sub(encrypted1, encrypted2);
cout << "Performing homomorphic multiplication ..." << endl;
BigPolyArray encryptedproduct = evaluator.multiply(encrypted1, encrypted2);

/** 根据加密参数和私钥初始化解密器 
 *  将运算后的密文多项式解密成明文多项式
 * /
cout << "Decrypting results ..." << endl;
Decryptor decryptor(parms, secret_key);
BigPoly decrypted1 = decryptor.decrypt(encrypted1);
BigPoly decrypted2 = decryptor.decrypt(encrypted2);
BigPoly decryptednegated1 = decryptor.decrypt(encryptednegated1);
BigPoly decryptedsum = decryptor.decrypt(encryptedsum);
BigPoly decrypteddiff = decryptor.decrypt(encrypteddiff);
BigPoly decryptedproduct = decryptor.decrypt(encryptedproduct);

/** 调用之前生成的编码器解码 
 *  将明文多项式结果解码成数字
 * /
int decoded1 = encoder.decode_int32(decrypted1);
int decoded2 = encoder.decode_int32(decrypted2);
int decodednegated1 = encoder.decode_int32(decryptednegated1);
int decodedsum = encoder.decode_int32(decryptedsum);
int decodeddiff = encoder.decode_int32(decrypteddiff);
int decodedproduct = encoder.decode_int32(decryptedproduct);

你可能感兴趣的:(密码学)