Author Topic: [Java] Cryptanalysis - Friedman Test  (Read 6239 times)

0 Members and 1 Guest are viewing this topic.

Offline Deque

  • P.I.N.N.
  • Global Moderator
  • Overlord
  • *
  • Posts: 1203
  • Cookies: 518
  • Programmer, Malware Analyst
    • View Profile
[Java] Cryptanalysis - Friedman Test
« on: February 12, 2013, 02:35:03 pm »
Friedman Test

The Friedman Test is used if you already know that a message was encrypted with Vigenère cipher. It uses the Index of Coincidence (IC) to compute the approximate length of the key. Once you have the length the cipher can be cracked using Kasiski examination and frequency analyses. Friedman Test is a great help for this.
If you have not heard anything about IC please read this thread first: Frequency Analysis and Index of Coincidence

If you want a message to try this out, take this (key length is five):

Quote
TFNMJBDCRITVVAFSRCJIFDPINNNMKAPELIWTTPYQFUIWJSJBIXULMGPXRZWNFDQXOPICRSALAERNVVKJHRVKJOJQIMBKBISTZKLZFSMVWPSWXJSLVXJSYIPYFERSWVEVLNFCBHFTDMRXDYTMHIVOIMJIVJZFIMMSFESSRQCQDNFIBISDFUTZUVZWTGZMAFSJQGMOZKLYTFAMHIKMVTCJQIIBQCWYJDUXJFZVQJOJKLRVJAXJEFKLRFYZWJJEIPXFZVIRBJKLNOV

This is the Java source for FriedmanTest (nothing complicated since I already made the IC class):

Code: (Java) [Select]
public class FriedmanTest implements Analysis {

        //language is needed for the language specific IC
    private Language language;

    public FriedmanTest(Language language) {
        this.language = language;
    }

        //returns the computed key length
    @Override
    public String analyse(String code) {
        IndexOfCoincidence ic = new IndexOfCoincidence();
        ic.analyse(code);
        double kappaRandom = ic.computeKappaRandom();
        double kappaText = ic.computeKappaText();
        long n = code.length();
        double kappaExpected = language.getIC() / ic.amountOfCharacters();
       
        double keyLength = computeKeyLength(kappaRandom, kappaText,
                kappaExpected, n);
        return "computed key length: " + keyLength;
    }

        //uses the formula for the approximate key length
    private double computeKeyLength(double kappaRandom, double kappaText,
            double kappaExpected, long n) {
        return ((kappaExpected - kappaRandom) * n)
                / ((n - 1) * kappaText - kappaRandom * n + kappaExpected);
    }

}

The enums in Java are pretty useful for saving some language specific data:

Code: (Java) [Select]
public enum Language {
    ENGLISH(1.73, "English"),
    GERMAN(2.05, "German"),
    FRENCH(2.02, "French"),
    ITALIAN(1.94, "Italian"),
    PORTUGUESE(1.94, "Portuguese"),
    RUSSIAN(1.76, "Russian"),
    SPANISH(1.94, "Spanish"),
    UNKNOWN(2.0, "Unknown");

    private double ic;
    private String name;

    private Language(double ic, String name) {
        this.ic = ic;
        this.name = name;
    }

    public double getIC() {
        return ic;
    }

    @Override
    public String toString() {
        return name;
    }
}

Deque
« Last Edit: February 12, 2013, 02:38:31 pm by Deque »