当前位置:   article > 正文

F(2^131)下有限域基本运算的实现(c++)_有限域运算编程

有限域运算编程

有限域实验

实验目标

实现F2131上的基本运算,并计算学号的逆元
不可约多项式f(x)=x131+x13+x2+x+1

算法原理

加法

F2131下,对于定义在该域上的任意多项式g(x)=i=0130aixi,由于ai只能取0或1,可将g(x)用长度为131的比特串来表示。
对于这样的多项式,加法和减法实际上是等价的,均为异或操作。(同次项系数相同则二者抵消为0,不同则保留为1的项)

取模

模运算建立在等式 x131+x13+x2+x+1=0modf(x) 的基础上
由上述加法法则可以得到 x131=x13+x2+x+1modf(x)
r(x)=x13+x2+x+1, m=131

假设x^j是一个高次项,那么可由下面的过程将其降次(图中省略了mod f(x)) 

xj=xjmxm=xjmr(x)deg(r)<m,deg(xj)=jdeg(xjmr(x))<j

这里原来是latex语法,由于csdn的问题,显示有问题,实际文本为:

x^j=x^{j-m}*x^m=x^{j-m}* r(x) \\ \because deg(r)<m, deg(x^j)=j\\ \therefore deg(x^{j-m}*r(x))<j

经过这样的运算后,xj从高次项变成了低次项。

那么对于需要取模的多项式,只要对其的每一个高次项进行这种运算,再将结果求和,就能得到取模后的结果

乘法

对于要进行乘法运算的两个多项式a(x)=i=0130aixi, b(x)=i=0130bixi
由分配律可知a(x)b(x)=i=0130a(x)bixi
对于多项式a(x),将其乘以一个xi,等价于将其比特串左移i位。
故算法可表示为

  1. input:a(x),b(x)
  2. output:c(x)=a(x)*b(x) mod f(x)
  3. c=0
  4. for i in (0,m):
  5. if b[i]==1:
  6. c ^= temp << i;
  7. return c mod f(x)

平方

求逆

由拓展欧几里得算法,对任意多项式a(x)和不可约多项式f(x),以下简写为a,f

具体迭代过程为

  1. x1=1;y1=0;
  2. x2=0;y2=1;
  3. k1=a;k2=f;
  4. while deg(k1)!=0:
  5. j=deg(k1)-deg(k2)
  6. if j <0:
  7. swap(k1,k2)
  8. swap(x1,x2)
  9. j=-j;
  10. k1=k1+(k2<<j)
  11. x1=x1+(x2<<j)
  12. return x1;

实验结果

  1. Convert 16336163 to bits:
  2. 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111110010100100100001011
  3. 16337163's inverse is:
  4. 10010010100000111011101011101101100010101100010000110100100110110001100001101110000111010101101110010100111010110010110111100011101
  5. The product of "16337163"and its inverse is:
  6. 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001

具体代码实现

程序基于c++的bitset实现。
p为不可约多项式,r为p去掉最高次的余式

加法

  1. bitset<M> add(const bitset<M> &a, const bitset<M> &b)
  2. {
  3. bitset<M> ans = a ^ b;
  4. return ans;
  5. }

取模

  1. bitset<M> mod(const bitset<2 * M> &a, const bitset<M> &r)
  2. {
  3. bitset<2 * M> x, y;
  4. bitset<2 * M> extend_r(r.to_string());
  5. x = a;
  6. y ^= bitset<2 * M>(x.to_string().substr(M)); //取比特串的低M位
  7. while (judge(x)) //judge函数功能:判断多项式的高M位是否存在1
  8. {
  9. y.reset();
  10. y ^= bitset<2 * M>(x.to_string().substr(M));
  11. for (int i = M; i < 2 * M; i++)
  12. if (x[i])
  13. y ^= extend_r << (i - M);
  14. x = y;
  15. }
  16. return bitset<M>(y.to_string().substr(M));
  17. }

乘法

  1. bitset<M> multiply(const bitset<M> &a, const bitset<M> &b, const bitset<M> &r)
  2. {
  3. bitset<2 * M> x;
  4. bitset<2 * M> temp(a.to_string());
  5. for (int i = 0; i < M; i++)
  6. {
  7. if (b[i])
  8. x ^= temp << i;
  9. }
  10. return mod(x, r);
  11. }

平方

  1. bitset<M> square(const bitset<M> &a, const bitset<M> &r)
  2. {
  3. bitset<2 * M> x;
  4. for (int i = 0; i < M; i++)
  5. x[i * 2] = a[i];
  6. return mod(x, r);
  7. }

求逆

  1. bitset<M> inverse(const bitset<M> &a, const bitset<M + 1> &p)
  2. {
  3. bitset<2 * M> b, c, u, v, temp;
  4. bitset<M> r(p.to_string().substr(1));
  5. int j;
  6. b[0] = 1;
  7. u = bitset<2 * M>(a.to_string());
  8. v = bitset<2 * M>(p.to_string());
  9. while (degree(u))
  10. {
  11. j = degree(u) - degree(v);
  12. if (j < 0)
  13. {
  14. j = -j;
  15. temp = u;
  16. u = v;
  17. v = temp;
  18. temp = b;
  19. b = c;
  20. c = temp;
  21. }
  22. u = u ^ (v << j);
  23. b = b ^ (c << j);
  24. }
  25. return mod(b, r);
  26. }

code.cpp

  1. #include <iostream>
  2. #include <string.h>
  3. #include <bitset>
  4. #include <vector>
  5. #include <string>
  6. using namespace std;
  7. #define M 131
  8. int degree(const bitset<2 * M> &a)
  9. {
  10. for (int i = 2 * M - 1; i >= 0; i--)
  11. if (a[i] || i == 0)
  12. return i;
  13. }
  14. bool judge(const bitset<2 * M> &a)
  15. {
  16. bitset<M> temp;
  17. bitset<2 * M> t(temp.set().to_string() + temp.to_string());
  18. t &= a;
  19. return t.any();
  20. }
  21. bitset<M> add(const bitset<M> &a, const bitset<M> &b)
  22. {
  23. bitset<M> ans = a ^ b;
  24. return ans;
  25. }
  26. bitset<M> mod(const bitset<2 * M> &a, const bitset<M> &r)
  27. {
  28. bitset<2 * M> x, y;
  29. bitset<2 * M> extend_r(r.to_string());
  30. x = a;
  31. y ^= bitset<2 * M>(x.to_string().substr(M));
  32. while (judge(x))
  33. {
  34. y.reset();
  35. y ^= bitset<2 * M>(x.to_string().substr(M));
  36. for (int i = M; i < 2 * M; i++)
  37. if (x[i])
  38. y ^= extend_r << (i - M);
  39. x = y;
  40. }
  41. return bitset<M>(y.to_string().substr(M));
  42. }
  43. bitset<M> multiply(const bitset<M> &a, const bitset<M> &b, const bitset<M> &r)
  44. {
  45. bitset<2 * M> x;
  46. bitset<2 * M> temp(a.to_string());
  47. for (int i = 0; i < M; i++)
  48. {
  49. if (b[i])
  50. x ^= temp << i;
  51. }
  52. return mod(x, r);
  53. }
  54. bitset<M> square(const bitset<M> &a, const bitset<M> &r)
  55. {
  56. bitset<2 * M> x;
  57. for (int i = 0; i < M; i++)
  58. x[i * 2] = a[i];
  59. return mod(x, r);
  60. }
  61. bitset<M> inverse(const bitset<M> &a, const bitset<M + 1> &p)
  62. {
  63. bitset<2 * M> b, c, u, v, temp;
  64. bitset<M> r(p.to_string().substr(1));
  65. int j;
  66. b[0] = 1;
  67. u = bitset<2 * M>(a.to_string());
  68. v = bitset<2 * M>(p.to_string());
  69. while (degree(u))
  70. {
  71. j = degree(u) - degree(v);
  72. if (j < 0)
  73. {
  74. j = -j;
  75. temp = u;
  76. u = v;
  77. v = temp;
  78. temp = b;
  79. b = c;
  80. c = temp;
  81. }
  82. u = u ^ (v << j);
  83. b = b ^ (c << j);
  84. }
  85. return mod(b, r);
  86. }
  87. int main()
  88. {
  89. bitset<M + 1> p("111");
  90. p[131] = 1;
  91. p[13] = 1;
  92. bitset<M> r("111");
  93. r[13] = 1;
  94. bitset<M> id(16337163);
  95. cout << "Convert 16336163 to bits:" << endl
  96. << id << endl
  97. << "16337163's inverse is:" << endl
  98. << inverse(id, p) << endl
  99. << "The product of \"16337163\"and its inverse is:" << endl
  100. << multiply(inverse(id, p), id, r) << endl;
  101. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号