我们先来简短认识一下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++实现某些公钥密码算法会用到,可以提高运算效率。实现全同态密码算法会常用到。

所以对于应用密码学来说 还挺有用的!

 
这个NTL 不是标准库中的 所以要自己装 同时 你找c reference也是找不到注解的
安装教程:https://www.jianshu.com/p/cfe0a8072be7
 
 
然后 看一下代码的实现
以下是主程序main.cpp:
#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++实现的更多相关文章

  1. Paillier同态加密实现

    一.C++(该方案只实现了加密以及解密) 1.git clone https://github.com/klei0229/paillier.git 2.下载GMP与NTL包: 下载版本以及操作参见ht ...

  2. 同态加密与 Paillier/RSA

    本文作者: wdxtub 本文链接: http://wdxtub.com/flt/flt-03/2020/12/02/ 白话同态加密 虽然同态加密即使现在听起来也很陌生,但是其实这个概念来自 1978 ...

  3. When I see you again(加密原理介绍,代码实现DES、AES、RSA、Base64、MD5)

    关于网络安全的数据加密部分,本来打算总结一篇博客搞定,没想到东西太多,这已是第三篇了,而且这篇写了多次,熬了多次夜,真是again and again.起个名字:数据加密三部曲,前两部链接如下: 整体 ...

  4. 同态加密-Homomorphic encryption

    同态加密(Homomorphic encryption)是一种加密形式,它允许人们对密文进行特定的代数运算得到仍然是加密的结果,将其解密所得到的结果与对明文进行同样的运算结果一样.换言之,这项技术令人 ...

  5. Rockey 4加密狗介绍

    Rockey 4加密狗介绍 特点:该加密狗是单片机加密狗时代飞天公司的主力产品,R4一样继承了R2的硬件特征,具有全球唯一性硬件ID.R4内置了硬件随机数生成器,可以进行一些抗跟踪,或在硬件算法中参与 ...

  6. 加密原理介绍,代码实现DES、AES、RSA、Base64、MD5

    阅读目录 github下载地址 一.DES对称加密 二.AES对称加密 三.RSA非对称加密 四.实际使用 五.关于Padding 关于电脑终端Openssl加密解密命令 关于网络安全的数据加密部分, ...

  7. 【云安全与同态加密_调研分析(8)】同态加密技术及其应用分析——By Me

    ◆同态加密技术(Homomorphic Encryption, HE)及其应用◆ ◆加密方案◆ ◆应用领域◆ ◆厂商◆ ◆同态加密现有产品形态和工程实现◆ ◆参考链接◆ ◆备注(其他参考信息)◆ 同态 ...

  8. ASP原码加密工具介绍

    ASP原码加密工具介绍 总是会有非常多方法暴露ASP的原程序.造成数据库的password 路径都能够轻易被其它人搞到,所以对ASP程序实行加密处理是个不错的解决方法.以下来介绍一个工具假设大家感兴趣 ...

  9. 无线网络(WLAN)常见加密方式介绍

    在使用无线路由器配置wifi安全设定的时候经常会遇到各种加密方式,即不懂意思也不知道如何选择.本文将对此做一个简单的介绍. 1.WEP 有线等效协议(Wired Equivalent Privacy, ...

随机推荐

  1. 【深入理解JVM】学习笔记——-1、JVM基本结构

    转载自:https://blog.csdn.net/singit/article/details/54920387?utm_source=blogkpcl11 什么是jvm?JVM的基本结构, 也就是 ...

  2. powershell中使用Send-MailMessage发送邮件

    在powershell中我们可以使用Send-MailMessage发送邮件,一般都是有这个命令的 笔者的总结是鉴于公司的环境的,大家在借鉴时,需要根据自己的实际情况进行修改 1.你笔者测试的格式如下 ...

  3. Kubernetes K8S之Ingress详解与示例

    K8S之Ingress概述与说明,并详解Ingress常用示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2C ...

  4. MyBatis学习(四)代码生成器MyBatis-Generator

    一.简介 前面写过一篇文章介绍了如何使用Mybatis,那么如果我门数据库中有许许多多的表的时候,每张表都手动去写对应的mapper的映射关系,会非常麻烦,那么我们可以使用代码生成器MyBatis-G ...

  5. js计算两个时间相差

    .filter('useTime', function() { return function(val) { // if (/.(.mp4)$/gi.test(url)) { // return JS ...

  6. Redis 作者 Antirez 与 Contributor Mattsta 之间关于 CRC 的 Battle

    大家好,我是 yes. 昨天表弟说有个学妹问他 Redis 为什么要用 CRC16(key) mod 16384 来计算 key 所处槽的位置,我想这 CRC 一般都是用来校验的,通过多项式转换成二进 ...

  7. matlab中repmat函数的用法

    转载:https://blog.csdn.net/facetosea1/article/details/83573859 B = repmat(A,m,n)B = repmat(A,[m n])B = ...

  8. 怀疑安装MySQL之后,导致OrCAD Capture、Allegro就打不开

    记得在异常出现之前,只安装了MySQL,之后OrCAD Capture.Allegro就打不开了. Capture.exe - 系统错误 allegro.exe - 系统错误 我尝试在Cadence的 ...

  9. 刷LeetCode的简易姿势

    近期抽空刷了刷LeetCode,算是补补课. 由于不是很习惯直接在网页上Coding&Debug,所以还是在本地环境下进行编码调试,觉得基本OK后再在网页上提交. 主要采用Python3进行提 ...

  10. 计数,dic的创建方式,求九九乘法表

    s1='char,python,nihao,ni,ni,python's=s1.split(',')print(s1)s2=list()for i in s: if i not in s2: s2.a ...