对FEAL-4的差分***
对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)<<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. 附录代码
- //Differential Cryptanalysis of FEAL-4
- //Uses a chosen-plaintext attack to fully recover the last round subkey
- //For use with tutorial at http://theamazingking.com/crypto-feal.php
- //Hack the Planet!
- #include <stdio.h>
- #include <math.h>
- //subkey为全局变量
- unsigned long subkey[6];
- //循环左移两位,先记录左移出的最高1位,在整体左移1位,
- //最高位再放到最低位。LL是unsigned long long赋值时的必须选择
- //实际a,b的取值只0~255,故最后要&=0xFFLL
- //long long 在vc6下没法通过,故用linux或vc2005
- //gcc -O3 feal4.c -o feal4
- unsigned long long shiftLeft2(unsigned long a)
- {
- unsigned long b;
- unsigned long carry = (a >> 7LL);
- carry &= 0x1LL;
- b = a << 1LL;
- b += carry;
- b &= 0xFFLL;
- carry = (b >> 7LL);
- carry &= 0x1LL;
- b <<= 1LL;
- b += carry;
- b &= 0xFFLL;
- return b;
- }
- //G函数
- unsigned long gBox(unsigned long a, unsigned long b, unsigned long mode)
- {
- return shiftLeft2((a + b + mode) % 256LL);
- }
- //轮函数
- unsigned long fBox(unsigned long plain)
- {
- //一个32BIT拆成4个8BIT
- unsigned long x0 = plain & 0xFFL;
- unsigned long x1 = (plain >> 8L) & 0xFFL;
- unsigned long x2 = (plain >> 16L) & 0xFFL;
- unsigned long x3 = (plain >> 24L) & 0xFFL;
- unsigned long t0 = (x2 ^ x3);
- unsigned long t1 = gBox(x0 ^ x1, t0, 1L);
- unsigned long y0 = gBox(x0, t1, 0L);
- unsigned long y1 = t1;
- unsigned long y2 = gBox(t0, t1, 0L);
- unsigned long y3 = gBox(x3, y2, 1L);
- //4个8BIT重组一个32BIT
- unsigned long ret = y3 << 24L;
- ret += (y2 << 16L);
- ret += (y1 << 8L);
- ret += y0;
- return ret;
- }
- unsigned long long encrypt(unsigned long long plain)
- {
- unsigned long left = (plain >> 32LL) & 0xFFFFFFFFLL;
- unsigned long right = plain & 0xFFFFFFFFLL;
- left = left ^ subkey[4];
- right = right ^ subkey[5];
- unsigned long round2Left = left ^ right;
- unsigned long round2Right = left ^ fBox(round2Left ^ subkey[0]);
- unsigned long round3Left = round2Right;
- unsigned long round3Right = round2Left ^ fBox(round2Right ^ subkey[1]);
- unsigned long round4Left = round3Right;
- unsigned long round4Right = round3Left ^ fBox(round3Right ^ subkey[2]);
- unsigned long cipherLeft = round4Left ^ fBox(round4Right ^ subkey[3]);
- unsigned long cipherRight = cipherLeft ^ round4Right;
- //32bit转64bit后的重组
- unsigned long long ret = (((unsigned long long)(cipherLeft)) << 32LL);
- ret += (((unsigned long long)(cipherRight)) & 0xFFFFFFFFLL);
- return ret;
- }
- void generateSubkeys(int seed)
- {
- srand(time(NULL));
- int c;
- //用两次rand函数更随机
- for(c = 0; c < 6; c++)
- {
- subkey[c] = rand() << 16L;
- subkey[c] += rand() & 0xFFFFL;
- }
- }
- int numPlain;
- unsigned long long plain0[10000];
- unsigned long long cipher0[10000];
- unsigned long long plain1[10000];
- unsigned long long cipher1[10000];
- unsigned long key3winner;
- void crackSubkey3ULTRA()
- {
- unsigned long fakeK;
- for(fakeK = 0x00000000L; fakeK < 0xFFFFFFFFL; fakeK++)
- {
- int score = 0;
- int c;
- for(c = 0; c < numPlain; c++)
- {
- unsigned long cipherLeft = (cipher0[c] >> 32LL);
- cipherLeft ^= (cipher1[c] >> 32LL);
- unsigned long cipherRight = cipher0[c] & 0xFFFFFFFFLL;
- cipherRight ^= (cipher1[c] & 0xFFFFFFFFLL);
- //Y没用
- unsigned long Y = cipherLeft ^ cipherRight;
- unsigned long Z = cipherLeft ^ 0x02000000L;
- unsigned long fakeRight = cipher0[c] & 0xFFFFFFFFLL;
- unsigned long fakeLeft = cipher0[c] >> 32LL;
- unsigned long fakeRight2 = cipher1[c] & 0xFFFFFFFFLL;
- unsigned long fakeLeft2 = cipher1[c] >> 32LL;
- unsigned long Y0 = fakeLeft ^ fakeRight;
- unsigned long Y1 = fakeLeft2 ^ fakeRight2;
- unsigned long fakeInput0 = Y0 ^ fakeK;
- unsigned long fakeInput1 = Y1 ^ fakeK;
- unsigned long fakeOut0 = fBox(fakeInput0);
- unsigned long fakeOut1 = fBox(fakeInput1);
- unsigned long fakeDiff = fakeOut0 ^ fakeOut1;
- if (fakeDiff == Z) score++; else break;
- }
- if (score == numPlain)
- {
- printf("DISCOVERED ROUND #4 SUBKEY = %08lx\n", fakeK);
- printf(" ACTUAL ROUND #4 SUBKEY = %08lx\n", subkey[3]);
- key3winner = fakeK;
- //不break应该能找到更多,可通过增加明/密文对去过滤
- //break;
- }
- }
- }
- void chosenPlaintext(unsigned long long diff)
- {
- srand(time(NULL));
- printf("PLAINTEXT DIFFERENTIAL = %llx\n\n", diff);
- int c;
- for(c = 0; c < numPlain; c++)
- {
- plain0[c] = (rand() & 0xFFFFLL) << 48LL;
- plain0[c] += (rand() & 0xFFFFLL) << 32LL;
- plain0[c] += (rand() & 0xFFFFLL) << 16LL;
- plain0[c] += (rand() & 0xFFFFLL);
- cipher0[c] = encrypt(plain0[c]);
- plain1[c] = plain0[c] ^ diff;
- cipher1[c] = encrypt(plain1[c]);
- }
- }
- int main()
- {
- generateSubkeys(time(NULL));
- printf("Imput the num of pairs:");
- scanf("%d",&numPlain);
- //numPlain = 6;
- chosenPlaintext(0x8080000080800000LL);
- unsigned long startTime = time(NULL);
- crackSubkey3ULTRA();
- unsigned long endTime = time(NULL);
- printf("Time to crack round #4 = %i seconds\n\n", (endTime - startTime));
- return 0;
- }
转载于:https://blog.51cto.com/linuxcumt/709624
对FEAL-4的差分***相关推荐
- MindArmour差分隐私
MindArmour差分隐私 总体设计 MindArmour的Differential-Privacy模块,实现了差分隐私训练的能力.模型的训练主要由构建训练数据集.计算损失.计算梯度以及更新模型参数 ...
- BZOJ.1558.[JSOI2009]等差数列(线段树 差分)
BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...
- 使用OpenCV,Python进行图像哈希(差分哈希 dHash)处理
使用OpenCV,Phthon进行图像哈希处理的一个重要应用是去除重复的图像: 当你有多个相册的图片,进行合并时,so boring,有一些图片是重复的,肉眼来看太难删除了. 图像哈希可以帮助你完美的 ...
- 基于运动信息的物体检测(背景差分法、帧间差分法和光流法)。
1.背景差分法: 它的基本思想是将输入图像与背景模型进行比较,通过判定灰度等特征的变化,或用直方图等统计信息的变化来分割运动目标. 首先建立好背景模型,存储背景图像.当当前帧与背景图像相减大于一定的阈 ...
- HDU1811 Rank of Tetris 拓扑排序+并查集 OR 差分约束最短路+并查集
题目链接 题意:就是给你一堆关系,看能不能排出个确定的顺序 做法: 1. 拓扑排序+并查集 应该很容易想到的一种思路,大于小于建立单向边.对于相等的呢,就把他们缩成一个点.就用并查集缩成一个点就行了 ...
- P3168 [CQOI2015]任务查询系统 差分+主席树
链接在这~:https://www.luogu.org/problem/P3168 主席静态区间修改,单点查询 区间(L,R)加1可以通过差分以后转换为L位置加1,R+1位置减1 我们只需要记录一下, ...
- ADPRL - 近似动态规划和强化学习 - Note 10 - 蒙特卡洛法和时序差分学习及其实例 (Monte Carlo and Temporal Difference)
Note 10 蒙特卡洛法和时序差分学习 Monte Carlo and Temporal Difference 蒙特卡洛法和时序差分学习 Note 10 蒙特卡洛法和时序差分学习 Monte Car ...
- 强化学习(五) - 时序差分学习(Temporal-Difference Learning)及其实例----Sarsa算法, Q学习, 期望Sarsa算法
强化学习(五) - 时序差分学习(Temporal-Difference Learning)及其实例 5.1 TD预测 例5.1 回家时间的估计 5.2 TD预测方法的优势 例5.2 随机移动 5.3 ...
- 树状数组的理解(前缀和 and 差分)
二更-- 有神仙反映数星星那个题外链炸了,我决定把图给你们粘一下,汉语翻译的话在一本通提高篇的树状数组那一章里有,同时也修改了一些汉语语法的错误 这段时间学了线段树组,当神仙们都在学kmp和hash的 ...
最新文章
- python画板颜色_教你在python中用不同的方式画不同颜色的画布
- ip分片 tcp分段(转)
- [分享]组织机构图控件
- 事务默认的传播属性和事务默认的隔离级别
- html click事件 参数,vue 实现click同时传入事件对象和自定义参数
- 将图片转换为base64_图片与base64相互转换
- 虚拟机安装ubuntu14.04.5系统
- mysql主库从库在同一台服务器_通过两种方式增加从库——不停止mysql服务
- LayaAir UI 组件 # CheckBox 复选框
- 计算机机房无尘,计算机机房建设标准
- 如何成为微信小程序的开发者?
- java代码取出EXCEL表数据并画折线图
- 起床综合困难症(位运算)
- python动态调用函数
- Edsger W. Dijkstra -- 巨人的肩膀
- python修改文件夹名字
- Hulu热招|广告智能团队
- 星期一到星期日的英文_缩写_读音_巧记方法
- 有损脑健康的七种坏习惯
- Dapr+Net6 服务调用09:集群指标收集-普罗米修斯