最近我有理由比较 Blowfish 算法。我正在比较DI Management的库和 PHP 的mcrypt的输出。我无法让他们以任何方式同意。
这使我进行了一次有趣的追逐。根据Bruce Schneier 网站上的这篇帖子,Blowfish 代码的早期版本中存在符号扩展错误,并且似乎 DI 管理代码实现了预错误报告代码。
错误报告中的简介部分说,
bfinit(char *key,int keybytes)
{
unsigned long data;
...
j=0;
...
data=0;
for(k=0;k<4;k++){
data=(data<<8)|key[j];/* choke*/
j+=1;
if(j==keybytes)
j=0;
}
...
}
每当 key[j] 的最高有效位是“1”时,它就会阻塞。例如,如果 key[j]=0x80,则 key[j],一个有符号字符,在与数据进行 OR 运算之前将符号扩展为 0xffffff80。
blf_Initialise
basBlowfish.bas中函数的等效代码是
wData = &H0
For k = 0 To 3
wData = uw_ShiftLeftBy8(wData) Or aKey(j)
j = j + 1
If j >= nKeyBytes Then j = 0
错误报告建议对 C 代码进行以下修复:
data<<=8;
data|=(unsigned long)key[j]&0xff;
我在 VB6 中实现为
wData = uw_ShiftLeftBy8(wData)
wData = wData Or ( aKey(j) And &HFF )
事实上,我已经编写了它以便使用这两种方法,然后放入一个断言来检查值是否相同,即:
wData = uw_ShiftLeftBy8(wData)
wData = wData Or (aKey(j) And &HFF)
wDCheck = uw_ShiftLeftBy8(wData) Or aKey(j)
Debug.Assert wData = wDCheck
当 aKey(j) 包含 255 时,我得到一个断言错误。
我读对了这种情况吗?是出现符号扩展错误还是我看到不存在的错误?
奇怪的是,DI 管理代码附带的测试似乎在有和没有这种变化的情况下都能正常工作(这可能意味着我对两种算法之间等价性的搜索可能取决于其他东西。)