// HelloWorldProgram.cs // using System; using System.Collections.Generic; #if (DEBUG) using System.Diagnostics; #endif // #if (DEBUG) using System.Text; using BroccoliProducts.Maths; namespace HelloWorldProgram { ///////////////////////////////////////////////////////////////// // declaration of Program class class HelloWorldProgram { ///////////////////////////////////////////////////////////// // main function static void Main(string[] args) { // declaration of local variables Random rnd = new Random(); JumboInteger Temp = null; // declare a format for displaying jumbo-integers in hexidecimal JumboInteger.eStringFormat fmt = JumboInteger.eStringFormat.Hexidecimal | JumboInteger.eStringFormat.AddSeperators | JumboInteger.eStringFormat.OmitBaseTag; // comment in this line to see all number as decimal values instead of hexidecimal fmt = JumboInteger.eStringFormat.Decimal; // display message Console.WriteLine("HelloWorldProgram started..."); Console.WriteLine("* * * Generating large prime numbers can take a few minutes. * * *"); ///////////////////////////////////////////////////////// // A - Convert our message into a number // the message M String strMessage = "Hello World!"; Console.WriteLine("\nMessage (M) = {0}", strMessage); // convert M to an array of bytes byte[] bufferPlainText = Encoding.Unicode.GetBytes(strMessage); JumboInteger M = new JumboInteger(); M.SetRaw(bufferPlainText); Console.WriteLine("\nMessage (M) as a number\nM = {0}", M.ToString(fmt)); ///////////////////////////////////////////////////////// // B - Generate two distinct prime numbers p and q // use 512 bit prime numbers // our message is 12*2 bytes (Unicode chars), 192 bits, so 512 bits is more than is needed UInt32 uiBits = 512; // choose prime number p Console.WriteLine("\nChoosing prime number p..."); JumboInteger p = new JumboInteger(); p.MakeRandomPrime(uiBits); Console.WriteLine("p = {0}", p.ToString(fmt)); // chose prime number q, which must not be the same as q Console.WriteLine("\nChoosing prime number q..."); JumboInteger q = new JumboInteger(); while (true) { // find a prime q q.MakeRandomPrime(uiBits); // ok, as long as p != q if (p != q) break; } Console.WriteLine("q = {0}", q.ToString(fmt) ); ///////////////////////////////////////////////////////// // C - Calculate N = p x q JumboInteger N = p * q; Console.WriteLine("\nN = p * q\nN = {0}", N.ToString(fmt)); ///////////////////////////////////////////////////////// // D - choose e and d // calculate phi = (p-1) * (q-1) JumboInteger phi = (p - 1) * (q - 1); Console.WriteLine("\nphi = (p-1) * (q-1)\nphi = {0}", phi.ToString(fmt)); // calculate the maximum value for e, between 1 and min(64000,N) Int32 iMax_e = 64000; if (N < 64000) iMax_e = N.ToInt32() - 1; // loop until a valid e and d are found JumboInteger e = new JumboInteger(); JumboInteger d = new JumboInteger(); while (true) { // pick an e between 3 and maximum-e e.SetInt32(rnd.Next(3, iMax_e)); // e must be relatively prime to phi (gcd(phi,e)==1) Temp = JumboInteger.Gcd(e, phi); if (Temp != 1) continue; // pick d, so that ed ==1 % phi d = JumboInteger.ModularInverse(e, phi); // break out of loop break; } // while-loop Console.WriteLine("\ne = {0}", e.ToString(fmt)); Console.WriteLine("\nd = {0}", d.ToString(fmt)); ///////////////////////////////////////////////////////// // E - dump key-pair Console.WriteLine("\nPUBLIC KEY [e,N]\nKey = [{0}, {1}]", e.ToString(fmt), N.ToString(fmt)); Console.WriteLine("\nPRIVATE KEY [d]\nKey = [{0}]", d.ToString(fmt)); ///////////////////////////////////////////////////////// // F - calculate cypherText C JumboInteger C = M.PowerMod(e, N); Console.WriteLine("\nCypher-text (C) as a number\nC = {0}", C.ToString(fmt)); ///////////////////////////////////////////////////////// // G - decrypt the cypher-text C into plain-text M2 // calculate M2 = (C ^ d) % N JumboInteger M2 = C.PowerMod(d, N); Console.WriteLine("\nDecyphered plain-text (M2) as a number\nM2 = {0}", M2.ToString(fmt)); // convert M2 into a text string String strPlainText = Encoding.Unicode.GetString(M2.ToRaw()); Console.WriteLine("\nPlain text (M2) = {0}", strPlainText); ///////////////////////////////////////////////////////// // application finished Console.WriteLine("\nHelloWorldProgram finished."); Console.WriteLine("Click any key to close..."); while (!Console.KeyAvailable) { } } } }