The Diffie-Hellman key exchange protocol (RFC2641) is an efficient way for two parties (that do not know each other beforehand) to establish a shared secret. This secret can then be used for encrypted communication between the two parties. Because of the simplicity of the algorithm it is a feasible to implement it in Javascript. It could serve as a way to communicate between to participants of a social network in a host-proof way (meaning the host can not access the messages that are exchanged between Alice and Bob).
The following straight forward implementation is based on the ingenious BigInt Javascript library created by Leemon Baird:
function d_h() { // Alice tries to send to Bob, they agree on a 256 bit prime var p = str2bigInt( "10883804965994030335610375728683210724614077" + "5791152305372594007835539736018383", 10, 80); var g = str2bigInt("2", 10, 80); // and on a generator // Alice chooses her secret randomly var a = str2bigInt( "3103830701216420526524336327874353922197141754" + "5159778383387464250", 10, 80); // Bob chooses his secret randomly var b = str2bigInt( "26264611999731746945409581849451656136966431" + "516270225144913718599547", 10, 80); // calculate the public key var A = powMod(g,a,p); var B = powMod(g,b,p); // A and B are exchanged publicly // Alice and Bob can compute the same key from A and B var a_sec = powMod(B, a, p); var b_sec = powMod(A, b, p); alert(bigInt2str(a_sec, 10) + '\n ' + bigInt2str(b_sec, 10)); }
In case you wonder how to choose p and g – so did I. Turns out a generator for those numbers is part of the Crypto++ library. The following application uses this library to calculate p and g with different length.
#include#include #include #include "dh.h" #include "osrng.h" using namespace std; using namespace CryptoPP; using namespace TCLAP; int main(int argc, char** argv) { // read command line CmdLine cmd("Diffie Hellman p g generator", ' ', "0.1"); UnlabeledMultiArg m("bv", "bits and values", true, ""); cmd.add( m ); cmd.parse(argc, argv); vector mv = m.getValue(); mv.push_back(1); unsigned int bv = mv[0]; unsigned int nv = mv[1]; AutoSeededRandomPool arngA; // generate p and g RandomNumberGenerator& rngA = *dynamic_cast (&arngA); for(unsigned short i=0; i The application uses the TCLAP library to parse the command line. The first parameter should be the width of the prime number in bits, the second optional parameter specifies how many primes and generators should be calculated.
Here's a list of p and g I generated with different widths:
128 bits: p=197221152031991558322935568090317202983 g=2 256 bits: p=11245712998331706449413325803449175679094351102802336690101496856041 0379195027 g=3 512 bits: p=85591083890203292422929753448312002013227700164244056883767436387780 3988137714894694780639823858404151944019992782250585325661689168497741 6276395927762259 g=3 1024 bits: p=10756096062425499020105845514001321706994933124811434157429824859705 5584898126321093330768462486995125563469663163251404817709163750190539 8111908385982976186475492023836046174671146008757104643109463540714363 4989690852152224155785251701387082100575086970999263664414942032660939 2283245879753842682719140993487 g=2 2048 bits: p=28401819833194672263220074318568239913240629340614134316461681527129 7400190276361407578313119949940155208450277590596255133024483132860231 2683364685437571458516690608818388566379408009734093619889676676688482 4330230759478149039933887325452487112982841213248410034360015394086822 8492443771741195501623918057531604439427869721645027989688343068984123 6647850119363273567137904693671110310979494733094653291727319950103948 4827099108375018229688415849095088940888827138097109161920916553046346 9800257941704054817481593649080741474714321422084101095199976587101477 59474207550469840261684005212634493995003979085986141372247 g=2Those numbers do not have to be calculated every time but in fact can be hard-coded in your application.