/*
Rsa.java - Cory Goldfuss - November 05, 2000
Program allows input of two prime numbers in order to find
a public and private key to allow for the encryption or decrpyion
of a letter.
----------------------------------------------
November 12, 2000
Found out that by using the Math.pow() call the computer rounds the
large numbers when it converts into scientific notation. Therefore I
implemented code that did the same thing as the Math.pow(), but within
the constraints of the language. I also implemented new code for
calculating D, where D is used in the decryption process. D is the inverse
of e mod phi. Both of these new implementations were translated from code
obtained from Steve Harnish.
Program now works correctly.....I've test large primes (greater than 50 billion)
and have yet to see it work when these large primes are used. The program
seems to "think" for a long time. I have yet to discover how long it is
actually going to take before it arrives at an answer.
------------------------------------------------
November 13, 2000
Finished GUI and added radio buttons. Program never finished computer when
using large primes.
*/
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class Rsa extends Applet implements ActionListener, ItemListener
{
public double p; // prime one
public double q; // prime two
public double n; // p * q
public double d; // a derived in A * x + B * y = 0 (from extended Euclidean)
public double exp; // compiler doesn't like use of letter e for variable
public double t; // object to be crypted
public double phi;
public double encrypted;
public double decrypted;
private boolean pFlag = false;
private boolean qFlag = false;
private boolean tFlag = false;
private boolean eFlag = false;
public void init()
{
// Take out this line if you don't use symantec.itools.net.RelativeURL or symantec.itools.awt.util.StatusScroller
//symantec.itools.lang.Context.setApplet(this);
// This code is automatically generated by Visual Cafe when you add
// components to the visual environment. It instantiates and initializes
// the components. To modify the code, only use code syntax that matches
// what Visual Cafe can generate, or Visual Cafe may be unable to back
// parse your Java file into its visual environment.
//{{INIT_CONTROLS
setLayout(null);
setBackground(java.awt.Color.lightGray);
setSize(426,368);
pLbl.setText("P");
pLbl.setAlignment(java.awt.Label.CENTER);
add(pLbl);
pLbl.setBackground(java.awt.Color.white);
pLbl.setFont(new Font("Dialog", Font.BOLD, 12));
pLbl.setBounds(12,24,33,26);
add(pBox);
pBox.setBounds(48,24,120,24);
qLbl.setText("Q");
qLbl.setAlignment(java.awt.Label.CENTER);
add(qLbl);
qLbl.setBackground(java.awt.Color.white);
qLbl.setFont(new Font("Dialog", Font.BOLD, 12));
qLbl.setBounds(12,60,33,26);
add(qBox);
qBox.setBounds(48,60,120,24);
eLbl.setText("E");
eLbl.setAlignment(java.awt.Label.CENTER);
add(eLbl);
eLbl.setBackground(java.awt.Color.white);
eLbl.setFont(new Font("Dialog", Font.BOLD, 12));
eLbl.setBounds(216,24,33,26);
add(eBox);
eBox.setBounds(252,24,120,24);
tLbl.setText("T");
tLbl.setAlignment(java.awt.Label.CENTER);
add(tLbl);
tLbl.setBackground(java.awt.Color.white);
tLbl.setFont(new Font("Dialog", Font.BOLD, 12));
tLbl.setBounds(216,60,33,26);
add(tBox);
tBox.setBounds(252,60,120,24);
phiLbl.setText("PHI");
phiLbl.setAlignment(java.awt.Label.CENTER);
add(phiLbl);
phiLbl.setBackground(java.awt.Color.white);
phiLbl.setFont(new Font("Dialog", Font.BOLD, 12));
phiLbl.setBounds(12,108,36,24);
add(phianswerLbl);
phianswerLbl.setBounds(48,108,84,23);
nLbl.setText("N");
nLbl.setAlignment(java.awt.Label.CENTER);
add(nLbl);
nLbl.setBackground(java.awt.Color.white);
nLbl.setFont(new Font("Dialog", Font.BOLD, 12));
nLbl.setBounds(12,144,33,26);
add(nanswerLbl);
nanswerLbl.setBounds(48,144,84,23);
phihelpLbl.setText("PHI = (P-1) * (Q-1)");
add(phihelpLbl);
phihelpLbl.setBounds(132,108,108,24);
nhelpLbl.setText("N = P * Q");
add(nhelpLbl);
nhelpLbl.setBounds(132,144,108,24);
dLbl.setText("D");
dLbl.setAlignment(java.awt.Label.CENTER);
add(dLbl);
dLbl.setBackground(java.awt.Color.white);
dLbl.setFont(new Font("Dialog", Font.BOLD, 12));
dLbl.setBounds(12,180,33,26);
add(danswerLbl);
danswerLbl.setBounds(48,180,84,23);
enteredtLbl.setText("Original T:");
enteredtLbl.setAlignment(java.awt.Label.CENTER);
add(enteredtLbl);
enteredtLbl.setBackground(java.awt.Color.orange);
enteredtLbl.setBounds(12,216,84,24);
add(tanswerLbl);
tanswerLbl.setBackground(java.awt.Color.white);
tanswerLbl.setBounds(108,216,108,24);
encryptLbl.setText("Encrypted T:");
encryptLbl.setAlignment(java.awt.Label.CENTER);
add(encryptLbl);
encryptLbl.setBackground(java.awt.Color.orange);
encryptLbl.setBounds(12,264,84,24);
encryptLbl.setVisible(false);
add(encryptanswerLbl);
encryptanswerLbl.setBackground(java.awt.Color.white);
encryptanswerLbl.setBounds(108,264,108,24);
encryptanswerLbl.setVisible(false);
decryptLbl.setText("Decrypted T:");
decryptLbl.setAlignment(java.awt.Label.CENTER);
add(decryptLbl);
decryptLbl.setBackground(java.awt.Color.orange);
decryptLbl.setBounds(12,312,84,24);
decryptLbl.setVisible(false);
add(decryptanswerLbl);
decryptanswerLbl.setBackground(java.awt.Color.white);
decryptanswerLbl.setBounds(108,312,108,24);
decryptanswerLbl.setVisible(false);
rstBtn.setLabel("Reset");
add(rstBtn);
rstBtn.setBackground(java.awt.Color.blue);
rstBtn.setForeground(java.awt.Color.white);
rstBtn.setBounds(348,300,60,24);
dhelpLbl.setText("D = (E mod PHI) ^ -1");
add(dhelpLbl);
dhelpLbl.setBounds(132,180,120,24);
radioEncrypt.setCheckboxGroup(Crypto);
radioEncrypt.setLabel("Encrypt");
add(radioEncrypt);
radioEncrypt.setBounds(300,132,72,28);
radioDecrypt.setCheckboxGroup(Crypto);
radioDecrypt.setLabel("Decrypt");
add(radioDecrypt);
radioDecrypt.setBounds(300,156,96,28);
instructionsTextArea.setEditable(false);
instructionsTextArea.setText("Process: Enter two large primes (P and Q).T is the message block to be altered. E is either already known or chosen to be relatively prime to N (where N = P * Q). After these are ALL entered, select either Encrypt or Decrypt using the radio buttons and then press the appropiate button below. Note: To check and see that the encrypted block is the same as the decrypted, you must first encrypt the block and then enter this value in T before selecting the Decrypt option.");
add(instructionsTextArea);
instructionsTextArea.setBounds(240,204,180,85);
encryptBtn.setLabel("Encrypt");
add(encryptBtn);
encryptBtn.setBackground(java.awt.Color.blue);
encryptBtn.setForeground(java.awt.Color.white);
encryptBtn.setBounds(240,300,60,24);
encryptBtn.setVisible(false);
decryptBtn.setLabel("Decrypt");
add(decryptBtn);
decryptBtn.setBackground(java.awt.Color.blue);
decryptBtn.setForeground(java.awt.Color.white);
decryptBtn.setBounds(240,336,60,24);
decryptBtn.setVisible(false);
//}}
pBox.addActionListener( this );
qBox.addActionListener( this );
tBox.addActionListener( this );
eBox.addActionListener( this );
rstBtn.addActionListener( this );
encryptBtn.addActionListener( this );
decryptBtn.addActionListener( this );
radioEncrypt.addItemListener( this );
radioDecrypt.addItemListener( this );
}
//{{DECLARE_CONTROLS
java.awt.Label pLbl = new java.awt.Label();
java.awt.TextField pBox = new java.awt.TextField();
java.awt.Label qLbl = new java.awt.Label();
java.awt.TextField qBox = new java.awt.TextField();
java.awt.Label eLbl = new java.awt.Label();
java.awt.TextField eBox = new java.awt.TextField();
java.awt.Label tLbl = new java.awt.Label();
java.awt.TextField tBox = new java.awt.TextField();
java.awt.Label phiLbl = new java.awt.Label();
java.awt.Label phianswerLbl = new java.awt.Label();
java.awt.Label nLbl = new java.awt.Label();
java.awt.Label nanswerLbl = new java.awt.Label();
java.awt.Label phihelpLbl = new java.awt.Label();
java.awt.Label nhelpLbl = new java.awt.Label();
java.awt.Label dLbl = new java.awt.Label();
java.awt.Label danswerLbl = new java.awt.Label();
java.awt.Label enteredtLbl = new java.awt.Label();
java.awt.Label tanswerLbl = new java.awt.Label();
java.awt.Label encryptLbl = new java.awt.Label();
java.awt.Label encryptanswerLbl = new java.awt.Label();
java.awt.Label decryptLbl = new java.awt.Label();
java.awt.Label decryptanswerLbl = new java.awt.Label();
java.awt.Button rstBtn = new java.awt.Button();
java.awt.Label dhelpLbl = new java.awt.Label();
java.awt.Checkbox radioEncrypt = new java.awt.Checkbox();
java.awt.CheckboxGroup Crypto = new java.awt.CheckboxGroup();
java.awt.Checkbox radioDecrypt = new java.awt.Checkbox();
java.awt.TextArea instructionsTextArea = new java.awt.TextArea("",0,0,TextArea.SCROLLBARS_VERTICAL_ONLY);
java.awt.Button encryptBtn = new java.awt.Button();
java.awt.Button decryptBtn = new java.awt.Button();
//}}
public void actionPerformed( ActionEvent e ){
if (e.getSource() == encryptBtn){ // encrypt
/* Turn off decryption labels */
decryptLbl.setVisible( false );
decryptanswerLbl.setVisible( false );
/* Encrypt Entered T */
encrypted = powerMod( t, exp, n );
encryptanswerLbl.setText(Double.toString(encrypted));
encryptLbl.setVisible( true );
encryptanswerLbl.setVisible( true );
}
if (e.getSource() == decryptBtn){
/* Turn off encryption labels */
encryptLbl.setVisible( false );
encryptanswerLbl.setVisible( false );
/* Decrpyt Message */
decrypted = powerMod( t, d, n );
decryptLbl.setVisible( true );
decryptanswerLbl.setVisible( true );
decryptanswerLbl.setText(Double.toString(decrypted));
}
if (e.getSource() == rstBtn){ // reset all inputs and labels
encryptLbl.setVisible( false );
encryptanswerLbl.setVisible( false );
decryptLbl.setVisible( false );
decryptanswerLbl.setVisible( false );
pBox.setText("");
qBox.setText("");
eBox.setText("");
tBox.setText("");
pFlag = false;
eFlag = false;
tFlag = false;
qFlag = false;
n = 0;
phi = 0;
exp = 0;
t = 0;
p = 0;
q = 0;
d = 0;
encrypted = 0;
decrypted = 0;
encryptBtn.setVisible( false );
decryptBtn.setVisible( false );
nanswerLbl.setText(Double.toString(n));
phianswerLbl.setText(Double.toString(phi));
danswerLbl.setText(Double.toString(d));
tanswerLbl.setText(Double.toString(t));
encryptanswerLbl.setText(Double.toString(encrypted));
decryptanswerLbl.setText(Double.toString(decrypted));
}
if (e.getSource() == pBox){
p = Double.parseDouble( e.getActionCommand() );
pFlag = true;
}
if (e.getSource() == qBox){
q = Double.parseDouble( e.getActionCommand() );
qFlag = true;
}
if (e.getSource() == tBox){
t = Double.parseDouble( e.getActionCommand() );
tFlag = true;
}
if (e.getSource() == eBox){
exp = Double.parseDouble( e.getActionCommand() );
eFlag = true;
}
if (pFlag && qFlag && eFlag && tFlag == true){ // received all input from user
n = p * q;
phi = ((p-1) * (q-1));
d = Inverse( exp, phi);
nanswerLbl.setText(Double.toString(n));
phianswerLbl.setText(Double.toString(phi));
danswerLbl.setText(Double.toString(d));
tanswerLbl.setText(Double.toString(t));
}
} // end action command
public void itemStateChanged( ItemEvent e ){
String choice = e.getItem().toString();
if ( choice.equalsIgnoreCase( "Encrypt" ) ){
decryptLbl.setVisible( false );
decryptanswerLbl.setVisible( false );
encryptBtn.setVisible( true );
decryptBtn.setVisible( false );
}
if ( choice.equalsIgnoreCase( "Decrypt" ) ){
encryptLbl.setVisible( false );
encryptanswerLbl.setVisible( false );
decryptBtn.setVisible( true );
encryptBtn.setVisible( false );
}
} // item listener
/* Both functions are used to overcome rounding error */
/* To give A^B modulo M */
private double powerMod( double a, double b, double m ){
double answer = 1;
for (int i = 1; i <= b; i++){
answer = ((a * answer) % m);
}
return( answer );
}
/* To give the inverse of X modulo M */
private double Inverse( double x, double m ){
double answer = 0;
for(int i = 1; i <= ( m - 1 ); i++){
if ( ( (x * i) % m ) == 1 ){
answer = i;
}
else{
continue;
}
}
return( answer );
}
}
\