繁体   English   中英

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

[英]Incorrect Multiplication/Division in Galois Field (2^8)

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

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

例:

//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;
}

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

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

我在这里错过了什么? 谢谢!

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

伽罗瓦域中的加法和乘法

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

首先,评论是错误的; 你保持指数在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)); 你应该找到它结账。

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

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

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

代码没有任何问题。 有限域乘法/除法与常规算法不同。 请参考cryptostackxchange中的这个问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM