我试图采用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")
}
或
function modInverse(){
System.out.println(BigInteger.valueOf(5).modInverse(BigInteger.valueOf(249996)));
}
我无法在javascript中找出解决d模块化逆的正确方法。
答案 0 :(得分:5)
我刚刚完成modular multiplicative inverse的定义,并从我理解的内容开始:
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
在你的情况下:
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
再次从wikipedia entry,可以使用执行以下操作的extended Euclidean GCD Algorithm来计算模块化逆:
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.
在你的情况下,等式将是这样的:
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
因此,如果我们只将该算法应用于此案例,我们将获得d
和z
的值。
对于ax + by = gcd(a,b)
,扩展gcd算法看起来像(source):
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];
}
该算法在时间 O(log(m)^ 2)中运行,假设| a | < m,并且通常比取幂更有效。
我不知道javascript中是否有内置函数。我怀疑是否存在,而且我是算法的粉丝,所以我想你可能想尝试这种方法。你可以摆弄它并改变它来处理你的价值范围,我希望它能让你开始朝着正确的方向前进。
答案 1 :(得分:1)
这是我在javascript中使用模块化逆函数的版本。它可以接受任何类型的输入。如果输入无效,则仅返回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)) // = 25
console.log(modInverse(7, 87)) // = 7
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