source: trunk/CrypPlugins/KeySearcher/KeyTranslators/ByteArrayKeyTranslator.cs @ 2061

Last change on this file since 2061 was 2061, checked in by Sven Rech, 11 years ago

Added code to generate openCL bruteforce code in KeySearcher.
Not used yet, so don't try it

File size: 9.5 KB
Line 
1/*                             
2   Copyright 2010 Sven Rech (svenrech at googlemail dot com), Uni Duisburg-Essen
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15*/
16
17using System;
18using System.Collections.Generic;
19using System.Linq;
20using System.Text;
21using Cryptool.PluginBase.Control;
22using KeySearcher.KeyPattern;
23
24namespace KeySearcher.KeyTranslators
25{
26    /// <summary>
27    /// Implements a simple translator for bytearray keys that are represented by the pattern "[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-...".
28    /// Is used by AES and DES.
29    /// </summary>
30    public class ByteArrayKeyTranslator : IKeyTranslator
31    {
32        private int progress = 0;
33        private KeyPattern.KeyPattern pattern;
34        private int[] movementStatus;
35        private byte[] keya;
36        private int[] movementPointers;
37        private IKeyMovement[] keyMovements;
38        private int openCLIndex = -1;
39        private int openCLSize;
40
41        #region KeyTranslator Members
42
43        public void SetKeys(object keys)
44        {
45            if (!(keys is KeyPattern.KeyPattern))
46                throw new Exception("Something went horribly wrong!");
47
48            pattern = (KeyPattern.KeyPattern)keys;
49
50            keyMovements = pattern.getKeyMovements();
51            movementStatus = pattern.getWildcardProgress();
52            if (movementStatus.Length != keyMovements.Length)
53                throw new Exception("Movements and Wildcards do not fit together!");
54           
55            movementPointers = new int[movementStatus.Length];
56            int mpc = 0;
57
58            byte[] keya2 = new byte[256];
59            int kc = 0;
60            string wildcardKey = pattern.WildcardKey;
61            int i = 0;
62
63            bool first = true;
64
65            while (i < wildcardKey.Length)
66            {
67                if (wildcardKey[i] == '[')
68                {
69                    i++;
70                    while (wildcardKey[i++] != ']') ;
71                    i--;
72
73                    movementPointers[mpc++] = kc++;
74
75                    first = false;
76                }
77                else if (wildcardKey[i] == '-')
78                {
79                    first = true;
80                }
81                else
82                {
83                    byte val = Convert.ToByte(""+wildcardKey[i], 16);
84                    if (first)
85                        keya2[kc/2] = (byte)((int)val << 4);
86                    else
87                        keya2[kc/2] |= val;
88
89                    kc++;
90
91                    first = false;
92                }
93
94                i++;
95            }
96
97            keya = new byte[kc/2];
98            for (int c = 0; c < (kc/2); c++)
99                keya[c] = keya2[c];
100
101            for (int x = 0; x < movementStatus.Length - 1; x++)
102                SetWildcard(x);
103        }
104
105        public byte[] GetKey()
106        {
107            return keya;
108        }
109
110        public bool NextKey()
111        {
112            int i = movementStatus.Length - 1;
113            progress++;
114            return IncrementMovementStatus(i);
115        }
116
117        private bool IncrementMovementStatus(int index)
118        {
119            movementStatus[index]++;
120           
121            while (index >= 0 && !WildcardInRange(index))
122            {               
123                movementStatus[index] = 0;
124                SetWildcard(index);
125
126                index--;
127                if (index >= 0)
128                    movementStatus[index]++;         
129            }
130
131            if (index >= 0)
132                SetWildcard(index);
133
134            return index >= 0;
135        }
136
137        public string GetKeyRepresentation()
138        {
139            return pattern.getKey(progress);
140        }
141
142        public string GetKeyRepresentation(int add)
143        {
144            return pattern.getKey(add);
145        }
146
147        /// <summary>
148        /// Sets wildcard i in keya to the current progress
149        /// </summary>
150        /// <param name="i">the wildcard index</param>
151        private void SetWildcard(int i)
152        {
153            int index = movementPointers[i] / 2;
154            byte mask;
155            byte shift;
156            if (movementPointers[i] % 2 == 0)
157            {
158                mask = 1+2+4+8;
159                shift = 4;
160            }
161            else
162            {
163                mask = 16+32+64+128;
164                shift = 0;
165            }
166
167            keya[index] = (byte)((keya[index] & mask) | (CalcWildcard(i) << shift));
168        }
169
170        private int CalcWildcard(int i)
171        {
172            IKeyMovement mov = keyMovements[i];
173            if (mov is LinearKeyMovement)
174            {
175                return movementStatus[i] * (mov as LinearKeyMovement).A + (mov as LinearKeyMovement).B;
176            }
177            else if (mov is IntervalKeyMovement)
178            {
179                return (mov as IntervalKeyMovement).IntervalList[movementStatus[i]];
180            }
181
182            throw new Exception("Movement not implemented!");
183        }
184
185        private bool WildcardInRange(int i)
186        {
187            IKeyMovement mov = keyMovements[i];
188            if (mov is LinearKeyMovement)
189            {
190                return movementStatus[i] < (mov as LinearKeyMovement).UpperBound;
191            }
192            else if (mov is IntervalKeyMovement)
193            {
194                return movementStatus[i] < (mov as IntervalKeyMovement).IntervalList.Count;
195            }
196
197            return false;           
198        }
199
200        public int GetProgress()
201        {
202            int result = progress;
203            pattern.addKey(progress);
204
205            progress = 0;
206            return result;
207        }
208
209        public string ModifyOpenCLCode(string code, int maxKeys)
210        {
211            string[] byteReplaceStrings = new string[32];
212            for (int i = 0; i < 32; i++)
213                byteReplaceStrings[i] = "$$ADDKEYBYTE"+i+"$$";
214           
215            //Find out how many wildcards/keys we can bruteforce at once:
216            int j = movementStatus.Length - 1;
217            int size = 1;
218            while ((size < maxKeys) && (j >= 0) && (movementStatus[j] == 0))
219                size *= keyMovements[j--].Count();
220
221            if (size < 256)
222                return null;    //it's futile to use OpenCL for so few keys
223
224            //generate the key movement string:
225            string[] movementStrings = new string[32];
226            string addVariable = "add";
227            for (int x = movementStatus.Length - 1; x > j; x--)
228            {
229                string movStr = string.Format("({0}%{1})", addVariable, keyMovements[x].Count());;
230
231                if (keyMovements[x] is LinearKeyMovement)
232                {
233                    var lkm = keyMovements[x] as LinearKeyMovement;
234                    movStr = string.Format("({0}*{1}+{2})", lkm.A, movStr, lkm.B);
235                }
236                else if (keyMovements[x] is IntervalKeyMovement)
237                {
238                    var ikm = keyMovements[x] as IntervalKeyMovement;
239
240                    //declare the invterval array:
241                    string s = string.Format("__constant int ikm{0}[{1}] = {{", x, ikm.Count());
242                    foreach (var c in ikm.IntervalList)
243                        s += c + ", ";
244                    s = s.Substring(0, s.Length - 2);
245                    s += "}; \n";
246                    code = code.Replace("$$MOVEMENTDECLARATIONS$$", s + "\n$$MOVEMENTDECLARATIONS$$");
247
248                    movStr = string.Format("ikm{0}[{1}]", x, movStr);
249                }
250                else
251                {
252                    throw new Exception("Key Movement not supported for OpenCL.");
253                }
254
255                if (movementPointers[x] % 2 == 0)
256                    movStr = "(" + movStr + " << 4)";
257                else
258                    movStr = "(" + movStr + ")";
259
260                addVariable = "(" + addVariable + "/" + keyMovements[x].Count() + ")";
261
262                int keyIndex = movementPointers[x]/2;
263                if (movementStrings[keyIndex] != null)
264                    movementStrings[keyIndex] += " | " + movStr;
265                else
266                    movementStrings[keyIndex] = movStr;
267            }
268
269            //put movement strings in code:
270            for (int y = 0; y < movementStrings.Length; y++)
271                code = code.Replace(byteReplaceStrings[y], movementStrings[y] ?? "0");
272
273            code = code.Replace("$$MOVEMENTDECLARATIONS$$", "");
274
275            //progress:
276            openCLIndex = j;
277            openCLSize = size;
278
279            return code;
280        }
281
282        public bool NextOpenCLBatch()
283        {
284            if (openCLIndex > -1)
285            {
286                progress += openCLSize;
287                return IncrementMovementStatus(openCLIndex);
288            }
289            else
290            {
291                throw new Exception("This method can only be called if OpenCL code was generated!");
292            }
293        }
294
295        #endregion
296
297    }
298}
Note: See TracBrowser for help on using the repository browser.