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

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

new key finding algorithm for KeySearcher

This update is really huge.

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