#! /usr/local/bin/perl -w use strict; # -------------------------------------------------------------- # the essence of RSA algorithm -- assymetrical\public-key cryptography # -------------------------------------------------------------- use Math::Pari qw(gcd PARI) ; # -------------------------------------------------------------- # m -- message my $m = 'IBM' ; print "original: $m\n" ; my $tmpl = 'C*' ; my @m = unpack($tmpl, $m) ; # string -> unsigned char values print "coded: @m\n" ; # n = pq -- in RSA, p & q = prime, each 1024 bits/308 digits long my $p = PARI("prime(".int(rand 50).")") ; my $q = PARI("prime(".int(rand 50).")") ; my $n = $p*$q ; # $n = Pari's obj # choose a random number r, s.t. # 1 < r < (p-1)(q-1) = b # gcd(r, b) = 1 -- relative prime my $b = ($p-1)*($q-1) ; my $r ; do {$r = int rand $b ; } until (gcd($r,$b) == 1) ; $r = PARI $r ; # rk = 1 mod (p-1)(q-1) -- d = private key; (n, r) public my $k = (1/$r)%$b ; # the math operators are Pari's, since vars = Pari # encrypt -- c = (m ^ r) mod n my @c ; map { $c[$_] = ($m[$_]**$r)%$n } 0..$#m ; # Perl uses ** for power print "ciphered: @c\n" ; # decrypt -- m = (c ^ k) mod n my @d ; map { $d[$_] = PARI("($c[$_]^$k)%$n") } 0..$#c ; # Pari uses ^ for power print "deciphered: @d\n" ; print "decoded: " . pack($tmpl, @d) . "\n" ; # just checking.... print "\nprimes: $p, $q\n" ; print "n: $n; (p-1)(q-1): $b\n" ; print "rand: $r; key: $k\n"