source: trunk/CrypPlugins/SDES/SDES.cs @ 1194

Last change on this file since 1194 was 1194, checked in by Sven Rech, 12 years ago

added IV to the IControlEncryption interface

File size: 73.1 KB
Line 
1/*                             
2   Copyright 2009 Team CrypTool (Sven Rech,Dennis Nolte,Raoul Falk,Nils Kopal), 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*/
16using System;
17using System.Collections.Generic;
18using System.Linq;
19using System.Text;
20using System.IO;
21using System.Security.Cryptography;
22using Cryptool.PluginBase;
23using System.ComponentModel;
24using Cryptool.PluginBase.Cryptography;
25using Cryptool.PluginBase.IO;
26using System.Windows.Controls;
27using Cryptool.PluginBase.Control;
28using System.Threading;
29using System.Windows.Threading;
30using System.Runtime.InteropServices;
31
32namespace Cryptool.Plugins.Cryptography.Encryption
33{
34    /// <summary>
35    /// This plugin encrypts / decrypts texts with the simplified DES alogrithm (SDES)
36    /// It can be used as plugin in a normal encryption/decryption chanin or be
37    /// used by the KeySearcher to do bruteforcing
38    /// </summary>
39    [Author("Nils Kopal", "nils.kopal@cryptool.de", "Uni Duisburg", "http://www.uni-duisburg-essen.de")]
40    [PluginInfo(false, "SDES", "Simplified Data Encryption Standard", "SDES/DetailedDescription/Description.xaml", "SDES/icon.png", "SDES/Images/encrypt.png", "SDES/Images/decrypt.png")]
41    [EncryptionType(EncryptionType.SymmetricBlock)]
42    public class SDES : IEncryption
43    {
44        #region Private variables
45
46        private SDESSettings settings;
47        private CryptoolStream inputStream;
48        private CryptoolStream outputStream;
49        private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
50        private byte[] inputKey;
51        private byte[] inputIV;       
52        private bool stop = false;
53        private UserControl presentation = new SDESPresentation();
54        private SDESControl controlSlave;
55
56        #endregion
57
58        #region events
59
60        public event PropertyChangedEventHandler PropertyChanged;
61        public event StatusChangedEventHandler OnPluginStatusChanged;
62        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
63        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
64
65        #endregion
66
67        #region public
68
69        /// <summary>
70        /// Tells you wether input changed or not
71        /// </summary>
72        public bool InputChanged
73        { get; set; }
74
75        /// <summary>
76        /// Constructs a new SDES
77        /// </summary>
78        public SDES()
79        {
80            InputChanged = false;
81            this.settings = new SDESSettings();
82            this.settings.OnPluginStatusChanged += settings_OnPluginStatusChanged;
83        }
84
85        /// <summary>       
86        /// The status of the plugin changes
87        /// </summary>
88        /// <param name="sender"></param>
89        /// <param name="args"></param>
90        void settings_OnPluginStatusChanged(IPlugin sender, StatusEventArgs args)
91        {
92            if(OnPluginStatusChanged != null)OnPluginStatusChanged(this, args);
93        }
94
95        /// <summary>
96        /// Sets/Gets the settings of this plugin
97        /// </summary>
98        public ISettings Settings
99        {
100            get { return this.settings; }
101            set { this.settings = (SDESSettings)value; }
102        }
103   
104        /// <summary>
105        /// Is this Plugin in Status stop?
106        /// </summary>
107        /// <returns></returns>
108        public bool getStop()
109        {
110            return stop;
111        }
112
113        /// <summary>
114        /// Gets/Sets the input of the SDES plugin (the text which should be encrypted/decrypted)
115        /// </summary>
116        [PropertyInfo(Direction.InputData, "Input", "Data to be encrypted or decrypted", null, true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
117        public CryptoolStream InputStream
118        {
119            get 
120            {
121                try
122                {
123                    if (inputStream != null)
124                    {
125                        CryptoolStream cs = new CryptoolStream();
126                        cs.OpenRead(inputStream.FileName);
127                        listCryptoolStreamsOut.Add(cs);
128                        return cs;
129                    }
130                    else return null;
131                }
132                catch (Exception ex)
133                {
134                    GuiLogMessage("getInputStream: " + ex.Message, NotificationLevel.Error);
135                    return null;
136                }
137
138            }
139            set 
140            {
141                this.inputStream = value;
142                if (value != null)
143                {
144                    listCryptoolStreamsOut.Add(value);                     
145                }
146                OnPropertyChanged("InputStream");
147            }
148        }
149
150        /// <summary>
151        /// Gets/Sets the output of the SDES plugin (the text which is encrypted/decrypted)
152        /// </summary>
153        [PropertyInfo(Direction.OutputData, "Output stream", "Encrypted or decrypted output data", null, true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
154        public CryptoolStream OutputStream
155        {
156            get
157            {
158                try
159                {
160                    if (this.outputStream != null)
161                    {
162                        CryptoolStream cs = new CryptoolStream();
163                        listCryptoolStreamsOut.Add(cs);
164                        cs.OpenRead(this.outputStream.FileName);
165                        return cs;
166                    }
167                    return null;
168                }
169                catch (Exception ex)
170                {
171                    GuiLogMessage("getOutputStream: " + ex.Message, NotificationLevel.Error);
172                    return null;
173                }
174            }
175            set
176            {
177
178                this.outputStream = value;
179                if (value != null)
180                {
181                    listCryptoolStreamsOut.Add(value);
182                }
183                OnPropertyChanged("OutputStream");
184            }
185        }
186
187        /// <summary>
188        /// Gets/Sets the key which should be used.Must be 10 bytes  (only 1 or 0 allowed).
189        /// </summary>
190        [PropertyInfo(Direction.InputData, "Key", "Must be 8 bytes (only 1 or 0 allowed).", null, true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
191        public byte[] InputKey
192        {
193            get { return this.inputKey; }
194            set
195            {
196                InputChanged = true;
197                this.inputKey = value;
198                OnPropertyChanged("InputKey");
199            }
200        }
201
202        /// <summary>
203        /// Gets/Sets the Initialization Vector which should be used.Must be 10 bytes  (only 1 or 0 allowed).
204        /// </summary>
205        [PropertyInfo(Direction.InputData, "IV", "IV to be used in chaining modes, must be 10 bytes (only 1 or 0 allowed).", null, true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
206        public byte[] InputIV
207        {
208            get { return this.inputIV; }
209            set
210            {
211                this.inputIV = value;
212                OnPropertyChanged("InputIV");
213            }
214        }
215
216        /// <summary>
217        /// Start encrypting
218        /// </summary>
219        public void Encrypt()
220        {
221            //Encrypt Stream
222            process(0);
223        }
224
225        /// <summary>
226        /// Start decrypting
227        /// </summary>
228        public void Decrypt()
229        {
230            //Decrypt Stream
231            process(1);
232        }
233
234        /// <summary>
235        /// Called by the environment to start this plugin
236        /// </summary>
237        public void Execute()
238        {
239            process(settings.Action);
240        }
241
242
243        /// <summary>
244        /// Get the Presentation of this plugin
245        /// </summary>
246        public UserControl Presentation
247        {
248            get { return this.presentation; }
249        }
250
251        /// <summary>
252        /// Get the QuickWatchPresentation of this plugin
253        /// </summary>
254        public UserControl QuickWatchPresentation
255        {
256            get { return null; }
257        }
258
259        /// <summary>
260        /// Called by the environment to do initialization
261        /// </summary>
262        public void Initialize()
263        {
264        }
265
266        /// <summary>
267        /// Called by the envorinment if this plugin is unloaded
268        /// closes all streams
269        /// </summary>
270        public void Dispose()
271        {
272            try
273            {
274                this.stop = false;
275                inputKey = null;
276                inputIV = null;
277
278                foreach (CryptoolStream stream in listCryptoolStreamsOut)
279                {
280                    stream.Close();
281                }
282                listCryptoolStreamsOut.Clear();
283
284            }
285            catch (Exception ex)
286            {
287                GuiLogMessage(ex.Message, NotificationLevel.Error);
288            }
289        }
290
291        /// <summary>
292        /// Called by the environment of this plugin to stop it
293        /// </summary>
294        public void Stop()
295        {
296            this.stop = true;
297        }
298
299        /// <summary>
300        /// Called by the environment of this plugin after execution
301        /// </summary>
302        public void PostExecution()
303        {
304            Dispose();
305        }
306
307        /// <summary>
308        /// Called by the environment of this plugin before execution
309        /// </summary>
310        public void PreExecution()
311        {
312            Dispose();
313        }
314
315        /// <summary>
316        /// A property of this plugin changed
317        /// </summary>
318        /// <param name="name">propertyname</param>
319        public void OnPropertyChanged(string name)
320        {
321            if (PropertyChanged != null)
322            {
323                PropertyChanged(this, new PropertyChangedEventArgs(name));
324            }
325        }
326
327        /// <summary>
328        /// Logs a message into the messages of crypttool
329        /// </summary>
330        /// <param name="message">message</param>
331        /// <param name="logLevel">logLevel</param>
332        public void GuiLogMessage(string message, NotificationLevel logLevel)
333        {
334            if (OnGuiLogNotificationOccured != null)
335            {
336                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, logLevel));
337            }
338        }
339
340        /// <summary>
341        /// Sets the current progess of this plugin
342        /// </summary>
343        /// <param name="value">value</param>
344        /// <param name="max">max</param>
345        public void ProgressChanged(double value, double max)
346        {
347            if (OnPluginProgressChanged != null)
348            {
349                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
350            }
351        }
352
353        /// <summary>
354        /// Called by the environment of this plugin if it is set to pause
355        /// </summary>
356        public void Pause()
357        {
358
359        }
360
361        /// <summary>
362        /// Sets/Gets the ControlSlave of this plugin
363        /// </summary>
364        [PropertyInfo(Direction.ControlSlave, "SDES Slave", "Direct access to SDES.", "", DisplayLevel.Beginner)]
365        public IControlEncryption ControlSlave
366        {
367            get
368            {
369                if (controlSlave == null)
370                    controlSlave = new SDESControl(this);
371                return controlSlave;
372            }
373        } 
374
375        #endregion public
376
377        #region private
378
379        /// <summary>
380        /// This method checks if the input stream is valid. If it is not valid it sets it to a dummy stream
381        /// (this funcionality is stolen from DES plugin ;) )
382        /// </summary>
383        private void checkForInputStream()
384        {
385            if (settings.Action == 0 && (inputStream == null || (inputStream != null && inputStream.Length == 0)))
386            {
387                //create some input
388                String dummystring = "Dummy string - no input provided - \"Hello SDES World\" - dummy string - no input provided!";
389                this.inputStream = new CryptoolStream();
390                this.inputStream.OpenRead(this.GetPluginInfoAttribute().Caption, Encoding.Default.GetBytes(dummystring.ToCharArray()));
391                // write a warning to the ouside word
392                GuiLogMessage("WARNING - No input provided. Using dummy data. (" + dummystring + ")", NotificationLevel.Warning);
393            }
394        }
395
396        /// <summary>
397        /// Checks if the Input key is not null and has length 10 and only contains 1s and 0s
398        /// and if Input IV is not null and has length 8 and only contains 1s and 0s
399        /// </summary>
400        /// <returns>true if ok</returns>
401        private bool areKeyAndIVValid()
402        {
403
404            if (this.inputKey == null || this.inputKey.Length != 10)
405            {
406                GuiLogMessage("The Key has to have the length of 10 bytes (containing only '1' and '0')", NotificationLevel.Error);
407                return false;
408            }
409            if (this.inputIV == null || this.inputIV.Length != 8)
410            {
411                GuiLogMessage("The IV has to have the length of 8 bytes (containing only '1' and '0')", NotificationLevel.Error);
412                return false;
413            }
414
415            foreach (char character in inputKey)
416            {
417                if (character != '0' && character != '1')
418                {
419                    GuiLogMessage("Invalid character in Key: '" + character + "' - may only contain '1' and '0'", NotificationLevel.Error);
420                    return false;
421                }
422            }
423
424            foreach (char character in inputIV)
425            {
426                if (character != '0' && character != '1')
427                {
428                    GuiLogMessage("Invalid character in IV: '" + character + "' - may only contain '1' and '0'", NotificationLevel.Error);
429                    return false;
430                }
431            }
432
433            return true;
434        }
435
436        /// <summary>
437        /// Starts the encryption/decryption process with SDES
438        /// </summary>
439        /// <param name="action">0 = encrypt, 1 = decrypt</param>
440        private void process(int action)
441        {
442            if (controlSlave is object && InputStream is object && InputIV is object)
443            {
444                controlSlave.onStatusChanged();
445            }
446
447            try
448            {
449                checkForInputStream();
450                if (!areKeyAndIVValid())
451                {
452                    return;
453                }
454
455                if (inputStream == null || (inputStream != null && inputStream.Length == 0))
456                {
457                    GuiLogMessage("No input given. Not using dummy data in decrypt mode. Aborting now.", NotificationLevel.Error);
458                    return;
459                }
460
461                if (this.inputStream.CanSeek) this.inputStream.Position = 0;
462               
463                outputStream = new CryptoolStream();
464                listCryptoolStreamsOut.Add(outputStream);
465                outputStream.OpenWrite(this.GetPluginInfoAttribute().Caption);
466               
467                System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();               
468                DateTime startTime = DateTime.Now;
469
470                //Encrypt
471                if(action == 0){
472                   
473                    if (this.settings.Mode == 0)
474                    {
475                        GuiLogMessage("Starting encryption with ecb", NotificationLevel.Info);
476                        ElectronicCodeBook ecb = new ElectronicCodeBook(this);
477                        ecb.encrypt(inputStream, outputStream, Tools.stringToBinaryByteArray(enc.GetString(this.inputKey)));
478                    }
479                    else if (this.settings.Mode == 1)
480                    {
481                        GuiLogMessage("Starting encryption with cbc", NotificationLevel.Info);
482                        CipherBlockChaining cbc = new CipherBlockChaining(this);
483                        cbc.encrypt(inputStream, outputStream, Tools.stringToBinaryByteArray(enc.GetString(this.inputKey)), Tools.stringToBinaryByteArray(enc.GetString(this.inputIV)));
484                    }
485                }
486                //Decrypt
487                else if (action == 1)
488                {
489                                       
490                    if (this.settings.Mode == 0)
491                    {
492                        GuiLogMessage("Starting decryption with ecb", NotificationLevel.Info);
493                        ElectronicCodeBook ecb = new ElectronicCodeBook(this);
494                        ecb.decrypt(inputStream, outputStream, Tools.stringToBinaryByteArray(enc.GetString(this.inputKey)));
495                    }
496                    if (this.settings.Mode == 1)
497                    {
498                        GuiLogMessage("Starting decryption with cbc", NotificationLevel.Info);
499                        CipherBlockChaining cbc = new CipherBlockChaining(this);
500                        cbc.decrypt(inputStream, outputStream, Tools.stringToBinaryByteArray(enc.GetString(this.inputKey)), Tools.stringToBinaryByteArray(enc.GetString(this.inputIV)));
501                    }
502                }
503
504                DateTime stopTime = DateTime.Now;
505                TimeSpan duration = stopTime - startTime;
506                if (!stop)
507                {
508                    GuiLogMessage("En-/Decryption complete! ", NotificationLevel.Info);
509                    GuiLogMessage("Wrote data to file: " + outputStream.FileName, NotificationLevel.Info);
510                    GuiLogMessage("Time used: " + duration.ToString(), NotificationLevel.Debug);
511                    OnPropertyChanged("OutputStream");
512               
513                }else{                   
514                    GuiLogMessage("Aborted!", NotificationLevel.Info);
515                }
516
517                //avoid unnecessary error messages because of wrong input/output streams:
518                outputStream.Close();
519                outputStream = null;
520                inputStream.Close();
521                inputStream = null;
522            }
523            catch (Exception exception)
524            {
525                GuiLogMessage(exception.Message, NotificationLevel.Error);
526                GuiLogMessage(exception.StackTrace, NotificationLevel.Error);
527            }
528            finally
529            {             
530                ProgressChanged(1, 1);
531            }
532        }
533
534        #endregion
535
536    }//end SDES
537
538    /// <summary>
539    /// This Class is for controlling the SDES with a "brute forcer" like KeySearcher
540    /// </summary>
541    public class SDESControl : IControlEncryption
542    {
543        #region private
544        private SDES plugin;
545        private byte[] input;
546        ElectronicCodeBook ecb;
547        CipherBlockChaining cbc;
548        #endregion
549
550        #region events
551        public event KeyPatternChanged keyPatternChanged; //not used, because we only have one key length
552        public event IControlStatusChangedEventHandler OnStatusChanged;
553        #endregion
554
555        #region public
556
557        /// <summary>
558        /// Constructs a new SDESControl
559        /// </summary>
560        /// <param name="Plugin"></param>
561        public SDESControl(SDES Plugin)
562        {
563            this.plugin = Plugin;
564            this.ecb = new ElectronicCodeBook(plugin);
565            this.cbc = new CipherBlockChaining(plugin);
566        }
567
568        /// <summary>
569        /// Called by SDES if its status changes
570        /// </summary>
571        public void onStatusChanged()
572        {
573            if(OnStatusChanged != null)
574                OnStatusChanged(this, true);
575        }
576     
577        /// <summary>
578        /// Called by a Master to start encryption
579        /// </summary>
580        /// <param name="key">key</param>
581        /// <param name="bytesToUse">bytesToUse</param>
582        /// <returns>encrypted text</returns>
583        public byte[] Encrypt(byte[] key, int bytesToUse)
584        {
585            return execute(key, bytesToUse, 0);
586        }
587
588        /// <summary>
589        /// Called by a Master to start decryption with ciphertext
590        /// </summary>
591        /// <param name="ciphertext">encrypted text</param>
592        /// <param name="key">key</param>
593        /// <param name="bytesToUse">bytesToUse</param>
594        /// <returns>decrypted text</returns>
595        public byte[] Decrypt(byte[] ciphertext, byte[] key, byte[] IV, int bytesToUse)
596        {
597            return execute(ciphertext, key, bytesToUse, 1);
598        }
599
600        /// <summary>
601        /// Called by a Master to start decryption with ciphertext
602        /// </summary>
603        /// <param name="ciphertext">encrypted text</param>
604        /// <param name="key">key</param>
605        /// <returns>decrypted text</returns>
606        public byte[] Decrypt(byte[] ciphertext, byte[] key, byte[] IV)
607        {
608            return execute(ciphertext, key, ciphertext.Length, 1);
609        }
610
611        /// <summary>
612        /// Called by a Master to start decryption
613        /// </summary>
614        /// <param name="key">key</param>
615        /// <param name="bytesToUse">bytesToUse</param>
616        /// <returns>decrypted text</returns>
617        public byte[] Decrypt(byte[] key, byte[] IV, int bytesToUse)
618        {
619            return execute(key, bytesToUse, 1);
620        }
621
622        /// <summary>
623        /// Get the key pattern of the SDES algorithm
624        /// </summary>
625        /// <returns>[01][01][01][01][01][01][01][01][01][01]</returns>
626        public string getKeyPattern()
627        {
628            return "[01][01][01][01][01][01][01][01][01][01]";
629        }
630
631        /// <summary>
632        /// Makes a byte Array out of a String
633        /// example
634        /// "10101" -> 1,0,1,0,1
635        ///
636        /// A 0 is interpreted as 0
637        /// any other character as 1
638        /// </summary>
639        /// <param name="key"></param>
640        /// <returns></returns>
641        public byte[] getKeyFromString(string key, ref int[] arrayPointers, ref int[] arraySuccessors, ref int[] arrayUppers)
642        {
643            byte[] bkey = new byte[10];
644            int count = 0;
645            foreach (char c in key)
646                if (c == '*')
647                    return null;    //blocks not supported yet
648                else if (c == '0')
649                    bkey[count++] = 0;
650                else
651                    bkey[count++] = 1;
652            return bkey;
653        }
654
655        public IControlEncryption clone()
656        {
657            return new SDESControl(plugin);
658        }
659
660        public void Dispose()
661        {
662            //closeStreams();
663        }
664
665        #endregion
666
667        #region private
668
669        /// <summary>
670        /// Called by itself to start encryption/decryption
671        /// </summary>
672        /// /// <param name="data">The data for encryption/decryption</param>
673        /// <param name="key">key</param>
674        /// <param name="bytesToUse">bytesToUse</param>
675        /// <returns>encrypted/decrypted text</returns>
676        private byte[] execute(byte[] data, byte[] key, int bytesToUse, int action)
677        {
678            byte[] output;
679            if (bytesToUse > 0)
680                output = new byte[bytesToUse];
681            else
682                output = new byte[data.Length];
683
684
685            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
686
687            string IVString = "00000000";
688            if (plugin.InputIV != null)
689            {
690                IVString = enc.GetString(plugin.InputIV);
691            }
692           
693            if (((SDESSettings)plugin.Settings).Mode == 0 && action == 0)
694            {
695                output = ecb.encrypt(data, key, bytesToUse);
696            }
697            else if (((SDESSettings)plugin.Settings).Mode == 1 && action == 0)
698            {
699                output = cbc.encrypt(data, key, Tools.stringToBinaryByteArray(IVString), bytesToUse);
700            }
701            else if (((SDESSettings)plugin.Settings).Mode == 0 && action == 1)
702            {
703                output = ecb.decrypt(data, key, bytesToUse);
704            }
705            else if (((SDESSettings)plugin.Settings).Mode == 1 && action == 1)
706            {
707                output = cbc.decrypt(data, key, Tools.stringToBinaryByteArray(IVString), bytesToUse);
708            }
709            return output;
710
711        }
712
713        /// <summary>
714        /// Called by itself to start encryption/decryption
715        /// </summary>
716        /// <param name="key">key</param>
717        /// <param name="bytesToUse">bytesToUse</param>
718        /// <returns>encrypted/decrypted text</returns>
719        private byte[] execute(byte[] key, int bytesToUse, int action)
720        {
721           
722            if (input == null || plugin.InputChanged)
723            {
724                plugin.InputChanged = false;
725                input = new byte[bytesToUse];
726
727                byte[] buffer = new byte[1];
728               
729                int i = 0;
730                CryptoolStream inputstream = plugin.InputStream;
731                while ((inputstream.Read(buffer, 0, 1)) > 0 && i < bytesToUse)
732                {
733                    input[i] = buffer[0];
734                    i++;
735                }
736            }
737
738            return execute(input, key, bytesToUse, action);
739        }
740
741        #endregion
742
743        #region IControlEncryption Member
744
745
746        public void changeSettings(string setting, object value)
747        {
748
749        }
750        #endregion
751    }
752       
753    /// <summary>
754    /// Encapsulates the SDES algorithm
755    /// </summary>
756    public class SDES_algorithm
757    {
758        private SDES mSdes;         //to call some methods on the plugin
759        private int fkstep = 0;     //for presentation to check the number of fk we are in
760        private int mode = 0;       //for presentation to check the mode we use (0 = en/1 = decrypt)
761
762        public SDES_algorithm(SDES sdes)
763        {
764            this.mSdes = sdes;
765        }
766
767        /// <summary>
768        /// Encrypt-function       
769        /// Encrypts the input plaintext with the given key
770        /// </summary>
771        /// <param name="plaintext">plaintext as byte array of size 8</param>
772        /// <param name="key">key as byte array of size 10</param>
773        /// <returns>ciphertext as byte array of size 8</returns>
774        public byte[] encrypt(byte[] plaintext, byte[] key)
775        {
776            this.mode = 0; // to tell presentation what we are doing
777
778            if (this.mSdes.Presentation.IsVisible)
779            {
780                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
781                {
782                    ((SDESPresentation)mSdes.Presentation).key_txt.Text =
783                    Tools.byteArrayToStringWithSpaces(key);
784                }
785                , null);
786            }
787            //calculate sub key 1
788            byte[] vp10 = p10(key);
789            if (this.mSdes.Presentation.IsVisible)
790            {
791                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
792                {
793                    ((SDESPresentation)mSdes.Presentation).key_txt_p10_input.Text =
794                    Tools.byteArrayToStringWithSpaces(key);
795                    ((SDESPresentation)mSdes.Presentation).key_txt_ls1_input_1.Text =
796                    Tools.byteArrayToStringWithSpaces(vp10);
797                }
798                , null);
799            }
800
801            byte[] vls1 = ls_1(vp10);
802            if (this.mSdes.Presentation.IsVisible)
803            {
804                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
805                {
806                    ((SDESPresentation)mSdes.Presentation).key_txt_p8_1_input.Text =
807                    Tools.byteArrayToStringWithSpaces(vls1);
808                }
809                , null);
810            }
811
812            byte[] key1 = p8(vls1);
813            if (this.mSdes.Presentation.IsVisible)
814            {
815                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
816                {
817                    ((SDESPresentation)mSdes.Presentation).key_txt_k1.Text =
818                    Tools.byteArrayToStringWithSpaces(key1);
819                }
820                , null);
821            }
822
823            //calculate sub key 2
824            vls1 = ls_1(vls1);
825            if (this.mSdes.Presentation.IsVisible)
826            {
827                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
828                {
829                    ((SDESPresentation)mSdes.Presentation).key_txt_p10_copy.Text =
830                    Tools.byteArrayToStringWithSpaces(vp10);
831                    ((SDESPresentation)mSdes.Presentation).key_txt_ls1_2.Text =
832                    Tools.byteArrayToStringWithSpaces(vp10);
833                    ((SDESPresentation)mSdes.Presentation).key_txt_ls1_3.Text =
834                   Tools.byteArrayToStringWithSpaces(vls1);
835                }
836                , null);
837            }
838
839            vls1 = ls_1(vls1);
840            if (this.mSdes.Presentation.IsVisible)
841            {
842                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
843                {
844                    ((SDESPresentation)mSdes.Presentation).key_txt_p8_2_input.Text =
845                    Tools.byteArrayToStringWithSpaces(vls1);
846                }
847               , null);
848            }
849
850            byte[] key2 = p8(vls1);
851            if (this.mSdes.Presentation.IsVisible)
852            {
853                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
854                {
855                    ((SDESPresentation)mSdes.Presentation).key_txt_k2.Text =
856                    Tools.byteArrayToStringWithSpaces(key2);
857                }
858               , null);
859            }
860
861            // ip_inverse(fk_2(sw(fk_1(ip(plaintext))))) :
862
863            byte[] ip = this.ip(plaintext);
864            if (this.mSdes.Presentation.IsVisible)
865            {
866                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
867                {
868                    ((SDESPresentation)mSdes.Presentation).encrypt_txt_plaintext.Text =
869                    Tools.byteArrayToStringWithSpaces(plaintext);
870                    ((SDESPresentation)mSdes.Presentation).encrypt_txt_ip_input.Text =
871                    Tools.byteArrayToStringWithSpaces(plaintext);
872                    ((SDESPresentation)mSdes.Presentation).encrypt_txt_ip_output.Text =
873                    Tools.byteArrayToStringWithSpaces(ip);
874                }
875               , null);
876            }
877
878            byte[] fk1 = fk(ip, key1);
879            if (this.mSdes.Presentation.IsVisible)
880            {
881                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
882                {
883                    ((SDESPresentation)mSdes.Presentation).encrypt_txt_sw_input.Text =
884                    Tools.byteArrayToStringWithSpaces(fk1);                   
885                }
886               , null);
887            }
888
889            byte[] swtch = sw(fk1);
890            if (this.mSdes.Presentation.IsVisible)
891            {
892                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
893                {
894                    ((SDESPresentation)mSdes.Presentation).encrypt_txt_sw_output.Text =
895                    Tools.byteArrayToStringWithSpaces(swtch);
896                }
897               , null);
898            }
899
900            byte[] fk2 = fk(swtch, key2);
901            if (this.mSdes.Presentation.IsVisible)
902            {
903                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
904                {
905                    ((SDESPresentation)mSdes.Presentation).encrypt_txt_ip_invers_input.Text =
906                    Tools.byteArrayToStringWithSpaces(fk2);
907                }
908               , null);
909            }                   
910
911            byte[] ciphertext = ip_inverse(fk2);
912            if (this.mSdes.Presentation.IsVisible)
913            {
914                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
915                {
916                    ((SDESPresentation)mSdes.Presentation).encrypt_txt_ip_invers_output.Text =
917                    Tools.byteArrayToStringWithSpaces(ciphertext);
918                }
919               , null);
920            }   
921
922            return ciphertext;
923
924        }//end encrypt
925
926        /// <summary>
927        /// Decrypt-function
928        /// Decrypts the input ciphertext with the given key
929        /// </summary>
930        /// <param name="ciphertext">ciphertext as byte array of size 8</param>
931        /// <param name="key"> key as byte array of size 10</param>
932        /// <returns>plaintext as byte array of size 8</returns>
933        public byte[] decrypt(byte[] ciphertext, byte[] key)
934        {
935            this.mode = 1; // to tell presentation what we are doing
936
937            if (this.mSdes.Presentation.IsVisible)
938            {
939                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
940                {
941                    ((SDESPresentation)mSdes.Presentation).key_txt.Text =
942                    Tools.byteArrayToStringWithSpaces(key);
943                }
944                , null);
945            }
946            //calculate sub key 1
947            byte[] vp10 = p10(key);
948            if (this.mSdes.Presentation.IsVisible)
949            {
950                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
951                {
952                    ((SDESPresentation)mSdes.Presentation).key_txt_p10_input.Text =
953                    Tools.byteArrayToStringWithSpaces(key);
954                    ((SDESPresentation)mSdes.Presentation).key_txt_ls1_input_1.Text =
955                    Tools.byteArrayToStringWithSpaces(vp10);
956                }
957                , null);
958            }
959
960            byte[] vls1 = ls_1(vp10);
961            if (this.mSdes.Presentation.IsVisible)
962            {
963                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
964                {
965                    ((SDESPresentation)mSdes.Presentation).key_txt_p8_1_input.Text =
966                    Tools.byteArrayToStringWithSpaces(vls1);
967                }
968                , null);
969            }
970
971            byte[] key1 = p8(vls1);
972            if (this.mSdes.Presentation.IsVisible)
973            {
974                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
975                {
976                    ((SDESPresentation)mSdes.Presentation).key_txt_k1.Text =
977                    Tools.byteArrayToStringWithSpaces(key1);
978                }
979                , null);
980            }
981
982            //calculate sub key 2
983            vls1 = ls_1(vls1);
984            if (this.mSdes.Presentation.IsVisible)
985            {
986                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
987                {
988                    ((SDESPresentation)mSdes.Presentation).key_txt_p10_copy.Text =
989                    Tools.byteArrayToStringWithSpaces(vp10);
990                    ((SDESPresentation)mSdes.Presentation).key_txt_ls1_2.Text =
991                    Tools.byteArrayToStringWithSpaces(vp10);
992                    ((SDESPresentation)mSdes.Presentation).key_txt_ls1_3.Text =
993                   Tools.byteArrayToStringWithSpaces(vls1);
994                }
995                , null);
996            }
997
998            vls1 = ls_1(vls1);
999            if (this.mSdes.Presentation.IsVisible)
1000            {
1001                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1002                {
1003                    ((SDESPresentation)mSdes.Presentation).key_txt_p8_2_input.Text =
1004                    Tools.byteArrayToStringWithSpaces(vls1);
1005                }
1006               , null);
1007            }
1008
1009            byte[] key2 = p8(vls1);
1010            if (this.mSdes.Presentation.IsVisible)
1011            {
1012                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1013                {
1014                    ((SDESPresentation)mSdes.Presentation).key_txt_k2.Text =
1015                    Tools.byteArrayToStringWithSpaces(key2);
1016                }
1017               , null);
1018            }
1019
1020            // ip_inverse(fk_1(sw(fk_2(ip(ciphertext))))) :
1021
1022            byte[] ip = this.ip(ciphertext);
1023            if (this.mSdes.Presentation.IsVisible)
1024            {
1025                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1026                {
1027                    ((SDESPresentation)mSdes.Presentation).decrypt_txt_plaintext.Text =
1028                    Tools.byteArrayToStringWithSpaces(ciphertext);
1029                    ((SDESPresentation)mSdes.Presentation).decrypt_txt_ip_input.Text =
1030                    Tools.byteArrayToStringWithSpaces(ciphertext);
1031                    ((SDESPresentation)mSdes.Presentation).decrypt_txt_ip_output.Text =
1032                    Tools.byteArrayToStringWithSpaces(ip);
1033                }
1034               , null);
1035            }
1036
1037            byte[] fk2 = fk(ip, key2);
1038            if (this.mSdes.Presentation.IsVisible)
1039            {
1040                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1041                {
1042                    ((SDESPresentation)mSdes.Presentation).decrypt_txt_sw_input.Text =
1043                    Tools.byteArrayToStringWithSpaces(fk2);                 
1044                }
1045               , null);
1046            }
1047
1048            byte[] swtch = sw(fk2); 
1049            if (this.mSdes.Presentation.IsVisible)
1050            {
1051                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1052                {
1053                    ((SDESPresentation)mSdes.Presentation).decrypt_txt_sw_output.Text =
1054                    Tools.byteArrayToStringWithSpaces(swtch);
1055                }
1056               , null);
1057            }
1058
1059            byte[] fk1 = fk(swtch, key1);
1060            if (this.mSdes.Presentation.IsVisible)
1061            {
1062                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1063                {
1064                    ((SDESPresentation)mSdes.Presentation).decrypt_txt_ip_invers_input.Text =
1065                    Tools.byteArrayToStringWithSpaces(fk1);
1066                }
1067               , null);
1068            }
1069
1070            byte[] plaintext = ip_inverse(fk1);
1071            if (this.mSdes.Presentation.IsVisible)
1072            {
1073                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1074                {
1075                    ((SDESPresentation)mSdes.Presentation).decrypt_txt_ip_invers_output.Text =
1076                    Tools.byteArrayToStringWithSpaces(plaintext);
1077                }
1078               , null);
1079            }           
1080
1081            return plaintext;
1082
1083        }//end decrypt
1084
1085        ///<summary>
1086        ///p10-function
1087        ///Permutates the input bytes array of "10 bits" to another by
1088        ///the following rule:
1089        ///
1090        ///src    dest
1091        ///1   -> 3
1092        ///2   -> 5
1093        ///3   -> 2
1094        ///4   -> 7
1095        ///5   -> 4
1096        ///6   -> 10
1097        ///7   -> 1
1098        ///8   -> 9
1099        ///9   -> 8
1100        ///10  -> 6
1101        ///</summary>
1102        ///<param name="bits">byte array of size 10</param>
1103        ///<returns>byte array of size 10</returns>
1104        ///
1105        private byte[] p10(byte[] bits)
1106        {
1107
1108            byte[] p10 = new byte[10];
1109
1110            p10[1 - 1] = bits[3 - 1];
1111            p10[2 - 1] = bits[5 - 1];
1112            p10[3 - 1] = bits[2 - 1];
1113            p10[4 - 1] = bits[7 - 1];
1114            p10[5 - 1] = bits[4 - 1];
1115            p10[6 - 1] = bits[10 - 1];
1116            p10[7 - 1] = bits[1 - 1];
1117            p10[8 - 1] = bits[9 - 1];
1118            p10[9 - 1] = bits[8 - 1];
1119            p10[10 - 1] = bits[6 - 1];
1120
1121            //mSdes.GuiLogMessage("P10 with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(p10), NotificationLevel.Debug);
1122            return p10;
1123
1124        }//end p10
1125
1126        ///<summary>
1127        ///p8-function
1128        ///Permutates the input bytes array of "8 bits" to another by
1129        ///the following rule:
1130        ///
1131        ///src    dest
1132        ///1   -> 6
1133        ///2   -> 3
1134        ///3   -> 7
1135        ///4   -> 4
1136        ///5   -> 8
1137        ///6   -> 5
1138        ///7   -> 10
1139        ///8   -> 9
1140        ///</summary>
1141        ///<param name="bits">byte array of size 10</param>
1142        ///<returns>byte array of size 8</returns>
1143        private byte[] p8(byte[] bits)
1144        {
1145
1146            byte[] p8 = new byte[8];
1147
1148            p8[1 - 1] = bits[6 - 1];
1149            p8[2 - 1] = bits[3 - 1];
1150            p8[3 - 1] = bits[7 - 1];
1151            p8[4 - 1] = bits[4 - 1];
1152            p8[5 - 1] = bits[8 - 1];
1153            p8[6 - 1] = bits[5 - 1];
1154            p8[7 - 1] = bits[10 - 1];
1155            p8[8 - 1] = bits[9 - 1];
1156
1157            //mSdes.GuiLogMessage("P8 with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(p8), NotificationLevel.Debug);
1158            return p8;
1159
1160        }//end p8
1161
1162        ///<summary>
1163        ///ip-function (initial permutation)
1164        ///Permutates the input array of "8 bits" to another by
1165        ///the following rule:
1166        ///
1167        ///src    dest
1168        ///1   -> 2
1169        ///2   -> 6
1170        ///3   -> 3
1171        ///4   -> 1
1172        ///5   -> 4
1173        ///6   -> 8
1174        ///7   -> 5
1175        ///8   -> 7
1176        ///</summary>
1177        ///<param name="bits">byte array of size 8</param>
1178        ///<returns>byte array of size 8</returns>
1179        private byte[] ip(byte[] bits)
1180        {
1181
1182            byte[] ip = new byte[8];
1183
1184            ip[1 - 1] = bits[2 - 1];
1185            ip[2 - 1] = bits[6 - 1];
1186            ip[3 - 1] = bits[3 - 1];
1187            ip[4 - 1] = bits[1 - 1];
1188            ip[5 - 1] = bits[4 - 1];
1189            ip[6 - 1] = bits[8 - 1];
1190            ip[7 - 1] = bits[5 - 1];
1191            ip[8 - 1] = bits[7 - 1];
1192
1193            //mSdes.GuiLogMessage("ip with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(ip), NotificationLevel.Debug);
1194            return ip;
1195
1196        }//end ip
1197
1198        ///<summary>
1199        ///ip^-1-function (initial permutation inverse)
1200        ///Permutates the input array of "8 bits" to another by
1201        ///the following rule:
1202        ///
1203        ///src    dest
1204        ///1   -> 4
1205        ///2   -> 1
1206        ///3   -> 3
1207        ///4   -> 5
1208        ///5   -> 7
1209        ///6   -> 2
1210        ///7   -> 8
1211        ///8   -> 6
1212        ///</summary>
1213        ///<param name="bits">byte array of size 8</param>
1214        ///<returns>byte array of size 8</returns>
1215        private byte[] ip_inverse(byte[] bits)
1216        {
1217
1218            byte[] ip_inverse = new byte[8];
1219
1220            ip_inverse[1 - 1] = bits[4 - 1];
1221            ip_inverse[2 - 1] = bits[1 - 1];
1222            ip_inverse[3 - 1] = bits[3 - 1];
1223            ip_inverse[4 - 1] = bits[5 - 1];
1224            ip_inverse[5 - 1] = bits[7 - 1];
1225            ip_inverse[6 - 1] = bits[2 - 1];
1226            ip_inverse[7 - 1] = bits[8 - 1];
1227            ip_inverse[8 - 1] = bits[6 - 1];
1228
1229            //mSdes.GuiLogMessage("ip_inverse with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(ip_inverse), NotificationLevel.Debug);             
1230            return ip_inverse;
1231
1232        }//end ip_inverse
1233
1234        ///<summary>
1235        ///fk-function
1236        ///
1237        ///combines the following functions:
1238        ///
1239        ///right is the right part of the input array
1240        ///left is the left part of the input array
1241        ///
1242        ///(right | left) := (inputarray))
1243        ///ret := exclusive_or(left,F(right,key)) + right)
1244        ///</summary>
1245        ///<param name="bits">byte array of size 8</param>
1246        ///<param name="key">byte array of size 8</param>
1247        ///<returns>byte array of size 8</returns>
1248        private byte[] fk(byte[] bits, byte[] key)
1249        {
1250            byte[] left = { bits[1 - 1], bits[2 - 1], bits[3 - 1], bits[4 - 1] };
1251            byte[] right = { bits[5 - 1], bits[6 - 1], bits[7 - 1], bits[8 - 1] };
1252
1253            byte[] exclusive_oder = Tools.exclusive_or(left, F(right, key));
1254
1255            byte[] ret = {exclusive_oder[1-1],exclusive_oder[2-1],exclusive_oder[3-1],exclusive_oder[4-1],
1256                                     right[1-1],right[2-1],right[3-1],right[4-1]};
1257
1258            fkstep++;
1259            if (fkstep == 2)
1260                fkstep = 0;
1261
1262            //mSdes.GuiLogMessage("fk with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(ret), NotificationLevel.Debug);
1263            return ret;
1264
1265        }//end fk
1266
1267        ///<summary>
1268        ///ls-1 function
1269        ///</summary>
1270        ///<param name="bits">byte array of size 10</param>
1271        ///<returns>byte array of size 10</returns>
1272        private byte[] ls_1(byte[] bits)
1273        {
1274
1275            byte[] ls_1 = new byte[10];
1276
1277            ls_1[1 - 1] = bits[2 - 1];
1278            ls_1[2 - 1] = bits[3 - 1];
1279            ls_1[3 - 1] = bits[4 - 1];
1280            ls_1[4 - 1] = bits[5 - 1];
1281            ls_1[5 - 1] = bits[1 - 1];
1282            ls_1[6 - 1] = bits[7 - 1];
1283            ls_1[7 - 1] = bits[8 - 1];
1284            ls_1[8 - 1] = bits[9 - 1];
1285            ls_1[9 - 1] = bits[10 - 1];
1286            ls_1[10 - 1] = bits[6 - 1];
1287
1288            //mSdes.GuiLogMessage("ls-1 with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(ls_1), NotificationLevel.Debug);
1289            return ls_1;
1290
1291        }//end ls_1
1292
1293        ///<summary>
1294        ///switch-function
1295        ///
1296        ///switches the left side and the right side of the 8 bit array
1297        ///(left|right) -> (right|left)
1298        ///</summary>
1299        ///<param name="bits">byte array of size 8</param>
1300        ///<returns>byte array of size 8</returns>
1301        private byte[] sw(byte[] bits)
1302        {
1303
1304            byte[] ret = {bits[5-1],bits[6-1],bits[7-1],bits[8-1],
1305                                         bits[1-1],bits[2-1],bits[3-1],bits[4-1]};
1306
1307            //mSdes.GuiLogMessage("sw with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(ret), NotificationLevel.Debug);
1308            return ret;
1309
1310        }//end sw
1311
1312        ///<summary>
1313        ///F-function
1314        ///
1315        ///combines both s-boxes and permutates the return value with p4
1316        ///p4( s0(exclusive_or(ep(number),key) | s1(exclusive_or(ep(number),key) )
1317        ///</summary>
1318        ///<param name="bits">byte array of size 8</param>
1319        ///<param name="bits">key of size 8</param>
1320        ///<returns>byte array of size 8</returns>
1321        private byte[] F(byte[] bits, byte[] key)
1322        {
1323
1324            byte[] ep = this.ep(bits);
1325
1326            byte[] exclusive = Tools.exclusive_or(ep, key);
1327
1328            byte[] s0_input = { exclusive[1 - 1], exclusive[2 - 1], exclusive[3 - 1], exclusive[4 - 1] };
1329            byte[] s0 = sbox_0(s0_input);
1330
1331            byte[] s1_input = { exclusive[5 - 1], exclusive[6 - 1], exclusive[7 - 1], exclusive[8 - 1] };
1332            byte[] s1 = sbox_1(s1_input);
1333
1334            byte[] s0_s1 = { s0[1 - 1], s0[2 - 1], s1[1 - 1], s1[2 - 1] };
1335            byte[] ret = p4(s0_s1);
1336
1337            if (this.mSdes.Presentation.IsVisible)
1338            {
1339                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1340                {
1341                    if (mode == 0 && fkstep == 0)
1342                    {
1343                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_sbox1_output.Text =
1344                        Tools.byteArrayToStringWithSpaces(ret);
1345                    }
1346                    if (mode == 0 && fkstep == 1)
1347                    {
1348                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_sbox2_output.Text =
1349                        Tools.byteArrayToStringWithSpaces(ret);
1350                    }
1351                    if (mode == 1 && fkstep == 0)
1352                    {
1353                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_sbox1_output.Text =
1354                        Tools.byteArrayToStringWithSpaces(ret);
1355                    }
1356                    if (mode == 1 && fkstep == 1)
1357                    {
1358                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_sbox2_output.Text =
1359                        Tools.byteArrayToStringWithSpaces(ret);
1360                    }
1361                }
1362               , null);
1363            }
1364
1365            //mSdes.GuiLogMessage("F with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(key) + " ist " + Tools.intArray2String(ret), NotificationLevel.Debug);
1366            return ret;
1367
1368        }//end F
1369
1370        ///<summary>
1371        ///p4-function
1372        ///Permutates the input array of "4 bits" to another by
1373        ///the following rule:
1374        ///
1375        ///src    dest
1376        ///1   -> 2
1377        ///2   -> 4
1378        ///3   -> 3
1379        ///4   -> 1
1380        ///</summary>
1381        ///<param name="bits">byte array of size 4</param>
1382        ///<returns>byte array of size 4</returns>
1383        private byte[] p4(byte[] bits)
1384        {
1385
1386            byte[] ret = new byte[4];
1387            ret[1 - 1] = bits[2 - 1];
1388            ret[2 - 1] = bits[4 - 1];
1389            ret[3 - 1] = bits[3 - 1];
1390            ret[4 - 1] = bits[1 - 1];
1391
1392            return ret;
1393
1394        }//end p4
1395
1396        ///<summary>
1397        ///ep-function
1398        ///Permutates the input array of "4 bits" to another array of "8 bits" by
1399        ///the following rule:
1400        ///
1401        ///src    dest
1402        ///1   -> 4
1403        ///2   -> 1
1404        ///3   -> 2
1405        ///4   -> 3
1406        ///5   -> 2
1407        ///6   -> 3
1408        ///7   -> 4
1409        ///8   -> 1
1410        ///</summary>
1411         ///<param name="bits">byte array of size 4</param>
1412        ///<returns>byte array of size 8</returns>
1413        private byte[] ep(byte[] bits)
1414        {
1415
1416            byte[] ep = new byte[8];
1417            ep[1 - 1] = bits[4 - 1];
1418            ep[2 - 1] = bits[1 - 1];
1419            ep[3 - 1] = bits[2 - 1];
1420            ep[4 - 1] = bits[3 - 1];
1421            ep[5 - 1] = bits[2 - 1];
1422            ep[6 - 1] = bits[3 - 1];
1423            ep[7 - 1] = bits[4 - 1];
1424            ep[8 - 1] = bits[1 - 1];
1425
1426            if (this.mSdes.Presentation.IsVisible)
1427            {
1428                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1429                {
1430                    if (mode == 0 && fkstep == 0)
1431                    {
1432                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_ep_output.Text =
1433                        Tools.byteArrayToStringWithSpaces(ep);
1434                    }
1435                    if (mode == 0 && fkstep == 1)
1436                    {
1437                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_ep_output1.Text =
1438                        Tools.byteArrayToStringWithSpaces(ep);
1439                    }
1440                    if (mode == 1 && fkstep == 0)
1441                    {
1442                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_ep_output.Text =
1443                        Tools.byteArrayToStringWithSpaces(ep);
1444                    }
1445                    if (mode == 1 && fkstep == 1)
1446                    {
1447                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_ep_output1.Text =
1448                        Tools.byteArrayToStringWithSpaces(ep);
1449                    }
1450                }
1451               , null);
1452            }
1453
1454            return ep;
1455        }
1456
1457        ///<summary>
1458        ///SBox-0
1459        ///
1460        ///S0 =  1 0 3 2
1461        ///      3 2 1 0
1462        ///      0 2 1 3   
1463        ///      3 1 3 2           
1464        ///</summary>
1465        ///<param name="bits">byte array of size 4</param>
1466        ///<returns>byte array of size 2</returns>
1467        private byte[] sbox_0(byte[] bits)
1468        {
1469
1470            int row = 2 * bits[1 - 1] + 1 * bits[4 - 1];
1471            int column = 2 * bits[2 - 1] + 1 * bits[3 - 1];
1472
1473            byte[,][] sbox_0 = new byte[4, 4][]
1474                            {
1475                            {new byte[] {0,1}, new byte[] {0,0}, new byte[] {1,1}, new byte[] {1,0}},
1476                                                {new byte[] {1,1}, new byte[] {1,0}, new byte[] {0,1}, new byte[] {0,0}},
1477                                                {new byte[] {0,0}, new byte[] {1,0}, new byte[] {0,1}, new byte[] {1,1}},
1478                                                {new byte[] {1,1}, new byte[] {0,1}, new byte[] {1,1}, new byte[] {1,0}}
1479                            };
1480
1481            byte[] ret = sbox_0[row, column];
1482
1483            if (this.mSdes.Presentation.IsVisible)
1484            {
1485                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1486                {
1487                    if (mode == 0 && fkstep == 0)
1488                    {
1489                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_s0_1_output.Text =
1490                        Tools.byteArrayToStringWithSpaces(ret);
1491                    }
1492                    if (mode == 0 && fkstep == 1)
1493                    {
1494                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_s0_2_output.Text =
1495                        Tools.byteArrayToStringWithSpaces(ret);
1496                    }
1497                    if (mode == 1 && fkstep == 0)
1498                    {
1499                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_s0_1_output.Text =
1500                        Tools.byteArrayToStringWithSpaces(ret);
1501                    }
1502                    if (mode == 1 && fkstep == 1)
1503                    {
1504                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_s0_2_output.Text =
1505                        Tools.byteArrayToStringWithSpaces(ret);
1506                    }
1507                }
1508               , null);
1509            }
1510
1511            //mSdes.GuiLogMessage("S0 with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(ret), NotificationLevel.Debug);
1512            return ret;
1513
1514        }//end sbox-0
1515
1516
1517        ///<summary>
1518        ///SBox-1
1519        ///
1520        ///S1 =  0 1 2 3
1521        ///      2 0 1 3
1522        ///      3 0 1 0
1523        ///      2 1 0 3
1524        ///</summary>
1525        ///<param name="bits">byte array of size 4</param>
1526        ///<returns>byte array of size 2</returns>
1527        private byte[] sbox_1(byte[] bits)
1528        {
1529
1530            int row = 2 * bits[1 - 1] + 1 * bits[4 - 1];
1531            int column = 2 * bits[2 - 1] + 1 * bits[3 - 1];
1532
1533            byte[,][] sbox_1 = new byte[4, 4][]
1534                            {
1535                            {new byte[] {0,0}, new byte[] {0,1}, new byte[] {1,0}, new byte[] {1,1}},
1536                                                        {new byte[] {1,0}, new byte[] {0,0}, new byte[] {0,1}, new byte[] {1,1}},
1537                                                        {new byte[] {1,1}, new byte[] {0,0}, new byte[] {0,1}, new byte[] {0,0}},
1538                                                        {new byte[] {1,0}, new byte[] {0,1}, new byte[] {0,0}, new byte[] {1,1}}
1539                            };
1540
1541            byte[] ret = sbox_1[row, column];
1542
1543            if (this.mSdes.Presentation.IsVisible)
1544            {
1545                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1546                {
1547                    if (mode == 0 && fkstep == 0)
1548                    {
1549                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_s1_1_output.Text =
1550                        Tools.byteArrayToStringWithSpaces(ret);
1551                    }
1552                    if (mode == 0 && fkstep == 1)
1553                    {
1554                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_s1_2_output.Text =
1555                        Tools.byteArrayToStringWithSpaces(ret);
1556                    }
1557                    if (mode == 1 && fkstep == 0)
1558                    {
1559                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_s1_1_output.Text =
1560                        Tools.byteArrayToStringWithSpaces(ret);
1561                    }
1562                    if (mode == 1 && fkstep == 1)
1563                    {
1564                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_s1_2_output.Text =
1565                        Tools.byteArrayToStringWithSpaces(ret);
1566                    }
1567                }
1568               , null);
1569            }
1570
1571            //mSdes.GuiLogMessage("S1 with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(ret), NotificationLevel.Debug);             
1572            return ret;
1573
1574        }//end sbox-1
1575
1576    }
1577
1578    ///<summary>
1579    ///Encapsulates some necessary functions
1580    ///</summary>
1581    public class Tools
1582    {
1583
1584        /// <summary>
1585        /// transforms a byte array into a String with spaces after each byte
1586        /// example:
1587        ///     1,0 => "1 0"
1588        /// </summary>
1589        /// <param name="byt">byt</param>
1590        /// <returns>s</returns>
1591        public static String byteArrayToStringWithSpaces(byte[] byt)
1592        {
1593            String s = "";
1594
1595            foreach (byte b in byt)
1596            {
1597                s = s + b + " ";
1598            }
1599            return s;
1600        }
1601        ///<summary>
1602        ///Converts an byte array to a String
1603        ///</summary>
1604        ///<param name="bits">byte array of size n</param>
1605        ///<returns>String</returns>
1606        public static String byteArray2String(byte[] bits)
1607        {
1608
1609            String ret = "";
1610            for (int i = 0; i < bits.Length; i++)
1611            {
1612                ret += ("" + bits[i]);
1613            }
1614            return ret;
1615
1616        }//end byteArray2String
1617
1618        ///<summary>
1619        ///Converts the given byte array to a printable String
1620        ///
1621        ///example {72, 101, 108, 108, 111} -> "Hello"
1622        ///</summary>
1623        ///<param name="bits">byte array of size n</param>
1624        ///<returns>String</returns>
1625        public static String byteArray2PrintableString(byte[] bits)
1626        {
1627
1628            String ret = "";
1629            for (int i = 0; i < bits.Length; i++)
1630            {
1631                ret += ("" + (char)bits[i]);
1632            }
1633            return ret;
1634
1635        }// byteArray2PrintableString
1636
1637        ///<summary>
1638        ///equals-function
1639        ///
1640        ///returns true if both integer arrays are equal
1641        ///</summary>
1642        ///<param name="a">byte array of size n</param>
1643        ///<param name="b">byte array of size n</param>
1644        ///<returns>bool</returns>
1645        public static bool byteArrays_Equals(byte[] a, byte[] b)
1646        {
1647
1648            for (int i = 0; i < a.Length; i++)
1649            {
1650                if (a[i] != b[i])
1651                {
1652                    return false;
1653                }
1654            }
1655
1656            return true;
1657
1658        }//end byteArrays_Equals       
1659
1660        ///<summary>
1661        ///converts an Byte to an byte array of (0,1)
1662        ///
1663        ///100 -> {1,1,0,0,1,0,0}
1664        ///</summary>
1665        ///<param name="byt">byte array of size n</param>
1666        ///<returns>byte array</returns>
1667        public static byte[] byteToByteArray(byte byt)
1668        {
1669
1670            byte[] bytearray = new byte[8];
1671
1672            for (int i = 7; i >= 0; i--)
1673            {
1674
1675                bytearray[i] = (byte)(byt % 2);
1676                byt = (byte)Math.Floor((double)(byt / 2));
1677
1678            }
1679
1680            return bytearray;
1681
1682        }//end byteTointArray
1683
1684        ///<summary>
1685        ///converts an byte array of (0,1) to an byte
1686        ///
1687        ///{1,1,0,0,1,0,0} -> 100
1688        ///</summary>
1689        ///<param name="bytearray">byte array of size n</param>
1690        ///<returns>byte</returns>
1691        public static byte byteArrayToByte(byte[] bytearray)
1692        {
1693
1694            int byt = 0;
1695
1696            byt = (bytearray[0] * 128)
1697                        + (bytearray[1] * 64)
1698                        + (bytearray[2] * 32)
1699                        + (bytearray[3] * 16)
1700                        + (bytearray[4] * 8)
1701                        + (bytearray[5] * 4)
1702                        + (bytearray[6] * 2)
1703                        + (bytearray[7] * 1);
1704
1705            return (byte)byt;
1706
1707        }//end byteArrayToInteger
1708
1709        ///<summary>
1710        ///Exclusiv-OR function
1711        ///
1712        ///Does a exlusiv-or on two byte arrays
1713        ///
1714        ///example {1,0,1} XOR {1,0,0} -> {0,0,1}
1715        ///</summary>
1716        ///<param name="bitsA">byte array of size n</param>
1717        ///<param name="bitsB">byte array of size n</param>
1718        ///<returns>byte array of size n</returns>
1719        public static byte[] exclusive_or(byte[] bitsA, byte[] bitsB)
1720        {
1721
1722            byte[] exclusive_or_AB = new byte[bitsA.Length];
1723
1724            for (int i = 0; i < bitsA.Length; i++)
1725            {
1726
1727                if ((bitsA[i] == 0 && bitsB[i] == 1) ||
1728                   (bitsA[i] == 1 && bitsB[i] == 0)
1729                )
1730                {
1731                    exclusive_or_AB[i] = 1;
1732                }
1733                else
1734                {
1735                    exclusive_or_AB[i] = 0;
1736                }//end if
1737
1738            }//end for
1739
1740            return exclusive_or_AB;
1741
1742        }//end exclusive_or
1743
1744        ///<summary>
1745        ///converts string to an byte array
1746        ///
1747        ///example "Hello" -> {72, 101, 108, 108, 111}
1748        ///</summary>
1749        ///<param name="s">String</param>
1750        ///<returns>byte array</returns>
1751        public static byte[] stringToByteArray(String s)
1752        {
1753            byte[] bytearray = new byte[s.Length];
1754
1755            for (int i = 0; i < s.Length; i++)
1756            {
1757                bytearray[i] = (byte)s[i];
1758            }
1759
1760            return bytearray;
1761
1762        }// end stringToByteArray
1763
1764        ///<summary>
1765        ///converts a binary string to an byte array
1766        ///
1767        ///example "10010" -> {1, 0, 0, 1, 0}
1768        ///</summary>
1769        ///<param name="s">String</param>
1770        ///<returns>byte array</returns>
1771        public static byte[] stringToBinaryByteArray(String s)
1772        {
1773            byte[] bytearray = new byte[s.Length];
1774
1775            for (int i = 0; i < s.Length; i++)
1776            {
1777                if (s[i] == '1')
1778                {
1779                    bytearray[i] = 1;
1780                }
1781                else if (s[i] == '0')
1782                {
1783                    bytearray[i] = 0;
1784                }
1785                else
1786                {
1787                    throw new Exception("Invalid Character '" + s[i] + "' at position " + i + " in String which represents binary values: " + s);
1788                }
1789            }
1790
1791            return bytearray;
1792
1793        }// end stringToByteArray
1794    }
1795
1796    ///<summary>
1797    ///Encapsulates the CipherBlockChaining algorithm
1798    ///</summary>
1799    public class CipherBlockChaining
1800    {
1801
1802        private SDES mSdes;
1803        private SDES_algorithm mAlgorithm;
1804
1805        /// <summary>
1806        /// Constructs a CipherBlockChaining for SDES
1807        /// </summary>
1808        /// <param name="sdes">plugin</param>
1809        public CipherBlockChaining(SDES sdes)
1810        {
1811            this.mSdes = sdes;
1812            this.mAlgorithm = new SDES_algorithm(sdes);
1813        }
1814
1815        ///<summary>
1816        ///Encrypts the given plaintext with the given key
1817        ///using CipherBlockChaining
1818        ///</summary>
1819        public void encrypt(CryptoolStream inputstream, CryptoolStream outputstream, byte[] key, byte[] vector)
1820        {
1821
1822            byte[] buffer = new byte[1];
1823            int position = 0;
1824
1825            while (!this.mSdes.getStop() && (inputstream.Read(buffer, 0, 1)) > 0)
1826            {
1827                //Step 1 get plaintext symbol
1828                byte symbol = buffer[0];
1829                //Step 2 exclusiv OR with vector
1830                vector = Tools.exclusive_or(vector, Tools.byteToByteArray(symbol));
1831                //Step 3 decrypt vector with key
1832                vector = mAlgorithm.encrypt(vector, key);
1833                //Step 4 store symbol in ciphertext
1834                outputstream.Write(Tools.byteArrayToByte(vector));
1835
1836                if ((int)(inputstream.Position * 100 / inputstream.Length) > position)
1837                {
1838                    position = (int)(inputstream.Position * 100 / inputstream.Length);
1839                    mSdes.ProgressChanged(inputstream.Position, inputstream.Length);
1840                }
1841                outputstream.Flush();
1842            }
1843
1844        }//end encrypt
1845
1846        ///
1847        ///Encrypts the given plaintext with the given key
1848        ///using CipherBlockChaining
1849        ///
1850        /// bytesToUse tells the algorithm how many bytes it has to encrypt
1851        /// bytesToUse = 0 => encrypt all
1852        public byte[] encrypt(byte[] input, byte[] key, byte[] vector, [Optional, DefaultParameterValue(0)] int bytesToUse)
1853        {
1854            int until = input.Length;           
1855
1856            if (bytesToUse < until && bytesToUse > 0)
1857                until = bytesToUse;
1858
1859            byte[] output = new byte[until];
1860
1861            for (int i = 0; i < until; i++)
1862            {
1863                vector = Tools.exclusive_or(vector, Tools.byteToByteArray(input[i]));
1864                vector = mAlgorithm.encrypt(vector, key);
1865                output[i] = Tools.byteArrayToByte(vector);
1866
1867            }//end while
1868           
1869            return output;
1870
1871        }//end encrypt
1872
1873        ///<summary>
1874        ///Decrypts the given plaintext with the given Key
1875        ///using CipherBlockChaining
1876        ///</summary>
1877        public void decrypt(CryptoolStream inputstream, CryptoolStream outputstream, byte[] key, byte[] vector)
1878        {
1879
1880            byte[] buffer = new byte[1];
1881            int position = 0;
1882
1883            while (!this.mSdes.getStop() && (inputstream.Read(buffer, 0, 1)) > 0)
1884            {
1885                //Step 1 get Symbol of Ciphertext
1886                byte symbol = buffer[0];
1887                //Step 2 Decrypt symbol with key and exclusiv-or with vector
1888                outputstream.Write((Tools.byteArrayToByte(Tools.exclusive_or(mAlgorithm.decrypt(Tools.byteToByteArray(symbol), key), vector))));
1889                //Step 3 let vector be the decrypted Symbol
1890                vector = Tools.byteToByteArray(buffer[0]);
1891
1892                if ((int)(inputstream.Position * 100 / inputstream.Length) > position)
1893                {
1894                    position = (int)(inputstream.Position * 100 / inputstream.Length);
1895                    mSdes.ProgressChanged(inputstream.Position, inputstream.Length);
1896                }
1897                outputstream.Flush();
1898            }
1899
1900        }//end decrypt
1901
1902        ///
1903        ///Decrypt the given plaintext with the given key
1904        ///using CipherBlockChaining
1905        ///
1906        /// bytesToUse tells the algorithm how many bytes it has to encrypt
1907        /// bytesToUse = 0 => encrypt all
1908        public byte[] decrypt(byte[] input, byte[] key, byte[] vector, [Optional, DefaultParameterValue(0)] int bytesToUse)
1909        {
1910
1911            int until = input.Length;
1912           
1913            if (bytesToUse < until && bytesToUse > 0)
1914                until = bytesToUse;
1915
1916            byte[] output = new byte[until];
1917
1918            for (int i = 0; i < until; i++)
1919            {
1920                output[i] = (Tools.byteArrayToByte(Tools.exclusive_or(mAlgorithm.decrypt(Tools.byteToByteArray(input[i]), key), vector)));
1921                vector = Tools.byteToByteArray(input[i]);
1922                           
1923            }//end while
1924
1925            return output;
1926
1927        }//end encrypt
1928
1929    }//end class CipherBlockChaining
1930
1931    ///<summary>
1932    ///Encapsulates the ElectronicCodeBook algorithm
1933    ///</summary>
1934    public class ElectronicCodeBook
1935    {
1936
1937        private SDES mSdes;
1938        private SDES_algorithm mAlgorithm;
1939
1940        /// <summary>
1941        /// Constructs a ElectronicCodeBook for SDES
1942        /// </summary>
1943        /// <param name="sdes">plugin</param>
1944        public ElectronicCodeBook(SDES sdes)
1945        {
1946            this.mSdes = sdes;
1947            this.mAlgorithm = new SDES_algorithm(sdes);
1948        }
1949
1950        ///
1951        ///Encrypts the given plaintext with the given key
1952        ///using ElectronicCodeBookMode
1953        ///
1954        public void encrypt(CryptoolStream inputstream, CryptoolStream outputstream, byte[] key)
1955        {
1956
1957            byte[] buffer = new byte[1];
1958            int position = 0;
1959
1960            while (!this.mSdes.getStop() && (inputstream.Read(buffer, 0, 1)) > 0)
1961            {
1962                //Step 1 get plaintext symbol
1963                byte symbol = buffer[0]; ;
1964                //Step 2 encrypt symbol
1965                outputstream.Write(Tools.byteArrayToByte(this.mAlgorithm.encrypt(Tools.byteToByteArray(symbol), key)));
1966
1967                if ((int)(inputstream.Position * 100 / inputstream.Length) > position)
1968                {
1969                    position = (int)(inputstream.Position * 100 / inputstream.Length);
1970                    mSdes.ProgressChanged(inputstream.Position, inputstream.Length);
1971                }
1972                outputstream.Flush();
1973
1974            }//end while
1975
1976        }//end encrypt
1977
1978        ///
1979        ///Encrypts the given plaintext with the given key
1980        ///using ElectronicCodeBookMode
1981        ///
1982        /// bytesToUse tells the algorithm how many bytes it has to encrypt
1983        /// bytesToUse = 0 => encrypt all
1984        public byte[] encrypt(byte[] input, byte[] key, [Optional, DefaultParameterValue(0)] int bytesToUse)
1985        {
1986
1987            int until = input.Length;
1988
1989            if(bytesToUse < until && bytesToUse > 0)
1990                until = bytesToUse;
1991
1992            byte[] output = new byte[until];
1993
1994            for(int i=0;i<until;i++)
1995            {               
1996                //Step 2 encrypt symbol
1997                output[i] = Tools.byteArrayToByte(this.mAlgorithm.encrypt(Tools.byteToByteArray(input[i]), key));
1998
1999            }//end while
2000
2001            return output;
2002
2003        }//end encrypt
2004
2005        ///<summary>
2006        ///Decrypts the given plaintext with the given Key
2007        ///using ElectronicCodeBook mode
2008        ///</summary>
2009        public void decrypt(CryptoolStream inputstream, CryptoolStream outputstream, byte[] key)
2010        {
2011
2012            byte[] buffer = new byte[1];
2013            int position = 0;
2014
2015            while (!this.mSdes.getStop() && (inputstream.Read(buffer, 0, 1)) > 0)
2016            {
2017                //Step 1 get plaintext symbol
2018                byte symbol = buffer[0];
2019                //Step 2 encrypt symbol
2020                outputstream.Write(Tools.byteArrayToByte(this.mAlgorithm.decrypt(Tools.byteToByteArray(symbol), key)));
2021
2022                if ((int)(inputstream.Position * 100 / inputstream.Length) > position)
2023                {
2024                    position = (int)(inputstream.Position * 100 / inputstream.Length);
2025                    mSdes.ProgressChanged(inputstream.Position, inputstream.Length);
2026                }
2027                outputstream.Flush();
2028
2029            }//end while
2030
2031        }//end decrypt
2032
2033        ///
2034        ///Decrypt the given plaintext with the given key
2035        ///using ElectronicCodeBookMode
2036        ///
2037        /// bytesToUse tells the algorithm how many bytes it has to decrypt
2038        /// bytesToUse = 0 => encrypt all
2039        public byte[] decrypt(byte[] input, byte[] key, [Optional, DefaultParameterValue(0)] int bytesToUse)
2040        {
2041            int until = input.Length;
2042
2043            if (bytesToUse < until && bytesToUse > 0)
2044                until = bytesToUse;
2045           
2046            byte[] output = new byte[until];
2047
2048            for (int i = 0; i < until; i++)
2049            {
2050                //Step 2 encrypt symbol
2051                output[i] = Tools.byteArrayToByte(this.mAlgorithm.decrypt(Tools.byteToByteArray(input[i]), key));
2052
2053            }//end while
2054
2055            return output;
2056
2057        }//end encrypt
2058
2059    }//end class ElectronicCodeBook
2060
2061}//end namespace Cryptool.Plugins.Cryptography.Encryption
Note: See TracBrowser for help on using the repository browser.