java编程实现ElGamal的加密和解密题目实例

2024-09-06 03:12

本文主要是介绍java编程实现ElGamal的加密和解密题目实例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.题目

编程实现ElGamal的加密和解密,假设用户A选择素数p=11和本原根g=2,并且选择私钥α=5,输出A的公钥;若用户B向用户A发送消息m=6,随机数k=7,输出对该消息加密后的密文,以及对密文进行解密的明文。

2.文字版题解

(1)求A的公钥

ElGamal的公钥=(选择的素数(p)、本原根(g)、由p,g,α运算得到的一个数(y))

ElGamal的私钥=选择的私钥(α)

A的公钥,只剩y不知道,则:

y=g*α mod p=2*5 mod 11=10

故A的公钥=(11,2,10)

(2)加密后的密文

公式:

r=g^k mod p

s=m*(y^k) mod p

解释:

(r,s)=加密得到的密文

m:消息发送方发送的消息

k:消息发送方选择的随机数

计算:

r=g^k mod p=2^7 mod 11=7

s=m*(y^k) mod p=6*10^7 mod 11=5

故加密得到的密文=(7,5)

(3)解密的明文

公式:   明文=   

注:括号上的-1是指括号内容mod p的逆元,不会计算题目数值逆元的看后面的教程

计算:

故解密得到的明文是6

附.如何求逆元

定义:对于正整数a和m,如果有ax≡1(mod m),那么把这个同余方程中的x最小正整数解叫做a模x的逆元

解法:

先化简原数:

1.ax≡1(modm)带入题目数值

(7^5)* x  ≡ 1 (mod 11)

2.因为:a*b mod c ≡(a mod c)*(b mod c) mod c

也就是相乘的几个数分别可以替换为‘原数mod被模数’

3.如:10*6 mod 2 ≡5*3 mod 2≡15 mod 2

4.故:

7^5mod11

≡7*7*7*7*7 mod 11

≡49*49*7mod11

≡5*5*7mod11

≡25*7mod11

≡3*7mod11

≡10mod11

化简后转为求10^(-1) mod 11(即10模11的逆元)

即求x:

10* x  ≡ 1 (mod 11)

1.代入法:

把数带入一个个尝试

2.辗转相除法:

举例求7^(-1) mod 25(即7模25的逆元):

即求x:

7* x  ≡ 1 (mod 25)

(1)把要操作的数中大的放前面

这里是(25,7)

(2)大数(25)=小数(7)乘一个尽可能大的数加上余数(>=1)

25=3*7+4

 (3)更新值并重复(2):大数的值是原来的小数(7),小数的值是被减剩余值(4)

7=1*4+3

4=1*3+1

(4)当被减剩余值为1时,停止更新并变换格式

如上述4=1*3+1中被减剩余值为1,变换格式为:1=4-3(省略了1*3中的1)

(5)从下到上(除最后一个)把之前剩余值代表式带入新式子

目的是只剩原始的两个操作数

7=1*4+3得到:剩余值3=7-4 带入 1=4-3 得:1=4-(7-4)=4*2-7

25=3*7+4得到:剩余值4=25-3*7 带入 1=4*2-7 得 1=(25-3*7 )*2-7=25*2-7*7

(6)转换所求原式子格式

7* x  ≡ 1 (mod 25)  转换为 1=7*x-25*b

注:

r≡a mod n可以表示为:a = qn + r,其中0 ≤ r < n,q是整数商

(7)若x为正数,则其为逆元;若x为负数,则x mod p为逆元,p是原式子所模的数

对比(5)(6)结果:

1=25*2-7*7

1=7*x-25*b

可知x=-7

故逆元=(-7)mod 25 =18

求10^(-1) mod 11(即10模11的逆元)

(1)11=10*1+1

(2)1=11-10

(3)逆元:(-1)mod11=10

3.相应代码

注释格式:序号(代码顺序)+注解

(1)求A的公钥

import java.util.Scanner;public class Main {public static void main(String[] args) {//1.输入基本数据Scanner sc = new Scanner(System.in);System.out.println("输入用户A选择的素数:");int p = sc.nextInt();System.out.println("输入用户A的本原根:");int g = sc.nextInt();System.out.println("输入用户A选择的私钥:");int α = sc.nextInt();//4.计算并输出公钥int y=publicKey(p,g,α);}//2.求公钥的方法public static int publicKey(int p,int g,int α){//3.Math.floorMod是用来取模的方法int y=Math.floorMod(g*α,p);System.out.println("公钥是("+p+","+g+","+y+")");return y;}
}

(2)求加密后的密文


//下面代码补充到主函数: //5.输入基本数据System.out.println("输入用户B发送的消息:");int m = sc.nextInt();System.out.println("输入用户B选择的随机数:");int k = sc.nextInt();//6.创建存储密文的变量int r=0,s=0;//9.计算密文并输出r=ciphertext_r(m,k,g,p,y,r);s=ciphertext_s(m,k,g,p,y,s);System.out.println("密文是:("+r+","+s+")");
//上面代码补充到主函数: //下面是新方法://7.求密文并输出的方法,不并作一个方法是需要返回两个变量public static int ciphertext_r(int m,int k,int g,int p,int y,int r) {//8.Math.pow(x, y)是求指数的方法,注意pow返回double,floorMod参数是intr=Math.floorMod((int)Math.pow(g, k),p);return r;}public static int ciphertext_s(int m,int k,int g,int p,int y,int s) {s=Math.floorMod((int)(m*Math.pow(y, k)),p);return s;}

(3)解密明文

//下面代码补充到主函数: //10.创建存储逆元的变量int x=1;//13.求逆元x=opposite(10, p, x);//14.创建存储明文的变量int clear =0;//18.计算明文并输出clear=clearText( s, r, α, p, x);System.out.println("明文是:"+clear);
//上面代码补充到主函数: //下面是新方法//15.求明文的方法public static int clearText(int s,int r,int α,int p,int x) {//16.求逆x=opposite((int)Math.pow(r,α),p,x);//17.返回输出明文return Math.floorMod(s*x,p);}//11.求逆元的方法,代入法public static int opposite(int a,int m,int x) {//12.从x=1开始循环判断是否满足ax≡1(mod m),满足则退出while(true){if(Math.floorMod(a*x,m)==1){break;}x++;}return x;}

4.完整代码

import java.util.Scanner;public class Main {public static void main(String[] args) {//1.输入基本数据Scanner sc = new Scanner(System.in);System.out.println("输入用户A选择的素数:");int p = sc.nextInt();System.out.println("输入用户A的本原根:");int g = sc.nextInt();System.out.println("输入用户A选择的私钥:");int α = sc.nextInt();//4.计算并输出公钥int y=publicKey(p,g,α);//5.输入基本数据System.out.println("输入用户B发送的消息:");int m = sc.nextInt();System.out.println("输入用户B选择的随机数:");int k = sc.nextInt();//6.创建存储密文的变量int r=0,s=0;//9.计算密文并输出r=ciphertext_r(m,k,g,p,y,r);s=ciphertext_s(m,k,g,p,y,s);System.out.println("密文是:("+r+","+s+")");//10.创建存储逆元的变量int x=1;//13.求逆元x=opposite(10, p, x);//14.创建存储明文的变量int clear =0;//18.计算明文并输出clear=clearText( s, r, α, p, x);System.out.println("明文是:"+clear);}//15.求明文的方法public static int clearText(int s,int r,int α,int p,int x) {//16.求逆x=opposite((int)Math.pow(r,α),p,x);//17.返回输出明文return Math.floorMod(s*x,p);}//11.求逆元的方法,代入法public static int opposite(int a,int m,int x) {//12.从x=1开始循环判断是否满足ax≡1(mod m),满足则退出while(true){if(Math.floorMod(a*x,m)==1){break;}x++;}return x;}//7.求密文并输出的方法,不并作一个方法是需要返回两个变量public static int ciphertext_r(int m,int k,int g,int p,int y,int r) {//8.Math.pow(x, y)是求指数的方法,注意pow返回double,floorMod参数是intr=Math.floorMod((int)Math.pow(g, k),p);return r;}public static int ciphertext_s(int m,int k,int g,int p,int y,int s) {s=Math.floorMod((int)(m*Math.pow(y, k)),p);return s;}//2.求公钥的方法public static int publicKey(int p,int g,int α){//3.Math.floorMod是用来取模的方法int y=Math.floorMod(g*α,p);System.out.println("公钥是("+p+","+g+","+y+")");return y;}
}

5.代码解果

这篇关于java编程实现ElGamal的加密和解密题目实例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1140841

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三