RSA简介(四)——求逆算法

  此处所谓求逆运算,是指在模乘群里求逆。

  第一节里提到互质的两个定义:

  (1)p,q两整数互质指p,q的最大公约数为1。

  (2)p.q两整数互质指存在整数a,b,使得ap+bq=1。

  只要明白了欧几里得算法,很容易就可以求出两整数的最大公约数,而这是一个小学时候就学习到的算法。这个算法有个可能让我们更熟悉的名字,叫辗转相除法。

  我经常搞不清楚被除数和除数,不知道会不会有人和我一样。所以我要先在这里写明一下,防止混淆,一个除法,除号前的叫被除数,除号后的脚除数。

  单次除法,X=m*Y+n,X为被除数,Y为除数,m为商,n为余数,X和Y的最大公约数等于Y和n的最大公约数。辗转相除法的每一轮除法,求最大公约数都是由求被除数、除数的最大公约数转变为被除数和玉树的最大公约数,最大公约数不变,数变小了。直到余数为0,求得最大公约数就是最一个除法下的除数。

  顺便说一下,整数环具有这种相除法的结构,但不是所有的环都具有此种结构,可以做相除法的环叫欧几里得整环(Euclidean domain),给个其他的例子,比如复系数多项式环、实系数多项式环、整数系数多项式环……跑题了,就此打住。

  

  互质的第二个定义里,如果对于互质的两个正整数p,q,p<q,我再加一个条件,要求0<a<q,那么a和b存在且唯一。这个时候,a就是q的以p为模的模乘逆元了。

  可以用辗转相除法伴随逆元的生成,原理大致如下:

  如果b0、b1开始做辗转相除法,步骤如下:

  b= a0*b+ b2

  b= a1*b+ b3

  b= a2*b+ b4

  ...

  bn-2 = an-2*bn-1 + bn

  bn-1 = an-1*b+ bn+1

  b= an*bn+1

  最后一步余数为0,也就是最大公约数是bn+1,除了最后一个式子其他式子移象,余数写在左边

  (1) b= b- a0*b1

  (2) b= b- a1*b2

  (3) b= b- a2*b3

  ...

  (n-1) bn=bn-2 - an-2*bn-1

  (n) bn+1 = bn-1 - an-1*bn

  我们开始分析, (1)式可以看成是把b2表示为b0和b1的线性组合,

  如果把(1)式带入(2)式,则得到把b3表示为b0和b1的线性组合,姑且称为(2.1),为了方便,把(1)给个一样的表示(1.1),

  把(1.1)和(2.1)带入(3),则得到把b4表示为b0和b1的线性组合,称为(3.1),

  把(2,1)和(3.1)带入(4),则得到把b5表示为b0和b1的线性组合,称为(4.1),

  ...

  直到把bn+1表示为b0和b1的线性组合

  我们这里是求逆元,如果b0和b1互质,那么bn+1应为1。

  bn+1表示为b0和b1的线性组合,b1前的系数就是b1在b0模乘下的逆元了,当然该系数还要除以b0取个余数。

  同样,还是写个bc程序来表示一下这个算法。

  

#!/usr/bin/bc -q
define inv(b0, b1)
{
        m=b0;
        x0 = 1;
        y0 = 0;
        x1 = 0;
        y1 = 1;
        while(1) {
                a = b0/b1;
                b = b0%b1;
                if(b==0) {
                        if(b1==1) {
                                y1 = y1 % m;
                                if(y1<0) {
                                        y1+=m;
                                }
                                return y1;
                        } else {
                                return -1;
                        }
                }
                /*
                tmp <= (x1,y1)
                (x1,y1) <= (x0,y0)-a(x1,y1)
                (x0,y0) <= tmp
                */
                tmpx = x1;
                tmpy = y1;
                x1 = x0-a*x1;
                y1 = y0-a*y1;
                x0 = tmpx;
                y0 = tmpy;

                b0 = b1;
                b1 = b;
        }
}

b0 = read();
b1 = read();
c1 = inv(b0,b1)
print "c1 = ",inv(b0,b1),"\n"
quit

  当然,算法中x0,x1是记录b0的系数,其实对于计算b1的逆元无用,所以可以省略。整个算法的平均时间复杂度为线性。 

  另外,此求逆算法在RSA中的应用不只在于求私钥的指数,也可用于优化模幂算法。

时间: 2024-10-10 01:42:02

RSA简介(四)——求逆算法的相关文章

如何防范算法求逆

假如您不幸遇到对Win32应用环境有足够了解的对手,以至于您的软件最终还是被凶悍的调试器任意蹂躏.但是您还远没有被打败,如果反调试技术(Anti-Debug)作为软件保护的第一道防线已经失守,您的对手只不过是掌握了一大堆汇编代码而已,毕竟代码和算法之间还是有相当距离的,所以您还有第二道防线可守--抗分析.在这道防线里,您有很多办法可以限制破解者掌握您的加密算法,从而阻止注册机或者破解补丁的出现. 一.前言 软件保护的目的是只向合法用户提供完整的功能,所以软件保护必然要包括验证用户合法性的环节,而

归并排序求逆序数(排序算法)

归并排序:归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为二路归并.--(摘自百度百科) 具体操作: 比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1:否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,

算法笔记_065:分治法求逆序对(Java)

目录 1 问题描述 2 解决方案 2.1 蛮力法 2.2 分治法(归并排序)   1 问题描述 给定一个随机数数组,求取这个数组中的逆序对总个数.要求时间效率尽可能高. 那么,何为逆序对? 引用自百度百科: 设 A 为一个有 n 个数字的有序集 (n>1),其中所有数字各不相同. 如果存在正整数 i, j 使得 1 ≤ i < j ≤ n 而且 A[i] > A[j],则 <A[i], A[j]> 这个有序对称为 A 的一个逆序对,也称作逆序数. 例如,数组(3,1,4,5,

论文翻译2:61蒙哥马利模块化逆算法回顾

摘要:我们修改Kaliski给出的算法来计算一个质数的整数模的蒙哥马利逆.我们也给出了一个新的定义介绍了计算经典模逆.Kaliski-Montgomery逆和新的Montgomery逆的高效算法.所提出的算法适用于通用微处理器上的软件实现. 关键词:模算术:模逆:几乎逆:蒙哥马利乘法:密码学 1介绍         模一个素数p的基本算术运算(即加法.乘法和求逆)在密码学中有许多应用,例如RSA算法中的解密运算[9].Diffie-Hellman密钥交换算法[1].美国政府数字签名标准[8]以及

利用归并排序求逆序对

1.归并排序 先回顾一下归并排序 归并排序中归和并的意义: 归:递归.递归的将输入数组进行分割至长度为1. 并:合并.将各长度为1的数组顺序合并,完成归并排序. 归并排序的整体思想为分治,主体算法为: public void mergeSort(int[]arr, intbegin, intend) { if (begin != end) { int mid = (begin + end) /2; mergeSort(arr,begin, mid); mergeSort(arr,mid + 1,

每日一题26:求逆序对数目与求和

求逆序对问题与解决方案原理 在一个数列中,如果规定从小到大为正序,那么如果排在后面的某个元素比前面的某一个元素小,那么就称这两个数构成一个逆序对,例如,数列5,4,3,2,1中,任一个数都与它前面的数构成逆序对,这个序列中一共就有1+2+3+4=10个逆序对,数列23541中有5个逆序对,那么任给定一个数列,如何知道有多少个逆序对呢?简单的方法是将每个元素与它后面的元素比较,然后就可以累加出总的逆序对数目,这种算法的复杂度是O(n^2).另一种比较快的方法是利用归并排序,得到的算法复杂度为O(n

44. 蛤蟆的数据结构笔记之四十四弗洛伊德Floyd算法

44. 蛤蟆的数据结构笔记之四十四弗洛伊德Floyd算法 本篇名言:"希望是厄运的忠实的姐妹. --普希金" 我们继续来看下数据结构图中的一个算法,这个算法来自图灵奖得主. 1.  Floyd算法介绍 Floyd算法又称为插点法,是一种用于寻找给定的加权图中多源点之间最短路径的算法.该算法名称以创始人之一.1978年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名.注意这个可不是心理学的那个弗洛伊德. 是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径

归并排序求逆序对

归并排序求逆序对 by mps [1]什么是逆序对? 对于一个数列需要按从小到大排序,如果有ai,aj且满足ai>aj和i<j则ai,aj为一组逆序对 [2]如何求逆序对? 我们发现,我们可以暴力枚举i,j,然后逐一判断并累加答案即可,时间复杂度O(N2)        但是对于数据量大一点的题目,只有不断地TLE了→_→ [3]归并排序求逆序对 逆序对的定义(见[1])是一组本应该有序的序列中的逆序对,那么我们就想到了排序,但由于是要22匹配,我们又想到了归并排序 归并排序大致内容如下: 将

求逆序数(归并排序)

求逆序数 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 现在,给你一个N个元素的序列,请你判断出它的逆序数是多少. 比如 1 3 2 的逆序数就是1. 输入 第一行输入一个整数T表示测试数据的组数(1<=T<=5) 每组测试数据的每一行是一个整数N表示数列中共有N个元素(2〈=N〈=1000000) 随后的一行共有N个整