有限域的构造
实验内容
- 构造有限域GF(2^127):不可约多项式为f(x)=x^127+x+1;
- 给出GF(2^127)上的加法、乘法、平方以及求逆的子程序;
- 将自己的学号转为二进制字符串,看作有限域中的元素a,计算元素的逆元素以及a^20190911(注:二进制的学号每一位数字用四位二进制比特串表示)
实验算法原理
有限域2^127一共有2^127个元素,可以使用一个127比特的二进制串表示有限域中的每一个元素。使用bitset对这个二进制串进行存储。如bitset<127> my_ele("1011")
表示的即是多项式x^3+x^+1
加法
由于多项式每一项的系数都只能取0或1,对于这样的多项式,加法和减法是等价的,即对应位进行异或操作
模运算
不可约多项式为
因此有
那么,当n大于127时,有
因此,对于一需要进行模运算的二进制串,就是将它索引大于等于127的且为1的位,转化成(x+1)*x^(n-127),也就是将二进制串(00…0011)左移n-127位加到二进制串的低127比特上。进行模运算时,注意从高位模起,这样就能确保比当前模运算位高的位全都已经为0
乘法
记两个操作数分别为被乘数和乘数。两个127bit的二进制串相乘,使用一个254bit的串就可以存储结果。
二进制乘法实际上是一个将被乘数左移,乘上乘数对应位置,然后将加到结果上的一个过程。
开始时记结果为0,因此,遍历乘数的每一位i(从索引0的低位开始),被乘数左移i位,乘上乘数第i位的值(0或1),然后将这个加到结果中即可。
最后,调用模函数对乘法的结果进行求模。
平方
对于二进制串
因此,只需要将原二进制串第i位的值对应到结果的第2i位即可
求逆
使用扩展欧几里得算法求逆,记任意多项式为g,不可约多项式为f,在GF(2^127)中,对于不可约多项式,任意一个多项式和它的最大公约式必定为1
则有
我们可以列出这样的一组式子
在初始条件下,我们令x1=1,y1=0,x2=0,y2=1,k1=g,k2=f
在每一轮比较k2和k2的最大幂次,计算两式的最大幂次差为e,幂次大的式子减去幂次小的式子乘上x^e的结果,更新幂次大的式子的值。每一轮计算的时候都记录下x1和x2的值,最终能够得到k的幂次为0的式子,也就是等号右边为1,那么这时候我们就能够得到g的逆即x的值了。
指数
使用快速幂算法
对于x^e,可以将e写成二进制的形式
其中ai取值为0或1,指示的是e的二进制串对应位置为0或者为1
那么,我们可以记初始结果为1,检查e的最低位,看是否为1,若为1,则答案就乘上x,在这之后,对x进行平方,再将e右移一位。
1 | bitset<SIZE_N> exponent(bitset<SIZE_N> n, bitset<SIZE_N> e){ |
完整代码如下
1 |
|
运行截图
求学号的逆以及20190911次方的结果如下
计算乘法、平方、求逆所花费的时间如下:
也可以进行交互式加法,乘法,求逆,指数等操作