2020暑假-Crypto

公钥算法的基本数论知识

欧几里得算法 \(\gcd\)

  • \[\gcd(r_0,r_1)=\gcd(r_0-r_1,r_1) \]

  • c++实现
    int gcd(int a,int b) 
    { 
      return b?gcd(b,a%b):a;
    }
    
  • python实现
    def gcd(a,b) :
      while b!=0 :
          if a<b:
              a,b=b,a
          if b==0 : 
              break
          a%=b
      return a
    

扩展欧几里得算法 exgcd

  • 可以用来计算模逆元
  • 除了用来计算\(\gcd(r_0,r_1)\),还能计算以下形式的线性组合

    \[\gcd(r_0,r_1)=s\cdot r_0+t\cdot r_1 \\ 丢番图方程(Diophantine\quad equation) \]

    计算s和t两个系数,执行标准欧几里得算法,但将每轮迭代种的余数\(r_{i}\)表示为以下形式的线性组合:

    \[r_{i}=s_{i}r_0+t_{i}r_1 \]

    如果这个过程成功了,则最后一轮迭代对应的等式为:

    \[r_1=\gcd(r_0,r_1)=s_{l}r_0+t_{l}r_1=sr_0+tr_1 \]

    范例请看《深入浅出密码学——常用加密技术原理与应用》P151
    假设当前迭代对应的索引为i,则前两轮迭代种计算的值为:

    \[r_{i-2}=[s_{i-2}]r_0+[t_{i-2}]r_1\\ r_{i-1}=[s_{i-1}]r_0+[t_{i-1}]r_1 \]

    在当前第i轮迭代种,首先需要从\(r_{i-1}\)\(r_{i-1}\)中计算商\(q_{i-1}\)和新余数\(r_{i}\):

    \[r_{i-2}=q_{i-1}\cdot r_{i-1}+r_{i} \]

    这个等式也可以写成:

    \[r_{i}=r_{i-2}-q_{i-1}\cdot r_{i-1} \]

    用前两个式子替换一下,得到:

    \[r_{i}=(s_{i-1}r_0+t_{i-2}r_1)-q_{i-1}(s_{i-1}r_0+t_{i-1}r_1) \]

    将这些项重新排序,就可得到想要的结果:

    \[r_i=[s_{i-2}-q_{i-1}s_{i-1}]r_0+[t_{i-2}-q_{i-1}t_{i-1}]r_1\\ r_i=[s_i]r_0+[t_i]r_1 \]

    上面的等式直观的给出了计算\(s_i\)\(t_i\)的递归公式即

    \[s_i=s_{i-2}-q_{i-1}s_{i-1}\\ t_i=t_{i-2}-q_{i-1}t_{i-1} \]

    这个递归表达式只对\(i \geqq 2\)的索引值有效,这些初始值为

    \[s_0=1,s_1=0,t_0=0,t_1=1 \]

  • 伪代码
输入:正整数r0,r1,且r0>r1
输出:gcd(r0,r1),以及满足gcd(r0,r1)=s*r0+t*r1的s和t
初始化:s[0]=1,t[0]=0,s[1]=0,t[1]=1,i=1
算法:
do
  i=i+1
  r[0]=r[i-2]mod r[i-1]
  q[i-1]=(r[i-1]-r[i])/r[i-1]
  s[i]=s[i-2]-q[i-1]*s[i-1]
  t[i]=t[i-2]-q[i-1]*t[i-1]
while r[i]!=0
return 
  gcd(r[0],r[1])=r[i-1]
  s=s[i-1]
  t=t[i-1]
  • c++实现
int exgcd(int a, int b, int &x, int &y) {         //x,y初始为任意值,最后变为一组特解
    if(b == 0) {        //对应最终情况,a=gcd(a,b),b=0,此时x=1,y为任意数
        x = 1;
        y = 0;
        return a;
    }
    int r = exgcd(b, a % b, x, y);      //先递归到最终情况,再反推出初始情况
    int t = x; x = y; y = t - a / b * y;
    return r;     //gcd(a,b)
}
  • python实现
def exgcd(a, b, x, y):
  if b==0:
    x=1
    y=0
    returna
  r=exgcd(b,a%b,x,y)
  t=x
  x=y
  y=t-a//b*y
  return r
  • exgcd(EEA)求逆元

    假设我们想计算\(r_1 \bmod r_0\)的逆元,其中\(r_1<r_0\)。只有在\(\gcd(r_0,r_1)=1\)的情况下逆元才存在。因此,使用EEA求逆元

    \[s\cdot r_0+t\cdot r_1=1\\ s\cdot0+t\cdot r_1 \equiv1 \bmod r_0 \\ r_1 \cdot t \equiv 1 \bmod r_0\\ \Rightarrow t=r_1^{-1}\bmod r_0 \]

    因此如果需要计算逆元\(a_1^{-1}\bmod m\),直接输入参数为m和a的EEA即可,计算得到的输出值t即为逆元

  • 计算逆元python

def EX_GCD(a,b,arr): #扩展欧几里得
    if b == 0:
        arr[0] = 1
        arr[1] = 0
        return a
    g = EX_GCD(b, a % b, arr)
    t = arr[0]
    arr[0] = arr[1]
    arr[1] = t - int(a / b) * arr[1]
    return g

def ModReverse(a,n): #ax=1(mod n) 求a模n的乘法逆x
    arr = [0,1,]
    gcd = EX_GCD(a,n,arr)
    if gcd == 1:
        return (arr[0] % n + n) % n
    else:
        return -1

欧拉函数

  • \(\mathbb{Z}_m\)内与\(m\)互素的整数个数可以表示为\(\Phi(m)\)
  • 定理:
    假设m可以因式分解为一下数的连乘

    \[m=P_1^{e_1}\cdot P_2^{e_2} \cdots P_n^{e_n} \]

    则有

    \[\Phi(m)=\prod_{i=1}^N (P_i^{e_i}-P_i^{e_{i-1}}) \]

费马小定理

  • 假定\(a\)为一个整数,\(p\)为一个素数,则:

    \[a^p \equiv a(\bmod \quad p) \]

    也可以表示为一下形式:

    \[a^{p-1} \equiv 1(\bmod p) \]

    对有限域\(GF(p)\)内所有整数元素都成立
  • 计算逆元

    \[a^{p-2} \cdot a \equiv1(\bmod p)\\ \Rightarrow a^{-1}\bmod a^{p-2}(\bmod p) \]

欧拉定理

  • 将费马小定理的模数推广到任何整数模,即可得欧拉定理
  • 假设\(a\)\(m\)都是整数,且\(\gcd(a,m)=1\),则:

    \[a^{\Phi(m)}\equiv1(\bmod m) \]

  • 费马小定理是欧拉定理的特殊形式:

    \[P为素数,\Phi(P)=(P^1-P^0)=P-1\\ \Rightarrow a^{\Phi(P)}=a^{P-1}\equiv1(\bmod P) \]

定义

群G,有时记为$ {G,* } $,是定义了一个二元运算的非空集合,这个二元运算可表示为 \(*\),G中的每一个序偶\((a,b)\)通过运算生成G中的元素\((a*b)\),并满足以下公理:

  • 封闭性:如果a和b都属于G,则\(a*b\)也属于G。
  • 结合律:对于G中任意a,b,c,都有\((a*b)*c=a*(b*c)\)成立。
  • 单位元:G中存在一个元素e,对于G中任意元素a,都有\(a*e=e*a=a\)
  • 逆元: G中都存在一个元素\(a’\),使得下式成立:\(a*a’=a’*a=e\)
    如果一个群的元素是有限的,则该群称为有限群,并且群的阶就等于群中元素的个数。否则,称该群为无限群。
    一个群如果还满足以下条件,则称为交换群:
  • 交换律:对于G中任意的元素a,b,都有\(a*b=b*a\)成立。

(来自段段ppt)

  • 二元运算:设\(s\)为集合,函数\(f:s\times s\rightarrow s\)称为\(s\)上的二元运算或代数运算(用*表示),满足以下性质
    • 可计算性:s中任何元素都可以进行这种运算;
    • 单值性:运算结果唯一;
    • 封闭性:s中任何两个元素运算结果都属于s。

说明:

  • *:通常指加法\((+或\oplus)\)和乘法\((\otimes或\times或\cdot)\)
  • 结合律:\((a*b)*c=a*(b*c)\)
  • 交换律:\(a*b=b*a\)
  • 单位元\(e\)\(a*e=e*a=a\)(加法为0,乘法为1)

  • 群的定义:设\(<G,*>\)是代数系统,*为G上的二元运算:

    • 如果运算*是可结合的->\(<G,*>\)半群;
    • 如果\(<G,*>\)为半群,且运算*存在单位元\(e \in G\)->\(<G,*>\)为幺半群;
    • 如果\(<G,*>\)为幺半群,G中的任何元素元素x都有逆元\(x^{-1}\in G\)->\(<G,*>\)为群,简记为G
  • 说明:

    • 运算*为乘法(加法)时,G叫做乘(加)群;
    • 群G中的元素个数叫做群G的阶,记为$ \left| G\right|$
    • 如果群G中的运算*还满足交换律,那么G叫做一个交换群或者Abel(阿贝尔)群。

image-20200918131849454

image-20200918131924012

RSA

rsa密钥生成与正确性验证

rsa密钥生成

输出: $k_{pub}=(N,e) $ 和私钥:\(k_{pr}=(d)\)

  1. 选择两个大素数 \(p\)\(q\)
  2. 计算 \(N=pq\)
  3. 计算 \(r=\Phi(n)=(p-1)(q-1)\)
  4. 选择满足以下条件的公开指数

\[\\ e\in\{1,2,\ldots,\Phi(n)-1\} \\ \gcd(e,\Phi(n))=1 \]

  1. 计算满足一下条件的私钥 \(d\)

\[d\cdot e\equiv1\bmod\Phi(n) \]

  • 条件\(\gcd(e,\Phi(n))=1\)保证\(e\)的逆元存在模\(\Phi(n)\),因此私钥\(d\)始终存在
  • 使用扩展欧几里得算法(EEA)(acm玩家:exgcd)立刻就可以计算出密钥\(d\)\(e\)
  • 通常在\(0<e<\Phi(n)\)内选择一个公开参数,且\(e\)满足\(\gcd(\Phi(n),e)=1\)
  • \(n\)\(e\)用于EEA中即可得以下关系

\[ \gcd(\Phi(n),e)=s\cdot \Phi(n)+t\cdot e \]

如果\(\gcd(e,\Phi(n))=1\),则\(e\)是一个有效的公钥。此外从这里可以看出,使用扩展欧几里得算法得到的参数t即为e的逆元,因此有

\[d=t \bmod\Phi(n) \]

如果\(e\)\(\Phi(n)\)不是互素的,则课选择一个新的\(e\)值,并重复此过程。

  • 注意,EEA的系数\(s\)对RSA而言不是必须的,因此也可以不计算

以上均参考《深入理解密码学》所写笔记


  • 我发现ctf-wiki上的内容更适合我这样的萌新入门,所以参考暂时转为ctf-wiki的cry板块
  • CTF-Wiki

RSA

基本原理

公钥与私钥的产生

1.随机选择两个不同大质数\(p\)\(q\),计算\(N=p\times q\)

2.根据欧拉函数,求得\(r=\phi(N)=\phi(p)\phi(q)=(p-1)(q-1)\)

3.选择一个小于\(r\)的整数\(e\),使\(e\)\(r\)互质。并求得\(e\)关于\(r\)的模反元素,命名为\(d\),有\(ed\equiv 1(\bmod r)\)

4.将\(p\)\(q\)的记录销毁
此时,\((N,e)\)是公钥,\((N,d)\)是私钥。

消息加密

首先需要将消息\(m\)以一个双方约定好的格式转化为一个小于\(N\),且与\(N\)互质的整数\(n\)。如果消息太长,可以将消息分为几段,这也就是我们所说的块加密,后对于每一部分利用如下公式加密:

\[n^e \equiv c(\bmod N) \]

消息解密

利用密钥\(d\)进行解密。

\[c^d \equiv n(\bmod N) \]

正确性证明

Rsa e attack

小公钥指数攻击

\(e\)特别小,比如\(e\)为3

RSA衍生算法--Rabin算法

  • \(e=2\)

Rsa d attack

Rsa module attack

共模攻击

攻击条件

当两个用户使用相同的模数\(N\)、不同的私钥时,加密同一明文消息时即存在共模攻击。

攻击原理

设两个用户的公钥分别为\(e_1\)\(e_2\),且两者互质。明文消息为\(m\),密文分别为:

\[c_1=m^{e_1}\bmod N \\ c_2=m^{e_2}\bmod N \]

当攻击者截获\(c_1\)\(c_2\)后,就可以恢复出明文。用扩展欧几里得算法求出\(re_1+se_2=1\bmod n\)的两个整数\(r\)\(s\),由此可得

\[\begin{align} c_1^rc_2^s &\equiv m^{re_1}m^{se_2} \bmod n \\&\equiv m^{(re_1+se_2)}\\&\equiv m\bmod n \\ \end{align} \]

模不互素

找公因数


date:9-18

暑假填坑疯狂木大木大木大

posted @ 2020-08-15 23:59  0xDkXy_DWM  阅读(249)  评论(0编辑  收藏  举报