在本人的其它博文中,介绍了主流的三种公钥加密算法:RSA、离散对数加密和椭圆曲线加密。出于可读性上的考虑,文章中尽量减少了代数相关的描述。实际上,他们或多或少都跟有限域扯上了关系,如果能从抽象代数角度去解释,会更简洁。
抽象代数,其实就是对我们日常使用的代数运算进行了抽象,将其泛化到更一般的领域。小学的时候我们学习加法和乘法,里面有说它们满足结合律、交换律、分配律。这么多年我们一直把这些性质当成自然而然的东西,但是在抽象代数中,定义某些运算时,他们未必就像在普通加法乘法里那么显然。
这是高中数学就有的内容。集合具有三个性质:
- 无序性。集合中的元素是无序的。
- 唯一性。集合中每个元素都是唯一、不重复的。
- 确定性。给定一个元素和一个集合,这个元素要么属于这个集合,要么不属于这个集合,不存在其它情况。
比较常见的集合有:整数集(Z Z )、有理数集(Q Q )、实数集(R R )等。
在一个集合S中定义了某种运算(记作加法“+”,但这个加法指代广泛意义上的运算,并不是指日常使用的加法),那么在这个集合上,如果这种运算满足以下性质,那么他和集合S共同组成一个半群,记作(S, +):
- 封闭性。也就是运算的结果始终在集合S内
- 结合律。也就是满足:(a + b) + c= a + (b + c)
例子:如果集合S是全体实数(记作“R”),而运算是实数加法,那么它们共同形成了一个半群,记作(R, +)
如果一个半群(S, +)中存在一个元素e,使得S中所有的元素a都满足:
a+e=e+a=a a+e=e+a=a
那么这个半群被称为幺半群,元素e被称为单位元或者幺元。
例子:(R, +)中,实数0符合这一要求,所以(R, +)是幺半群,0是它的单位元。
如果一个幺半群(S, +)中的每一个元素a都有唯一一个元素b与之对应且满足以下性质:
a+b=b+a=e,其中e是单位元 a+b=b+a=e,其中e是单位元
那么这个幺半群就是一个群。群中元素a和元素b互为逆元,记作a = -b或者b = -a。逆元存在,也就定义了群上的减法。a减去b,其实就是a加上b的逆元。也就是
a−b=a+(−b) a−b=a+(−b)
例子:(R, +)中,每一个正数都和一个负数一一对应,他们的和为0。0取负是它自身。所以(R, +)是一个群。
如果一个群(S, +)符合交换律,即对于集合中任意元素a和b,满足:
a+b=b+a a+b=b+a
那么这个群被称为交换群,又叫阿贝尔群。
例子:两个实数相加谁先谁后对结果没影响,满足交换律,所以(R, +)是一个交换群。
在一个交换群(S, +)上, 再定义另外一种运算(记作乘法“⋅”,同样地这个乘法也不是指日常使用的乘法),得到(S, +, ⋅)。如果(S, +, ⋅)满足以下性质:
- (S, ⋅)是一个幺半群。
- 两种运算满足分配律,即a(b + c) = ab + ac
那么那么(S, +, ⋅)形成一个环。此时群(S, +)的单位元被称为环(S, +, ⋅)的零元。
例子:实数集R和实数乘法形成一个幺半群(R, ⋅),单位元是实数1,而且和实数加法满足分配律,所以(R, +, ⋅)是一个环。
如果幺半群(S, ⋅)里除了零元以外的所有元素都有逆元,那么(S, +, ⋅)被称为除环。
为了避免和(S, +)里的逆元混淆,(S, +)里的逆元称为加法逆元,(S, ⋅)里的则是乘法逆元。
(S, +, ⋅)中乘法逆元存在,也就定义了除法,元素a除以元素b实际上就是a乘以b的乘法逆元。也就是
a÷b=ab −1 a÷b=ab−1
例子:(R, ⋅)中,除了实数0((R, +)的单位元)以外所有数都有倒数,一个数和他的倒数之积为1(单位元),也就是一个实数的倒数就是它的乘法逆元。所以(R, +, ⋅)是一个除环。但是如果把其中的实数集改为整数集,就不满足这个性质了,因为大于1的整数倒数不在整数集中,因此没有乘法逆元。
如果环(S, +, ⋅)中,(S, ⋅)满足交换律,那么(S, +, ⋅)被称为交换环。
例子:实数乘法满足交换律,所以(R, +, ⋅)是一个交换环。
如果一个环(S, +, ⋅),既是除环又是交换环,那么它是一个域。
例子:(R, +, ⋅)既是除环又是交换环,所以它是一个域,称为实数域。
实数有无限多个,所以实数域是一个无限域。而如果一个域的元素是有限的,那么他就是一个有限域,又叫伽(ga1)罗瓦域(就是那个为爱死于决斗的数学家)。
有限域中元素的个数被称为有限域的阶(order)。有限域的阶一定是某个素数p的k次幂(k是正整数)。
最常见的有限域莫过于模素数p有限域GF(p)。
GF(p)是定义在整数集合{0, 1, … , p-1}上的域。GF(p)上的加法和乘法分别是模加法和模乘法。
模加法模乘法和普通的整数加法乘法类似,唯一不同的是,当运算的结果超出范围时,要将运算结果对素数p取模。比如GF(7)定义在{0, 1, 2, 3, 4, 5, 6}上,它的加法和乘法是这样的:
1+2=3mod75+6=11mod71∗2=2mod74∗5=20mod7 =3=4=2=6 1+2=3mod7=35+6=11mod7=41∗2=2mod7=24∗5=20mod7=6
a减去b,其实就是a加上b的加法逆元,关键是找到b的加法逆元。
1−2=1+(−2)=1+5=6mod71−2=−1mod7 =6 又或者=6 1−2=1+(−2)=1+5=6mod7=6 又或者1−2=−1mod7=6
到了除法,就没那么直观了。
a除以b,需要找到b的乘法逆元(在这里又被称为数论倒数)。即满足以下式子的整数x:
bx=1mod7 bx=1mod7
也就是解下面的方程:
bx=1+7k,其中k∈Z + bx=1+7k,其中k∈Z+
这个方程的求解需要用到扩展欧几里得算法,在本人的另一篇博文中有详细介绍,这里不再赘述。下面直接给出结果:
3÷4=3∗(4 −1 )=3∗2=6mod7=6 3÷4=3∗(4−1)=3∗2=6mod7=6
除了GF(p)外,常见的有限域还有GF(2^m)。它在里德-所罗门编码(二维码使用的编码)以及椭圆曲线加密中都有使用。
GF(2^m)正如他的名称,包含2^m个元素。为什么是2的m次方而不是3的m次方或者5的m次方呢?
因为计算机是二进制的,2^m个元素恰好跟长度为m的二进制数(0∼2 m −1 0∼2m−1 )一一对应。比如GF(2^8),刚好跟计算机中8个二进制位,也就是一个字节(0~255)对应。所以它在计算机或者专用硬件上可以有很高的运算效率。
为了方便,我们把GF(2^m)中的元素表示成长度为m的二进制形式。下面以m=3为例
GF(2^m)上的加法和减法都是异或运算。加法单位元是0。
010和110都是GF(2^3)的元素。那么
010+110=010⊕110010−110=010⊕110 =100=100 010+110=010⊕110=100010−110=010⊕110=100
因为长度为m的二进制数异或结果还是长度为m的二进制数,所以不需要考虑结果超出范围的情况。
乘法其实就是移位加上异或。乘法单位元是1。
举个栗子,111乘以101,基于乘法分配律,可以得到:
111∗101 =111∗100+111∗00+111∗1=11100+0000+111=11100⊕111=11011 111∗101=111∗100+111∗00+111∗1=11100+0000+111=11100⊕111=11011
如果直接相乘得到的结果长度不大于m,这就是最终结果。但是这里得到的结果是11011,长度超过了3,那么就要想办法对它进行处理。怎么处理呢?还是对一个“素数”取模。
需要注意,这里的“素数”并不是普通的素数,而是基于上述乘法,无法由两个数相乘得到的数。这样的“素数”可能有多个,不同的选择会有不同的结果。
对于GF(2^3),1011就是其中一个“素数”。11011对1011取模,过程如下:
11011mod1011 =11011−1011∗10mod1011=11011⊕10110mod1011=1101mod1011=1101−1011∗1=1101⊕1011=110 11011mod1011=11011−1011∗10mod1011=11011⊕10110mod1011=1101mod1011=1101−1011∗1=1101⊕1011=110
实际上这个计算过程类似于除法的竖式运算。
除法依然是乘以一个倒数,使用的方法同GF(p)一样是扩展欧几里得算法,这里不作介绍。