我正在尝试使用日志和指数表在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表是否正确。
我在这里缺少什么?谢谢!
答案 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。