#!/usr/bin/perl use strict; use warnings; use Math::BigInt lib => 'GMP'; my $g = new Math::BigInt('5'); # typically 2 or 5 my $p = new Math::BigInt( "537139360602477525125655043677356597740" . "672426915294213641576278281056255413159" . "9074907426010737503501" # any 100+ digit prime will do ); my $a = new Math::BigInt(join("", map(chr(48+int rand 10), 1 .. 50))); # $a is the lhs secret my $b = new Math::BigInt(join("", map(chr(48+int rand 10), 1 .. 50))); # $b is the rhs secret my ($A, $B, $Kab, $Kba); print "g=$g\n"; # $p and $g generate a group print "p=$p\n"; # cyclic group G print "a=$a\n"; # $p and $g are chosen in the clear print "b=$b\n"; print "\n"; # it's safe to send A=g^a mod p in the clear $A = $g->copy->bmodpow( $a, $p ); # it's safe to send B=g^b mod p in the clear $B = $g->copy->bmodpow( $b, $p ); # g^b^a mod p should be equal to g^a^b mod p $Kba = $B->copy->bmodpow( $a, $p ); $Kab = $A->copy->bmodpow( $b, $p ); # so we both know the secret without transmitting it! # magic! print "These better be equal:\n\t$Kab\n\t$Kba\n\n";