伽罗瓦域中的乘法/除法不正确(2 ^ 8)

时间:2013-08-25 10:36:06

标签: c++ cryptography galois-field

我正在尝试使用日志和指数表在GF(2 ^ 8)中实现乘法和除法。我使用指数3作为我的生成器,使用来自here的指令。

但是我失败了一些琐碎的测试用例。

示例:

//passes  
assert((GF256elm(4) / GF256elm(1)) == GF256elm(4));  
assert((GF256elm(32) / GF256elm(16)) == GF256elm(2));  
assert((GF256elm(15) / GF256elm(5)) == GF256elm(3));  
assert((GF256elm(88) / GF256elm(8)) == GF256elm(11));  
//fails, but should pass
assert((GF256elm(77) / GF256elm(11)) == GF256elm(7));
assert((GF256elm(77) / GF256elm(7)) == GF256elm(11));  

前四行通过,但是在第5行和第6行都失败了。
经过进一步调查后,我发现当存在“包裹”时会发生这些错误,即log3(a) + log3(b) > 255(乘法情况)或log3(a) - log3(b) < 0。然而,该值是“修改的”,使得它们使用真模数保持在0~255。

GF256elm& GF256elm::operator/=(const GF256elm& other) { //C++ operator override for division
    int t = _logTable[val] - _logTable[other.val]; //log3(a) - log3(b)
    int temp =  ((t % 255) + 255) % 255; //this wraps the value to between 0~254 inclusive.
    val = _expTable[temp];
    return *this;
}

/运算符是使用上面的/=覆盖实现的,所以没有特别的事情发生。

我已检查生成的log / exp表是否正确。

我在这里缺少什么?谢谢!

3 个答案:

答案 0 :(得分:4)

首先,仔细阅读这个问题及其所有答案和评论:

Addition and multiplication in a Galois Field

我认为您的代码没问题,但您有两个问题。

首先,评论是错误的;你保持指数在0-254范围内,而不是0-255。

其次,你的“琐碎”测试案例是错误的。

在此字段中,将数字视为多项式,其系数来自数字的二进制表示。例如,由于5 = 2 ^ 2 + 1,在该字段中“5”表示x ^ 2 + 1。

所以“5”*“3”=(x ^ 2 + 1)*(x + 1)= x ^ 3 + x ^ 2 + x + 1,或“15”。这就是您的测试用例assert((GF256elm(15) / GF256elm(5)) == GF256elm(3));有效的原因。它与你通常认为五次三等于十五的概念无关。同样地,对于您的其他工作测试用例,您将注意到这些测试用例主要涉及两个权限。

然而,“7”*“11”=(x ^ 2 + x + 1)*(x ^ 3 + x + 1)= x ^ 5 + x ^ 4 + 2x ^ 3 + 2x ^ 2 + 2x + 1

但是系数都是模2,所以这实际上是x ^ 5 + x ^ 4 + 1 =“49”。这就是你最后两个测试用例失败的原因。

如果您尝试assert(GF256elm(49) / GF256elm(7) == GF256elm(11));,您应该会检查它。

答案 1 :(得分:0)

x % n的计算结果为0到(n - 1)之间的整数。

这意味着x % 255的计算结果为0到254之间的整数,而不是0到255之间。

您应该使用256替换255,或者使用0xff执行按位AND以获得相同的结果。后者更快,尽管编译器很可能足够聪明,可以将它们优化为相同的字节码。

答案 2 :(得分:0)

代码没有问题。有限域乘法/除法与常规算法不同。请参阅cryptostackxchange中的this question