问题
After watching this video http://youtu.be/3QnD2c4Xovk
I've been trying to follow it step by step, and haven't been able to produce the same results.
Notably, when I try to do Math.pow(3, 54)%17, I get 7. While the speaker gets 15.
I wrote a method that is supposed to simulate Diffie Hellman's key exchange using exactly what I found on http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
This is my code:
function diffieHellman(generator, prime, alice_secret, bob_secret){
var alice_public = Math.pow(generator, alice_secret)%prime
, bob_public = Math.pow(generator, bob_secret)%prime
, alice_private = Math.pow(bob_public, alice_secret)%prime
, bob_private = Math.pow(alice_public, bob_secret)%prime;
console.log("alice"
, "\n\t", "secret -- ", alice_secret
, "\n\t", "public -- ", alice_public
, "\n\t", "private -- ", alice_private
)
console.log("bob"
, "\n\t", "secret -- ", bob_secret
, "\n\t", "public -- ", bob_public
, "\n\t", "private -- ", bob_private
)
return {
alice:{
secret: alice_secret
, public: alice_public
, private: alice_private
},
bob:{
secret: bob_secret
, public: bob_public
, private: bob_private
}
}
};
These examples work:
diffieHellman(3, 17, 4, 12) // 1, 1
diffieHellman(3, 23, 6, 19) // 12, 12
diffieHellman(3, 13, 8, 4) // 9, 9
However, some numbers don't work
diffieHellman(3, 17, 40, 120) // 13, 0
diffieHellman(3, 23, 16, 129) // 21, 2
diffieHellman(3, 13, 44, 11) // 9, 1
What am I doing wrong?
Edit -- I'm not trying to implement Diffie-Hellman's Key Exchange in Javascript for a project. It's just the language I'm most comfortable with, but I am afraid if this could be a javascript limitation.
回答1:
3^54 is 58149737003040059690390169. It causes an overflow, therefore you should implement modular exponentation, since i don't know javascript too well i have written a c code which should be easy to implement in javascript :
int power(int a, int b, int prime){
int result;
if(b == 0){
result = 1;
}else if(b == 1){
result = a % prime;
}else if(b % 2 == 0){
result = power((a*a) % prime, b/2, prime);
result = result % prime;
}else{
result = power((a*a) % prime, b/2, prime);
result = (result * a) % prime;
}
return result;
}
Now you can call this function :
int value = power(3, 54, 17);
and it should work.
Edit: added javascript version
function power(a, b, prime) {
if (b <= 0) {
return 1;
} else if (b === 1) {
return a % prime;
} else if (b % 2 === 0) {
return power((a * a) % prime, b / 2 | 0, prime) % prime;
} else {
return (power((a * a) % prime, b / 2 | 0, prime) * a) % prime;
}
}
回答2:
The problem is the limited precision of Javascript numbers that causes rounding errors in your code where you first exponentiate and then calculate the modulus. For your example numbers, you could fix this by periodically calculating the modulus inside the exponentiation, e.g. by never calculating more than a square before taking the modulus. But for actual cryptography your calculations will involve numbers too big to be handled as Javascript numbers (and most programming languages pose the same problem). The usual approach is to use a large integer (or even arbitrary precision) library. If you do end up implementing your own cryptography, please watch out for side channels, e.g. by calling library functions that are not constant time or allow cache-based attacks by using data dependent array indices.
来源:https://stackoverflow.com/questions/24677932/diffie-hellman-key-exchange-with-javascript-sometimes-wrong