如何解决双精度数据类型和uint64之间的精度差异

时间:2019-07-28 09:34:48

标签: matlab modular-arithmetic block-cipher

我正在使用MATLAB实现三鱼分组密码。首先,我在uint8数字上实现了该算法以验证我的代码。一切正常,解密成功。但是当我将数字替换为uint64时,纯文本无法正确检索。
我一遍又一遍地追踪结果,以找出原因,但到目前为止我找不到。加密和解密之间的前四个数字有所不同,即沿x循环加密为9824265115183455531,但解密为9824265115183455488。

我认为这种差异背后的原因是在函数AddMod64和SubMod64中找到了幂64的算术模2。但是到目前为止,我真的无法解决它。

我知道

    double(2^64) = 18446744073709552000

uint64(2^64) = 18446744073709551615 % z = ( x + y ) % 2^64
function z = AddMod64(x , y)
    m = uint64(2^64);
    z = double(mod(mod(double(x),m)+mod(double(y),m),m));
end
% z = (x - y ) % 2^64
function z = SubMod64(x , y)
    m = uint64(2^64);
    z = double(mod(mod(double(x),m) - mod(double(y),m),m)); 
end

1 个答案:

答案 0 :(得分:1)

double(2^64)已经是错误的结果,double类型最多只能容纳2^52-1作为整数,而不能四舍五入。

此外,当您执行uint64(2^64)时,将使用double计算功效,得出错误的结果,然后将其转换为uint64。而且,由于uint64保持的最大值是2 ^ 64-1,所以整个操作是错误的。

改为使用maxint

m = maxint('uint64');

在MATLAB中进行模加法非常棘手,因为MATLAB使用整数进行饱和算术运算。在进行计算之前,您需要测试溢出。

if x > m - y
   x = y - (m - x + 1);
else
   x = x + y
end