import com.abl.crypto.*; //StreamCipher, PlainText import com.abl.gui.*; //Console, SurveyController, SurveyView import com.abl.PlayingCards.*; //CardLabels, Card, DeckOfCards import com.abl.util.TextBuffer; import java.applet.Applet; //PkgsDemo: /** an example of how to use several com.abl.* packages @version 1/19/2001 @author I made this. -- prie, 5/10/99 */ public class PkgsDemo extends Applet { public static void main(String[] args) { //for running standalone //simpleDemo(); pontifexDemo(); } public void start() { //for running "inAnApplet" boolean inAnApplet = true; Console.setAppContext(inAnApplet); /* (until Java 1.2) */ //simpleDemo(); pontifexDemo(); } public String getAppletInfo() { return "Packages Demo; copyleft 2001; ABL Research, Inc. "; } private static void simpleDemo() { Console.println("A solitaire deck shuffled once:"); CardLabels solitaire = new CardLabels(); //52 ace-low cards plus 2 jokers DeckOfCards solitaireDeck = new DeckOfCards(solitaire); solitaireDeck.shuffle(); for (int i = 1; i <= solitaireDeck.size(); i++) { //display ordering Card faceUp = solitaireDeck.draw(); Console.println( faceUp.toString() ); } } private static void pontifexDemo() { TextBuffer outBuffer = new TextBuffer(); outBuffer.appendln("The Solitaire Encryption Algorithm uses a solitaire deck as a key to generate a"); outBuffer.appendln("keystream for encrypting a message. The ordering of the deck is the 236-bit (54!)"); outBuffer.appendln("key: two people with identical decks can securely exchange one message."); outBuffer.appendln("Another message requires another key/ordering to maximize security."); //create a solitaire deck CardLabels solitaire = new CardLabels(); //52 ace-low cards plus 2 jokers DeckOfCards solitaireDeck = new DeckOfCards(solitaire); outBuffer.appendln("For instance, a solitaire deck shuffled 10 times in a repeatable way could be a key:"); long orderingSeed = 123456789; //sets the pseudo-random-number generator int shuffles = 10; solitaireDeck.stack(orderingSeed, shuffles); for (int i = 1; i <= solitaireDeck.size(); i++) { Card faceUp = solitaireDeck.draw(); outBuffer.appendln( faceUp.toString() ); } //print and clear the output buffer Console.println(outBuffer.toString()); outBuffer = new TextBuffer(); //get user's message SurveyController surveyController = new SurveyController(); //set up survey window String message = surveyController.askUser("TheIchneumonProjectIsAheadOfSchedule"); outBuffer.appendln("original message: " + message); //convert user's message to plaintext for encryption PlainText plainText = new PlainText(); plainText.append(message); outBuffer.appendln("plaintext message: " + plainText.toString() ); //get a cipher stream via the Solitaire Encryption Algorithm (codename: Pontifex) StreamCipher streamCipher = new StreamCipher(); //a collection of encryption algorithms int[] keystream = streamCipher.pontifex( (plainText.toString() ).length(), solitaireDeck); outBuffer.append("cipher stream:"); for (int i = 0; i < keystream.length; i++) outBuffer.append(" " + Integer.toString(keystream[i]) ); outBuffer.appendln(""); //newline //encrypt plaintext message with the cipher stream /* PlainText only folds text to uppercase; more needed, maybe regexp ("2" --> "two", "$" --> "dollar") or a CharacterSet class */ /* CharacterSet-dependent: 64, toUppercase, toCharArray */ /* CardLabels-dependent: 26 (suits*faces), CharacterSet.length */ // char[] plainChar = ( plainText.toString() ).toCharArray(); //2-byte Unicode char[] cipherChar = new char[keystream.length]; for (int i = 0; i < keystream.length; i++) { //64 is Unicode "offset" for uppercase alphabet int cipherInt = (int)plainChar[i] - 64 + keystream[i]; if (cipherInt > 26) cipherInt -= 26; cipherChar[i] = (char)(64 + cipherInt); } String cipherText = new String(cipherChar); outBuffer.appendln("encrypted message: " + cipherText); //decrypt cipher-text message with the stream //(undo the above) cipherChar = ( cipherText.toUpperCase() ).toCharArray(); //2-byte Unicode plainChar = new char[keystream.length]; for (int i = 0; i < keystream.length; i++) { //64 is Unicode "offset" for uppercase alphabet int plainInt = (int)cipherChar[i] - 64 - keystream[i]; if (plainInt < 1) plainInt += 26; plainChar[i] = (char)(64 + plainInt); } String newText = new String(plainChar); outBuffer.appendln("decrypted message: " + newText); Console.println(outBuffer.toString()); } }