我正在做一些与大学相关的Diffie Hellmann练习,并尝试使用红宝石。 可悲的是,红宝石似乎无法处理大型指数:
警告:在** b中,b可能太大了 NaN的
[...]
周围有什么办法吗? (例如,一个特殊的数学课或那条线上的东西?)
P.S。这是有问题的代码:
generator = 7789
prime = 1017473
alice_secret = 415492
bob_secret = 725193
puts from_alice_to_bob = (generator**alice_secret) % prime
puts from_bob_to_alice = (generator**bob_secret) % prime
puts bobs_key_calculation = (from_alice_to_bob**bob_secret) % prime
puts alices_key_calculation = (from_bob_to_alice**alice_secret) % prime
答案 0 :(得分:10)
您需要执行所谓的modular exponentiation。
答案 1 :(得分:3)
如果你可以使用OpenSSL绑定,那么你可以在Ruby中进行快速模幂运算
puts some_large_int.to_bn.mod_exp(exp,mod)
答案 2 :(得分:2)
有一种很好的方法来计算^ b mod n而不会获得这些巨大的数字。
你将自己走一条指数,在每个阶段取模数。 有一个技巧,你可以将其分解为一系列的两个权力。
这是一个链接,其中有一个使用它来做RSA的例子,来自我前一段时间的课程: 具体来说,在第二页上,您可以看到一个示例: http://www.math.uwaterloo.ca/~cd2rober/Math135/RSAExample.pdf
使用维基百科的一些示例伪代码进行更多解释:http://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method
答案 3 :(得分:1)
我不知道红宝石,但即使是一个对bignum友好的数学库也很难以天真的方式评估这样的表达方式(7789对权力415492有大约160万位)。
在没有爆炸的情况下解决a^b mod p
的方法是在每次取幂时进行mod p
ing - 我猜这种语言不能正常运行它本身,因此必须得到帮助。
答案 4 :(得分:1)
我已经做了一些自己的尝试。到目前为止,通过平方的指数运作良好,但与bigNum相同的问题。
这样一个递归的东西def exponentiation(base, exp, y = 1)
if(exp == 0)
return y
end
case exp%2
when 0 then
exp = exp/2
base = (base*base)%@@mod
exponentiation(base, exp, y)
when 1 then
y = (base*y)%@@mod
exp = exp - 1
exponentiation(base, exp, y)
end
end
但是,正如我所知道的那样,依靠红宝石的黄金级别来做任何实质性的事情都是一个可怕的想法。 Ruby使用了Eratosthenes的Sieve作为它的主要生成器,但更糟糕的是,它使用了试验分区用于gcd等......
哦,@@ mod是一个类变量,所以如果你打算自己使用它,你可能想把它作为一个参数添加。
我已经很快就能开始工作了将a.exponentiation(100000000000000,1222555345678)
该范围内的数字。
(使用@@ mod = 80233)
答案 5 :(得分:1)
好的,让平方法适用于
a = Mod.new(80233788)
puts a.exponentiation(298989898980988987789898789098767978698745859720452521, 12225553456987474747474744778)
输出:59357797
我认为这应该足以解决您在加密课程中遇到的任何问题
答案 6 :(得分:0)
如果你真的想要进行BIG模幂运算,这里是wiki页面的一个实现。
#base expantion number to selected base
def baseExpantion(number, base)
q = number
k = ""
while q > 0 do
a = q % base
q = q / base
k = a.to_s() + k
end
return k
end
#iterative for modular exponentiation
def modular(n, b, m)
x = 1
power = baseExpantion(b, 2) #base two
i = power.size - 1
if power.split("")[i] == "1"
x = x * n
x = x % m
end
while i > 0 do
n *= n
n = n % m
if power.split("")[i-1] == "1"
x *= n
x = x % m
end
i -= 1
end
return x
end
使用wolfram alpha进行测试的结果
答案 7 :(得分:0)
这受到维基百科上的example示例的启发:
def powmod(base, exponent, modulus)
return modulus==1 ? 0 : begin
result = 1
base = base % modulus
while exponent > 0
result = result*base%modulus if exponent%2 == 1
exponent = exponent >> 1
base = base*base%modulus
end
result
end
end