当前位置: 首页 > backend >正文

Paillier加密方案的原理、实现与应用(dev)

一、实验目的

1、掌握NTL的基本配置和方法

2、掌握Paillier加密方案的原理与实现

①钥匙生成:首先,生成一把钥匙,包括钥匙和私钥匙。钥匙由两个大素数(p,q)的乘积n和一个整数g组成,私钥匙由这两个大素数组成。

②加密过程:将明文m加密为密文c。加密时使用峰值n和g,以及一个随机数r。加密计算公式为c = E(m,r) = gmrn mod n2,其中m为明文,r为随机数。

③解密过程:利用私钥中的素数p和q,以及密文c进行解密。解密计算公式为[m = m = D(c,lambda) = (L(clambda mod n2) / L(glambda mod n2)) mod n,其中lambda = text{lcm}(p-1, q-1)),mu是模逆,L(u) = (u-1)/ n.

 二、实验设计

通过网盘分享的文件:WinNTL-11_5_0
链接: https://pan.baidu.com/s/1rkG9reIxSoJcbuyuEDWJGw?pwd=a898 提取码: a898 
--来自百度网盘超级会员v5的分享

  1. 关于NTL的基本配置方法:

①在官网Download NTL (libntl.org)下载NTL的压缩文件,选择11.5.0如下:

②打开dev,创建静态库的新项目,命名为CNTL,如下:

③将NTL文件中的src文件夹下的内容全部添加,过程如下:

④将下载来的include文件夹包含进CNTL如下:

⑤进行编译,自动生成.a的文件

查看项目文件,NTL--->Debug下,存在NTL.lib文件,

⑦生成的CNTL.a文件复制到dev所在文件夹的lib文件夹中,配置完成

  1. 进行检测:

①创建一个常规的项目,命名为test,如下:

WinNTL-11_3_4下include中的test里面找到quicktest,复制其代码放在刚创建好,并按上面配置好环境,如下:

③发现代码运行成功,即检测完成。

  1. Paillier加密方案代码的实现:

Paillier算法加密解密可以自己做,但是由于能力有限,经百度后得到下面的代码:

#include <NTL/ZZ.h>
#include <NTL/ZZ_pXFactoring.h>#include <iostream>
#include <math.h>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
#include <assert.h>using namespace std;
using namespace NTL;class Paillier {
public:/* 构造函数和完全重新开始生成函数 */Paillier();Paillier(const NTL::ZZ& modulus, const NTL::ZZ& lambda);//分别为找到公钥路径和私钥路径./* Paillier加密函数。接收来自*整数模n(Paillier.module)并以*模n**2的整数。* 参数* ==========* NTL::ZZ message :明文作为一个数字进行加密.* NTL:ZZ ciphertext : 加密过后的信息.*/NTL::ZZ encrypt(const NTL::ZZ& message);/* 提供随机生成的加密函数** Random number should be coprime to modulus.**参数* ==========* NTL::ZZ message : 明文,作为一个数字进行加密.* NTL::ZZ random : 随机生成的掩码.* =======* NTL:ZZ ciphertext : 加密过后的密文.*/NTL::ZZ encrypt(const NTL::ZZ& message, const NTL::ZZ& random);/* Paillier解密函数。接收来自Z mod的密文* n**2并在Z mod n中返回一条消息。** 参数* ==========* NTL::ZZ cipertext :需要解密的密文.* =======* NTL::ZZ 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;/*l函数* Parameters* ==========* NTL::ZZ x : l的参量.* NTL::ZZ n : paillier模量.* =======* 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);
};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() {long keyLength = 512;NTL::ZZ p, q;GenPrimePair(p, q, keyLength);modulus = p * q;generator = modulus + 1;NTL::ZZ phi = (p - 1) * (q - 1);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) {NTL::ZZ deMasked = NTL::PowerMod(ciphertext, lambda, modulus * modulus);NTL::ZZ power = L_function(deMasked);return (power * lambdaInverse) % modulus;
}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;  //"随机生成p 为 "cout <<  "q=" <<q<< endl;  //"随机生成q 为”cout << "n=" <<n<< endl;   //"随机生成大素数n 为"cout <<  "lambda=" <<lambda<< endl;  //"生成lamdba为"ZZ c = paillier.encrypt(m, (ZZ)131);cout << "c=" <<c<< endl; //  "密文c 为 "ZZ m2 = paillier.decrypt(c);cout << "m2=" <<m2<< endl;  //"解密得出明文为m2 为"if (m == m2) {cout << "m = m2, encryption and decryption successful" << endl;}system("pause");return 0;
}

③在项目中写入Paillier加密的代码,编译运行实现得到结果。如下:

三、实验记录

1、操作实验结果截屏如下:

其中p,q是随机生成的两个大质数,n=p*q,lambda=(p-1)*(q-1),m是明文,c是密文,

m2是生成的密文后,密文解密后得到的,经程序比对,m2=m,则解密成功

  1. 相关问题:
    在最开始的时候发现一直无法自动生成.a的文件,经百度后发现是dev版本的问题,经调整后,可以生成.a的文件了。

四、实验思考或体会

通过实验,我理解了Paillier算法的原理,并设计了用C++高级程序语言实现Paillier算法的加解密。

首先,设计一个Paillier类将成员类型设置为NTL库里的ZZ大整数类型,以防溢出;

然后对主要的生成素数对p,q,按照加密解密公式c = E(m,r) = gmrn mod n2/m = D(c,lambda) = (L(clambda mod n2) / L(glambda mod n2)) mod n,写出c++程序,对加密和解密等函数进行实现

最后掌握了Paillier算法在C++上的实现。

http://www.xdnf.cn/news/7755.html

相关文章:

  • Cribl 使用Function 的实际例子-02
  • MinerU可视化界面程序部署(Windows环境)
  • HarmonyOS5云服务技术分享--退出登录文档问题
  • Jenkins安装和配置
  • 无人机精准降落与避障模块技术解析
  • ZYNQ Cache一致性问题解析与实战:从原理到创新优化
  • SAGE:基于SAM进行二级蒸馏的多模态图像融合新方法,CVPR2025
  • 测试概念
  • 嵌入式项目之交叉编译m2440篇
  • 基于望获操作系统的具身智能人形机器人典型应用案例
  • CompleteableFuture的异步任务编排
  • python读写bin文件
  • 《算法笔记》11.7小节——动态规划专题->背包问题 问题 C: 货币系统
  • SCAU18923--二叉树的直径
  • NC65联查单据问题总结
  • 宽带卫星通信介绍
  • 今日行情明日机会——20250520
  • 基于双通道频谱分析的振动信号故障诊断1
  • 波峰波谷策略
  • 野火鲁班猫(arrch64架构debian)从零实现用MobileFaceNet算法进行实时人脸识别(三)用yolov5-face算法实现人脸检测
  • 【BIO、NIO、AIO的区别?】
  • 【嵌入式】I2S音频接口3分钟入门
  • 独热编码笔记
  • 字符画生成(伟大的CSDN)
  • windows安装WS,实测可行
  • 2.4.1死锁的概念
  • 中小型制造业信息化战略规划指南
  • SpringBoot 自动配置
  • 【课堂笔记】指数族与广义线性模型(GLMs)
  • zipkin+micrometer实现链路追踪