# How to organize and run functions?

I am very new to Mathematica. I thought I would try it out for my first assignment in my computer science class. Until now I have only used C-base languages including C#, Java, Objective-C, and Python. This assignment is to implement RSA encryption and I thought Mathematica would be perfect for this.

My code works when it is run outside of functions, but for some reason I can not figure out how to make functions and run them properly.

Can someone please explain what is wrong with how I have my document set up right now? Thank you.

My Document (after attempting to run)

It seems like Mathematica is trying to run the document even though I have not called any of the functions.

-
It's nice that you're trying to learn Mathematica. Creating and defining functions are very basic (typically first lessons in Mathematica) and hence is generally expected on this site that users know how to do them. But worry not, this tutorial (and the additional tutorial links in the bottom of that page, esp. "Defining functions" and "Immediate and Delayed Definitions") will be helpful to get started. You can give that a try and get back if you get stuck :) –  rm -rf Sep 22 '12 at 5:32
Mathematica is very unlike any other language you are likely to be familiar with. Suffice it to say that the concepts of defining and calling functions do not really exist as such, although the difficulties you encounter here are simply due to incorrect use of syntax in attempting to declare functions as it would be done in other languages. First of all, you should review the documentation: in the Virtual Book, start with the Core Language topic and work from there. –  Oleksandr R. Sep 22 '12 at 5:36
Functions in Mathematica are applied in terms of patterns, although you don't need to worry about that for the time being (just keep it in mind). Another useful tip is the F1 button. Click on a symbol and press F1 to see its help page. –  amr Sep 22 '12 at 6:12
Your 'while' construction looks wrong to me. –  cormullion Sep 22 '12 at 9:06
Since no one has explicitly said what you might need,I thought I would. There are several ways to define functions, but the one you might find most comfortable here is: myFunc[par1_,par2_,... ]:=Module[{localVar1, localVar2,...}, statement1; statement2; ... ] where the ellipsis indicate that you may use as many of the relevant construction as you wish. –  image_doctor Sep 22 '12 at 10:48

Let's do this:

As R.M suggested in the comments, you should learn the way Mathematica defines functions.

Here's how I've defined your functions:

keygen[keybitlength_] :=
Module[{kbl, kbl1, pPrime, qPrime, nKey, phiOFn, eKey, dKey},
kbl = 2^(keybitlength/2);
kbl1 = 2^(keybitlength/2 - 1);
pPrime = RandomPrime[{kbl1, kbl}];
qPrime = RandomPrime[{kbl1, kbl}];
nKey = pPrime*qPrime;
phiOFn = (pPrime - 1) (qPrime - 1);
While[eKey = RandomPrime[{2, phiOFn}]; ! CoprimeQ[eKey, phiOFn]];
dKey = PowerMod[eKey, -1, phiOFn];
{{eKey, nKey}, {dKey, nKey}}]

encryption[message_, list : {eKey_, nKey_}] := PowerMod[message, eKey, nKey]

decryption[encmessage_, list : {dKey_, nKey_}] := PowerMod[encmessage, dKey, nKey]


Now it's simple to use this for numeric values:

keys = keygen[32]

(*{{1680015751, 2207995403}, {383738359, 2207995403}}*)

encryption[123456, keys[[1]]]

(*1731973844*)

decryption[1731973844,keys[[2]]]

(*123456*)


The best way I can figure out to do strings is a ToCharacterCode method.

Let's redefine the encryption and decryption functions to handle these.

encryption[message_, list : {eKey_, nKey_}] :=
Module[{temp},
If[StringQ[message], (temp = ToCharacterCode[message];PowerMod[#, eKey, nKey] & /@temp),
PowerMod[message, eKey, nKey]]]

decryption[encmessage_, list : {dKey_, nKey_}] := Module[{temp},
If[ListQ[encmessage], (temp = PowerMod[#, dKey, nKey] & /@ encmessage;
FromCharacterCode[temp]), PowerMod[encmessage, dKey, nKey]]]


Testing:

keys = keygen[16]
enc = encryption["Hello World!", keys[[1]]]
decryption[enc, keys[[2]]]

(*{{35437, 41693}, {39973, 41693}}*)
(*{2592, 40831, 8438, 8438, 12888, 12500, 32151, 12888, 21729, 8438, 39307, 198}*)
(*"Hello World!"*)

-
Thanks! I was actually just asking about the three functions I had already written, the text was coming next. That's awesome that Mathematica has a ToCharachterCode function though! –  Keegan McCarthy Sep 22 '12 at 17:06
Two simplifications of the code: phiOFn = nKey - pPrime - qPrime + 1; is easily replaced with phiOFn = EulerPhi[nKey];, and the lines eKey = RandomPrime[{2, phiOFn}]; While[Not[CoprimeQ[eKey, phiOFn]], eKey = RandomPrime[{2, phiOFn}]]; can be replaced with While[eKey = RandomPrime[{2, phiOFn}]; ! CoprimeQ[eKey, phiOFn]];, since While[] doesn't really need a body (thanks to Oleksandr R. for the heads-up!). FWIW, it might be a good idea to assign 2^(keybitlength/2) to another variable so that it does not have to be computed twice. –  Ｊ. Ｍ. Sep 22 '12 at 18:39
@J.M. I'll agree with you on the While[] function, but the EulerPhi implement while nifty that Mathematica has that function is about three times slower that (pPrime-1)(qPrime-1). I'll update the code... –  kale Sep 22 '12 at 18:58
@J.M. Any ideas on the string encryption? I'm not sure the ToCharacterCode is the best way. –  kale Sep 22 '12 at 19:01
@kale My class is actually working on our own string encryption. I can post it when we finish, if you'd like. –  Keegan McCarthy Sep 22 '12 at 19:47
show 1 more comment