本文介绍密码学中常用的一些符号和数学知识。

标准符号

#S\#S,集合SS中的元素数目

FqF_q,q个元素的有限域

desc(A)desc(A),代数结构A的描述

xDx\larr D,根据分布DD进行赋值

xUSx\larr _US,按SS为均匀分布进行赋值

ord(x)ord(x),群元素的阶

<g><g>,由g生成的循环群

概率论和信息论

概率论和信息论是现代密码技术发展必不可少的工具。

现代密码系统,特别是公钥密码系统,对概率行为的要求已经达到相当苛刻的程度:语义安全性。

概率论的基本概念

SS为一个任意确定的点的集合,称之为概率空间(或样本空间)。任意元素xSx\in S称为样点(也称为结果、简单事件或不可分事件;为了简单我们将只用点)。一个事件(也称为合成事件或可分事件)是SS的一个子集,通常用一个大写字母表示(比如EE)。一次实验或观察是一种从SS中产生(取出)一个点的动作。一个事件EE的发生就是一个试验产生某个点xSx\in S,并满足:xEx\in E

概率的经典定义

假设一个实验可以从n=#Sn=\# S个等可能的点中产生一个点,并且每次实验必须产生一个点。令mm表示事件EE包含的点的数目,那么mn\frac{m}{n}为事件EE发生的概率,并记为Prob[E]=mnProb[E]=\frac{m}{n}

概率的统计定义

假设在相同条件下进行了nn次实验,其中事件EE发生了μ\mu次,如果对所有足够大的nnμn\frac{\mu}{n}保持不变,那么就是说事件EE的概率为μn\frac{\mu}{n},记为,Prob[E]μnProb[E]\approx \frac{\mu}{n}

随机变量及其概率分布

在密码学中,我们主要考虑定义在离散空间上的函数。设离散空间SS包含有限个或者可数个孤立的点x1,...,x_1,...,

离散随机变量及其分布函数

一个离散随机变量是一个实验的数字化结果。它是定义在样本空间上的函数

SS为一个概率空间,ξ\xi为一个随机变量。ξ\xi的分布函数是SRS\rarr R的一个函数,以一个概率值Prob[ξ=xi]=piProb[\xi=x_i]=p_i

均匀分布

密码学中最常用的随机变量服从均匀分布:Prob[ξ=xi]=1#SProb[\xi=x_i]=\frac{1}{ \# S}

SS表示最长为kk比特的非负数集合,依据均匀分布,从SS中随机取出一个数,所取的数为k比特的概率是12\frac{1}{2}

二项式分布

假定一个实验只有两个结果,记为“成功”和“失败”(例如,抛一枚硬币只有两个结果,“正面”和“反面")。独立地重复进行该实验,如果每一次实验结果仅有两种可能的点,且它们的概率在整个实验过程中保持不变,那么这样的实验就称为贝努利试验(bernoulli trials)。

假设在任何一次试验中:Prob[Y]=p,Prob[N]=1pProb[Y]=p,Prob[N]=1-p

那么Prob[n test,k N]=Cnkpk(1p)nkProb[n\ test,k\ N]=C_n^kp^k(1-p)^{n-k}

如果随机变量ξn\xi_n取值为0,1,n,且对每一个p,0<p<10< p<1,有Prob[ξn=k]=Cnkpk(1p)nkProb[\xi_n=k]=C_n^kp^k(1-p)^{n-k}

那么我们说ξn\xi _n服从贝努利分布

生日悖论

对任意函数f:XYf:X\rarr Y,其中YY为包含n个元素的集合,我们来解决下面的问题:

对于一个概率界限ϵ,0<ϵ<1\epsilon,0<\epsilon<1,找一个整数kk,使得对于kk个两两互异的值x1,x2,...,xkUXx_1,x_2,...,x_k\in_U Xkk个函数值f(x1),f(x2),...,f(xk)f(x_1),f(x_2),...,f(x_k)对某些iji\ne jProb[f(xi)=f(xj)]ϵProb[f(x_i)=f(x_j)]\ge \epsilon

即在kk个函数值中,以不小于ϵ\epsilon的概率发生碰撞

上述问题可以表示成:从装有nn个不同颜色小球的袋子中去一个球,记下该球的颜色,然后放回。找到一个整数kk,至少出现一次颜色匹配的概率为ϵ\epsilon。令yiy_i表示第ii次取出的小球的颜色,第二次取出小球颜色不同的概率为11/n1-1/n,以此类推,第kk个球还未发生碰撞的概率为(11n)(12n)...(1k1n)(1-\frac{1}{n})(1-\frac{2}{n})...(1-\frac{k-1}{n})

当n足够大且x相对较小时1+xn=exn1+\frac{x}{n}=e^{\frac{x}{n}}

因此(11n)(12n)...(1k1n)=ek(k1)2n(1-\frac{1}{n})(1-\frac{2}{n})...(1-\frac{k-1}{n})=e^{-\frac{k(k-1)}{2n}}

这是不碰撞的概率,因此碰撞的概率为1ek(k1)2n=ϵ1-e^{-\frac{k(k-1)}{2n}}=\epsilon

我们有k2nlog11ϵk\approx \sqrt {2n\log \frac{1}{1-\epsilon}}

考虑ϵ=1/2\epsilon=1/2,则k=1.1774nk=1.1774\sqrt{n},它表示对于一个输出空间大小为nn的随机函数,我们只需计算大约n\sqrt n个函数值,就能以一个不可忽略的概率发现一个碰撞。

如果说,我们将一组数据作为某个密码函数的原像隐藏,如果该数据的平方根不够大,那么就可以通过随即计算函数值来找出这组数据。这种攻击被称为生日攻击。它来源于:n=365,k22.49n=365,k\approx22.49,为了以大于50%的概率从房间中找到有两个人的生日相同,在该房间中只需有23人即可。

生日悖论的应用:指数计算的Pollard袋鼠算法

pp为素数,f(x)=gx(mod p)f(x)=g^x(mod\ p)是一个随机函数,对于x=1,2,..,p1x=1,2,..,p-1,函数值f(x)f(x)在整数区间[1,p1][1,p-1]范围内任意变化,这个函数具有单向性。求逆十分困难。

在某些情况下,我们知道a和b,可以计算f(a),f(a+1),...f(a),f(a+1),...在穷尽b-a步之前找到x。如果b-a太大,那么这种穷搜索方法不现实。但如果ba\sqrt{b-a}是一个容易处理的值,那么生日悖论在ba\sqrt{b-a}步求f(x)f(x)中起到作用。

Pollard发现了这种方法,他称之为λ\lambda算法或袋鼠算法。

Pollard用两个袋鼠描述他的算法,一只是驯养的袋鼠TT,另一只是野生的袋鼠WW,已知f(x)=gx(mod p)f(x)=g^x(mod\ p)求解x的问题可以模型化为TT追捕WW。这一点是通过让袋鼠沿着跳跃的方式完成的。

S={s(0),s(1),...,s(J1)}={20,21,...,2J1}S=\{s(0),s(1),...,s(J-1)\}=\{2^0,2^1,...,2^{J-1}\}

袋鼠每一次跳跃的距离为SS中随机的一个数,每只袋鼠都随身携带一个里程表来计算它跳过的总距离。

TT从已知点t0=gb(mod p)t_0=g^b(mod\ p)开始跳,TT是驯服的袋鼠,它的路线为t(i+1)=t(i)gs(t(i)mod J)(mod p)t(i+1)=t(i)g^{s(t(i)mod\ J)}(mod\ p)

在跳了n此后,TT携带的里程表记录着它目前跳过的距离d(n)=Σi=0ns(t(i)mod J)d(n)=\Sigma_{i=0}^ns(t(i)mod\ J)

我们将上面的表达式重新表达为t(n)=gb+d(n1)mod pt(n)=g^{b+d(n-1)}mod\ p

WW是野生的,它从一个未知的点w0=gxmod pw_0=g^xmod\ p,它的路线为w(i+1)=w(i)gs(w(i)mod J)(mod p)w(i+1)=w(i)g^{s(w(i)mod\ J)}(mod\ p)

WW携带的里程表记录着它目前跳过的距离D(j)=Σk=0js(wkmod J)D(j)=\Sigma_{k=0}^js(w_kmod\ J)

我们将上面的表达式重新表达为w(i)=gx+D(i1)mod pw(i)=g^{x+D(i-1)}mod\ p

显然,它们的足迹t(i)t(i)w(j)w(j)是两个随机函数,根据生日悖论,在TTWW分别大约跳nban\approx\sqrt{b-a}步内,发生碰撞,也就是跳在了同一个点。如果超过nban\approx\sqrt{b-a},那么碰撞发生的概率趋向于1.

信息论

香农关于消息源的熵(entropy)的定义用来衡量这个源所含信息量的多少。这个量度以源输出的所有可能的消息集上的概率分布函数形式给出。

L=a1,a2,...,anL={a_1,a_2,...,a_n}为由n个不同符号组成的语言,假设信源SS以独立的概率Prob[a1],Prob[a2],...,Prob[an]Prob[a_1],Prob[a_2],...,Prob[a_n]分别输出这些符号,并且满足Σi=1nProb[ai]=1\Sigma_{i=1}^nProb[a_i]=1

S的熵为H(S)=Σi=1nProb[ai]log2(1Prob[ai])H(S)=\Sigma_{i=1}^nProb[a_i]\log_2(\frac{1}{Prob[a_i]}),我们称之为“每个信源输出的比特数”

如果SS以概率1输出某个符号,例如a1a_1,则熵函数H(S)H(S)有最小值0,这是因为H(S)=Prob[a1]log2(1Prob[a1])=log21=0H(S)=Prob[a_1]\log_2(\frac{1}{Prob[a_1]})=\log_21=0,这种情况说明,当我们确信信源SS确定地仅输出a1a_1,我们没必要浪费比特来记录它。