对FEAL-4的差分***

1. FEAL密码算法简介

FEAL密码算法家族是日本NTT(日本电报电话公司)的清水(Shimizi)和宫口(Miyaguchi)设计的(1986)。作为一种分组密码,与DES相比其主要想法为增加每一圈迭代的算法强度,因此可以通过减少迭代次数而提高运算速度。

FEAL-8即为8圈迭代的FEAL密码算法。FEAL密码算法推出之后,引起有关专家的注意。密码专家比哈姆和沙米尔利用差分密码分析技术发现,可以用比穷举法更快的速度破译FEAL密码。如FEAL-8只需2000个选择明文即可破译,而FEAL-4更只需8个精心选择的明文便可破译。

这个小密码系统用来做破译练手最合适不过了,本文对http://www.theamazingking.com/crypto-feal.php中的文章进行了学习,记录笔记如下。

2. FEAL密码算法结构

FEAL密码算法仅4圈,数据块为64位。最核心的便是轮函数f,输入、输出均32位。抗差分或线性分析均取决于此函数的设计。故用红色标出,其实Feistel结构本身的混淆是有限的。Feistel结构的优点是其轮函数可以是单向的,这样密码算法有更好的统计属性。而SPN网络的SBOX虽求逆困难,但不能单向,否则无法解密。

图1 FEAL密码结构

这里的密钥K0~K5均是从初始密钥K扩展而来,每个32位。而实际的***结果是完全攻破6*32=192位密钥。所以,密钥协商算法是单向的也没关系,可以把子密钥看做随机生成。

2.1 FEAL轮函数结构

图2 FEAL轮函数结构

轮函数的关键是非线性性,移位和异或都起到了这样的作用。输入为32位字,分为4个8位的小块。

3. FEAL密码算法差分***

差分***的本质是利用非线性变换的并非完全随机性。即对于特定的输入差分,输出的差分并不是均匀分布的。

3.1 概率为100%的差分特征

图3 概率为100%的差分特征

由于轮函数的输入是32位,所以不可能像小SBOX一样,穷举所有差分。

3.2概率为100%的差分特征原理

这里要把轮函数分解为(a+b+x mod 255)<&lt;2,首先+x对差分来说可忽略。而mod 255对输入差分为0x80,0x00来说,其输出必然0x80。参见图4.(详细解释见原文)

图4 概率为100%的差分特征

对于轮函数对差分的跟踪,如图5.

图5 轮函数对差分的跟踪

3.3 概率为100%的4轮差分特征的寻找

这里应用了中间相遇***的原理,即从前向后利用明文差分找到两轮输入差分。同时,从后向前,利用密文差分找到两轮差分。

图6 4轮差分特征

利用输入明文差分P0 XOR P1 = 0x8080000080800000 可以如图6追踪前两轮的差分传播。但只能分析到红色部分之前。因为 0x02000000作为输入差分是很难预测其输出差分的。

而若想找到最后一轮的子密钥k3,则需要知道最后一轮函数f 的输出差分。而该输出差分恰好等于左边32位的密文差分与0x02000000的异或。

3.4 最后一轮的子密钥k3的获取

这里的关键点在于最后一轮函数的输入差分及输出差分的获取,由图7可知,最后一轮函数f的输入差分可通过穷举密钥获得。这里看似输入差分似乎与子密钥k3没有关系,但子密钥k3能影响具体的输出差分(已经计算出)的值。正确的子密钥k3会使其输出差分完全吻合,即该子密钥的分数为6,见伪码图8

图7 对密钥的寻找

图8 伪代码

4. 试验结果

对于6个明、密文对,每次总能找到4个可能的最后一轮子密钥,但如何排除?(增加更多的明、密文对并不能排除,换条差分路径也许可以?)对其他轮子密钥,在已知第四轮子密钥的情况下,可效仿求第三轮子密钥。但结果亦不唯一。只能在找到的结果中用穷举去排除。只要结果比穷举2^64小(初始密钥64位),就算成功。

5. 附录代码

  1. //Differential Cryptanalysis of FEAL-4
  2. //Uses a chosen-plaintext attack to fully recover the last round subkey
  3. //For use with tutorial at http://theamazingking.com/crypto-feal.php
  4. //Hack the Planet!
  5. #include &lt;stdio.h>
  6. #include <math.h>
  7. //subkey为全局变量
  8. unsigned long subkey[6];
  9. //循环左移两位,先记录左移出的最高1位,在整体左移1位,
  10. //最高位再放到最低位。LL是unsigned long long赋值时的必须选择
  11. //实际a,b的取值只0~255,故最后要&=0xFFLL
  12. //long long 在vc6下没法通过,故用linux或vc2005
  13. //gcc -O3 feal4.c -o feal4
  14. unsigned long long shiftLeft2(unsigned long a)
  15. {
  16. unsigned long b;
  17. unsigned long carry = (a &gt;&gt; 7LL);
  18. carry &= 0x1LL;
  19. b = a <&lt; 1LL;
  20. b += carry;
  21. b &= 0xFFLL;
  22. carry = (b >&gt; 7LL);
  23. carry &= 0x1LL;
  24. b <&lt;= 1LL;
  25. b += carry;
  26. b &= 0xFFLL;
  27. return b;
  28. }
  29. //G函数
  30. unsigned long gBox(unsigned long a, unsigned long b, unsigned long mode)
  31. {
  32. return shiftLeft2((a + b + mode) % 256LL);
  33. }
  34. //轮函数
  35. unsigned long fBox(unsigned long plain)
  36. {
  37. //一个32BIT拆成4个8BIT
  38. unsigned long x0 = plain & 0xFFL;
  39. unsigned long x1 = (plain >&gt; 8L) & 0xFFL;
  40. unsigned long x2 = (plain &gt;&gt; 16L) & 0xFFL;
  41. unsigned long x3 = (plain &gt;&gt; 24L) & 0xFFL;
  42. unsigned long t0 = (x2 ^ x3);
  43. unsigned long t1 = gBox(x0 ^ x1, t0, 1L);
  44. unsigned long y0 = gBox(x0, t1, 0L);
  45. unsigned long y1 = t1;
  46. unsigned long y2 = gBox(t0, t1, 0L);
  47. unsigned long y3 = gBox(x3, y2, 1L);
  48. //4个8BIT重组一个32BIT
  49. unsigned long ret = y3 <&lt; 24L;
  50. ret += (y2 &lt;&lt; 16L);
  51. ret += (y1 &lt;&lt; 8L);
  52. ret += y0;
  53. return ret;
  54. }
  55. unsigned long long encrypt(unsigned long long plain)
  56. {
  57. unsigned long left = (plain >&gt; 32LL) & 0xFFFFFFFFLL;
  58. unsigned long right = plain & 0xFFFFFFFFLL;
  59. left = left ^ subkey[4];
  60. right = right ^ subkey[5];
  61. unsigned long round2Left = left ^ right;
  62. unsigned long round2Right = left ^ fBox(round2Left ^ subkey[0]);
  63. unsigned long round3Left = round2Right;
  64. unsigned long round3Right = round2Left ^ fBox(round2Right ^ subkey[1]);
  65. unsigned long round4Left = round3Right;
  66. unsigned long round4Right = round3Left ^ fBox(round3Right ^ subkey[2]);
  67. unsigned long cipherLeft = round4Left ^ fBox(round4Right ^ subkey[3]);
  68. unsigned long cipherRight = cipherLeft ^ round4Right;
  69. //32bit转64bit后的重组
  70. unsigned long long ret = (((unsigned long long)(cipherLeft)) <&lt; 32LL);
  71. ret += (((unsigned long long)(cipherRight)) & 0xFFFFFFFFLL);
  72. return ret;
  73. }
  74. void generateSubkeys(int seed)
  75. {
  76. srand(time(NULL));
  77. int c;
  78. //用两次rand函数更随机
  79. for(c = 0; c &lt; 6; c++)
  80. {
  81. subkey[c] = rand() &lt;&lt; 16L;
  82. subkey[c] += rand() & 0xFFFFL;
  83. }
  84. }
  85. int numPlain;
  86. unsigned long long plain0[10000];
  87. unsigned long long cipher0[10000];
  88. unsigned long long plain1[10000];
  89. unsigned long long cipher1[10000];
  90. unsigned long key3winner;
  91. void crackSubkey3ULTRA()
  92. {
  93. unsigned long fakeK;
  94. for(fakeK = 0x00000000L; fakeK &lt; 0xFFFFFFFFL; fakeK++)
  95. {
  96. int score = 0;
  97. int c;
  98. for(c = 0; c &lt; numPlain; c++)
  99. {
  100. unsigned long cipherLeft = (cipher0[c] >&gt; 32LL);
  101. cipherLeft ^= (cipher1[c] &gt;&gt; 32LL);
  102. unsigned long cipherRight = cipher0[c] & 0xFFFFFFFFLL;
  103. cipherRight ^= (cipher1[c] & 0xFFFFFFFFLL);
  104. //Y没用
  105. unsigned long Y = cipherLeft ^ cipherRight;
  106. unsigned long Z = cipherLeft ^ 0x02000000L;
  107. unsigned long fakeRight = cipher0[c] & 0xFFFFFFFFLL;
  108. unsigned long fakeLeft = cipher0[c] &gt;&gt; 32LL;
  109. unsigned long fakeRight2 = cipher1[c] & 0xFFFFFFFFLL;
  110. unsigned long fakeLeft2 = cipher1[c] &gt;&gt; 32LL;
  111. unsigned long Y0 = fakeLeft ^ fakeRight;
  112. unsigned long Y1 = fakeLeft2 ^ fakeRight2;
  113. unsigned long fakeInput0 = Y0 ^ fakeK;
  114. unsigned long fakeInput1 = Y1 ^ fakeK;
  115. unsigned long fakeOut0 = fBox(fakeInput0);
  116. unsigned long fakeOut1 = fBox(fakeInput1);
  117. unsigned long fakeDiff = fakeOut0 ^ fakeOut1;
  118. if (fakeDiff == Z) score++; else break;
  119. }
  120. if (score == numPlain)
  121. {
  122. printf("DISCOVERED ROUND #4 SUBKEY = %08lx\n", fakeK);
  123. printf(" ACTUAL ROUND #4 SUBKEY = %08lx\n", subkey[3]);
  124. key3winner = fakeK;
  125. //不break应该能找到更多,可通过增加明/密文对去过滤
  126. //break;
  127. }
  128. }
  129. }
  130. void chosenPlaintext(unsigned long long diff)
  131. {
  132. srand(time(NULL));
  133. printf("PLAINTEXT DIFFERENTIAL = %llx\n\n", diff);
  134. int c;
  135. for(c = 0; c &lt; numPlain; c++)
  136. {
  137. plain0[c] = (rand() & 0xFFFFLL) &lt;&lt; 48LL;
  138. plain0[c] += (rand() & 0xFFFFLL) &lt;&lt; 32LL;
  139. plain0[c] += (rand() & 0xFFFFLL) &lt;&lt; 16LL;
  140. plain0[c] += (rand() & 0xFFFFLL);
  141. cipher0[c] = encrypt(plain0[c]);
  142. plain1[c] = plain0[c] ^ diff;
  143. cipher1[c] = encrypt(plain1[c]);
  144. }
  145. }
  146. int main()
  147. {
  148. generateSubkeys(time(NULL));
  149. printf("Imput the num of pairs:");
  150. scanf("%d",&numPlain);
  151. //numPlain = 6;
  152. chosenPlaintext(0x8080000080800000LL);
  153. unsigned long startTime = time(NULL);
  154. crackSubkey3ULTRA();
  155. unsigned long endTime = time(NULL);
  156. printf("Time to crack round #4 = %i seconds\n\n", (endTime - startTime));
  157. return 0;
  158. }

转载于:https://blog.51cto.com/linuxcumt/709624

对FEAL-4的差分***相关推荐

  1. MindArmour差分隐私

    MindArmour差分隐私 总体设计 MindArmour的Differential-Privacy模块,实现了差分隐私训练的能力.模型的训练主要由构建训练数据集.计算损失.计算梯度以及更新模型参数 ...

  2. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)

    BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...

  3. 使用OpenCV,Python进行图像哈希(差分哈希 dHash)处理

    使用OpenCV,Phthon进行图像哈希处理的一个重要应用是去除重复的图像: 当你有多个相册的图片,进行合并时,so boring,有一些图片是重复的,肉眼来看太难删除了. 图像哈希可以帮助你完美的 ...

  4. 基于运动信息的物体检测(背景差分法、帧间差分法和光流法)。

    1.背景差分法: 它的基本思想是将输入图像与背景模型进行比较,通过判定灰度等特征的变化,或用直方图等统计信息的变化来分割运动目标. 首先建立好背景模型,存储背景图像.当当前帧与背景图像相减大于一定的阈 ...

  5. HDU1811 Rank of Tetris 拓扑排序+并查集 OR 差分约束最短路+并查集

    题目链接 题意:就是给你一堆关系,看能不能排出个确定的顺序 做法: 1. 拓扑排序+并查集 应该很容易想到的一种思路,大于小于建立单向边.对于相等的呢,就把他们缩成一个点.就用并查集缩成一个点就行了 ...

  6. P3168 [CQOI2015]任务查询系统 差分+主席树

    链接在这~:https://www.luogu.org/problem/P3168 主席静态区间修改,单点查询 区间(L,R)加1可以通过差分以后转换为L位置加1,R+1位置减1 我们只需要记录一下, ...

  7. ADPRL - 近似动态规划和强化学习 - Note 10 - 蒙特卡洛法和时序差分学习及其实例 (Monte Carlo and Temporal Difference)

    Note 10 蒙特卡洛法和时序差分学习 Monte Carlo and Temporal Difference 蒙特卡洛法和时序差分学习 Note 10 蒙特卡洛法和时序差分学习 Monte Car ...

  8. 强化学习(五) - 时序差分学习(Temporal-Difference Learning)及其实例----Sarsa算法, Q学习, 期望Sarsa算法

    强化学习(五) - 时序差分学习(Temporal-Difference Learning)及其实例 5.1 TD预测 例5.1 回家时间的估计 5.2 TD预测方法的优势 例5.2 随机移动 5.3 ...

  9. 树状数组的理解(前缀和 and 差分)

    二更-- 有神仙反映数星星那个题外链炸了,我决定把图给你们粘一下,汉语翻译的话在一本通提高篇的树状数组那一章里有,同时也修改了一些汉语语法的错误 这段时间学了线段树组,当神仙们都在学kmp和hash的 ...

最新文章

  1. python画板颜色_教你在python中用不同的方式画不同颜色的画布
  2. ip分片 tcp分段(转)
  3. [分享]组织机构图控件
  4. 事务默认的传播属性和事务默认的隔离级别
  5. html click事件 参数,vue 实现click同时传入事件对象和自定义参数
  6. 将图片转换为base64_图片与base64相互转换
  7. 虚拟机安装ubuntu14.04.5系统
  8. mysql主库从库在同一台服务器_通过两种方式增加从库——不停止mysql服务
  9. LayaAir UI 组件 # CheckBox 复选框
  10. 计算机机房无尘,计算机机房建设标准
  11. 如何成为微信小程序的开发者?
  12. java代码取出EXCEL表数据并画折线图
  13. 起床综合困难症(位运算)
  14. python动态调用函数
  15. Edsger W. Dijkstra -- 巨人的肩膀
  16. python修改文件夹名字
  17. Hulu热招|广告智能团队
  18. 星期一到星期日的英文_缩写_读音_巧记方法
  19. 有损脑健康的七种坏习惯
  20. Dapr+Net6 服务调用09:集群指标收集-普罗米修斯

热门文章

  1. 神经网络检测Java溢出攻击
  2. 如何使用江苏电信的免费无线网
  3. 腾讯:专注于通用领域的知识图谱—Topbase 学习笔记
  4. 【BZOJ4384】【POI2015】Trzy wieże (……)
  5. C. Sweets Eating
  6. 媒体称广东可能开征新售住房房产税
  7. Centos设置屏幕不休眠
  8. 图像色彩通道分离与合并--opencv学习笔记
  9. Cortex-M3双堆栈MSP和PSP
  10. 编程艺术第二十三 四章 十一续 杨氏矩阵查找 倒排索引关键词Hash编码