【问题标题】:Get modulo from two 4x64bit integer arrays从两个 4x64 位整数数组中取模
【发布时间】:2020-09-25 21:59:30
【问题描述】:

我使用 OpenCL 进行 GPGPU 编程,但不幸的是没有原生的 256 位整数支持。我决定将 256 位整数拆分为四个 64 位整数。基本操作的很好的解决方案,但我怎样才能得到它们的模数?

我需要这样做:

(uint256) % (uint256)

但是使用 OpenCL,我只能拥有这个:

[ (uint64), (uint64), (uint64), (uint64) ] % [ (uint64), (uint64), (uint64), (uint64) ]

那么我该如何实现呢?我应该使用什么算法,最重要的 - 什么是最容易实现的?

附:我需要它来进行公钥加密。

编辑:我没有实现加法和减法。

【问题讨论】:

  • 谢谢!你有什么推荐的读物吗?
  • 你能用铅笔做你想做的事吗?找一只橡皮鸭……慢慢说……你考虑过一些扩展的精度库吗?所以......看起来你还没有尝试过任何东西。请查看minimal reproducible example
  • 我试图在谷歌上搜索它,但我没有找到任何东西。 OpenCL不像C/C++,没有gmp之类的库。
  • "我没有实现加法和减法。" --> 你需要加法方面的帮助吗?
  • 加减法。我将不胜感激。

标签: c++ c algorithm math opencl


【解决方案1】:

这是一个简单(且相当高效)的算法,它仅使用减法、乘以 2、除以 2 和比较来计算 a % b(所有这些都易于为您的 uint256 实现)。

uint256 modulo(uint256 a, uint256 b) {
  int i = 0;
  while (b <= a) {
    b = b * 2; // watch out for overflow!
    i++;
  }
  while (i--) {
    b = b / 2;
    if (b <= a) {
      a = a - b;
    }
  }
  return a;
}

这是一个例子:

start: a = 40, b = 7
i = 1, a = 40, b = 14
i = 2, a = 40, b = 28
i = 3, a = 40, b = 56

i = 3, b = 28, a = 40 - 28 = 12
i = 2, b = 14, a = 12 (b > a so nothing happens)
i = 1, b = 7, a = 12 - 7 = 5
i = 0, so we stop and return a = 5

编辑:为什么这样有效? 如果满足以下条件,则计算模余数的天真方法:

int modulo(int a, int b) {
  while (a >= b) {
    a -= b;
  }
  return a;
}

建议的解决方案使用相同的想法,但以更有效的方式。我们知道我们最终会从a 中减去b 正好是k 次。我们不知道k 的值。 k 可以二进制表示为2^0 * k_0 + 2^1 * k_1 + 2^2 * k_2 + ...。该算法从 2^i 的最大值开始,并尝试减去 2^i * b。因此,我们实现了对数时间复杂度而不是线性时间复杂度。

免责声明:我不会使用这个实现是真正的加密实现,因为它容易受到侧通道攻击(不同的执行时间取决于输入)。

【讨论】:

  • 好吧,我已经问过如何为两个 4x64 位整数数组实现取模,而不是两个 uint256。关键是我只能使用 64 位整数。
  • @AlexanderSadovskyi 您提到“基本运算的非常好的解决方案”,所以我假设您已经实现了减法等基本运算。上述算法适用于任何整数实现,只要您可以执行开头提到的 4 个操作即可。只需更换例如b = b * 2 实现将 uint256 乘以 2(这很简单)等。
  • 我的意思是基本的按位运算。我没有实现任何东西,因为我唯一需要的是取模。
  • 能否请您添加一种方法来思考为什么会这样?
  • @גלעדברקן 添加说明
猜你喜欢
  • 2011-09-12
  • 2016-03-11
  • 2012-06-11
  • 2022-01-25
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
  • 2016-12-15
相关资源
最近更新 更多