首先说,除去人为因素的干预下(比如代码写得太烂,对比平台不公平等),现有的技术水平下,RSA无论是加密还是解密,一般是要比同长度的AES慢的。选择特定参数,比如e=65537,是会使得加密比解密快很多,但与AES仍然不是一个量级。事实上,RSA-OAEP在RSA加密前就需要两个Hash运算:直观上,这两个HASH运算与AES就是一个级别的复杂度,甚至用时会超过AES。
造成这种现象的本质,在于基础运算的不同。RSA的基本运算是模幂,模的部分有优化算法处理,暂且不谈,我们只看幂运算本身:幂运算的基础单位是乘法,而乘法的基础单位是加法。这个加法,就是我们最熟悉,最常见的整数加。尽管如此,如果学过数字逻辑或者硬件设计的话,应该听说过这个“加法”在电路上比异或(XOR)要麻烦的多。有各种超前进位,并行进位的加法器设计,但没听说有什么异或器设计,是不是?
我们以5+9和5 xor 9的二进制运算为例:
0101 (5) 0101 (5)
+ xor
1001 (9) 1001 (9)
------------- -------------
1110 (14) 1100 (13)
如果手算一下上面这个过程,你会明显看到,XOR的每个比特运算完全独立,与前后的比特无关;而加法的每个比特均需要考虑低位的进位。这样,计算最高位时,原则上需要等待低位的所有比特计算完毕,而异或并没有这个限制。这个现象称为进位链(carry chain): 尽管可以用各种技术降低它的影响,但从根本上,它使得加法很难与异或得到相同的效率。
现有的处理器可以提供单周期的加法或者乘法操作,但这里的前提是: 1) 付出了额外的电路资源 2)固定了位宽,比如32bit或者64bit;3)根据木桶短板的方式拉低了主频,比如单做xor可能可以提高主频,但为了考虑加法,降低了实际提供的主频。也就是说,对于任意长度电路计算,异或仍要比加密高效得多。
RSA目前的推荐长度至少2048,即使用中国剩余定理,也需要1024bit的幂运算,即大量的1024bit的加法。考虑一下1024bit的进位链对于最高位的压力,就很好理解它在速度上的劣势了。
相反,如果是1024bit的AES,分组可能就是先拆分成16个128-bit AES。AES的基础运算实际有3种,Sbox,XOR以及移位。在现有的CMOS数字逻辑里,移位代价极低。异或前面说过,代价较低。唯一代价较高的运算是Sbox: 然而,尽管8bit的Sbox可能比8-bit的加法器更慢,但AES也只使用8-bit的Sbox而已。每轮的16个Sbox之间并没有关系,完全可以并行。此外,尽管操作复杂,由于空间很小,只有256种可能,完全可以预计算结果,进行查表处理。这也是Sbox最常见的处理方法:尽管存储器的读取速度依然比CPU低一个量级,相比于1024bit的进位链,依然有很大的优势。反过来,1024bit的加法空间太大,显然是没有办法进行预计算查表处理的。
但是,从上面这个论述中也能看到,两者实际达到的效果也有不小的差距。安全性论述起来很复杂,但简单来说,RSA可以提供很多复杂的应用,而AES,即使套用了很多复杂的工作模式,也很难达到相同的覆盖面。许多公钥系统的价值更多体现在它能提供的特定安全功能上,而不是能快速完成文本加密。