Paillier同态加密的介绍以及c++实现
我们先来简短认识一下Paillier同态加密算法:

如果就这么按照定义来用最简朴的c++程序写 就像这样:
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include<cmath>
#define MIN 32768 //随机数产生的范围
#define MAX 65536 using namespace std;
int p, q; bool judgeprime(int i) {
int j;
for (j = 2; j <= sqrt(i); j++)
if (i % j == 0)
break;
if (j > sqrt(i))
return true;
} int gcd(int a, int b)///辗转相除法求最大公约数 最朴实的求法
{ int t = a;
while (a % b)
{
a = b;
b = t % b;
t = a;
}
return b;
}
int lcm(int a,int b)
{
return a * b / gcd(a, b);
} void get2prime()
{
srand((unsigned)time(NULL));
while (1)
{
p = MIN + (rand() % (MAX - MIN));
q = MIN + (rand() % (MAX - MIN));
if (gcd(p * q, (p - 1) * (q - 1)) == 1 && judgeprime(p) && judgeprime(q))
break; } }
int N;
int Lfun(int x)
{
int b; b = (x - 1) / N;
return b;
} int main()
{ get2prime();
N = p*q;
cout << "p:" << p << " " << "q:" << q << endl;
int lan;
lan = lcm(p - 1, q - 1);
int g = 0;
int k;
k = Lfun( int (pow(g, lan)) % (N * N));
srand((unsigned)time(NULL));
while (1)
{
g = rand() % (N * N); if (gcd(k, N) == 1)
break; }
cout << "算法公钥为 " << g << " ," << N << endl; }
这个代码当时写错了
当时没有系统学习数论 对于乘法群 生成元 循环群的理解有差错
不过先不影响这个
得...这时间复杂度...
光这个公钥就跑不出来
但是怎么去缩小时间复杂度 至今没有办法
去gayhub找了找别人的代码 这没办法 我真 不知道有NTL这玩意 这个只能自己多敲代码多实践才能发现
原来 c++还有一种便携结构和算法库 叫做NTL
可实现任意长度的整数,向量,矩阵和整系数多项式和有限域上的运算。
在当前平台支持C++11,NTL可以编译线程安全的和异常安全模式
说白了就是一个C++的非标准外部库文件。要使用的的话得自己编译安装。一般利用C++实现某些公钥密码算法会用到,可以提高运算效率。实现全同态密码算法会常用到。
所以对于应用密码学来说 还挺有用的!
#include <iostream>
#include <math.h>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
#include <assert.h> #include "paillier.h" using namespace std;
using namespace NTL; ZZ lcm(ZZ x, ZZ y){
ZZ ans = (x * y) / NTL::GCD(x,y);
return ans;
} int main()
{ ZZ p = ZZ(43);
ZZ q = ZZ(41);
ZZ lambda = lcm(p - 1, q - 1);
Paillier paillier(p*q, lambda); ZZ m = ZZ(10);
ZZ n = p * q; cout << "p = " << p << endl;
cout << "q = " << q << endl;
cout << "n = " << n << endl;
cout << "lamdba = " << lambda << endl; ZZ c = paillier.encrypt(m, (ZZ)131 );
cout << "c = " << c << endl;
ZZ m2 = paillier.decrypt(c);
cout << "m2 = " << m2 << endl; if (m == m2){
cout << "m = m2, encryption and decryption successful" << endl;
} return 0;
}
以下是
paillier.cpp文件
#include "paillier.h"
NTL::ZZ generateCoprimeNumber(const NTL::ZZ& n) {
NTL::ZZ ret;
while (true) {
ret = RandomBnd(n);
if (NTL::GCD(ret, n) == 1) { return ret; }
}
}
Paillier::Paillier() {
/* Length in bits. */
long keyLength = 512;
NTL::ZZ p, q;
GenPrimePair(p, q, keyLength);
modulus = p * q;
generator = modulus + 1;
NTL::ZZ phi = (p - 1) * (q - 1);
// LCM(p, q) = p * q / GCD(p, q);
lambda = phi / NTL::GCD(p - 1, q - 1);
lambdaInverse = NTL::InvMod(lambda, modulus);
}
Paillier::Paillier(const NTL::ZZ& modulus, const NTL::ZZ& lambda) {
this->modulus = modulus;
generator = this->modulus + 1;
this->lambda = lambda;
lambdaInverse = NTL::InvMod(this->lambda, this->modulus);
}
void Paillier::GenPrimePair(NTL::ZZ& p, NTL::ZZ& q,
long keyLength) {
while (true) {
long err = 80;
p = NTL::GenPrime_ZZ(keyLength/2, err);
NTL::ZZ q = NTL::GenPrime_ZZ(keyLength/2, err);
while (p != q) {
q = NTL::GenPrime_ZZ(keyLength/2, err);
}
NTL::ZZ n = p * q;
NTL::ZZ phi = (p - 1) * (q - 1);
if (NTL::GCD(n, phi) == 1) return;
}
}
NTL::ZZ Paillier::encrypt(const NTL::ZZ& message) {
NTL::ZZ random = generateCoprimeNumber(modulus);
NTL::ZZ ciphertext =
NTL::PowerMod(generator, message, modulus * modulus) *
NTL::PowerMod(random, modulus, modulus * modulus);
return ciphertext % (modulus * modulus);
}
NTL::ZZ Paillier::encrypt(const NTL::ZZ& message, const NTL::ZZ& random) {
NTL::ZZ ciphertext =
NTL::PowerMod(generator, message, modulus * modulus) *
NTL::PowerMod(random, modulus, modulus * modulus);
return ciphertext % (modulus * modulus);
}
NTL::ZZ Paillier::decrypt(const NTL::ZZ& ciphertext) {
/* NOTE: NTL::PowerMod will fail if the first input is too large
* (which I assume means larger than modulus).
*/
NTL::ZZ deMasked = NTL::PowerMod(
ciphertext, lambda, modulus * modulus);
NTL::ZZ power = L_function(deMasked);
return (power * lambdaInverse) % modulus;
}
以下是paillier.h文件
#include <NTL/ZZ.h>
#include <NTL/ZZ_pXFactoring.h> class Paillier {
public:
/* Completely generate everything, from scratch */
Paillier();
Paillier(const NTL::ZZ& modulus, const NTL::ZZ& lambda);
//Paillier(path to public key, path to private key). /* Paillier encryption function. Takes in a message from the
* integers modulo n (Paillier.modulus) and returns a message in
* the integers modulo n**2.
*
* Parameters
* ==========
* NTL::ZZ message : The message to encrypt, as a number.
*
* Returns
* =======
* NTL:ZZ ciphertext : The encyrpted message.
*/
NTL::ZZ encrypt(const NTL::ZZ& message); /* Paillier encryption function with provided randomness, if user
* wants to provide their own randomness.
*
* Random number should be coprime to modulus.
*
* Parameters
* ==========
* NTL::ZZ message : The message to encrypt, as a number.
* NTL::ZZ random : The random mask.
*
* Returns
* =======
* NTL:ZZ ciphertext : The encyrpted message.
*/
NTL::ZZ encrypt(const NTL::ZZ& message, const NTL::ZZ& random); /* Paillier decryption function. Takes in a cipertext from Z mod
* n**2 and returns a message in the Z mod n.
*
* Parameters
* ==========
* NTL::ZZ cipertext : The encrypted message.
*
* Returns
* =======
* NTL::ZZ message : The original message.
*/
NTL::ZZ decrypt(const NTL::ZZ& ciphertext); private:
/* modulus = pq, where p and q are primes */
NTL::ZZ modulus;
NTL::ZZ generator;
NTL::ZZ lambda;
NTL::ZZ lambdaInverse; /* The L function in the paillier cryptosystem. See
* <https://en.wikipedia.org/wiki/Paillier_cryptosystem> for more
* details.
*
* Parameters
* ==========
* NTL::ZZ x : The argument to L.
* NTL::ZZ n : The paillier modulus.
*
* Returns
* =======
* NTL::ZZ result : (x - 1) / n
*/
NTL::ZZ L_function(const NTL::ZZ& n) { return (n - 1) / modulus; } void GenPrimePair(NTL::ZZ& p, NTL::ZZ& q, long keyLength);
};
Paillier同态加密的介绍以及c++实现的更多相关文章
- Paillier同态加密实现
一.C++(该方案只实现了加密以及解密) 1.git clone https://github.com/klei0229/paillier.git 2.下载GMP与NTL包: 下载版本以及操作参见ht ...
- 同态加密与 Paillier/RSA
本文作者: wdxtub 本文链接: http://wdxtub.com/flt/flt-03/2020/12/02/ 白话同态加密 虽然同态加密即使现在听起来也很陌生,但是其实这个概念来自 1978 ...
- When I see you again(加密原理介绍,代码实现DES、AES、RSA、Base64、MD5)
关于网络安全的数据加密部分,本来打算总结一篇博客搞定,没想到东西太多,这已是第三篇了,而且这篇写了多次,熬了多次夜,真是again and again.起个名字:数据加密三部曲,前两部链接如下: 整体 ...
- 同态加密-Homomorphic encryption
同态加密(Homomorphic encryption)是一种加密形式,它允许人们对密文进行特定的代数运算得到仍然是加密的结果,将其解密所得到的结果与对明文进行同样的运算结果一样.换言之,这项技术令人 ...
- Rockey 4加密狗介绍
Rockey 4加密狗介绍 特点:该加密狗是单片机加密狗时代飞天公司的主力产品,R4一样继承了R2的硬件特征,具有全球唯一性硬件ID.R4内置了硬件随机数生成器,可以进行一些抗跟踪,或在硬件算法中参与 ...
- 加密原理介绍,代码实现DES、AES、RSA、Base64、MD5
阅读目录 github下载地址 一.DES对称加密 二.AES对称加密 三.RSA非对称加密 四.实际使用 五.关于Padding 关于电脑终端Openssl加密解密命令 关于网络安全的数据加密部分, ...
- 【云安全与同态加密_调研分析(8)】同态加密技术及其应用分析——By Me
◆同态加密技术(Homomorphic Encryption, HE)及其应用◆ ◆加密方案◆ ◆应用领域◆ ◆厂商◆ ◆同态加密现有产品形态和工程实现◆ ◆参考链接◆ ◆备注(其他参考信息)◆ 同态 ...
- ASP原码加密工具介绍
ASP原码加密工具介绍 总是会有非常多方法暴露ASP的原程序.造成数据库的password 路径都能够轻易被其它人搞到,所以对ASP程序实行加密处理是个不错的解决方法.以下来介绍一个工具假设大家感兴趣 ...
- 无线网络(WLAN)常见加密方式介绍
在使用无线路由器配置wifi安全设定的时候经常会遇到各种加密方式,即不懂意思也不知道如何选择.本文将对此做一个简单的介绍. 1.WEP 有线等效协议(Wired Equivalent Privacy, ...
随机推荐
- 【机器学习】梯度下降 II
Gradient Descent 梯度下降 II 关于 Gradient Descent 的直观解释,参考上一篇博客[机器学习]梯度下降 I 本模块介绍几种梯度下降模型.定义符号标记如下: \(\th ...
- 搜索引擎学习(一)初识Lucene
一.Lucene相关基础概念 定义:一个简易的工具包,实现文件搜索的功能,支持中文,关键字,多条件查询,凡是文件名或文件内容包含的都查出来. 数据分类:结构化数据(固定格式或有限长度的数据)和非结构化 ...
- 刷题[CISCN2019 华北赛区 Day2 Web1]Hack World
解题思路 打开发现是很简单的页面,告诉了表名和列名,只需知道字段即可 尝试一下,输入1,2都有内容,后面无内容.输入1'让他报错,发现返回bool(false) 大概思路就是布尔型注入了,通过不断返回 ...
- Hive中的数据类型以及案例实操
@ 目录 基本数据类型 集合数据类型 案例实操 基本数据类型 对于Hive的String类型相当于数据库的varchar类型,该类型是一个可变的字符串,不过它不能声明其中最多能存储多少个字符,理论上它 ...
- 【宝塔面板】centOS部署前后端分离所有遇到的坑,Django
1:刚刚买完服务器,在宝塔面板安装完一切工具,Django顺利运行后(不能运行一般是起了中文名) # 问题:想迁移数据库,结果发现-bash: python3: command not found# ...
- Clover 引导 Windows 及 Linux 双系统
Clover 引导 Windows 及 Linux 双系统UEFI cnblogs @ Orcim 此 文比较详细地介绍了通过修改 Clover 的配置文件,添加 Clover 启动项的方法(添加 ...
- C#入门——Console.Write()与Console.WriteLine()
参考:https://blog.csdn.net/qujunyao/article/details/72884670 两者区别: Console.Write("abc"); 输出到 ...
- Matlab 中 imshow 函数
转自: https://blog.csdn.net/xiaochou87/article/details/43488829 matlab中显示图像的语句是: ...
- 总线SPI的Arduino库函数
来源参考:https://www.cnblogs.com/MyAutomation/p/9348480.html 总线SPI的Arduino库函数 SPI基本知识 SPI:高速同步串行口.是一种标准的 ...
- matlab中fopen 打开文件或获得有关打开文件的信息
参考:https://ww2.mathworks.cn/help/matlab/ref/fopen.html?searchHighlight=fopen&s_tid=doc_srchtitle ...