source: trunk/CrypPlugins/HIGHT/HIGHT.cs @ 2263

Last change on this file since 2263 was 1042, checked in by Sören Rinne, 12 years ago
  • bugfixing
  • replaced all licenses with the short version
File size: 37.8 KB
Line 
1/*
2   Copyright 2009 Sören Rinne, Ruhr-Universität Bochum, Germany
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;
21
22using Cryptool.PluginBase;
23using System.IO;
24using System.ComponentModel;
25using Cryptool.PluginBase.Cryptography;
26using Cryptool.PluginBase.IO;
27using System.Windows.Controls;
28using Cryptool.PluginBase.Miscellaneous;
29using System.Security.Cryptography;
30
31namespace Cryptool.HIGHT
32{
33    [Author("Soeren Rinne", "soeren.rinne@cryptool.de", "Ruhr-Universitaet Bochum, Chair for Embedded Security (EmSec)", "http://www.crypto.ruhr-uni-bochum.de/")]
34    [PluginInfo(false, "HIGHT", "HIGHT is a HIgh security and liGHT weight block cipher", "HIGHT/DetailedDescription/Description.xaml", "HIGHT/Images/HIGHT.png", "HIGHT/Images/encrypt.png", "HIGHT/Images/decrypt.png")]
35    [EncryptionType(EncryptionType.SymmetricBlock)]
36    public class HIGHT : IEncryption
37    {
38        #region IPlugin Members
39
40        private HIGHTSettings settings;
41        private CryptoolStream inputStream;
42        private CryptoolStream outputStream;
43        private byte[] inputKey;
44        private bool stop = false;
45        private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
46
47        #endregion
48
49        public HIGHT()
50        {
51            this.settings = new HIGHTSettings();
52            //((HIGHTSettings)(this.settings)).LogMessage += HIGHT_LogMessage;
53        }
54
55        public ISettings Settings
56        {
57            get { return (ISettings)this.settings; }
58            set { this.settings = (HIGHTSettings)value; }
59        }
60
61        [PropertyInfo(Direction.InputData, "Input", "Data to be encrypted or decrypted.", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
62        public CryptoolStream InputStream
63        {
64            get 
65            {
66              if (inputStream != null)
67              {
68                CryptoolStream cs = new CryptoolStream();
69                cs.OpenRead(inputStream.FileName);
70                listCryptoolStreamsOut.Add(cs);
71                return cs;
72              }
73              else return null;
74            }
75            set 
76            { 
77              this.inputStream = value;
78              if (value != null) listCryptoolStreamsOut.Add(value);
79              OnPropertyChanged("InputStream");
80            }
81        }
82
83        [PropertyInfo(Direction.InputData, "Key", "Must be 16 bytes (128 bit).", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
84        public byte[] InputKey
85        {
86            get { return this.inputKey; }
87            set
88            {
89                this.inputKey = value;
90                OnPropertyChanged("InputKey");
91            }
92        }
93
94        [PropertyInfo(Direction.OutputData, "Output stream", "Encrypted or decrypted output data", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
95        public CryptoolStream OutputStream
96        {
97            get
98            {
99                if (this.outputStream != null)
100                {
101                    CryptoolStream cs = new CryptoolStream();
102                    listCryptoolStreamsOut.Add(cs);
103                    cs.OpenRead(this.outputStream.FileName);
104                    return cs;
105                }
106                return null;
107            }
108            set
109            {
110                outputStream = value;
111                if (value != null) listCryptoolStreamsOut.Add(value);
112                OnPropertyChanged("OutputStream");
113            }
114        }
115
116        public void Dispose()
117        {
118            try
119            {
120                stop = false;
121                inputKey = null;
122                outputStream = null;
123                inputStream = null;
124
125                if (inputStream != null)
126                {
127                    inputStream.Flush();
128                    inputStream.Close();
129                    inputStream = null;
130                }
131                if (outputStream != null)
132                {
133                    outputStream.Flush();
134                    outputStream.Close();
135                    outputStream = null;
136                }
137                foreach (CryptoolStream stream in listCryptoolStreamsOut)
138                {
139                    stream.Close();
140                }
141                listCryptoolStreamsOut.Clear();
142            }
143            catch (Exception ex)
144            {
145                GuiLogMessage(ex.Message, NotificationLevel.Error);
146            }
147            this.stop = false;
148        }
149
150        private void checkForInputStream()
151        {
152            if (settings.Action == 0 && (inputStream == null || (inputStream != null && inputStream.Length == 0)))
153            {
154                //create some input
155                String dummystring = "12345678";
156                this.inputStream = new CryptoolStream();
157                this.inputStream.OpenRead(this.GetPluginInfoAttribute().Caption, Encoding.Default.GetBytes(dummystring.ToCharArray()));
158                // write a warning to the outside world
159                GuiLogMessage("WARNING - No input provided. Using dummy data. (" + dummystring + ")", NotificationLevel.Warning);
160            }
161        }
162
163        public void Execute()
164        {
165            process(settings.Action, settings.Padding);
166        }
167
168        private void process(int action, int padding)
169        {
170            //Encrypt/Decrypt Stream
171            try
172            {               
173                checkForInputStream();
174
175                if (inputStream == null || (inputStream != null && inputStream.Length == 0))
176                {
177                    GuiLogMessage("No input given. Not using dummy data in decrypt mode. Aborting now.", NotificationLevel.Error);
178                    return;
179                }
180
181                if (this.inputStream.CanSeek) this.inputStream.Position = 0;
182
183                outputStream = new CryptoolStream();
184                listCryptoolStreamsOut.Add(outputStream);
185                outputStream.OpenWrite(this.GetPluginInfoAttribute().Caption);
186
187                long inputbytes = inputStream.Length;
188                GuiLogMessage("inputStream length [bytes]: " + inputStream.Length.ToString(), NotificationLevel.Debug);
189               
190                int bytesRead = 0;
191                int blocksRead = 0;
192                int position;
193                int blocks;
194
195                // get number of blocks
196                if (((int)inputbytes % 8) == 0)
197                {
198                    blocks = (int)inputbytes / 8;
199                }
200                else
201                {
202                    blocks = (int)Math.Round(inputbytes / 8 + 0.4, 0) + 1;
203                }
204
205                byte[] inputbuffer = new byte[8 * blocks];
206                byte[] outputbuffer = new byte[4];
207                GuiLogMessage("# of blocks: " + blocks.ToString(), NotificationLevel.Debug);
208
209                //read input
210                //GuiLogMessage("Current position: " + inputStream.Position.ToString(), NotificationLevel.Debug);
211                for (blocksRead = 0; blocksRead <= blocks - 1; blocksRead++)
212                {
213                    for (position = bytesRead; position <= (blocksRead * 8 + 7); position++)
214                    {
215                        // no padding to do
216                        if (position < inputbytes)
217                        {
218                            inputbuffer[position] = (byte)inputStream.ReadByte();
219                        }
220                        else // padding to do!
221                        {
222                            if (padding == 0)
223                            {
224                                // padding with zeros
225                                inputbuffer[position] = 48; 
226                            }
227                            else if (padding == 2)
228                            {
229                                // padding with PKCS7
230                                int temp = 8 - (int)inputbytes % 8 + 48;
231                                inputbuffer[position] = (byte)temp;
232                            }
233                            else
234                            {
235                                // no padding
236                                inputbuffer[position] = (byte)inputStream.ReadByte();
237                                GuiLogMessage("Byte is: " + inputbuffer[position].ToString(), NotificationLevel.Info);
238                            }
239                        }
240                        bytesRead++;
241                        //GuiLogMessage("Current position: " + inputStream.Position.ToString(), NotificationLevel.Debug);
242                        //GuiLogMessage("Content of buffer[" + position + "]: " + buffer[position].ToString(), NotificationLevel.Debug);
243                    }
244                }
245
246                //GuiLogMessage("vector[0] before coding: " + vector[0].ToString(), NotificationLevel.Debug);
247                //GuiLogMessage("vector[1] before coding: " + vector[1].ToString(), NotificationLevel.Debug);
248
249                uint[] key = new uint[4];
250                long keybytes = inputKey.Length;
251                GuiLogMessage("inputKey length [byte]: " + keybytes.ToString(), NotificationLevel.Debug);
252
253                if (keybytes != 16)
254                {
255                    GuiLogMessage("Given key has false length. Please provide a key with 128 Bits length. Aborting now.", NotificationLevel.Error);
256                    return;
257                }
258                else
259                {
260                    key[0] = BitConverter.ToUInt32(inputKey, 0);
261                    key[1] = BitConverter.ToUInt32(inputKey, 4);
262                    key[2] = BitConverter.ToUInt32(inputKey, 8);
263                    key[3] = BitConverter.ToUInt32(inputKey, 12);
264                }
265
266                //encryption or decryption
267                GuiLogMessage("Action is: " + action, NotificationLevel.Debug);
268                DateTime startTime = DateTime.Now;
269               
270                uint[] vector = new uint[2];
271
272                if (action == 0)
273                {
274                    StatusChanged((int)HIGHTImage.Encode);
275                    GuiLogMessage("Starting encryption [Keysize=128 Bits, Blocksize=64 Bits]", NotificationLevel.Info);
276                    for (int i = 0; i <= blocks - 1; i++)
277                    {
278                        vector[0] = BitConverter.ToUInt32(inputbuffer, (i * 8));
279                        vector[1] = BitConverter.ToUInt32(inputbuffer, (i * 8 + 4));
280
281                        //GuiLogMessage("vector[0]: " + vector[0].ToString("X"), NotificationLevel.Info);
282                        //GuiLogMessage("vector[1]: " + vector[1].ToString("X"), NotificationLevel.Info);
283
284                        vector = general_test(vector, key, 0);
285
286                        //write buffer to output stream
287                        outputbuffer = BitConverter.GetBytes(vector[0]);
288                        outputStream.Write(outputbuffer, 0, 4);
289                        outputbuffer = BitConverter.GetBytes(vector[1]);
290                        outputStream.Write(outputbuffer, 0, 4);
291                    }
292                } else if (action == 1) {
293                    StatusChanged((int)HIGHTImage.Decode);
294                    GuiLogMessage("Starting decryption [Keysize=128 Bits, Blocksize=64 Bits]", NotificationLevel.Info);
295                    for (int i = 0; i <= blocks - 1; i++)
296                    {
297                        vector[0] = BitConverter.ToUInt32(inputbuffer, i * 8);
298                        vector[1] = BitConverter.ToUInt32(inputbuffer, i * 8 + 4);
299
300                        vector = general_test(vector, key, 1);
301
302                        //write buffer to output stream
303                        outputbuffer = BitConverter.GetBytes(vector[0]);
304                        outputStream.Write(outputbuffer, 0, 4);
305                        outputbuffer = BitConverter.GetBytes(vector[1]);
306                        outputStream.Write(outputbuffer, 0, 4);
307                    }
308                }
309
310                /*while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0 && !stop)
311                {
312                    outputStream.Write(buffer, 0, bytesRead);
313                    if ((int)(inputStream.Position * 100 / inputStream.Length) > position)
314                    {
315                        position = (int)(inputStream.Position * 100 / inputStream.Length);
316                        //ProgressChanged(inputStream.Position, inputStream.Length);
317                    }
318                }*/
319
320                long outbytes = outputStream.Length;
321                DateTime stopTime = DateTime.Now;
322                TimeSpan duration = stopTime - startTime;
323                //(outputStream as CryptoolStream).FinishWrite();
324
325                if (!stop)
326                {
327                    if (action == 0)
328                    {
329                        GuiLogMessage("Encryption complete! (in: " + inputStream.Length.ToString() + " bytes, out: " + outbytes.ToString() + " bytes)", NotificationLevel.Info);
330                    }
331                    else
332                    {
333                        GuiLogMessage("Decryption complete! (in: " + inputStream.Length.ToString() + " bytes, out: " + outbytes.ToString() + " bytes)", NotificationLevel.Info);
334                    }
335                    GuiLogMessage("Wrote data to file: " + outputStream.FileName, NotificationLevel.Debug);
336                    GuiLogMessage("Time used: " + duration.ToString(), NotificationLevel.Debug);
337                    outputStream.Close();
338                    OnPropertyChanged("OutputStream");
339                }
340
341                if (stop)
342                {
343                    outputStream.Close();
344                    GuiLogMessage("Aborted!", NotificationLevel.Info);
345                }
346            }
347            /*catch (CryptographicException cryptographicException)
348            {
349                // TODO: For an unknown reason p_crypto_stream can not be closed after exception.
350                // Trying so makes p_crypto_stream throw the same exception again. So in Dispose
351                // the error messages will be doubled.
352                // As a workaround we set p_crypto_stream to null here.
353                p_crypto_stream = null;
354                //GuiLogMessage(cryptographicException.Message, NotificationLevel.Error);
355            }*/
356            catch (Exception exception)
357            {
358                GuiLogMessage(exception.Message, NotificationLevel.Error);
359            }
360            finally
361            {
362                ProgressChanged(1, 1);
363            }
364        }
365
366        public uint[] F0 = new uint[256] {
367                        0, 134, 13, 139, 26, 156, 23, 145, 52, 178, 57, 191, 46, 168, 35, 165, 
368                        104, 238, 101, 227, 114, 244, 127, 249, 92, 218, 81, 215, 70, 192, 75, 205, 
369                        208, 86, 221, 91, 202, 76, 199, 65, 228, 98, 233, 111, 254, 120, 243, 117, 
370                        184, 62, 181, 51, 162, 36, 175, 41, 140, 10, 129, 7, 150, 16, 155, 29, 
371                        161, 39, 172, 42, 187, 61, 182, 48, 149, 19, 152, 30, 143, 9, 130, 4, 
372                        201, 79, 196, 66, 211, 85, 222, 88, 253, 123, 240, 118, 231, 97, 234, 108, 
373                        113, 247, 124, 250, 107, 237, 102, 224, 69, 195, 72, 206, 95, 217, 82, 212, 
374                        25, 159, 20, 146, 3, 133, 14, 136, 45, 171, 32, 166, 55, 177, 58, 188, 
375                        67, 197, 78, 200, 89, 223, 84, 210, 119, 241, 122, 252, 109, 235, 96, 230, 
376                        43, 173, 38, 160, 49, 183, 60, 186, 31, 153, 18, 148, 5, 131, 8, 142, 
377                        147, 21, 158, 24, 137, 15, 132, 2, 167, 33, 170, 44, 189, 59, 176, 54, 
378                        251, 125, 246, 112, 225, 103, 236, 106, 207, 73, 194, 68, 213, 83, 216, 94, 
379                        226, 100, 239, 105, 248, 126, 245, 115, 214, 80, 219, 93, 204, 74, 193, 71, 
380                        138, 12, 135, 1, 144, 22, 157, 27, 190, 56, 179, 53, 164, 34, 169, 47, 
381                        50, 180, 63, 185, 40, 174, 37, 163, 6, 128, 11, 141, 28, 154, 17, 151, 
382                        90, 220, 87, 209, 64, 198, 77, 203, 110, 232, 99, 229, 116, 242, 121, 255};
383
384        public uint[] F1 = new uint[256] {
385                        0, 88, 176, 232, 97, 57, 209, 137, 194, 154, 114, 42, 163, 251, 19, 75, 
386                        133, 221, 53, 109, 228, 188, 84, 12, 71, 31, 247, 175, 38, 126, 150, 206, 
387                        11, 83, 187, 227, 106, 50, 218, 130, 201, 145, 121, 33, 168, 240, 24, 64, 
388                        142, 214, 62, 102, 239, 183, 95, 7, 76, 20, 252, 164, 45, 117, 157, 197, 
389                        22, 78, 166, 254, 119, 47, 199, 159, 212, 140, 100, 60, 181, 237, 5, 93, 
390                        147, 203, 35, 123, 242, 170, 66, 26, 81, 9, 225, 185, 48, 104, 128, 216, 
391                        29, 69, 173, 245, 124, 36, 204, 148, 223, 135, 111, 55, 190, 230, 14, 86, 
392                        152, 192, 40, 112, 249, 161, 73, 17, 90, 2, 234, 178, 59, 99, 139, 211, 
393                        44, 116, 156, 196, 77, 21, 253, 165, 238, 182, 94, 6, 143, 215, 63, 103, 
394                        169, 241, 25, 65, 200, 144, 120, 32, 107, 51, 219, 131, 10, 82, 186, 226, 
395                        39, 127, 151, 207, 70, 30, 246, 174, 229, 189, 85, 13, 132, 220, 52, 108, 
396                        162, 250, 18, 74, 195, 155, 115, 43, 96, 56, 208, 136, 1, 89, 177, 233, 
397                        58, 98, 138, 210, 91, 3, 235, 179, 248, 160, 72, 16, 153, 193, 41, 113, 
398                        191, 231, 15, 87, 222, 134, 110, 54, 125, 37, 205, 149, 28, 68, 172, 244, 
399                        49, 105, 129, 217, 80, 8, 224, 184, 243, 171, 67, 27, 146, 202, 34, 122, 
400                        180, 236, 4, 92, 213, 141, 101, 61, 118, 46, 198, 158, 23, 79, 167, 255};
401
402        public uint Delta0 = 0x5a;
403
404        private uint LFSR_h(uint state) {
405            uint temp = state & 0x9;                                                   
406            if (temp == 0 || temp == 9) temp = 0;               
407            else temp = 0x40;                                                   
408            state = temp | (state>>1);
409
410            return state;
411        }
412
413        private void HIGHT_Keyschedule(uint[] mk, ref uint[] sk)
414        {
415            int i, j;
416
417            for(i=0 ; i < 128 ; i++)
418            {
419                    Delta[i] = Delta0;
420                    Delta0 = LFSR_h(Delta0);
421                //GuiLogMessage("Delta0: " + Delta0.ToString("X1"), NotificationLevel.Info);
422            }
423               
424            for(i=0 ; i < 8 ; i++)
425            {
426                for (j = 0; j < 8; j++)
427                {
428                    sk[16 * i + j] = mk[(j - i) < 0 ? (j - i + 8) : (j - i)] + Delta[16 * i + j];
429                }
430
431                for (j = 0; j < 8; j++)
432                {
433                    sk[16 * i + j + 8] = mk[(j - i) < 0 ? (j - i + 16) : (j - i + 8)] + Delta[16 * i + j + 8];
434                }
435            }
436        }
437       
438        private void Transformation(ref uint x6, ref uint x4, ref uint x2, ref uint x0, uint mk3, uint mk2, uint mk1, uint mk0)
439        {
440                x0 += mk0;
441                x2 ^= mk1;
442                x4 += mk2;
443                x6 ^= mk3;
444        }
445
446        private void Round(ref uint x7, uint x6, ref uint x5, uint x4, ref uint x3, uint x2, ref uint x1, uint x0, uint i, uint[] sk)
447        {
448            x1 = (x1 + (F1[x0] ^ sk[i]))%256;
449            x3 = (x3 ^ (F0[x2] + sk[i + 1]))%256;
450            x5 = (x5 + (F1[x4] ^ sk[i + 2]))%256;
451            x7 = (x7 ^ (F0[x6] + sk[i + 3]))%256;
452        }
453
454        public static uint[] Delta = new uint[128];
455
456        private void HIGHT_Enc(uint[] x, ref uint[] y, uint[] mk, uint[] sk) {
457
458                Transformation(ref x[6], ref x[4], ref x[2], ref x[0], mk[3], mk[2], mk[1], mk[0]);     // Initial Transformation
459
460            Round(ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], 0, sk);               //Round1
461            Round(ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], 4, sk);               //Round2
462            Round(ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], 8, sk);               //Round3
463            Round(ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], 12, sk);              //Round4
464            Round(ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], 16, sk);              //Round5
465            Round(ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], 20, sk);              //Round6
466            Round(ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], 24, sk);              //Round7
467            Round(ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], 28, sk);              //Round8
468            Round(ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], 32, sk);              //Round9
469            Round(ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], 36, sk);              //Round10
470            Round(ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], 40, sk);              //Round11
471            Round(ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], 44, sk);              //Round12
472            Round(ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], 48, sk);              //Round13
473            Round(ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], 52, sk);              //Round14
474            Round(ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], 56, sk);              //Round15
475            Round(ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], 60, sk);              //Round16
476            Round(ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], 64, sk);              //Round17
477            Round(ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], 68, sk);              //Round18
478            Round(ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], 72, sk);              //Round19
479            Round(ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], 76, sk);              //Round20
480            Round(ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], 80, sk);              //Round21
481            Round(ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], 84, sk);              //Round22
482            Round(ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], 88, sk);              //Round23
483            Round(ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], 92, sk);              //Round24
484            Round(ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], 96, sk);              //Round25
485            Round(ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], 100, sk);             //Round26
486            Round(ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], 104, sk);             //Round27
487            Round(ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], 108, sk);             //Round28
488            Round(ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], 112, sk);             //Round29
489            Round(ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], 116, sk);             //Round30
490            Round(ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], 120, sk);             //Round31
491            Round(ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], 124, sk);             //Round32
492
493                Transformation(ref x[7],ref x[5],ref x[3],ref x[1],mk[15],mk[14],mk[13],mk[12]);        // Final Transformation
494
495                y[7] = x[0]; y[6] = x[7]; y[5] = x[6]; y[4] = x[5];
496                y[3] = x[4]; y[2] = x[3]; y[1] = x[2]; y[0] = x[1];
497
498        }
499
500        private void DTransformation(ref uint x6, ref uint x4, ref uint x2, ref uint x0, uint mk3, uint mk2, uint mk1, uint mk0)
501        {
502            x0 = (x0 - mk0)%256;
503                x2 ^= mk1;
504                x4 = (x4 - mk2)%256;
505                x6 ^= mk3;
506        }
507
508        private void DRound( ref uint x7, uint x6, ref uint x5, uint x4, ref uint x3, uint x2, ref uint x1, uint x0, uint i, uint[] sk) 
509        {
510            x1 = (x1 - (F1[x0] ^ sk[i]))%256;
511            x3 = (x3 ^ (F0[x2] + sk[i+1]))%256;
512            x5 = (x5 - (F1[x4] ^ sk[i+2]))%256;
513            x7 = (x7 ^ (F0[x6] + sk[i+3]))%256;
514        }
515
516        private void HIGHT_Dec(uint[] x, ref uint[] y, uint[] mk, uint[] sk) {
517               
518            DTransformation(ref x[6],ref x[4],ref x[2],ref x[0],mk[15],mk[14],mk[13],mk[12]);   // Initial Transformation
519
520            DRound(ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], 124, sk);            //Round1
521            DRound(ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], 120, sk);            //Round2
522            DRound(ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], 116, sk);            //Round3
523            DRound(ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], 112, sk);            //Round4
524            DRound(ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], 108, sk);            //Round5
525            DRound(ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], 104, sk);            //Round6
526            DRound(ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], 100, sk);            //Round7
527            DRound(ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], 96, sk);                     //Round8
528            DRound(ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], 92, sk);                     //Round9
529            DRound(ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], 88, sk);                     //Round10
530            DRound(ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], 84, sk);                     //Round11
531            DRound(ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], 80, sk);                     //Round12
532            DRound(ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], 76, sk);                     //Round13
533            DRound(ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], 72, sk);                     //Round14
534            DRound(ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], 68, sk);                     //Round15
535            DRound(ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], 64, sk);                     //Round16
536            DRound(ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], 60, sk);                     //Round17
537            DRound(ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], 56, sk);                     //Round18
538            DRound(ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], 52, sk);                     //Round19
539            DRound(ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], 48, sk);                     //Round20
540            DRound(ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], 44, sk);                     //Round21
541            DRound(ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], 40, sk);                     //Round22
542            DRound(ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], 36, sk);                     //Round23
543            DRound(ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], 32, sk);                     //Round24
544            DRound(ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], 28, sk);                     //Round25
545            DRound(ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], 24, sk);                     //Round26
546            DRound(ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], ref x[3], x[2], 20, sk);                     //Round27
547            DRound(ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], ref x[4], x[3], 16, sk);                     //Round28
548            DRound(ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], ref x[5], x[4], 12, sk);                     //Round29
549            DRound(ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], ref x[6], x[5], 8, sk);                      //Round30
550            DRound(ref x[5], x[4], ref x[3], x[2], ref x[1], x[0], ref x[7], x[6], 4, sk);                      //Round31
551            DRound(ref x[6], x[5], ref x[4], x[3], ref x[2], x[1], ref x[0], x[7], 0, sk);                      //Round32
552
553            DTransformation(ref x[5],ref x[3],ref x[1],ref x[7],mk[3],mk[2],mk[1],mk[0]);       // Final Transformation
554
555            y[7] = x[6]; y[6] = x[5]; y[5] = x[4]; y[4] = x[3];
556            y[3] = x[2]; y[2] = x[1]; y[1] = x[0]; y[0] = x[7];
557               
558        }
559
560        private uint[] general_test(uint[] text, uint[] key, uint mode){
561
562            //GuiLogMessage("HIGHT Test Plaintext Original: " + plaintext[0].ToString("X") + " " + plaintext[1].ToString("X"), NotificationLevel.Info);
563
564            uint[] MK = new uint[16];// {0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00};
565            uint[] Plain = new uint[8];// { 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01 };
566            uint[] SK = new uint[128];
567            uint[] Cipher = new uint[8];
568            uint[] temp, Plain_tmp, Cipher_tmp = new uint[8];
569            uint[] key_temp = new uint[16];
570
571            //MK = Plain = SK = Cipher = temp = Plain_tmp = Cipher_tmp = key_temp = null;
572
573            // convert key into 8 bit values
574            key_temp = key;
575            MK[12] = key_temp[0] >> 24;
576            key_temp = key;
577            MK[13] = key_temp[0] << 8;
578            MK[13] = MK[13] >> 24;
579            key_temp = key;
580            MK[14] = key_temp[0] << 16;
581            MK[14] = MK[14] >> 24;
582            key_temp = key;
583            MK[15] = key_temp[0] << 24;
584            MK[15] = MK[15] >> 24;
585
586            key_temp = key;
587            MK[8] = key_temp[1] >> 24;
588            key_temp = key;
589            MK[9] = key_temp[1] << 8;
590            MK[9] = MK[9] >> 24;
591            key_temp = key;
592            MK[10] = key_temp[1] << 16;
593            MK[10] = MK[10] >> 24;
594            key_temp = key;
595            MK[11] = key_temp[1] << 24;
596            MK[11] = MK[11] >> 24;
597
598            key_temp = key;
599            MK[4] = key_temp[2] >> 24;
600            key_temp = key;
601            MK[5] = key_temp[2] << 8;
602            MK[5] = MK[5] >> 24;
603            key_temp = key;
604            MK[6] = key_temp[2] << 16;
605            MK[6] = MK[6] >> 24;
606            key_temp = key;
607            MK[7] = key_temp[2] << 24;
608            MK[7] = MK[7] >> 24;
609
610            key_temp = key;
611            MK[0] = key_temp[3] >> 24;
612            key_temp = key;
613            MK[1] = key_temp[3] << 8;
614            MK[1] = MK[1] >> 24;
615            key_temp = key;
616            MK[2] = key_temp[3] << 16;
617            MK[2] = MK[2] >> 24;
618            key_temp = key;
619            MK[3] = key_temp[3] << 24;
620            MK[3] = MK[3] >> 24;
621
622            // run keyschedule of HIGHT
623                HIGHT_Keyschedule(MK, ref SK);
624
625            // choose encryption/decryption
626            if (mode == 0)
627            {
628                //convert 32 bit entries into 8 bit/1 byte entries
629                temp = text;
630
631                Plain[4] = temp[0] >> 24;
632                temp = text;
633                Plain[5] = temp[0] << 8;
634                Plain[5] = Plain[5] >> 24;
635                temp = text;
636                Plain[6] = temp[0] << 16;
637                Plain[6] = Plain[6] >> 24;
638                temp = text;
639                Plain[7] = temp[0] << 24;
640                Plain[7] = Plain[7] >> 24;
641                temp = text;
642
643                Plain[0] = temp[1] >> 24;
644                temp = text;
645                Plain[1] = temp[1] << 8;
646                Plain[1] = Plain[1] >> 24;
647                temp = text;
648                Plain[2] = temp[1] << 16;
649                Plain[2] = Plain[2] >> 24;
650                temp = text;
651                Plain[3] = temp[1] << 24;
652                Plain[3] = Plain[3] >> 24;
653                temp = text;
654
655                //GuiLogMessage("HIGHT Cipher before: " + Cipher[0].ToString("X1") + " " + Cipher[1].ToString("X1") + " " + Cipher[2].ToString("X1") + " " + Cipher[3].ToString("X1") + " " + Cipher[4].ToString("X1") + " " + Cipher[5].ToString("X1") + " " + Cipher[6].ToString("X1") + " " + Cipher[7].ToString("X1") + " ", NotificationLevel.Info);
656                //GuiLogMessage("HIGHT Plain before: " + Plain[0].ToString("X1") + " " + Plain[1].ToString("X1") + " " + Plain[2].ToString("X1") + " " + Plain[3].ToString("X1") + " " + Plain[4].ToString("X1") + " " + Plain[5].ToString("X1") + " " + Plain[6].ToString("X1") + " " + Plain[7].ToString("X1") + " ", NotificationLevel.Info);
657
658                Plain_tmp = Plain;
659                HIGHT_Enc(Plain_tmp, ref Cipher, MK, SK);
660
661                Cipher_tmp = Cipher;
662
663                //reconvert 8 bit entries into 32 bit entries
664                text[0] = (Cipher_tmp[0] << 24) + (Cipher_tmp[1] << 16) + (Cipher_tmp[2] << 8) + Cipher_tmp[3];
665                text[1] = (Cipher_tmp[4] << 24) + (Cipher_tmp[5] << 16) + (Cipher_tmp[6] << 8) + Cipher_tmp[7];
666
667                //GuiLogMessage("HIGHT Cipher after Enc: " + Cipher[0].ToString("X1") + " " + Cipher[1].ToString("X1") + " " + Cipher[2].ToString("X1") + " " + Cipher[3].ToString("X1") + " " + Cipher[4].ToString("X1") + " " + Cipher[5].ToString("X1") + " " + Cipher[6].ToString("X1") + " " + Cipher[7].ToString("X1") + " ", NotificationLevel.Info);
668                //GuiLogMessage("HIGHT Plain after Enc: " + Plain[0].ToString("X1") + " " + Plain[1].ToString("X1") + " " + Plain[2].ToString("X1") + " " + Plain[3].ToString("X1") + " " + Plain[4].ToString("X1") + " " + Plain[5].ToString("X1") + " " + Plain[6].ToString("X1") + " " + Plain[7].ToString("X1") + " ", NotificationLevel.Info);
669            }
670            else
671            {
672                //convert 32 bit entries into 8 bit entries
673                temp = text;
674
675                Cipher[0] = temp[0] >> 24;
676                temp = text;
677                Cipher[1] = temp[0] << 8;
678                Cipher[1] = Cipher[1] >> 24;
679                temp = text;
680                Cipher[2] = temp[0] << 16;
681                Cipher[2] = Cipher[2] >> 24;
682                temp = text;
683                Cipher[3] = temp[0] << 24;
684                Cipher[3] = Cipher[3] >> 24;
685                temp = text;
686
687                Cipher[4] = temp[1] >> 24;
688                temp = text;
689                Cipher[5] = temp[1] << 8;
690                Cipher[5] = Cipher[5] >> 24;
691                temp = text;
692                Cipher[6] = temp[1] << 16;
693                Cipher[6] = Cipher[6] >> 24;
694                temp = text;
695                Cipher[7] = temp[1] << 24;
696                Cipher[7] = Cipher[7] >> 24;
697                temp = text;
698
699                Cipher_tmp = Cipher;
700
701                //GuiLogMessage("HIGHT Cipher before: " + Cipher[0].ToString("X1") + " " + Cipher[1].ToString("X1") + " " + Cipher[2].ToString("X1") + " " + Cipher[3].ToString("X1") + " " + Cipher[4].ToString("X1") + " " + Cipher[5].ToString("X1") + " " + Cipher[6].ToString("X1") + " " + Cipher[7].ToString("X1") + " ", NotificationLevel.Info);
702                //GuiLogMessage("HIGHT Plain before: " + Plain[0].ToString("X1") + " " + Plain[1].ToString("X1") + " " + Plain[2].ToString("X1") + " " + Plain[3].ToString("X1") + " " + Plain[4].ToString("X1") + " " + Plain[5].ToString("X1") + " " + Plain[6].ToString("X1") + " " + Plain[7].ToString("X1") + " ", NotificationLevel.Info);
703               
704                HIGHT_Dec(Cipher_tmp, ref Plain, MK, SK);
705
706                Plain_tmp = Plain;
707                //reconvert 8 bit entries into 32 bit entries
708                text[1] = (Plain[0] << 24) + (Plain[1] << 16) + (Plain[2] << 8) + Plain[3];
709                text[0] = (Plain[4] << 24) + (Plain[5] << 16) + (Plain[6] << 8) + Plain[7];
710
711                //GuiLogMessage("HIGHT Cipher after Dec: " + Cipher[0].ToString("X1") + " " + Cipher[1].ToString("X1") + " " + Cipher[2].ToString("X1") + " " + Cipher[3].ToString("X1") + " " + Cipher[4].ToString("X1") + " " + Cipher[5].ToString("X1") + " " + Cipher[6].ToString("X1") + " " + Cipher[7].ToString("X1") + " ", NotificationLevel.Info);
712                //GuiLogMessage("HIGHT Plain after Dec: " + Plain[0].ToString("X1") + " " + Plain[1].ToString("X1") + " " + Plain[2].ToString("X1") + " " + Plain[3].ToString("X1") + " " + Plain[4].ToString("X1") + " " + Plain[5].ToString("X1") + " " + Plain[6].ToString("X1") + " " + Plain[7].ToString("X1") + " ", NotificationLevel.Info);
713            }
714
715            return text;
716        }
717
718        public void Encrypt()
719        {
720            //Encrypt Stream
721            process(0, settings.Padding);
722        }
723
724        public void Decrypt()
725        {
726            //Decrypt Stream
727            process(1, settings.Padding);
728        }
729
730        public void Initialize()
731        {
732        }
733
734        public event StatusChangedEventHandler OnPluginStatusChanged;
735
736        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
737        private void GuiLogMessage(string message, NotificationLevel logLevel)
738        {
739            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(message, this, logLevel));
740        }
741
742        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
743        private void ProgressChanged(double value, double max)
744        {
745            EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
746        }
747
748        public void Pause()
749        {
750        }
751
752        public void PostExecution()
753        {
754            Dispose();
755        }
756
757        public void PreExecution()
758        {
759            Dispose();
760        }
761
762        public UserControl Presentation
763        {
764            get { return null; }
765        }
766
767        public UserControl QuickWatchPresentation
768        {
769            get { return null; }
770        }
771
772        public void Stop()
773        {
774            this.stop = true;
775        }
776
777        #region INotifyPropertyChanged Members
778
779        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
780
781        public void OnPropertyChanged(string name)
782        {
783            EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
784            /*if (PropertyChanged != null)
785            {
786              PropertyChanged(this, new PropertyChangedEventArgs(name));
787            }*/
788        }
789
790        private void StatusChanged(int imageIndex)
791        {
792            EventsHelper.StatusChanged(OnPluginStatusChanged, this, new StatusEventArgs(StatusChangedMode.ImageUpdate, imageIndex));
793        }
794
795        #endregion
796    }
797
798    enum HIGHTImage
799    {
800        Default,
801        Encode,
802        Decode
803    }
804}
Note: See TracBrowser for help on using the repository browser.