【问题标题】:Incorrect Multiplication/Division in Galois Field (2^8)伽罗瓦域中不正确的乘法/除法 (2^8)
【发布时间】:2013-08-25 10:36:06
【问题描述】:

我正在尝试使用对数和指数表在 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;
}

/ 运算符是使用上面的 /= 覆盖实现的,因此没有什么特别的发生。

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

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

【问题讨论】:

  • 我很抱歉。是的,我已经实现了它,应该提到它。它基本上只是在 LHS 和 RHS 术语上使用 /= 并返回结果,所以没有什么花哨的。编辑了我的答案。

标签: c++ cryptography galois-field


【解决方案1】:

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

Addition and multiplication in a Galois Field

我认为你的代码还可以,但是你有两个问题。

首先,cmets 是错误的;您将指数保持在 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)); 有效的原因。这与你通常认为的五乘三等于十五无关。同样,对于您的其他工作测试用例,您会注意到它们大多涉及 2 的幂。

但是,“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));,您应该会发现它已结帐。

【讨论】:

  • 我知道(并且有意)将它放在 0~254 的范围内,正如我的评论中所解释的那样。感谢您解释有限域中的乘法概念。由于对有限域缺乏了解,我确实放下了糟糕的测试用例。
  • @jtcwang 但您的 代码 中的评论说 //this wraps the value to between 0~255
  • 将修复。感谢您发现
【解决方案2】:

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

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

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

【讨论】:

  • 顺便说一句,这不仅适用于 C++ %,而且一般适用于整数除法余数(模)。精度:当x 被签名时(例如int x),x % 255 可以计算为介于 -254 和 254(含)之间的整数(这就是为什么 OP 的代码是 ((t % 255) + 255) % 255 而不仅仅是 t % 255)。跨度>
  • 我之前尝试过,但它不起作用。以我对 GF(2^8) 的有限理解,exp/log 表的模式在第 255 个元素上重复。即元素 [1] 与 [255] 相同,因此做了 255 模数。
【解决方案3】:

代码没有问题。有限域乘法/除法不同于普通算术。请参考cryptostackxchange中的this question

【讨论】:

    猜你喜欢
    • 2015-07-10
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多