实现 RSA 算法之基础公式证明(第一章)(老物)

写这篇日志是拖了很久的事情,以前说要写些算法相关的文章给想学信息安全学(简称信安),密码学的同学提供些入门资料,毕竟这种知识教师上课也不会细讲太多(纯理论偏重),更不用说理解和应用了,说到RSA公钥(yue)算法的认识,我最早是在32个计算机中的重要算法中看到的,不过在后来自己查阅数学建模和算法导论上分别看到了其实现和说明,只可惜对数学部分的解释基本没有,可能这部分数论知识证明出来的意义不大(因为就算你不懂,记住公式也懂用),就算是我在实际应用中也是挑选特殊情况的欧拉函数以及内置特定素数生成来应用。当然,要完整地讲解RSA也有不少东西可以拿出来说的,所以我决定分多几个章节发出来,作为科班出身的我的学习原则,凡事讲究万丈高楼平地而起,永远都是先把理论部分着重讲解后再谈及实现和应用。

目前计划分以下章节进行讲解:

一、RSA 所需的数学理论
二、如何实现应用 RSA 算法
三、如何改进和优化 RSA 算法

第一章节 RSA 所需的数学理论

RSA 是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被 ISO 推荐为公钥数据加密标准。RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。—— from baidu

与之相对的有AES为代表的对称密码算法,我将依次罗列其中应用到的数学理论及公式:

1.素数(质数)
2.互质数
3.指数运算
4.整除运算
5.模运算
6.欧几里得(辗转相除法)
7.欧拉函数与欧拉定理
8.拓展欧几里何求解乘法逆元(模反元素)

以下开始依次讲解:

1.素数(质数)

质数是高中数学基本知识点,定义除了 1 和它本身以外不再被其他的除数整除。

2.互质数

又称互素数。若 N 个整数的最大公因子是 1 ,则称这 N 个整数互质,例如: 4 和 13 就是互质。

3.指数运算

例如 n^m ,其中, n 称为“底数”, m 称为“指数”,可以理解为 n*n*n*n*n*n*n......*n (共m个)。

4.整除运算

a / b 等于不带余数的整数 c ,则b可以整除 a ,记作: b∣a (读作a能被b整除),对任意整数 a,b,b > 0 ,存在唯一的数对 q , r ,使 a = bq + r ,其中 0 ≤ r < b ,这个事实称为带余除法定理,是整除理论的基础。

5.模运算(mod)

指两个整数 a 和 b,若它们除以正整数m所得的余数相等,则称 a 和 b 对于模 m 同余,记作: a ≡ b (mod m);读作: a 同余于 b 模 m ,或者 a 与 b 关于模 m 同余。例如:26 ≡ 14 (mod 12)。

其基本性质
(1)若p|(a-b),则 a ≡ b (% p)。例如 11 ≡ 4 (% 7),18 ≡ 4(% 7)
(2)(a % p)=(b % p)意味 a ≡ b (% p)
(3)对称性:a ≡ b (% p)等价于 b ≡ a (% p)
(4)传递性:若 a ≡ b (% p)且 b ≡ c (% p),则 a ≡ c (% p)

6.欧几里得(辗转相除法)

算法理论描述: 若 c|a ,c|b ,则称 c 是 a 和 b 的公因数。若d是a和b的公因数,d≥0,且d可被a,b的任意公因数(意指下方C代码中GCD(b,a%b)中的a%b)整除,则d是a,b的最大公因数。若a,b的最大公因数等于1,则称a,b互素,也称互质。累次利用带余除法可以求出a,b的最大公因数,这种方法常称为辗转相除法。又称欧几里得算法。
以下给出我的证明:
a可以表示成a = kb + r(a,b,k,r皆为正整数),则r = a mod b,假设d是a,b的一个公约数,记作d|a,d|b,即a和b都可以被d整除。而r = a - kb,两边同时除以d,r/d=a/d-kb/d=m,等式左边可知m为整数,因此d|r,因此d也是(b,a mod b)的公约数,所以(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证(a,b)=(b,a mod b)。
一般来说,没有接触过这个算法的同学可能不好理解,当你尝试去代入数据的时候就可以慢慢接受这个算法的原理了,证明方法有很多种,实在不能理解可以@我来给你洗洗脑。

写成C代码则如下

int GCD(int a, int b)
{
    return b==0 ? a : GCD(b, a%b);
}

在一般的RSA的真实运用中并不会使用该算法,该算法仅仅是用于RSA参数生成模块的封装判断随机两值是否互质.

7.欧拉函数与欧拉定理

一.欧拉函数的证明:

先贴一个百度百科的科普一下:
在数论中,对正整数n,欧拉函数是小于或等于n的正整数中与n互质的数的数目。
此函数以其首名研究者欧拉命名,它又称为φ函数、欧拉商数等。例如,φ(8)=4,因为1,3,5,7均和8互质。
欧拉函数实际上是模n的同余类所构成的乘法群(即环的所有单位元组成的乘法群)的阶。
这个性质与拉格朗日定理一起构成了欧拉定理的证明。
要真正实现数学公式上的欧拉函数难度还真的有点高,首先先理解并证明中国剩余定理(反正我是懵逼了),然后再在代码上实现中国剩余定理对应的数学符号.但是呢,如果不谈证明欧拉函数的数学原理的正确性,仅从该定理上引出的性质,我们可以很轻松的用筛法来通过计算机实现欧拉函数,实现原理同筛法求素数(这个应该不会有人不懂吧)

int eular(int n)
{
    int ret=1, i;
    for(i=2;i*i<=n;i++)
    {
         if(n%i==0)
         {
                n/=i,ret*=i-1;
                while(n%i==0) n/=i, ret*=i;
         }
    }
    if(n>1) ret*=n-1;
    return ret;
}

实现目标: φ函数φ(n)是小于或等于n的正整数中与n互质的数的数目。
但是,在真正应用RSA的场合中,是不需要这个函数的,这个函数同辗转相除法一样,仅仅是为了RSA参数生成模块的封装。
为什么这么说呢?因为欧拉函数有两个特殊性质:
1.如果n是质数,则 φ(n)=n-1。因为质数与小于它的每一个数,都构成互质关系。比如5与1、2、3、4都构成互质关系。
2.如果n可以分解成两个互质的整数之积,n = p1 × p2 则 φ(n) = φ(p1p2) = φ(p1)φ(p2)
所以我们在应用RSA的时候呢,是自己挑选合适的双质数直接应用特殊性质的欧拉函数的,这也将会在后面的代码部分中谈及.

二.欧拉定理的证明

接着我们证明一下数论中的欧拉定理:
在数论中,欧拉定理,(也称费马-欧拉定理)是一个关于同余的性质。
欧拉定理表明,若n,a为正整数,且n,a互质,则: a ^ φ(n) ≡ 1 (mod n)
证明:
首先证明下面这个命题:
对于集合 Zn = {x1,x2,...,xφ(n)} ,考虑集合 S = {a*x1(mod n),a*x2(mod n),...,a*xφ(n)(mod n)}
则设 S = Zn
1) 由于 a,n 互质, xi 也与 n 互质,则 axi 也一定于 n 互质,因此任意 xi , axi(mod n) 必然是 Zn 的一个元素
2) 对于 Zn 中两个元素 xi 和 xj ,如果xi ≠ xj则axi(mod n) ≠ axj(mod n),这个由a、n互质和消去律可以得出。
所以,很明显,S = Zn
既然这样,那么有如下关系,由 S = Zn => S mod n = Zn mod n 展开

S mod n = (ax1 × ax2×...×axφ(n)) mod n
        = (ax1 mod n × ax2 mod n × ... × axφ(n) mod n) mod n
        = (x1 × x2 × ... × xφ(n)) mod n = Zn mod n

考虑上面等式左边和右边
左边等于((a^φ(n) × (x1 × x2 × ... × xφ(n))mod n) mod n
右边等于(x1 × x2 × ... × xφ(n))mod n
而(x1 × x2 × ... × xφ(n))mod n和n互质
根据消去律:可以从等式两边约去,就得到:
a^φ(n) ≡ 1 (mod n)
对于这种依赖定义进行证明的定理,我个人认为还是看最终结论,然后像看待一般的定理一样去运用就好。毕竟不是数学系的我也没法把这些数学的东西说得很彻底很明白,当然对于这个定理我会在之后附上一个证明.

这个定理在RSA中相当重要,它还有一种特例情况被称为费马小定理,
写作: a^(p-1) ≡ 1 (mod p),注:欧拉函数中质数p对应的φ(p) = p-1,故有a^φ(p) ≡ 1 (mod p)
此部分就此告一段落,此部分主要是为了最后一个理论服务

8.拓展欧几里何求解乘法逆元(模反元素)

由于这一部分的重要性我将给出完整的定理正确性证明.
乘法逆元(模反元素)是什么?
如果两个正整数a和n互质,那么一定可以找到整数b,使得 ab-1 被n整除,或者说ab被n除的余数是1。
a * b ≡ 1 (mod n)
此时b就叫做a的乘法逆元(模反元素)
例如:4关于1模7的乘法逆元为多少?
4X≡1 mod 7
这个方程等价于求一个X和K,满足 4X=7K+1,其中X和K都是整数。
ax ≡ 1 mod f ,则称a关于模f的乘法逆元为x。也可表示为ax≡1(mod f)。
当a与f互素时,a关于模f的乘法逆元有解。
如果不互素,则无解。
如果f为素数,则从1到f-1的任意数都与f互素,即在1到f-1之间都恰好有一个关于模f的乘法逆元。
接着根据欧拉定理可以证明模反元素必然存在。
a^φ(p) ≡ 1 (mod p) => a * a^(φ(p)-1) ≡ 1 (mod p),此时 a^(φ(p)-1) 为其乘法逆元
既然知道了乘法逆元是什么,那么如何求解它呢?扩展欧几里何定理究竟是什么呢?
扩展欧几里何用以求解线性同余方程, 对于不完全为 0 的整数 a,b,gcd(a,b)表示 a,b 的最大公约数。那么一定存在整数 x,y 使得 gcd(a,b) = ax+by

求乘法逆元算法原理

当a 与 b 互质时存在: a*x + b*y = gcd(a, b) = 1, 证此时解x为a的乘法逆元
根据整除理论可知: a 可以表示成 a = kb + r(a,b,k,r皆为正整数) ,则 a = r (mod b)
a*x + b*y = gcd(a, b) = 1 可知 a*x = -y*b + 1 => r = 1, k = -y, 即 a*x = 1 (mod b)
根据乘法逆元性质可知 a 与 b 互质时存在乘法逆元解
根据欧几里何定理可知 gcd(a, b) = gcd(b, a % b)
根据取模运算性质可知 a % b = a - (a / b) * b ( % 是 C语言中的取模运算))

a*x + b*y = gcd(a, b)
        = gcd(b, a % b)
        = b*x1 + (a - (a / b)*b)*y1 
        = b*x1 + a*y1 – (a/b)*b*y1
        = a*y1 + b*(x1 – a/b*y1)

其中 x = y1, y = (x1 – a/b*y1) 为递推式的条件(可用以构造递归函数))
基于上述原理进行下述运算

例: 求二元一次不定方程47x+30y=1的x整数解。
    47=30*1+17 ①   
    30=17*1+13 ②
    17=13*1+4  ③
    13=4*3+1   ④
    1=1+0   ⑤
然后把它们改写成“余数等于”的形式
    17=47*1+30*(-1) ① 
    13=30*1+17*(-1) ②
    4=17*1+13*(-1)  ③ 
    1=13*1+4*(-3)   ④
然后把它们“倒回去”
    1=1+0   ⑤
    代入 ④
    1=13*1+4*(-3)   ④
    代入 ③
    1=13*1+[17*1+13*(-1)]*(-3)=13*4+17*(-3) 
    代入 ②
    1=[30*1+17*(-1)]*4+17*(-3)=30*4+17*(-7) 
    代入 ①
    1=30*4+[47*1+30*(-1)]*(-7)=30*11+47*(-7)
得解x=-7, y=11。

注: 欧几里德算法求解同余方程组时的停止的状态是:
当 b=0, gcd(a,b)=a, 那么此时一定有x=1,而 b 的系数可以是 0 或者其他值
这时,我们就会有: a1 + b0 = gcd(a, b) => x=1, y=0
其上算式原理的就是利用最后gcd(a, b) = 1的情况下逆向返回通解

1=1+0
=> 1=13*1+4*(-3) 
=> 1=13*1+[17*1+13*(-1)]*(-3) 
=> 1=13*1+[17*1+[13=30*1+17*(-1)]*(-1)]*(-3) 
=> 1=13*1+[17*1+[13=30*1+[47*1+30*(-1)]*(-1)]*(-1)]*(-3) 
= 47*x + 30*y = 1

化简后得到的结果 x 就是乘法逆元。

// C代码实现拓展欧几里德
int ExtendGCD(int a, int b, int &x, int &y)
{
    //当 b=0,gcd(a,b)=a。此时 x=1,y=0
    if (b == 0)
    {
         x = 1, y = 0;
         return a;
    }
    int result = ExtendGCD(b, a % b, x, y), t = x;
    x = y, y = t - a / b * y;
    return result;
}

关于RSA运用到的数学部分已经全部讲出,如果有同学存在不明白不清楚的可以先自己反复看反复思考,最后带着疑问私聊我或者@我,今天就完成这一章,还有两章代码实现的精华我过几天找找整理一下那些去年的代码,然后分C++和C编程思想两种版本的代码发出来给大家吧
注:代码优化是属于C编程范畴的,讲究完全实现,要付费才可以查看的哦(说笑的) =- =

posted @ 2019-09-13 20:24 Juwan 阅读(...) 评论(...) 编辑 收藏