Encrypt [publickey_, message_] :=
Module [{n, e, c},
   n = publickey [[1]];
   e = publickey [[2]];
   c = PowerMod [message, e, n]
];


Decrypt [privatekey_, message_] :=
   Encrypt [privatekey, message]


HasPassedMillerRabin [n_, numberOfTests_] :=
Module[{k, s, couldBePrime, numberOfPerformedTests, a, 
        rHasBeenFound, r, a2rk},
   s = 1;
   k = n - 1;
   While [EvenQ [k],
            (* n-1 = 2^s * k *)
      k = Quotient [k, 2];
      s = s + 1;
   ];
   couldBePrime = True;
   numberOfPerformedTests = 0;
   While [(numberOfPerformedTests < numberOfTests) && couldBePrime,
      a = Random [Integer,{2, n-1}];
      rHasBeenFound = False; 
      r = 0;
      a2rk = PowerMod [a, k, n];
      rHasBeenFound = (a2rk === 1);
      While [Not[rHasBeenFound] && (r <= s - 1),
         rHasBeenFound = (a2rk === n-1);
         r = r + 1;
         a2rk = PowerMod [a2rk, 2, n];
      ];
      couldBePrime = rHasBeenFound;
      numberOfPerformedTests = numberOfPerformedTests + 1;
   ];
   couldBePrime
];
     
