ElGamal算法的基本原理及实现
时间:2019-09-18
本文章向大家介绍ElGamal算法的基本原理及实现,主要包括ElGamal算法的基本原理及实现使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1、准备步骤
1)取大素数 p 和 g(g < p,g 最好是 p 的素根)
注解:若 a 是素数 p 的一个素根,则 a mod p, a^2 mod p , …, a^p-1 mod p 是 1 到 p - 1 的排列
2)随机选取一整数 x (1 <= x <= (p - 2),(p,g,x) 是私钥)
3)计算 y = g^x (mod p) ( (p,g,y) 是公钥)
2、加密过程
1)随机选取一整数 k (1 <= k <= (p - 2) 且 k 与 (p - 1) 互素)
2)计算 a = g^k mod p,b = m*y^k mod p(m 为要加密的明文)
3)密文 C = (a, b)
3、解密过程
1)m = b * a^(-x) mod p
注解:ba^(-x) mod p Ξ m * y^k * g^(-xk) Ξ m * g^(xk) * g^(-xk) Ξ m
加密及解密的实现:
1 import java.util.ArrayList; 2 3 public class Main { 4 static ArrayList<Integer> suArr = new ArrayList<>(); 5 public static void main(String[] args) { 6 int max = 8096, p, g, x, y, k, a, b; 7 double buff; 8 char[] m = "ABC".toCharArray(); // 加密字符串"ABC" 9 ArrayList<Integer> C = new ArrayList<>(); // 存取加密后的密文 10 int size1; 11 suArr.add(2); 12 13 // 随机取一个小于2048的素数g 14 for (int i = 3; i <= 2048; i++) { 15 if (isSuShu(i)) suArr.add(i); 16 } 17 size1 = suArr.size(); 18 g = getRanNum(size1); 19 20 // 随机取一个大素数p 21 for (int i = 2049; i <= max; i++) { 22 if (isSuShu(i)) suArr.add(i); 23 } 24 p = getRanNum(suArr.size() - size1, size1); 25 26 // x是1~(p-2)中的一个数 27 x = (int)(Math.random() * (p-2) + 1); 28 // k是1~(p-2)中的一个数且k与p-1互素 29 k = (int)(Math.random() * (p-2) + 1); 30 while (isHuZhi(k, p-1) != 1) { 31 k = (int)(Math.random() * (p-2)); 32 } 33 34 // y = g^x mod p 35 y = myPow(g, x, p); 36 37 // a = g^k mod p 38 a = myPow(g, k, p); 39 C.add(a); 40 41 // 加密过程,即计算b = m*y^k mod p (m是明文) 42 for (char c : m) { 43 C.add((int)c*myPow(y, k, p)); 44 } 45 46 buff = myPow(a, x, p); 47 // 将解密后的明文输出 48 for (int i = 1; i < C.size(); i++) { 49 System.out.print((char)(C.get(i) * (1/buff))); 50 } 51 52 } 53 54 // 判断一个数是否为素数 55 public static boolean isSuShu(int num) { 56 int max = (int) Math.sqrt(num); 57 for (int i = 2; i <= max; i++) { 58 if (num % i == 0) 59 return false; 60 } 61 return true; 62 } 63 64 // 在素数数组中随机取一个数 65 public static int getRanNum(int size) { 66 return suArr.get((int) (Math.random() * (size))); 67 } 68 69 // 在素数数组中的(left, arr.size())之间随机取一个数 70 public static int getRanNum(int size, int left) { 71 return suArr.get((int) (Math.random() * (size)) + left); 72 } 73 74 // 判断两个数是否互质 75 public static int isHuZhi(int a, int b) { 76 return b == 0 ? a : isHuZhi(b, a % b); 77 } 78 79 public static int myPow(int a, int b, int m) { 80 int res = 1; 81 a %= m; 82 while (b != 0) { 83 if ((b & 1) == 1) 84 res = (res * a) % m; 85 a = (a * a) % m; 86 b >>= 1; 87 } 88 return res; 89 } 90 91 public static int getSuGen(int p) { 92 boolean isSuGen; 93 for (int g : suArr) { 94 isSuGen = true; 95 for (int i = 1; i < p; i++) { 96 if (myPow(g, i, p) != i) isSuGen = false; 97 } 98 if (isSuGen) return g; 99 } 100 return 2; // 如果在素数数组中找不到p的素根,则返回一个默认值 101 } 102 } 103 104 /* 105 * 参考: 106 * 素根的定义:a是素数p 的一个素根,如果a mod p, a^2 mod p , …, a^p-1 mod p 是1到p-1的排列,称a是P的一个素根 107 * 加密时x和k的选取:https://blog.csdn.net/qq_34490018/article/details/79758620 108 */
原文地址:https://www.cnblogs.com/GjqDream/p/11543367.html
- 3399: [Usaco2009 Mar]Sand Castle城堡
- 遗传算法(1)
- LOJ#6284. 数列分块入门 8
- 3713: [PA2014]Iloczyn
- 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)
- SQL Server 深入解析索引存储(下)
- 2751: [HAOI2012]容易题(easy)
- codevs3002 石子归并 3
- 算法模板——计算几何2(二维凸包——Andrew算法)
- 算法模板——splay区间反转 2
- 算法模板——Dinic网络最大流 2
- 1935: [Shoi2007]Tree 园丁的烦恼
- 1339 / 1163: [Baltic2008]Mafia
- 4010: [HNOI2015]菜肴制作
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- bugzilla安装详解
- sudo和su的用法
- 网站打开缓慢排查思路
- linux下rsync+inotify实时同步
- mysql迁移数据目录
- Problem with the SSL CA cert (path? access rights?)
- Linux笔记(12)| 几种并发式IO的实现方法
- 使用ansible部署DNS主从(ubuntu)
- “一瓶一证”防伪溯源,腾讯安全领御与百年张裕达成战略合作
- ubuntu离线安装python环境
- ubuntu下解决Unment dependencies问题
- 【Vulnhub】Literally Vulnerable
- 内核通信之 Netlink 源码分析和实例分析
- supervisor简单使用
- 干货!Python常用数据类型的基本操作(长文系列第一篇)