目录
一、前言
在公钥加密体系中,除了基于大整数分解问题的RSA加密体制,另一类重要的加密体制是基于离散对数的难解性,如ECC椭圆曲线加密、Diffie-Hellman算法、ElGamal算法等。为了解决离散对数问题,本文首先介绍一些近世代数的基本知识,之后介绍几类基于离散对数的加密体制,最后列出几道CTF中的相关赛题。
二、代数基本知识
2.1群
2.1.1定义
设G是非空集合,若在G内定义一种代数运算⨀,且满足下列4个条件,则称G(对运算⨀)构成一个群:
- 封闭性:对任意的 a , b a,b a,b ∈ \in ∈ G G G,恒有 a ⨀ b a⨀b a⨀b ∈ \in ∈ G G G;
- 结合律:对任意的 a , b , c a,b,c a,b,c ∈ \in ∈ G G G,恒有 ( a ⨀ b ) ⨀ c = a ⨀ ( b ⨀ c ) (a⨀b)⨀c = a⨀(b⨀c) (a⨀b)⨀c=a⨀(b⨀c)
- 有单位元:存在 e e e ∈ \in ∈ G G G,对任意的 a a a ∈ \in ∈ G G G,有 a ⨀ e = e ⨀ a = a a⨀e=e⨀a=a a⨀e=e⨀a=a
- 每个元存在逆元:对任意 a a a ∈ \in ∈ G G G,存在 b b b ∈ \in ∈ G G G,使得 a ⨀ b = b ⨀ a = e a⨀b=b⨀a=e a⨀b=b⨀a=e,称 b b b 为 a a a 的逆元。
其中运算
⨀
⨀
⨀可以是通常的乘法或者是加法。若
⨀
⨀
⨀为乘法,则称
G
G
G为乘法群,单位元记为
1
1
1。若
⨀
⨀
⨀为加法,则称
G
G
G为加法群,单位元记为
0
0
0。
一般情况下,记:
a
⨀
a
⨀
…
⨀
a
⏟
k
个
\underbrace{a⨀a⨀…⨀a}_{k个}
k个
a⨀a⨀…⨀a=
a
a
ak
群 G G G所含元素的个数,称为该群的阶。 若群 G G G含有有限个元素,则称 G G G为有限群,否则,为无限群。
若对群 G G G中任何 a , b a,b a,b ∈ \in ∈ G G G,有 a ⨀ b = b ⨀ a a⨀b = b⨀a a⨀b=b⨀a,则称 G G G为交换群或 A b e l Abel Abel群。
2.1.2循环群
定义:设 ( G , ⋅ ) (G,· ) (G,⋅)是一个群,如果群 G G G中存在一个元素 α \alpha α,使得对群 G G G任意元素 b b b都存在一个整数 i i i,使得 b = b= b= a a ai则我们称 G G G是一个循环群。元素 α \alpha α是 G G G的一个生成元。
2.1.3加法循环群
整数的加法群是一个无限循环群,它由1生成。在这种情况下,幂被解释为用加法合成的,因此 n n n是1的n次幂。
例:(Z6, ⨁ \bigoplus ⨁)是循环群,其中Z6={0,1,2,3,4,5}, ⨁ \bigoplus ⨁为模6加法,其中生成元为1或5。
生成元的含义可以理解为:1或5的加法,可以实现群Z6内所有的元素。
5 mod 6 = 5,35 mod 6 = 5
10 mod 6 = 4,40 mod 6 = 4,
15 mod 6 = 3,45 mod 6 = 3
20 mod 6 = 2,50 mod 6 = 2
25 mod 6 = 1,55 mod 6= 1
30 mod 6 = 0,60 mod 6= 0
所以通过生成元5的模6加法,可以得到群内的所有元素,实现循环群。而2,3,4不能作为生成元,是因为这些元素的模6加法并不能得到群内的所有元素,而且并不是连续循环的数。
乘法循环群也是同样的道理。
有限循环群的生成元还具有以下性质:
(元素的阶):循环群
(
G
,
⋅
)
(G,·)
(G,⋅),
α
\alpha
α为
G
G
G的一个生成元,
1
1
1为
G
G
G的单位元,
G
G
G的阶为
n
n
n,则:
a
a
an
=
1
=1
=1
2.2环
2.2.1定义
若集合 R R R上定义了两种二元运算: + + +(加法)和x(乘法),且满足下列四个条件,则称 R R R 对这两种运算构成了一个环,记为 ( R , + , x ) (R,+,x) (R,+,x):
- ( R , + ) (R,+) (R,+)是一个Abel群, R R R关于加法是一个交换群,其恒等元为零元,用 0 0 0表示。
- 乘法的封闭性:如果 a a a和 b b b都属于 R R R,则 a b ab ab也属于 R R R。
- 乘法的结合律:对于 R R R中的任意元素 a 、 b 、 c a、b、c a、b、c,有 a ( b e ) = ( a b ) c a(be) =(ab)c a(be)=(ab)c成立。
- 分配律:对于 R R R中的任意元素 a 、 b 、 c a、b、c a、b、c,下面两个式子总成立: a ( b + c ) = a b + a c a(b+c) = ab+ ac a(b+c)=ab+ac; ( a + b ) c = a c + b e (a+b)c=ac+be (a+b)c=ac+be
本质上说,环就是一个集合,我们可以在其上进行加法、减法 [ a − b = a + ( − b ) ] [a - b = a + ( - b ) ] [a−b=a+(−b)]和乘法而不脱离该集合。
例:实数上所有n阶方阵的集合关于加法和乘法构成一个环。
2.2.2交换环
定义:环如果还满足乘法的交换律,即对于 R R R中任意元素 a 、 b a、b a、b,有 a b = b a ab=ba ab=ba成立,则被称为是交换环
例:偶整数集合(包括正数、负数和0)记为 S S S,在普通加法和乘法运算下是交换环;实数上所有n阶方阵的集合关于加法和乘法则不构成一个交换环。
2.2.3整环
定义:整环是满足以下公理的交换环:
- 乘法单位元:在 R R R中存在元素 1 1 1,使得对于 R R R中的任意元素 a a a,有 a 1 = 1 a = a a 1 = 1 a = a a1=1a=a成立。
- 无零因子:如果有 R R R中元素 a 、 b a、b a、b,且 a b = 0 ab= 0 ab=0,则必有 $a = 0 $或 b = 0 b = 0 b=0。
例:普通加法和乘法运算下的整数集合(包括正数、负数和0)是一个整环。
2.3域
定义:设 F F F是一个交换环,若 F F F中的所有的非零元素对乘法都存在逆元,则 F F F称为一个域。如果一个域所包含的元素是有限的则称此域是有限域,否则称为无限域。有限域中所含元素的个数称为有限域 ( R , + , x ) (R,+,x) (R,+,x)的阶。
本质上说,域就是一个集合,我们可以在其上进行加法、减法、乘法和除法而不脱离该集合。
除法又按以下规则来定义:
a
/
b
=
a
(
a/b=a(
a/b=a(
b
b
b-1
)
)
)。
例:有理数集合、实数集合以及复数集合都是域。而所有整数的集合并不是一个域,因为并不是集合中所有的元素都有乘法逆元;实际上,整数集合中只有元素 1 1 1和 − 1 -1 −1有乘法逆元。
群、环、域的公理总结:
2.4有限域
定义1: 有限域又常称为 G a l o i s Galois Galois域,并以 G F ( q ) GF(q) GF(q)或 F q F~q~ F q 表示,其中 q q q表示有限域的阶。
定义2: 设 F 1 、 F 2 F~1~、F~2~ F 1 、F 2 是两个域,称 F 1 F~1~ F 1 到 F 2 F~2~ F 2 的一个可逆映射 σ \sigma σ为一个同构(映射),如果 σ \sigma σ是保持运算的映射,即对任意的 a , b a,b a,b ∈ \in ∈ F 1 F~1~ F 1 ,有: σ \sigma σ(a + b) = σ \sigma σ(a) + σ \sigma σ(b), σ \sigma σ(a · b)= σ \sigma σ(a) · σ \sigma σ(b)
定理3: 设 F F F是有限域,则有:
- 在同构的意义下,阶与 F F F相同的有限域只有一个,同阶的有限域必同构
- 有限域 F F F的阶必为某个素数的幂
- 设 F F F的阶为 q = p q = p q=pn , p p p是一个素数,则 F F F的任何一个子域的阶为 p p pm,其中 m m m是 n n n的因子
- F F Fq* 为有限域 F F Fq的所有非零元构成的集合,则 F F Fq*关于乘法做成一个阶为 q − 1 q-1 q−1的循环群。因此,对所有的 a a a ∈ \in ∈ F F Fq,有 a a aq = a =a =a 。这个群称为 F F Fq的乘法群,乘法群 F F Fq* 的生成元称为 F F Fq的本原元,共有 ϕ \phi ϕ ( q − 1 ) (q-1) (q−1)个本原元。
- 设 F F Fq(其中 q = p q=p q=pn)是一个有限域,则对任何 a , b a,b a,b ∈ \in ∈ F F Fq以及非负整数 K K K ≥ \geq ≥ 0 0 0,有: ( a + b ) (a+b) (a+b)pk = = = a a apk b b bpk
2.5多项式环
定义: 设 F F F是一个域,多项式f(x)=anxn+···+a1x+a0,其中 a i a_i ai ∈ \in ∈ F F F, n n n ∈ \in ∈ N N N。
若 a n ≠ 0 a_n\not=0 an=0,称 n n n为该多项式的次数,称为首项系数。
对于域 F F F上 x x x的多项式的全体组成的集合记为 F [ x ] F[x] F[x]。多项式 a ( x ) a(x) a(x) 的次数记为 d e g ( a ( x ) ) deg(a(x)) deg(a(x))
设存在多项式 f ( x ) f(x) f(x)与 g ( x ) g(x) g(x),满足:
- 加法运算: f ( x ) + g ( x ) f(x)+g(x) f(x)+g(x) ∈ \in ∈ F [ x ] F[x] F[x]
- 乘法运算: f ( x ) ⋅ g ( x ) f(x)·g(x) f(x)⋅g(x) ∈ \in ∈ F [ x ] F[x] F[x]
容易验证 F [ x ] F[x] F[x]对这样定义的多项式加法与乘法构成一个交换环,称为多项式交换环。
不可约多项式: 设 f ( x ) f(x) f(x)是 F [ x ] F[x] F[x]上的一个次数大于零的多项式,如果它不能分解成两个低次数的多项式的乘积,则称 f [ x ] f[x] f[x]是 F F F上的不可约多项式。
三、加密算法
3.1. Z p Z~p~ Z p 上的离散对数问题
Z p Z~p~ Z p 上的离散对数问题是指对于循环群 Z p Z~p~ Z p (p是一个素数), α \alpha α是群 Z p Z~p~ Z p 的生成元,对于任意的 c c c ∈ \in ∈ Z p Z~p~ Z p 寻找唯一 的整数 d d d ( 0 (0 (0 ≤ \leq ≤ d d d ≤ \leq ≤ p − 1 ) p-1) p−1)满足: C ≡ a d ( m o d p ) C≡a^d(modp) C≡ad(modp)
我们把整数 d d d记为 l o g log logα c c c,并称之为离散对数。
3.2ElGamal算法
背景: ElGamal是建立在解有限乘法群上的离散对数问题的困难性基础上的一种公钥密码体制。
算法描述:
- 公开参数:取大素数 p p p,并取 α \alpha α是乘法群 Z p Z~p~ Z p * { 1 , … , p − 1 1,…,p-1 1,…,p−1 }的一个生成元。
- 密钥生成:随机选取整数 d : 0 < d < ( p − 1 ) d:0 < d < ( p - 1) d:0<d<(p−1)并计算 β \beta β= α \alpha αd m o d p mod p modp。其中公开参数: p p p和 α \alpha α ;公钥: β \beta β;私钥: d d d
- 加密运算:对于明文 m m m,选取随机整数 k : 0 < k < ( p − 1 ) k:0<k<(p-1) k:0<k<(p−1),计算: c 1 = c_1= c1= α \alpha αk m o d p mod p modp, c 2 = m c_2=m c2=m β \beta βk m o d p mod p modp,得到密文 c = ( c 1 , c 2 ) c=(c_1,c_2) c=(c1,c2)。
- 解密运算:对于密文 c = ( c 1 , c 2 ) c=(c_1,c_2) c=(c1,c2),用私钥 d d d解密。 m = c 2 m=c_2 m=c2 ( c 1 (c_1 (c1d ) ) )-1 m o d p mod p modp
计算离散对数的算法:
- Shanks算法
- 小步大步发(baby-step 、giant-step)算法
- Pohlig-Hellman算法
- 指数演算法(index-calculus)
3.3Diffie-Hellman算法
背景: Diffie-Hellman算法由Whitfield Diffie 和 Martin Hellman 提出,该算法的安全性也是基于一般有限域上的离散对数问题的难解性。该算法的目的是使两个用户能安全地交换密钥,以便在后续的通信中用该密钥对消息加密。该算法本身只限于进行密钥交换。
算法描述:
3.4椭圆曲线密码
四、相关赛题
4.1
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from Crypto.Util.number import *
import random
n = 2 ** 512
m = random.randint(2, n-1) | 1
c = pow(m, bytes_to_long(flag), n)
print 'm = ' + str(m)
print 'c = ' + str(c)
# m = 391190709124527428959489662565274039318305952172936859403855079581402770986890308469084735451207885386318986881041563704825943945069343345307381099559075
# c = 6665851394203214245856789450723658632520816791621796775909766895233000234023642878786025644953797995373211308485605397024123180085924117610802485972584499
加密过程为:c = pow(m, bytes_to_long(flag), n)
即已知c, m, n求离散对数:bytes_to_long(flag) = log(mmodn) (c mod n)
题解:
m = 391190709124527428959489662565274039318305952172936859403855079581402770986890308469084735451207885386318986881041563704825943945069343345307381099559075
c = 6665851394203214245856789450723658632520816791621796775909766895233000234023642878786025644953797995373211308485605397024123180085924117610802485972584499
n = 2 ** 512
import sympy
from Crypto.Util.number import *
flag=sympy.discrete_log(n,c,m)
print(long_to_bytes(flag))