summaryrefslogtreecommitdiff
path: root/A5.1/C#/A5/Program.cs
blob: efa41503938a6407bbc3f74d771f7429de688629 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
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
                    }
                }
            }
        }
    }
}
personal git repositories of Harald Welte. Your mileage may vary