[关闭]
@2017libin 2019-12-16T13:07:43.000000Z 字数 1841 阅读 61

实现s_box

密码学


思路

  使用笨方法,按照书上所说的三步走,还没想出更加高效的实现方法。输入一个十六进制数并输出相应的s_box中的值,进行简单的查表操作就可以了。具体代码如下。

代码:

  1. #include <iostream>
  2. #include <iomanip>
  3. using namespace std;
  4. int C = 0X63;
  5. int s_box[16][16];
  6. int x, y, d;
  7. int q = 0, r = 0;
  8. //定义G(2^8)中的 x*2
  9. int mul2(int x) {
  10. if (x & 0x80) return ((x << 1) ^ 27) & 255; //&255表示 只取一个字节
  11. else return (x << 1) & 255;
  12. }
  13. //G(2^8)乘法
  14. int mul(int x, int y) {
  15. int r = 0, tmp = x;
  16. while (y) {
  17. if (y % 2) r ^= tmp; //加法取模相当于亦或
  18. tmp = mul2(tmp);
  19. y /= 2;
  20. }
  21. return r;
  22. }
  23. //获取最高位1的位置
  24. int hight_index(int x) {
  25. if (!x) return 0; //x等于0,返回0。表示不存在最高位的1
  26. int index = 1;
  27. while (x >> 1) {
  28. x = x >> 1;
  29. ++index;
  30. }
  31. return index;
  32. }
  33. //G(2^n)除法
  34. void divi(int a, int b) {
  35. int tmp = 0;
  36. r = 0; q = 0;
  37. while (b <= a) {
  38. tmp = 1;
  39. int indexB = hight_index(b), indexA = hight_index(a);
  40. int dis = indexA - indexB;
  41. tmp = tmp << dis;
  42. q += tmp;
  43. a = a ^ (tmp*b);
  44. }
  45. r = a;
  46. }
  47. //ax + by = d = gcd(a,b), 其中a>b
  48. int egcd(int a, int b) {
  49. int x1 = 1, y1 = 0, x2 = 0, y2 = 1;
  50. int tmp_x, tmp_y;
  51. while (b) {
  52. divi(a, b);
  53. tmp_x = x2;
  54. tmp_y = y2;
  55. x2 = x1 ^ mul(x2, q); //1式 减去 (2式 * q), 接着轮换系数
  56. y2 = y1 ^ mul(y2, q);
  57. x1 = tmp_x;
  58. y1 = tmp_y;
  59. a = b;
  60. b = r;
  61. }
  62. return y1;
  63. }
  64. // ---------------------------------------- 分割线 -------------------------------
  65. //第二步:对s_box中的每个元素求逆元
  66. void inverseSBox() {
  67. for (int i = 0; i < 16; ++i)
  68. for (int j = 0; j < 16; ++j)
  69. s_box[i][j] = egcd(283, s_box[i][j]);
  70. }
  71. int getIndexBit(int x, int index) {
  72. return (x >> index) & 1;
  73. }
  74. int transform(int x) {
  75. int trans_x = 0;
  76. for (int i = 0; i < 8; ++i) {
  77. int tmp = 0;
  78. tmp = getIndexBit(x, i) ^ getIndexBit(x, (i + 4) % 8) ^ getIndexBit(x, (i + 5) % 8) ^ getIndexBit(x, (i + 6) % 8) ^ getIndexBit(x, (i + 7) % 8) ^ getIndexBit(C, i);
  79. trans_x = trans_x | (tmp << i);
  80. }
  81. return trans_x;
  82. }
  83. //第三步:对s_box中的元素进行变化
  84. void transformSBox() {
  85. for (int i = 0; i < 16; ++i) {
  86. for (int j = 0; j < 16; ++j) {
  87. s_box[i][j] = transform(s_box[i][j]);
  88. }
  89. }
  90. }
  91. void printSBox() {
  92. for (int i = 0; i < 16; ++i) {
  93. for (int j = 0; j < 16; ++j)
  94. cout << hex << setw(3) << s_box[i][j] << " ";
  95. cout << endl;
  96. }
  97. }
  98. int main() {
  99. for (int i = 0; i < 16; ++i)
  100. for (int j = 0; j < 16; ++j)
  101. cin >> hex >> s_box[i][j];
  102. inverseSBox();
  103. transformSBox();
  104. printSBox();
  105. //输入一个值并输出相应的s_box值
  106. int xy;
  107. cin >> hex >> xy;
  108. int xx = (xy >> 4) & 15;
  109. int yy = xy & 15;
  110. cout << hex << xy << "对应的s_box值为" << s_box[xx][yy] << endl;
  111. system("pause");
  112. return 0;
  113. }

s_box.png

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注