6

我只是在做一些与大学相关的 Diffie Hellmann 练习,并尝试使用 ruby​​。可悲的是,ruby 似乎无法处理大指数:

警告:在 a**b 中,b 可能太大
NaN
[...]

有什么办法围绕它吗?(例如特殊的数学课或类似的东西?)

ps这里是有问题的代码:

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
4

8 回答 8

10

您需要执行所谓的模幂运算

于 2009-11-18T20:09:55.193 回答
3

如果您可以使用 OpenSSL 绑定,那么您可以在 Ruby 中进行快速模幂运算

puts some_large_int.to_bn.mod_exp(exp,mod)
于 2012-04-17T18:03:40.450 回答
2

有一种很好的方法来计算 a^b mod n 而无需获得这些巨大的数字。

您将自己完成求幂,在每个阶段取模。有一个技巧,您可以将其分解为一系列 2 的幂。

这是一个使用它来执行 RSA 的示例的链接,来自我不久前参加的一门课程:具体来说,在第二页上,您可以看到一个示例: http: //www.math.uwaterloo.ca/~cd2rober/Math135 /RSAExample.pdf

来自维基百科的一些示例伪代码的更多解释:http ://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method

于 2009-11-18T20:17:48.807 回答
1

我不知道 ruby​​,但即使是对 bignum 友好的数学库也很难以天真的方式评估这样的表达式(7789 的 415492 次方大约有 160 万位数字)。

a^b mod p不爆炸的情况下解决问题的方法是在每次取幂时mod p进行ing - 我猜该语言无法自行解决此问题,因此必须得到帮助。

于 2009-11-18T20:10:47.470 回答
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​​ 的主要类来做任何实质性的事情都是一个糟糕的主意。Ruby 使用 Eratosthenes 筛作为它的主要生成器,但更糟糕的是,它对 gcd 等使用 Trial 除法......

哦,@@mod 是一个类变量,所以如果你打算自己使用它,你可能想将它添加为参数或其他东西。我已经让它很快工作了

把 a.exponentiation (100000000000000, 1222555345678)

该范围内的数字。

(使用@@mod = 80233)

于 2009-11-23T03:38:35.897 回答
1

好的,可以使用平方方法

a = Mod.new(80233788)
puts a.exponentiation(298989898980988987789898789098767978698745859720452521, 12225553456987474747474744778)

输出:59357797

我认为这应该足以解决您在加密课程中可能遇到的任何问题

于 2009-11-23T03:55:48.060 回答
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 测试的结果

于 2014-02-22T22:47:55.293 回答
0

这是受维基百科上从右到左的二进制方法示例的启发:

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
于 2016-03-18T21:32:34.793 回答