关于AES的列混合计算和解密流程问题
我们知道AES的加解密过程都可以用有限域中的计算表示出来。关于AES的加解密过程,很多教材资料都有详细描述,这里我想强调①关于AES加密过程中的MixColumn阶段是如何计算的;②AES的解密流程问题。
关于AES算法的全部代码可以看这个AES加解密算法全过程实现(C++)
AES的列混合计算
我们经常会看到参考资料说AES的列混合过程是对状态矩阵的每一列左乘一个确定的矩阵(如下图),一般表示为
然后我们乘了之后会发现结果并不对。事实上,这里表示的并不是简单的矩阵乘法,而是上的多项式模乘。
从AES的列混合定义说起
列混合的定义是:MixColumn(State)是将状态矩阵的每一列看成上的一个多项式,且与一个固定的多项式相乘后模。例如:对于状态矩阵的某一列
看成多项式,列混合就是计算。这样的定义也才是符合"AES的加解密过程都可以用有限域中的计算表示出来"这句话嘛。
那问题来了,这个多项式相乘的计算怎么就成上述的矩阵形式?这就关乎这个多项式了。对于任意,有。例如:。根据这个事实,我们可以计算多项式相乘再取模的结果(在计算时,就等于,就等于,就等于1):
把上述结果写成矩阵形式,不正是
所以现在你懂了这个矩阵式子表达的意思了吧。
如何计算
那这个矩阵如何计算呢?对于上面的矩阵,我们有。这里的02要转化成上的多项式。(因为02=00000010,写成多项式就是)同理,03,01和每个都要写成上的多项式,乘法和加法都是模上的加法和乘法(这是AES选的上的不可约多项式)。
简化计算
模的加法很简单,就直接异或。乘法计算就比较复杂了。其实多项式相乘本就比较麻烦,这里还要模,而且这个很不友好,不像模那么有特点,所以这个多项式模乘需要寻找更好的方法。这里就介绍一种较为方便的方法。我们观察上面的矩阵,发现每个只需乘01、02、03这3个数,并不用乘其他数,所以只要知道如何乘01,02,03即可。
乘01
01表示成多项式就是1,对任何,,再模依旧是。
乘02
02表示多项式,对任何,相当于先把表示的二进制串左移1位。移位后,若首位上是1,则再将该二进制串的后8位异或0x1b得到结果;若首位上是0,取后8位就是结果。例如:, 转化乘二进制就是00100011,应该这么计算:先左移1位成为001000110,首位(最左边)上是0,所以后8位01000110=0x46就是结果。再如,转化成二进制是10100011,计算:左移一位得101000110,首位是1,则取后8位异或0x1b得01011101,即0x5d。
为什么是这样算?很简单,由于02表示多项式x,相当于的多项式乘x,也就是多项式系数不变,每一项次数加1,这不就是相当于左移一位嘛。再一步,要模:如果乘完之后的多项式次数小于8,就不用模了,这就是上面说的首位为0的情况;如果乘完之后多项式次数等于8,就要模,但是稍加分析会发现此时的多项式一定是小于,所以模的余式就相当于减的结果,我们知道,上的减就是异或,的后8位表示成16进制就是0x1b,所以异或0x1b,此时对应着上面的首位是1的情况
乘03
知道了01和02的乘法,03=01+02,可以利用分配律计算出03。
例如:.
在AES解密的时候,也可以通过这种方法计算。
解密流程
我们知道加密过程每一轮的轮函数包括:字节替换、行移位、列混合、轮密钥加,并且顺序是固定的。需要指出的是,解密时的轮函数的顺序是:逆行移位、逆字节替换、轮密钥加、逆列混合。如果不理解的看下图便很明白!