离散数学2
# 离散对数
离散困难问题:模幂运算逆向求解计算不可行
## 有限域上的离散对数:
- p:素数
- n:大于等于一的正整数
- $ F_(p^n)$:有限域的个数有限,且是p的n次方个
## 有限域:
- α ∈ Fpn , α 不等于0,本源元
- <α>={$α^i$|i =0,1,2,...,p^n −2}
- <α>=$ F∗_(p^n)$ (=$F_(p^n)$ \ {0})
## 密码学中的有限域:
- n = 1
- $F_p$: p元的有限域
- Fp ={0,1,2,...,p−1}mod p(P是一个特别大的素数)
## DLP
- α: 本源元,可公开
- d: 整数 0<d<p−1
- 算β = $α^d$
(知道α、β,无法计算d)
离散对数问题:
告诉你α、β,在多项式时间内计算d
解决密钥协商问题:(有相同的密钥才能做保密通信)
- Diffie-hellman解决密钥协商问题
给一个$F_p$,α是一个本原源,d是一个随机数,$β = α^d$,a选一个x(0< x < p-1),算$X=α^x$,把X发给b,X公开发送,b得到X后,b选一个y,计算$Y=α^y$,把Y给a,算 $α^{xy}$=$Y^x= K_a$,b算$α^{xy}$= $X^y=K_b$
($K_a=K_b$,实现了密钥协商,有共同的密钥了,去做加密解密,别人算不出来)
对于监听的攻击者有用,对于主动攻击的无用

## Diffie-hellman
- 真正的问题不是离散对数上的问题,是*cdh、ddh*问题。
- 安全基础:ddh、cdh问题(比离散对数弱)
- 攻击者窃听得到$α^x,α^y$,目标是:计算$α^{xy}$(最后的协商好的密钥)
### CDH假设(计算的dh问题)
给$α^x、α^y$,都是非零随机数,对于任何攻击者都不可能在概率多项式时间内把$α^{xy}$(密钥)算出来
### DDH假设(判定的dh问题)
$α^x,α^y,α^z,x、y$随机数,任意的概率多项式算法,无法区分$α^x,α^y,α^{xy}$和$α^x,α^y,α^z$
***伪随机函数用ddh来构造***
- cdh能解决,ddh也可以
- ddh能解决,cdh不一定
- ddh要求更强
### 中间人攻击:
e不仅仅是监听,e冒充a、b的身份给b、a发消息,e就有了a、b的密钥,a选一个x(0< x < p-1),算$X=α^x$,把X发给b(e),X公开发送,b得到X后,b选一个y,$计算Y=α^y,把Y给a(e)$,算$α^{xy}$=$Y^x=K_a$,b算$α^{xy}$=$X^y=K_b$
$$(K_a =K_1,K_b =K_2)$$

#### 中间人攻击解决方法:
- 身份认证:传消息时,确保对方的真实身份,认证的Diffie-hellman,采用MQV协议方案(椭圆曲线时讲)
- 引入第三方 安全信道 转移一下
#### 中间人攻击成功的原因:
冒充
## 密码学的功能
- 加密:基础功能
- 认证:重要功能,包括身份认证、消息认证(银行、指纹打卡)
## Diffie-hellma计算题
- $给α^x 和 α^y求α^xy$
n=⌈$log_2p$⌉(n是p的比特长度,是数据规模)
k=⌈$\sqrt n$⌉ + ⌈$log_2n$⌉
给$α^x和α^y$,计算$α^{xy}$最高位的几个bit的算法。
如果能算最高的几个bit,就能算出全部的$α^{xy}$
## 3L算法(不太明白)


# 数字签名算法
## DSA(数字信号运算法则)
H: 加密哈希函数 //用标准Hash函数
(L,N): (1024, 160), (2048, 224), ***(2048, 256)***, (3072, 256)
p: L位素数 //2048bit的素数
q: N位素数,q |(p−1) //256bit的素数,q整除p-1
g ∈ $F_p$: //g本身不为1,$g^q$=1,在有限域中计算
## 私钥和公钥:
私钥: 0 < x < q //_**x不能公开**_
公钥: $y = g^x$ //y可以公开
## 签名:(私钥签名)
m: 要签名的文件(可以公开)
k: 随机数, 1 < k < q //**k是临时的随机数,不能公开**
计算 $r=(g^k modp)modq$
如果r = 0, 重选一个随机数k开始
计算 $s = (H(m) + xr)/k$ mod q
如果s = 0, 重选一个随机数k开始
签名: (r,s) //r,s可以公开
## 验证:(公钥验证)
0 < r < q 或 0 < s < q
计算 w = 1/s mod q
计算 u1 = H(m) · w mod q
计算 u2 =r·w modq
计算 v = ($g^{u_1}y^{u_2}$ mod p) mod q
当且仅当 v = r 签名有效
## 随机数,随机性不够的结果
对于许多DSA签名,k的一些连续bit是已知的,就能得到私钥(不安全)
能得到log2 q个签名
可证明恢复签名者私钥x的概率多项式时间算法
某些连续位:最高有效位或最低有效位,√log2 q
**所以,随机数很重要!!**
# ElGamal加密:
安全基础:DDH问题
攻击者的能力:选择明文攻击
[ElGamal安全性证明](https://blog.csdn.net/weixin_43811210/article/details/106577828)
***解决公钥加密问题、数字签名问题***
## Alice, Bob
- 公开参数: Fp(有限域), n: prime number, 1不等于α ∈ Fp∗, $α^n$ = 1
- Alice:
私钥 x ∈ Z∗n,
公钥 $β = α^x$
p、α、n、公钥可以公开,唯一保密的是x
### 加密(公钥加密)
消息 m ∈ Fp∗ //有限域中的非零元素
Bob 选择k←−Zn,并计算$c1 =α^k,c2 =mβ^k $ //核心是有一个随机数
Bob 发送 (c1, c2) to Alice
### 解密(私钥解密)
Alice 计算: $m ⇐ c_2/c_1^x$ //x是私钥只有a知道
**公钥加密 私钥解密**
看加密是不是安全的,要看攻击者做什么事情,攻击者被动的在听,不能主动的发消息,就是选择明文攻击,那么ElGamal加密就是语义安全的
//语义安全:攻击者通过得到的东西无法得到明文的信息
## 选择明文攻击(CPA)下的不可区分的:
- 生成一对加密的公钥私钥对(pk,sk)//**私钥保密**
- 攻击者(概率多项式时间算法)被赋予公钥pk,并且可以对公钥进行加密,生成任意数目(多项式数)的密文
- 攻击者生成两条消息m0和m1,其中|m0|=|m1|,并将它们和pk发送给挑战者。
- 然后随机选一个m0或m1,使用公钥对消息m0或m1进行加密,并将密文c返回给攻击者。
- 攻击者猜c是对m0还是m1加密得到的
- 猜中的概率是1/2,说明选择明文攻击下是不可区分的
从密文得不到明文的信息:
给两个明文m0m1加密的密文c0c1,攻击者 不知道哪个是m0的密文,哪个是m1的密文
怎么衡量攻击者的能力、定义攻击者的行为:攻击者拿着公钥和公开的参数,对消息进行公钥加密,生成两条一样长的消息m0和m1,把m0和m1和公钥给我,我在m0和m1中随机选一个,用公钥进行加密,加密后的密文是c,把c返回给攻击者,攻击者猜c是对m0还是m1加密得到的,最后看猜对的概率是不是1/2,这样在选择明文攻击下就是安全的
攻击者区分不出哪个是对m0的密文哪个是对m1的密文,这个意思是说,他得不到明文任何1bit的信息
### 安全讨论:DDH
如果DDH成立,那么在选择明文攻击下是安全的
证明:
- m0 → C0 = (α^k,m0β^k),m1 → C1 = (α^s,m1β^s)
//如果两个密文可以区分,m0m1是公开的,ks是随机的,
- 则 如果(α^k , m0β^k ) 和 (α^s , m1β^s ) 可区分 ⇒ (β, α^k , m0β^k ) 和 (β, α^s , m1β^s ) 可区分
//k、s随机,β是公钥,m0m1公开
- (β,α^k,m0β^k) = (α^x,α^k,m0α^xk),
(β,α^s,m1β^s) = (α^x,α^s,m1α^xs),
像 Diffie-Hellman 的三元组 (x, k, s ←− Zn)
z ←− Zn, (α^x,α^k,m0α^xk) 和 (α^x,α^k,α^z) 可区分, 或(α^x, α^s , m1α^xs ) 和 (α^x , α^s , α^z ) 可区分
- 根据 DDH 假设, (α^x , α^k , α^xk ) 和 (α^x , α^k , α^z ) 不可区分
⇒ (α^x,α^k,m0α^xk)和(α^x,α^k,α^z)不可区分
- 根据 DDH 假设, (α^x,α^s,α^xs)和(α^x,α^s,α^z)不可区分
⇒ (α^x,α^s,m0α^xs)和(α^x,α^s,α^z)不可区分
矛盾(反证法)
- DDH的假设下,对于选择明文攻击的攻击者,ElGamal加密是安全的,攻击者还从密文得不到任何bit的信息
### 安全基础:
- EIgalma加密在CPA下安全,基于DDH假设,//由于ElGamal是一种公共密钥加密方案,因此,它对单个查询是安全的,它对q个查询也是安全的。
- 如果攻击者算离散对数就不安全,
- 若攻击者解ddh问题EIgalma加密也不安全。
- 所以安全和攻击者的能力有关系
**攻击者知道m0、m1,挑战者生成秘文C0、C1,返回给攻击者,攻击者区分不出C0、C1是对m0、m1哪个的的加密**
## 选择密文攻击
- m0 → C0 = $(α^k,m_0β^k)$
- m1 → C1 = $(α^s,m_1β^s)$
- C0,C1 → $(α^{k+s},m_0m_1β^{k+s}) → m_0m_1$
用两个密文,能生成一个合法的密文,这个密文对应的明文是前面两个明文的乘积,说明加密方案是有缺陷的,有太多的代数结构,泄露一些信息,在CCA2情况下是不安全的。
攻击者自己做出CO,知道m0和C0,把构造得到的乘积密文,要求解密,得到m0*m1。已知了mO,就可以得到m1
### 选择密文攻击,简称CCA1,不是适应性的
1.挑战者生成公钥私钥对pk,sk,并将公钥pk发送给攻击者。
2.攻击者可以生成任意的密文,想怎么算怎么算
3.可以要求对攻击者的密文做解密
4.把攻击者把两个明文m0和m1发给挑战者,挑战者选择m0或m1,用公钥加密生成密文c,并将C返回给攻击者。
5.攻击者还可以自己算很多东西,但是攻击者不能再要求挑战者解密
6.最后,猜密文c是用m0加密还是m1加密
7.如果猜对的概率是1/2,表示一个方案是IND-CCA1安全的
cpa只是攻击者自己算,没有要求有私钥的挑战者帮攻击者解密,得到密文以后攻击者也没有任何运算
cca1攻击者想算什么算什么,同时还可以随机生成任意密文,让挑战者帮忙解,当把c返回给攻击者时,攻击者还可以自己算很多东西,到最后猜是对m0加密还是对m1加密,猜中的概率应该是1/2(与1/2的差距是可忽视的),说明在cca1下是安全的
### 选择密文攻击,简称CCA2,是适应性的
1.挑战者生成公钥私钥对pk,sk,并将公钥pk发送给攻击者。
2.攻击者可以生成任意的密文,想怎么算怎么算
3.可以要求对攻击者的密文做解密
4.把攻击者把两个一样长的 明文m0和m1发给挑战者,挑战者选择m0或m1,用公钥加密生成密文c,并将C返回给攻击者。
5.攻击者还可以自己算很多东西,攻击者也可以要求挑战者解密,但是挑战者不能帮忙解密C,其他都可以 //与CCA1的不同
6.最后,猜密文c是用m0加密还是m1加密
7.如果猜对的概率是1/2,表示一个方案是IND-CCA2安全的
构造一个加密方案,需要证明CCA2下是安全的,怎么证明呢:把攻击者的攻击能力归于底层的攻击困难问题
为什么ElGamal加密在CCA2下不安全?
- 会受到选择密文攻击(攻击性太强)
- 前面攻击者可以做很多加密,后面攻击者可以让我方解很多密文
CCA1 与 CCA2 的区别
CCA2 与 CCA1 只有一个区别,那就是在生成挑战密文后,CCA2依然允许敌手进行解密询问(限制是不能允许敌手询问挑战密文的解密询问)。
[CCA1与CPA的区别](https://www.jianshu.com/p/5e8673e10e72)
cca是主动的攻击,cpa是被动的监听
cpa改成cca:选择密文增加密文格式的限制,让攻击者无法分离密文
[从CPA安全到CCA安全](https://blog.csdn.net/zmrlinux/article/details/108159619)
做密码学要明白
1.安全基础是什么?什么样的困难问题?(数学上、密码学上、计算机上、物理上)基于某种缺陷
2.攻击者的具体能力的精确刻画(密码学的语言或数学的语言)
### CCA2安全公共参数:
- Fp,n: 素数,1不等于α∈Fp∗,α^n =1
- G =< α > //α的多少次方变出来的
- Hash 函数 H(·) : {0,1}∗ → Zn
- 私钥: x1, x2, y1, y2, z ←− Zn
- 公钥: c = g^x1g^x2,d = g1^y1*g2^y2,h = g1^z
- 加密:
消息 m ∈ G
r ←− Z n
u1 = $g_1^r,$
u2 = $g_2^r,$
e =$ h^rm,$
f =$ H(u1_,u_2,e)$ //hash函数h把u1、u2、e,和f彻底绑定在一起,因为是单向函数
v = $c^rd^{rf}$
密文: u1, u2, e, v
// Elgamal加密只有两部分$c1=α^k和c2=mβ^k$
- 解密:(用私钥)
1. 计算 f = H(u1, u2, e), //f谁都可以算
2. 并检查$u^{x_1+y_1f}*u^{x_2+y_2f}=v $//v是密文的一部分,做密文格式的校验
如果是,输出$m=e/u_1^z$
// Elgamal解密$m=c_2/c_1^x$,Elgamal密文随机的,CCA2方案攻击者随机生成的密文多半是有问题的。
目前所有CCA2安全方案的基本思路
# 承诺方案
[承诺](https://blog.csdn.net/shangsongwww/article/details/110233192)
所有信封封装好,出价的人不能改,其他人看不到。(公平问题)
一个非交互式的提交方案由两个PPT算法组成:Setup和Commit
满足以下特点:
1. 在输入1^λ时,Setup算法PP←Setup(1λ)输出包含消息空间MPP、随机数RPP和承诺值CPP定义的公共参数PP。//λ是参数
2. 承诺算法CommitPP是一个函数MPP×RPP→CPP。对于消息v∈MPP,算法选择,$r←−RPP,并计算C=CommitPP(v,r)。
//CPP是那封信,MPP是新的内容,RPP是随机数
//承诺方案:承诺值v,随机数r,算出c
要求:
1. 隐藏性,通过C不能得到任何一个bit的v的信息
2. 不可能找出v0、v1、r0、r1使得算出来的c一样
3. 同态性(有了更好)
Commit(v0, r0) · Commit(v1, r1) = Commit(v0 + v1, r0 + r1)
构造承诺最简单的方式:哈希承诺
$C=H(v)$,哈希承诺的构造简单、使用方便,满足密码学承诺基本的特性,适用于对隐私数据机密性要求不高的应用场景。
密码学承诺的应用涉及承诺方、验证方两个参与方,以及以下两个使用阶段。第一阶段为承诺生成(Commit)阶段,承诺方选择一个敏感数据v,计算出对应的承诺c,然后将承诺c发送给验证方。通过承诺c,验证方确定承诺方对于还未解密的敏感数据v只能有唯一的解读方式,无法违约。第二阶段为承诺披露(Reveal)阶段,学术界通常也称之为承诺打开-验证(Open-Verify)阶段。承诺方公布敏感数据v的明文和其他的相关参数,验证方重复承诺生成的计算过程,比较新生成的承诺与之前接收到的承诺c是否一致,一致则表示验证成功,否则失败。
一个设计良好的密码学承诺具备如下特性:
隐匿性(hiding):在打开关于v的承诺c之前,验证方不知道承诺方选择的敏感数据v。
绑定性(binding):在关于v的承诺c生成之后,承诺方难以将已承诺的敏感数据解释成另一个不同的数据v'。
## Pedersen承诺方案(比特币、区块链常用的承诺方案)
n是个素数,1不等于α∈Fp∗,$α^n =1$,G=<α>.
这个元素里随机找个值β,使得β相对于α的离散对数未知
对于消息v∈Zn,承诺算法选择r←−Zn,并计算$C=α^vβ^r$。//有c得不到v的信息,
//别人通过C算不出来v,自己也不可能找个其他值不是v而能得到C
Pedersen承诺重在“承诺”,适用于数据属主向第三方证明承诺中的敏感数据满足一定的约束关系,由于不直接提供解密功能,不能直接支持需要互不透露敏感数据明文的多方协同计算,这一点与密码学领域的同态加解密算法有很大区别,切勿混淆概念。
## 伪随机函数(先不看)
构造:
- P, Q: 大素数
- |P| = n //p是nbit的
- Q|(P − 1) //q是p-1的一个因子
- g∈Zp,g^Q =1,g不等于1 //Zp是有限域
- < g >= {g i |i = 0, 1, 2, ..., Q − 1} →− n+1
- a = (a0,a1,a2,...,an) ∈ ZQ //私钥
- x = (x1,x2,...,xn) ∈ F2 //明文,输入,比特串
- 密钥: P,Q,g, a // p,q,g可以公开
- 输入:x
- 整数乘
模组数

通过询问M,得到一个函数,R是纯随机的,f是通过向量a的不同得到的
通过很多次的询问也区分不出来到底哪一个是真随机的M
Diffie-hellma密钥协商
认证的密钥协商(抵抗中间人攻击)
公钥算法的 签名加密
承诺方案
基于ddh构造伪随机函数
# RSA
***第一个实用的公钥密码体制,量子计算机下不安全***
- P,Q:两个大素数
- N=PQ
- 
- 公钥:N,e
- 私钥:P,Q,d
- 加密:

- 解密:

- 签名:

- 认证:

**唯一不能公开的是d**
当mn不互素时:加密、解密是错的;算最大公因子时,会把n分解,就会找出私钥
## RSA算法的安全基础(RSA问题):
- 公钥:N,e
- 密文:C
- 给密钥和密文计算M
## 强RSA假设:
- 给(n,c)找不出(m,e)e大于等于3的奇数,使得

//e=3时不安全
- 强RSA假设成立——>RSA成立——>因式分解问题成立
小e
