计算机如何计算没有溢出错误的指数数学?


32

通过研究一些RSA加密/解密方法,我发现了这篇文章:RSA算法的示例

它需要此来解密此消息 在此处输入图片说明

的总结果在此处输入图片说明是如此之大,对于一台64位/ 32位计算机,我不认为它可以在一个寄存器中保存这么大的值。计算机如何做到无溢出?


这个问题是本周超级用户问题
阅读博客条目以获取更多详细信息,或者自己撰写博客


6
我想知道如果将其迁移到cs.stackexchange.com,是否会得到更好的答案。在CS / Math网站上似乎更合适,因为CS / Math网站更着重于低水平的实际细节。
Zoredache

1
这对于超级用户足够有效。
詹姆斯·默兹

Answers:


40

因为整数模运算是ℤ->ℤ/nℤ的一个环同态(Wikipedia),

(X * Y) mod N = (X mod N) * (Y mod N) mod N

您可以使用一些简单的代数来验证自己。(请注意,mod由于在模块化环中定义了乘法,因此出现了最后的最后一行。)

计算机使用此技巧可以在模块化环中计算指数,而不必计算大量数字。

               / 1 I = 0,
               |
(X ^ I)mod N = <(X *(X ^(I-1)mod N))mod NI奇数,
               |
               \(X ^(I / 2)mod N)^ 2 mod NI偶数&I / = 0。

以算法形式,

-- compute X^I mod N
function expmod(X, I, N)
    if I is zero
        return 1
    elif I is odd
        return (expmod(X, I-1, N) * X) mod N
    else
        Y <- expmod(X, I/2, N)
        return (Y*Y) mod N
    end if
end function

(855^2753) mod 3233如果愿意,可以使用它仅用16位寄存器进行计算。

但是,RSA中的X和N值要大得多,太大而无法放入寄存器中。模数通常为1024-4096位长!因此,您可以让计算机以“长”方式进行乘法,就像我们手动进行乘法一样。计算机将只使用“单词” 0-2 16 -1或类似的字词,而不是使用数字0-9 。(仅使用16位意味着我们可以将两个16位数字相乘并获得完整的32位结果,而无需诉诸汇编语言。在汇编语言中,通常很容易获得完整的64位结果,或者对于64位计算机,即完整的128位结果。)

-- Multiply two bigints by each other
function mul(uint16 X[N], uint16 Y[N]):
    Z <- new array uint16[N*2]
    for I in 1..N
        -- C is the "carry"
        C <- 0
        -- Add Y[1..N] * X[I] to Z
        for J in 1..N
            T <- X[I] * Y[J] + C + Z[I + J - 1]
            Z[I + J - 1] <- T & 0xffff
            C <- T >> 16
        end
        -- Keep adding the "carry"
        for J in (I+N)..(N*2)
            T <- C + Z[J]
            Z[J] <- T & 0xffff
            C <- T >> 16
        end
    end
    return Z
end
-- footnote: I wrote this off the top of my head
-- so, who knows what kind of errors it might have

这将在X上将X乘以Y的时间大约等于X上的单词数乘以Y上的单词数。这称为O(N 2)时间。如果您看一下上面的算法并将其分开,那就是他们在学校教的相同的“长乘法”。您没有可存储10位数字的时间表,但是如果您坐下来计算出来,仍然可以乘以1,926,348 x 8,192,004。

长乘法:

    1,234
  x 5,678
---------
    9,872
   86,38
  740,4
6,170
---------
7,006,652

实际上,周围有一些乘法运算的更快算法(Wikipedia),例如Strassen的快速傅立叶方法,还有一些更简单的方法,它们进行额外的加法和减法,但乘法次数较少,因此总体上更快。诸如GMP之类的数字库能够根据数字的大小来选择不同的算法:对于最大的数字,傅里叶变换只是最快的,对于较小的数字,傅里叶变换则使用较简单的算法。


+1,但是mod N在中国余数定理的末尾您却错过了一个额外的东西。((16 mod 5)不等于(4 mod 5) * (4 mod 5):前者是1,后者是16。)
ruakh

@ruakh:已更正。尽管我真的想说,R / kR与R / k1R x R / k2R x ... R / knR同构,其中k1..kn是成对的互质数,它们的乘积是k,R是主要的理想域。我已经超载*了这么久,很难看到它的任何东西,但模块化。换句话说,按照我通常的符号约定,这mod是多余的。
Dietrich Epp

1
@Synetech:但是我非常喜欢这四个词:“为读者而运动”。
Dietrich Epp

1
(X * Y) mod N = (X mod N) * (Y mod N) mod N是对的,但这与中国剩余定理没有关系。
丹尼斯

1
@丹尼斯:我现在在答案中阐明了共域的结构。(对我而言,这从来都不是模棱两可,因为我写了它……)
Dietrich Epp

9

答案很简单,那就是他们做不到,不是靠自己。确实,如果采用x位机的概念,那么可以用有限数量的位数表示有限数量的数字,就像可以用2位数字表示的数量有限一样十进制系统。

话虽如此,大量计算机表示是密码学领域的重要组成部分。有许多种方法可以在计算机中表示非常大的数字,每种数字都与之不同。

这些方法中的每一种都有不同的优点和缺点,尽管我没有/不能在这里列出所有方法,但我将只介绍一种。

假设整数只能容纳0-99之间的值。一个人怎么能代表100?起初这似乎是不可能的,但这是因为我们只考虑了一个变量。如果我有所谓的整数units和一个叫hundreds,我可以很容易地代表100: hundreds = 1; units = 0;。我可以轻松地代表更大的数字,例如9223 :hundreds = 92; units = 23

尽管这是一种简单的方法,但可以认为它效率很低。像大多数限制计算机功能的算法一样,这通常是功耗(代表大量数字)和效率(快速检索/存储)之间的一场拉锯战。就像我之前说的,有很多方法可以表示计算机中的大数。只要找到一种方法并尝试一下即可!

希望这能回答您的问题!

进一步阅读:文章和一个可以派上用场以获取更多信息。


3

可以做到这一点的方式(有更快的方法涉及重复平方等)是通过相乘,并且在每次相乘后取模。只要模数平方小于2 ^ 32(或2 ^ 64),就永远不会溢出。


3

用同样的方法。

我猜想您不会立即知道342 * 189是什么。但是您确实知道以下事实:

9 * 2 = 18
9 * 4 = 36
9 * 3 = 27
8 * 2 = 16
8 * 4 = 32
8 * 3 = 24
1 * 2 = 2
1 * 4 = 4
1 * 3 = 3

18 + 360 + 2700 + 160 + 3200 + 24000 + 200 + 4000 + 30000 = 64638

通过了解这些简单的事实,并学会了一种操作它们的技术,您可以进行原本无法做到的算术运算。

同样,一台不能同时处理超过64位数学运算的计算机可以轻松地将较大的问题分解成较小的部分,再将这些较小的部分分解,然后重新组合起来,以解决先前较大的问题。无法回答的问题。


0

就加法和减法而言,如果算术运算已溢出,则许多CPU都有一个“进位”设置。因此,如果结果需要存储8个字节,并且CPU是32位(相当于4个8位字节),则它可以执行两个加法运算,首先是“低位字”,然后是“高位字”进位位可以防止溢出。必须先清除进位。这是为什么更高位数的CPU可以提高性能的原因之一,因为不必这样做。

当然,这是基于我有限的8位CPU汇编程序经验。我不知道带有乘法和除法指令的现代CPU的进位位是如何工作的。非Intel RISC CPU的行为也可能有所不同。

我对浮点数学不是很了解,但是基本上字节代表固定数量的位,但没有特定的位。这就是为什么它被称为“浮动”点。因此,例如,数字34459234将消耗与3.4459234或3.4459234E + 20大致相同的内存空间(即3.4459234 x 10 ^ 20)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.