在JavaScript中计算模块化逆

Liz*_*iej 7 javascript algorithm rsa inverse modular-arithmetic

我试图采用ed = 1 mod((p-1)(q-1))并求解d,就像RSA算法一样.

e = 5,(p-1)*(q-1)= 249996

我在javascript中尝试了很多代码,例如:

function modInverse(){
var e = 5;
var p = 499;
var q = 503;
var d = e.modInverse((p-1) * (q-1));
DisplayResult(d, "privateKeyResultLabel")
}
Run Code Online (Sandbox Code Playgroud)

要么

function modInverse(){ 
System.out.println(BigInteger.valueOf(5).modInverse(BigInteger.valueOf(249996)));
}
Run Code Online (Sandbox Code Playgroud)

我只是无法弄清楚正确的方法来解决d,模块化逆,在javascript中.

Dip*_*ipu 6

这种模块化逆的实现可以接受任何类型的输入。如果不支持输入类型,NaN则返回。此外,它不使用递归。

function modInverse(a, m) {
  // validate inputs
  [a, m] = [Number(a), Number(m)]
  if (Number.isNaN(a) || Number.isNaN(m)) {
    return NaN // invalid input
  }
  a = (a % m + m) % m
  if (!a || m < 2) {
    return NaN // invalid input
  }
  // find the gcd
  const s = []
  let b = m
  while(b) {
    [a, b] = [b, a % b]
    s.push({a, b})
  }
  if (a !== 1) {
    return NaN // inverse does not exists
  }
  // find the inverse
  let x = 1
  let y = 0
  for(let i = s.length - 2; i >= 0; --i) {
    [x, y] = [y,  x - y * Math.floor(s[i].a / s[i].b)]
  }
  return (y % m + m) % m
}

// Tests
console.log(modInverse(1, 2))       // = 1
console.log(modInverse(3, 6))       // = NaN
console.log(modInverse(25, 87))     // = 7
console.log(modInverse(7, 87))      // = 25
console.log(modInverse(19, 1212393831))     // = 701912218
console.log(modInverse(31, 73714876143))    // = 45180085378
console.log(modInverse(3, 73714876143))     // = NaN
console.log(modInverse(-7, 87))     // = 62
console.log(modInverse(-25, 87))    // = 80
console.log(modInverse(0, 3))       // = NaN
console.log(modInverse(0, 0))       // = NaN
Run Code Online (Sandbox Code Playgroud)


Viv*_*han 5

我只是通过模块乘法逆的定义,并从我的理解:

ax = 1 (mod m)
=> m is a divisor of ax -1 and x is the inverse we are looking for
=> ax - 1 = q*m (where q is some integer)
And the most important thing is gcd(a, m) = 1
i.e. a and m are co-primes
Run Code Online (Sandbox Code Playgroud)

在你的情况下:

ed = 1 mod((p-1)(q-1)) //p, q and e are given 
=> ed - 1 = z*((p-1)(q-1)) //where z is some integer and we need to find d
Run Code Online (Sandbox Code Playgroud)

再次从维基百科条目中,可以使用扩展的欧几里德GCD算法计算模块化逆,其执行以下操作:

 ax + by = g //where g = gcd(a,b) i.e. a and b are co-primes
 //The extended gcd algorithm gives us the value of x and y as well.
Run Code Online (Sandbox Code Playgroud)

在你的情况下,等式将是这样的:

 ed - z*((p-1)(q-1)) = 1; //Compare it with the structure given above

 a -> e
 x -> d
 b -> (p-1)(q-1)
 y -> z
Run Code Online (Sandbox Code Playgroud)

因此,如果我们只是应用该算法这种情况下,我们将得到的数值dz.

因为ax + by = gcd(a,b),扩展的gcd算法看起来像():

 function xgcd(a, b) { 

   if (b == 0) {
     return [1, 0, a];
   }

   temp = xgcd(b, a % b);
   x = temp[0];
   y = temp[1];
   d = temp[2];
   return [y, x-y*Math.floor(a/b), d];
 }
Run Code Online (Sandbox Code Playgroud)

该算法在时间O(log(m)^ 2)中运行,假设| a | <m,并且通常比取幂更有效.

我不知道javascript中是否有内置函数.我怀疑是否存在,而且我是算法的粉丝,所以我想你可能想尝试这种方法.你可以摆弄它并改变它来处理你的价值范围,我希望它能让你开始朝着正确的方向前进.