From 239963273242004426adcaf902459a9e1531ab1a Mon Sep 17 00:00:00 2001 From: Andreas Bogk Date: Thu, 15 Jan 2009 17:19:59 +0100 Subject: C# implementation of A5/1. --- A5.1/C#/A5.sln | 20 + A5.1/C#/A5/A5.csproj | 60 +++ A5.1/C#/A5/A5Engine.cs | 443 +++++++++++++++++++++ A5.1/C#/A5/Program.cs | 150 +++++++ A5.1/C#/A5/Properties/AssemblyInfo.cs | 36 ++ A5.1/C#/A5/bin/Debug/A5.exe | Bin 0 -> 13312 bytes A5.1/C#/A5/bin/Debug/A5.pdb | Bin 0 -> 34304 bytes A5.1/C#/A5/bin/Debug/A5.vshost.exe | Bin 0 -> 14328 bytes A5.1/C#/A5/bin/Debug/A5.vshost.exe.manifest | 11 + .../C#/A5/obj/Debug/A5.csproj.FileListAbsolute.txt | 5 + A5.1/C#/A5/obj/Debug/A5.exe | Bin 0 -> 13312 bytes A5.1/C#/A5/obj/Debug/A5.pdb | Bin 0 -> 34304 bytes 12 files changed, 725 insertions(+) create mode 100644 A5.1/C#/A5.sln create mode 100644 A5.1/C#/A5/A5.csproj create mode 100644 A5.1/C#/A5/A5Engine.cs create mode 100644 A5.1/C#/A5/Program.cs create mode 100644 A5.1/C#/A5/Properties/AssemblyInfo.cs create mode 100644 A5.1/C#/A5/bin/Debug/A5.exe create mode 100644 A5.1/C#/A5/bin/Debug/A5.pdb create mode 100644 A5.1/C#/A5/bin/Debug/A5.vshost.exe create mode 100644 A5.1/C#/A5/bin/Debug/A5.vshost.exe.manifest create mode 100644 A5.1/C#/A5/obj/Debug/A5.csproj.FileListAbsolute.txt create mode 100644 A5.1/C#/A5/obj/Debug/A5.exe create mode 100644 A5.1/C#/A5/obj/Debug/A5.pdb diff --git a/A5.1/C#/A5.sln b/A5.1/C#/A5.sln new file mode 100644 index 0000000..43e63dd --- /dev/null +++ b/A5.1/C#/A5.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "A5", "A5\A5.csproj", "{2D7658AD-F358-402A-B869-65EF26DE8080}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2D7658AD-F358-402A-B869-65EF26DE8080}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2D7658AD-F358-402A-B869-65EF26DE8080}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2D7658AD-F358-402A-B869-65EF26DE8080}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2D7658AD-F358-402A-B869-65EF26DE8080}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/A5.1/C#/A5/A5.csproj b/A5.1/C#/A5/A5.csproj new file mode 100644 index 0000000..0562241 --- /dev/null +++ b/A5.1/C#/A5/A5.csproj @@ -0,0 +1,60 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {2D7658AD-F358-402A-B869-65EF26DE8080} + Exe + Properties + A5 + A5 + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + + \ No newline at end of file diff --git a/A5.1/C#/A5/A5Engine.cs b/A5.1/C#/A5/A5Engine.cs new file mode 100644 index 0000000..040c245 --- /dev/null +++ b/A5.1/C#/A5/A5Engine.cs @@ -0,0 +1,443 @@ +/* + * A5/1 Implementation + * + * Information: http://en.wikipedia.org/wiki/A5/1 + * Released : 24/10/2008 + * App Options: -d (Debugging mode) + * + * Written by : Brett Gervasoni (brett.gervasoni [at] gmail.com) + * Thanks to : Angus McMahon (angusmcmahon [at] gmail.com) + * + * Notes: + * - Debugging mode will show step by step processes + * - The code has been designed to be easily expandable, so that more secure + * versions of the A5 family can be introduced. + * - Various properties of the A5Engine class can be modified + * - If order matters then put things in order to begin with! + * Polynomials, clocking bits, and maximum register lengths. + * - If data is not in order the application will try its best to make + * the cipher work. + * - Polynomials for each register are chosen based on their largest exponent + * being less than register length. + * + * Instructions: + * numRegisters = The number of registers to use + * maxRegLens = The max register length for each register + * regIndexes = The clocking bits for each register + * polynomialsArray = The polynomials to use for each register + * sourceArray = Random binary bits + * */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace A5 +{ + class A5Engine + { + public bool dbMode; //Debug mode + + private int nRegisters; //number of registers + private int[] mRegLens; //max register lengths + private int[] sArray; //source array + private int[] rIndexes; //register indexes (clocking bits) + private string[] pArray; //polynomials + private int[][] registers; //registers + + private int[][] uExponents; //exponents being used + + /* --- Setting properties --- */ + public int numRegisters + { + get + { return nRegisters; } + set + { nRegisters = value; } + } + + public int[] maxRegLens + { + get + { return mRegLens; } + set + { mRegLens = value; } + } + + public int[] sourceArray + { + get + { return sArray; } + set + { sArray = value; } + } + + public int[] regIndexes + { + get + { return rIndexes; } + set + { rIndexes = value; } + } + + public string[] polynomialsArray + { + get + { return pArray; } + set + { pArray = value; } + } + + public int[][] Registers + { + get + { return registers; } + set + { registers = value; } + } + + /* --- Begin methods ---*/ + private void slowText(string message) + { + foreach (char c in message.ToCharArray()) + { + Console.Write(c); + System.Threading.Thread.Sleep(60); + } + + Console.WriteLine(); + } + + public void Intro() + { + string message = "#################################################################\n"; + message += "# A5/1 Implementation #\n"; + message += "# #\n"; + message += "# Information: http://en.wikipedia.org/wiki/A5/1 #\n"; + message += "# Released: 24th October 2008 #\n"; + message += "# App Options: -d [NumOfLoops] (Debugging mode) #\n"; + message += "# #\n"; + message += "# Written By: Brett Gervasoni (brett.gervasoni [at] gmail.com) #\n"; + message += "#################################################################\n"; + + Console.WriteLine(message); + + string matrix = "Now you will see how deep the rabit hole really goes..."; + slowText(matrix); + + System.Threading.Thread.Sleep(2500); + } + + public int GetMaxRegLensTotal() + { + int total = 0; + + foreach (int len in mRegLens) + total += len; + + return total; + } + + private int XorValues(int val1, int val2) + { + int res = 0; + + if (val1 != val2) + res = 1; + + return res; + } + + private int XorRegValues(int[] vToXor) + { + int final = 0; + + for (int i = 0; i < vToXor.Length; i++) + final = XorValues(final, vToXor[i]); + + return final; + } + + private int[][] RemoveIntArrElement(int[][] oArray, int index) + { + int[][] nArray = new int[oArray.Length-1][]; + + for (int i = 0; i < oArray.Length; i++) + { + if (i != index) + { + nArray[i-1] = new int[oArray[i].Length]; + for (int x = 0; x < oArray[i].Length; x++) + { + nArray[i-1][x] = oArray[i][x]; + } + } + } + + return nArray; + } + + private int[][] ExtractPolyExponents(string[] polynomialsArray) + { + int[][] exponents = new int[polynomialsArray.Length][]; + + for (int i = 0; i < polynomialsArray.Length; i++) + { + Regex expression = new Regex(@"x\^(\d+)"); + MatchCollection polyMatches = expression.Matches(polynomialsArray[i]); + + exponents[i] = new int[polyMatches.Count]; + + for (int x = 0; x < polyMatches.Count; x++) + { + //Console.WriteLine(polyMatches[x].Groups[1].ToString()); + exponents[i][x] = int.Parse(polyMatches[x].Groups[1].ToString()); + } + } + + return exponents; + } + + private int FindLargestInt(int[] intArray) + { + int largest = 0; + + foreach (int num in intArray) + { + if (num > largest) + largest = num; + } + + return largest; + } + + private int[][] PolySelection() + { + int[][] exponents = ExtractPolyExponents(pArray); + int[][] usingPolynomials = new int[nRegisters][]; + + int counter = 0; + int j = 0; //since i variable is reset + for (int i = 0; i < exponents.Length; i++) + { + if (counter == nRegisters) + break; + + int largest = FindLargestInt(exponents[i]); + + if (largest < mRegLens[j]) + { + usingPolynomials[counter] = new int[exponents[i].Length]; + + for (int x = 0; x < exponents[i].Length; x++) + usingPolynomials[counter][x] = exponents[i][x]; + + exponents = RemoveIntArrElement(exponents, i); + + i = -1; //reset loop + counter++; + } + + j++; + } + + return usingPolynomials; + } + + private int[] RegisterFill(int offset, int regNum) + { + int[] outArray = new int[regNum]; + + for (int i = 0; i < regNum; i++) + { + outArray[i] = sArray[offset + i]; + } + + return outArray; + } + + private int[] GetIndexValues() + { + int[] indexValues = new int[registers.Length]; + + for (int i = 0; i < registers.Length; i++) + { + indexValues[i] = registers[i][rIndexes[i]]; + } + + return indexValues; + } + + private int[] FindFrequency(int[] indexValues) + { + int[] tally = new int[2]; //size of 2 since its just binary + + foreach (int val in indexValues) + { + if (val == 0) + tally[0]++; + else if (val == 1) + tally[1]++; + } + + return tally; + } + + public int[][] CreateRegisters() + { + int[][] filledRegisters = new int[nRegisters][]; + int offset = 0; + + //Does source array have enough data to fill? + if (GetMaxRegLensTotal() <= sArray.Length) + { + for (int i = 0; i < nRegisters; i++) + { + filledRegisters[i] = RegisterFill(offset, mRegLens[i]); + offset += mRegLens[i]; + } + } + + uExponents = PolySelection(); + + if (dbMode) + { + //Exponents in use + int counter = 0; + + Console.WriteLine("[exponents]"); + foreach (int[] set in uExponents) + { + Console.WriteLine("set: {0}", counter.ToString()); + + foreach (int exp in set) + Console.Write(exp.ToString() + " "); + + Console.WriteLine(); + counter++; + } + + Console.WriteLine("[/exponents]"); + } + + return filledRegisters; + } + + public int GetOutValue() + { + int[] vToXor = new int[registers.Length]; + int outValue = 0; + + for (int i = 0; i < registers.Length; i++) + vToXor[i] = registers[i][0]; + + outValue = XorRegValues(vToXor); + + return outValue; + } + + public int[] RegistersToShift() + { + int[] indexValues = GetIndexValues(); + int[] tally = FindFrequency(indexValues); + + int highest = 0; + int movVal = 0; + + if (dbMode) + { + Console.WriteLine("[indexValues]:"); + foreach (int v in indexValues) + Console.Write(v.ToString() + " "); + Console.WriteLine("\n[/indexValues]:"); + + Console.WriteLine("[tally]:"); + foreach (int v in tally) + Console.Write(v.ToString() + " "); + Console.WriteLine("\n[/tally]:"); + } + + foreach (int count in tally) + { + if (count > highest) + highest = count; + } + + for (int i = 0; i < tally.Length; i++) + { + if (tally[i] == highest) + movVal = i; + } + + ArrayList regTS = new ArrayList(); + + for (int i = 0; i < indexValues.Length; i++) + { + if (indexValues[i] == movVal) + regTS.Add(i); + } + + return (int[])regTS.ToArray(typeof(int)); + } + + private int[] GetFeedbackValues(int[] regTS) + { + int[] regTSFBV = new int[regTS.Length]; //Reg To Shift Feed Back Values (regTSFBV) + + for (int i = 0; i < regTS.Length; i++) + { + int[] feedbackSet = new int[uExponents[regTS[i]].Length]; + + for (int x = 0; x < uExponents[regTS[i]].Length; x++) + { + feedbackSet[x] = registers[regTS[i]][uExponents[regTS[i]][x]]; + } + + regTSFBV[i] = XorRegValues(feedbackSet); + } + + return regTSFBV; + } + + public void RegisterShift(int[] regTS) + { + int[] shiftedElements = new int[regTS.Length]; + int[] regTSFBV = GetFeedbackValues(regTS); + + if (dbMode) + { + Console.WriteLine("[regTS]:"); + foreach (int v in regTS) + Console.Write(v.ToString() + " "); + Console.WriteLine("\n[/regTS]:"); + + Console.WriteLine("[regTSFBV]:"); + foreach (int v in regTSFBV) + Console.Write(v.ToString() + " "); + Console.WriteLine("\n[/regTSFBV]:"); + } + + for (int i = 0; i < regTS.Length; i++) + { + int[] regShifting = registers[regTS[i]]; //Alias the register to shift + + shiftedElements[i] = registers[regTS[i]][0]; //Copy position zero value in registers to shift + + //Creates new register with appropriate max reg length + int[] nRegister = new int[regShifting.Length]; //Could also use mRegLens[regTS[i]].Length + + //Fill values to length -1 + for (int x = 0; x < (regShifting.Length - 1); x++) + nRegister[x] = regShifting[x + 1]; //+1 Grabbing everything after position zero + + //Now put feedback values on the end (former RegisterPush method) + nRegister[nRegister.Length - 1] = regTSFBV[i]; + + registers[regTS[i]] = nRegister; //assign to register (update) + } + } + } +} \ No newline at end of file diff --git a/A5.1/C#/A5/Program.cs b/A5.1/C#/A5/Program.cs new file mode 100644 index 0000000..efa4150 --- /dev/null +++ b/A5.1/C#/A5/Program.cs @@ -0,0 +1,150 @@ +/* + * A5/1 Implementation + * + * Information: http://en.wikipedia.org/wiki/A5/1 + * Released : 24/10/2008 + * App Options: -d (Debugging mode) + * + * Written by : Brett Gervasoni (brett.gervasoni [at] gmail.com) + * Thanks to : Angus McMahon (angusmcmahon [at] gmail.com) + * + * Notes: + * - Debugging mode will show step by step processes + * - The code has been designed to be easily expandable, so that more secure + * versions of the A5 family can be introduced. + * - Various properties of the A5Engine class can be modified + * - If order matters then put things in order to begin with! + * Polynomials, clocking bits, and maximum register lengths. + * - If data is not in order the application will try its best to make + * the cipher work. + * - Polynomials for each register are chosen based on their largest exponent + * being less than register length. + * + * Instructions: + * numRegisters = The number of registers to use + * maxRegLens = The max register length for each register + * regIndexes = The clocking bits for each register + * polynomialsArray = The polynomials to use for each register + * sourceArray = Random binary bits + * */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace A5 +{ + class Program + { + static void Main(string[] args) + { + //Create registers + A5Engine A5eng = new A5Engine(); + + //To expand the algorithm... + //Edit below properties + A5eng.numRegisters = 3; //Number of registers to use + A5eng.maxRegLens = new int[] { 19, 22, 23 }; //Test max reg lengths: { 5,5,5 }; + A5eng.regIndexes = new int[] { 8, 10, 10 }; //Test clocking bits: { 0,0,0 }; + + //Test polynomials: { "x^1+x^2+x^3+1", "x^0+x^2+x^3+1", "x^3+x^4+1" }; + A5eng.polynomialsArray = new string[] { "x^8+x^17+x^16+x^13+1", + "x^21+x^20+1", + "x^22+x^21+x^20+x^7+1" }; + A5eng.sourceArray = new int[] { 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, + 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }; + + /* DO NOT EDIT BELOW THIS POINT */ + int numRegPushes = 100; + bool testPassed = true; //For cipher check + + if (args.Length > 0) + { + if (args[0] == "-d") + { + A5eng.dbMode = true; + if (args.Length > 1) + { + try + { + numRegPushes = int.Parse(args[1]); + } + catch (Exception ex) + { + testPassed = false; + + Console.WriteLine("Error: Numeric values only!"); + Console.WriteLine("Exception: " + ex.Message); + } + } + } + } + + if (A5eng.sourceArray.Length < A5eng.GetMaxRegLensTotal()) + { + testPassed = false; + Console.WriteLine("[-] Not enough source data!"); + } + + if (A5eng.polynomialsArray.Length != A5eng.numRegisters) + { + testPassed = false; + Console.WriteLine("[-] Not enough polynomials"); + } + + if (testPassed) + { + A5eng.Registers = A5eng.CreateRegisters(); + + if (A5eng.dbMode) + { + Console.WriteLine("Output (debugging mode): "); + for (int ia = 0; ia < numRegPushes; ia++) + { + Console.WriteLine("[register]"); + int c = 0; + foreach (int[] p in A5eng.Registers) + { + Console.Write("register: {0} ", c); + foreach (int poly in p) + { + Console.Write(poly.ToString()); + } + Console.WriteLine(); + + c++; + } + Console.WriteLine("[/register]"); + + int[] regTS = A5eng.RegistersToShift(); + A5eng.RegisterShift(regTS); + + System.Threading.Thread.Sleep(20); //Slow the output + } + + Console.WriteLine("\n{0} loops of A5/1 have been completed.", numRegPushes.ToString()); + } + else + { + A5eng.Intro(); + + Console.WriteLine("Output: "); + while (true) + { + Console.Write(A5eng.GetOutValue().ToString()); + + int[] regTS = A5eng.RegistersToShift(); + A5eng.RegisterShift(regTS); + + System.Threading.Thread.Sleep(20); //Slow the output + } + } + } + } + } +} diff --git a/A5.1/C#/A5/Properties/AssemblyInfo.cs b/A5.1/C#/A5/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..eb08b29 --- /dev/null +++ b/A5.1/C#/A5/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("A5")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("A5")] +[assembly: AssemblyCopyright("Copyright © 2008")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9c339432-71f0-44fd-8e07-f8f83a148db7")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/A5.1/C#/A5/bin/Debug/A5.exe b/A5.1/C#/A5/bin/Debug/A5.exe new file mode 100644 index 0000000..536aae5 Binary files /dev/null and b/A5.1/C#/A5/bin/Debug/A5.exe differ diff --git a/A5.1/C#/A5/bin/Debug/A5.pdb b/A5.1/C#/A5/bin/Debug/A5.pdb new file mode 100644 index 0000000..12425d9 Binary files /dev/null and b/A5.1/C#/A5/bin/Debug/A5.pdb differ diff --git a/A5.1/C#/A5/bin/Debug/A5.vshost.exe b/A5.1/C#/A5/bin/Debug/A5.vshost.exe new file mode 100644 index 0000000..69ed6c0 Binary files /dev/null and b/A5.1/C#/A5/bin/Debug/A5.vshost.exe differ diff --git a/A5.1/C#/A5/bin/Debug/A5.vshost.exe.manifest b/A5.1/C#/A5/bin/Debug/A5.vshost.exe.manifest new file mode 100644 index 0000000..f96b1d6 --- /dev/null +++ b/A5.1/C#/A5/bin/Debug/A5.vshost.exe.manifest @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/A5.1/C#/A5/obj/Debug/A5.csproj.FileListAbsolute.txt b/A5.1/C#/A5/obj/Debug/A5.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..af8c666 --- /dev/null +++ b/A5.1/C#/A5/obj/Debug/A5.csproj.FileListAbsolute.txt @@ -0,0 +1,5 @@ +C:\Users\Brett\Documents\Visual Studio 2008\Projects\A5\A5\bin\Debug\A5.exe +C:\Users\Brett\Documents\Visual Studio 2008\Projects\A5\A5\bin\Debug\A5.pdb +C:\Users\Brett\Documents\Visual Studio 2008\Projects\A5\A5\obj\Debug\ResolveAssemblyReference.cache +C:\Users\Brett\Documents\Visual Studio 2008\Projects\A5\A5\obj\Debug\A5.exe +C:\Users\Brett\Documents\Visual Studio 2008\Projects\A5\A5\obj\Debug\A5.pdb diff --git a/A5.1/C#/A5/obj/Debug/A5.exe b/A5.1/C#/A5/obj/Debug/A5.exe new file mode 100644 index 0000000..536aae5 Binary files /dev/null and b/A5.1/C#/A5/obj/Debug/A5.exe differ diff --git a/A5.1/C#/A5/obj/Debug/A5.pdb b/A5.1/C#/A5/obj/Debug/A5.pdb new file mode 100644 index 0000000..12425d9 Binary files /dev/null and b/A5.1/C#/A5/obj/Debug/A5.pdb differ -- cgit v1.2.3