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

Last change on this file since 1804 was 1804, checked in by kopal, 11 years ago

now outputStream and InputStream will not be set to null after execution => now its possible to get output even if the execute run is over

File size: 73.0 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 10 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 8 bytes  (only 1 or 0 allowed).
204        /// </summary>
205        [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)]
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.Flush();
519                outputStream.Close();
520                inputStream.Close();               
521            }
522            catch (Exception exception)
523            {
524                GuiLogMessage(exception.Message, NotificationLevel.Error);
525                GuiLogMessage(exception.StackTrace, NotificationLevel.Error);
526            }
527            finally
528            {             
529                ProgressChanged(1, 1);
530            }
531        }
532
533        #endregion
534
535    }//end SDES
536
537    /// <summary>
538    /// This Class is for controlling the SDES with a "brute forcer" like KeySearcher
539    /// </summary>
540    public class SDESControl : IControlEncryption
541    {
542        #region private
543        private SDES plugin;
544        private byte[] input;
545        ElectronicCodeBook ecb;
546        CipherBlockChaining cbc;
547        #endregion
548
549        #region events
550        public event KeyPatternChanged keyPatternChanged; //not used, because we only have one key length
551        public event IControlStatusChangedEventHandler OnStatusChanged;
552        #endregion
553
554        #region public
555
556        /// <summary>
557        /// Constructs a new SDESControl
558        /// </summary>
559        /// <param name="Plugin"></param>
560        public SDESControl(SDES Plugin)
561        {
562            this.plugin = Plugin;
563            this.ecb = new ElectronicCodeBook(plugin);
564            this.cbc = new CipherBlockChaining(plugin);
565        }
566
567        /// <summary>
568        /// Called by SDES if its status changes
569        /// </summary>
570        public void onStatusChanged()
571        {
572            if(OnStatusChanged != null)
573                OnStatusChanged(this, true);
574        }
575     
576        /// <summary>
577        /// Called by a Master to start encryption
578        /// </summary>
579        /// <param name="key">key</param>
580        /// <param name="bytesToUse">bytesToUse</param>
581        /// <returns>encrypted text</returns>
582        public byte[] Encrypt(byte[] key, int bytesToUse)
583        {
584            return execute(key, bytesToUse, 0);
585        }
586
587        /// <summary>
588        /// Called by a Master to start decryption with ciphertext
589        /// </summary>
590        /// <param name="ciphertext">encrypted text</param>
591        /// <param name="key">key</param>
592        /// <param name="bytesToUse">bytesToUse</param>
593        /// <returns>decrypted text</returns>
594        public byte[] Decrypt(byte[] ciphertext, byte[] key, byte[] IV, int bytesToUse)
595        {
596            return execute(ciphertext, key, bytesToUse, 1);
597        }
598
599        /// <summary>
600        /// Called by a Master to start decryption with ciphertext
601        /// </summary>
602        /// <param name="ciphertext">encrypted text</param>
603        /// <param name="key">key</param>
604        /// <returns>decrypted text</returns>
605        public byte[] Decrypt(byte[] ciphertext, byte[] key, byte[] IV)
606        {
607            return execute(ciphertext, key, ciphertext.Length, 1);
608        }
609
610        /// <summary>
611        /// Called by a Master to start decryption
612        /// </summary>
613        /// <param name="key">key</param>
614        /// <param name="bytesToUse">bytesToUse</param>
615        /// <returns>decrypted text</returns>
616        public byte[] Decrypt(byte[] key, byte[] IV, int bytesToUse)
617        {
618            return execute(key, bytesToUse, 1);
619        }
620
621        /// <summary>
622        /// Get the key pattern of the SDES algorithm
623        /// </summary>
624        /// <returns>[01][01][01][01][01][01][01][01][01][01]</returns>
625        public string getKeyPattern()
626        {
627            return "[01][01][01][01][01][01][01][01][01][01]";
628        }
629
630        /// <summary>
631        /// Makes a byte Array out of a String
632        /// example
633        /// "10101" -> 1,0,1,0,1
634        ///
635        /// A 0 is interpreted as 0
636        /// any other character as 1
637        /// </summary>
638        /// <param name="key"></param>
639        /// <returns></returns>
640        public byte[] getKeyFromString(string key, ref int[] arrayPointers, ref int[] arraySuccessors, ref int[] arrayUppers)
641        {
642            byte[] bkey = new byte[10];
643            int count = 0;
644            foreach (char c in key)
645                if (c == '*')
646                    return null;    //blocks not supported yet
647                else if (c == '0')
648                    bkey[count++] = 0;
649                else
650                    bkey[count++] = 1;
651            return bkey;
652        }
653
654        public IControlEncryption clone()
655        {
656            return new SDESControl(plugin);
657        }
658
659        public void Dispose()
660        {
661            //closeStreams();
662        }
663
664        #endregion
665
666        #region private
667
668        /// <summary>
669        /// Called by itself to start encryption/decryption
670        /// </summary>
671        /// /// <param name="data">The data for encryption/decryption</param>
672        /// <param name="key">key</param>
673        /// <param name="bytesToUse">bytesToUse</param>
674        /// <returns>encrypted/decrypted text</returns>
675        private byte[] execute(byte[] data, byte[] key, int bytesToUse, int action)
676        {
677            byte[] output;
678            if (bytesToUse > 0)
679                output = new byte[bytesToUse];
680            else
681                output = new byte[data.Length];
682
683
684            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
685
686            string IVString = "00000000";
687            if (plugin.InputIV != null)
688            {
689                IVString = enc.GetString(plugin.InputIV);
690            }
691           
692            if (((SDESSettings)plugin.Settings).Mode == 0 && action == 0)
693            {
694                output = ecb.encrypt(data, key, bytesToUse);
695            }
696            else if (((SDESSettings)plugin.Settings).Mode == 1 && action == 0)
697            {
698                output = cbc.encrypt(data, key, Tools.stringToBinaryByteArray(IVString), bytesToUse);
699            }
700            else if (((SDESSettings)plugin.Settings).Mode == 0 && action == 1)
701            {
702                output = ecb.decrypt(data, key, bytesToUse);
703            }
704            else if (((SDESSettings)plugin.Settings).Mode == 1 && action == 1)
705            {
706                output = cbc.decrypt(data, key, Tools.stringToBinaryByteArray(IVString), bytesToUse);
707            }
708            return output;
709
710        }
711
712        /// <summary>
713        /// Called by itself to start encryption/decryption
714        /// </summary>
715        /// <param name="key">key</param>
716        /// <param name="bytesToUse">bytesToUse</param>
717        /// <returns>encrypted/decrypted text</returns>
718        private byte[] execute(byte[] key, int bytesToUse, int action)
719        {
720           
721            if (input == null || plugin.InputChanged)
722            {
723                plugin.InputChanged = false;
724                input = new byte[bytesToUse];
725
726                byte[] buffer = new byte[1];
727               
728                int i = 0;
729                CryptoolStream inputstream = plugin.InputStream;
730                while ((inputstream.Read(buffer, 0, 1)) > 0 && i < bytesToUse)
731                {
732                    input[i] = buffer[0];
733                    i++;
734                }
735            }
736
737            return execute(input, key, bytesToUse, action);
738        }
739
740        #endregion
741
742        #region IControlEncryption Member
743
744
745        public void changeSettings(string setting, object value)
746        {
747
748        }
749        #endregion
750    }
751       
752    /// <summary>
753    /// Encapsulates the SDES algorithm
754    /// </summary>
755    public class SDES_algorithm
756    {
757        private SDES mSdes;         //to call some methods on the plugin
758        private int fkstep = 0;     //for presentation to check the number of fk we are in
759        private int mode = 0;       //for presentation to check the mode we use (0 = en/1 = decrypt)
760
761        public SDES_algorithm(SDES sdes)
762        {
763            this.mSdes = sdes;
764        }
765
766        /// <summary>
767        /// Encrypt-function       
768        /// Encrypts the input plaintext with the given key
769        /// </summary>
770        /// <param name="plaintext">plaintext as byte array of size 8</param>
771        /// <param name="key">key as byte array of size 10</param>
772        /// <returns>ciphertext as byte array of size 8</returns>
773        public byte[] encrypt(byte[] plaintext, byte[] key)
774        {
775            this.mode = 0; // to tell presentation what we are doing
776
777            if (this.mSdes.Presentation.IsVisible)
778            {
779                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
780                {
781                    ((SDESPresentation)mSdes.Presentation).key_txt.Text =
782                    Tools.byteArrayToStringWithSpaces(key);
783                }
784                , null);
785            }
786            //calculate sub key 1
787            byte[] vp10 = p10(key);
788            if (this.mSdes.Presentation.IsVisible)
789            {
790                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
791                {
792                    ((SDESPresentation)mSdes.Presentation).key_txt_p10_input.Text =
793                    Tools.byteArrayToStringWithSpaces(key);
794                    ((SDESPresentation)mSdes.Presentation).key_txt_ls1_input_1.Text =
795                    Tools.byteArrayToStringWithSpaces(vp10);
796                }
797                , null);
798            }
799
800            byte[] vls1 = ls_1(vp10);
801            if (this.mSdes.Presentation.IsVisible)
802            {
803                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
804                {
805                    ((SDESPresentation)mSdes.Presentation).key_txt_p8_1_input.Text =
806                    Tools.byteArrayToStringWithSpaces(vls1);
807                }
808                , null);
809            }
810
811            byte[] key1 = p8(vls1);
812            if (this.mSdes.Presentation.IsVisible)
813            {
814                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
815                {
816                    ((SDESPresentation)mSdes.Presentation).key_txt_k1.Text =
817                    Tools.byteArrayToStringWithSpaces(key1);
818                }
819                , null);
820            }
821
822            //calculate sub key 2
823            vls1 = ls_1(vls1);
824            if (this.mSdes.Presentation.IsVisible)
825            {
826                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
827                {
828                    ((SDESPresentation)mSdes.Presentation).key_txt_p10_copy.Text =
829                    Tools.byteArrayToStringWithSpaces(vp10);
830                    ((SDESPresentation)mSdes.Presentation).key_txt_ls1_2.Text =
831                    Tools.byteArrayToStringWithSpaces(vp10);
832                    ((SDESPresentation)mSdes.Presentation).key_txt_ls1_3.Text =
833                   Tools.byteArrayToStringWithSpaces(vls1);
834                }
835                , null);
836            }
837
838            vls1 = ls_1(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_p8_2_input.Text =
844                    Tools.byteArrayToStringWithSpaces(vls1);
845                }
846               , null);
847            }
848
849            byte[] key2 = p8(vls1);
850            if (this.mSdes.Presentation.IsVisible)
851            {
852                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
853                {
854                    ((SDESPresentation)mSdes.Presentation).key_txt_k2.Text =
855                    Tools.byteArrayToStringWithSpaces(key2);
856                }
857               , null);
858            }
859
860            // ip_inverse(fk_2(sw(fk_1(ip(plaintext))))) :
861
862            byte[] ip = this.ip(plaintext);
863            if (this.mSdes.Presentation.IsVisible)
864            {
865                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
866                {
867                    ((SDESPresentation)mSdes.Presentation).encrypt_txt_plaintext.Text =
868                    Tools.byteArrayToStringWithSpaces(plaintext);
869                    ((SDESPresentation)mSdes.Presentation).encrypt_txt_ip_input.Text =
870                    Tools.byteArrayToStringWithSpaces(plaintext);
871                    ((SDESPresentation)mSdes.Presentation).encrypt_txt_ip_output.Text =
872                    Tools.byteArrayToStringWithSpaces(ip);
873                }
874               , null);
875            }
876
877            byte[] fk1 = fk(ip, key1);
878            if (this.mSdes.Presentation.IsVisible)
879            {
880                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
881                {
882                    ((SDESPresentation)mSdes.Presentation).encrypt_txt_sw_input.Text =
883                    Tools.byteArrayToStringWithSpaces(fk1);                   
884                }
885               , null);
886            }
887
888            byte[] swtch = sw(fk1);
889            if (this.mSdes.Presentation.IsVisible)
890            {
891                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
892                {
893                    ((SDESPresentation)mSdes.Presentation).encrypt_txt_sw_output.Text =
894                    Tools.byteArrayToStringWithSpaces(swtch);
895                }
896               , null);
897            }
898
899            byte[] fk2 = fk(swtch, key2);
900            if (this.mSdes.Presentation.IsVisible)
901            {
902                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
903                {
904                    ((SDESPresentation)mSdes.Presentation).encrypt_txt_ip_invers_input.Text =
905                    Tools.byteArrayToStringWithSpaces(fk2);
906                }
907               , null);
908            }                   
909
910            byte[] ciphertext = ip_inverse(fk2);
911            if (this.mSdes.Presentation.IsVisible)
912            {
913                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
914                {
915                    ((SDESPresentation)mSdes.Presentation).encrypt_txt_ip_invers_output.Text =
916                    Tools.byteArrayToStringWithSpaces(ciphertext);
917                }
918               , null);
919            }   
920
921            return ciphertext;
922
923        }//end encrypt
924
925        /// <summary>
926        /// Decrypt-function
927        /// Decrypts the input ciphertext with the given key
928        /// </summary>
929        /// <param name="ciphertext">ciphertext as byte array of size 8</param>
930        /// <param name="key"> key as byte array of size 10</param>
931        /// <returns>plaintext as byte array of size 8</returns>
932        public byte[] decrypt(byte[] ciphertext, byte[] key)
933        {
934            this.mode = 1; // to tell presentation what we are doing
935
936            if (this.mSdes.Presentation.IsVisible)
937            {
938                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
939                {
940                    ((SDESPresentation)mSdes.Presentation).key_txt.Text =
941                    Tools.byteArrayToStringWithSpaces(key);
942                }
943                , null);
944            }
945            //calculate sub key 1
946            byte[] vp10 = p10(key);
947            if (this.mSdes.Presentation.IsVisible)
948            {
949                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
950                {
951                    ((SDESPresentation)mSdes.Presentation).key_txt_p10_input.Text =
952                    Tools.byteArrayToStringWithSpaces(key);
953                    ((SDESPresentation)mSdes.Presentation).key_txt_ls1_input_1.Text =
954                    Tools.byteArrayToStringWithSpaces(vp10);
955                }
956                , null);
957            }
958
959            byte[] vls1 = ls_1(vp10);
960            if (this.mSdes.Presentation.IsVisible)
961            {
962                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
963                {
964                    ((SDESPresentation)mSdes.Presentation).key_txt_p8_1_input.Text =
965                    Tools.byteArrayToStringWithSpaces(vls1);
966                }
967                , null);
968            }
969
970            byte[] key1 = p8(vls1);
971            if (this.mSdes.Presentation.IsVisible)
972            {
973                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
974                {
975                    ((SDESPresentation)mSdes.Presentation).key_txt_k1.Text =
976                    Tools.byteArrayToStringWithSpaces(key1);
977                }
978                , null);
979            }
980
981            //calculate sub key 2
982            vls1 = ls_1(vls1);
983            if (this.mSdes.Presentation.IsVisible)
984            {
985                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
986                {
987                    ((SDESPresentation)mSdes.Presentation).key_txt_p10_copy.Text =
988                    Tools.byteArrayToStringWithSpaces(vp10);
989                    ((SDESPresentation)mSdes.Presentation).key_txt_ls1_2.Text =
990                    Tools.byteArrayToStringWithSpaces(vp10);
991                    ((SDESPresentation)mSdes.Presentation).key_txt_ls1_3.Text =
992                   Tools.byteArrayToStringWithSpaces(vls1);
993                }
994                , null);
995            }
996
997            vls1 = ls_1(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_p8_2_input.Text =
1003                    Tools.byteArrayToStringWithSpaces(vls1);
1004                }
1005               , null);
1006            }
1007
1008            byte[] key2 = p8(vls1);
1009            if (this.mSdes.Presentation.IsVisible)
1010            {
1011                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1012                {
1013                    ((SDESPresentation)mSdes.Presentation).key_txt_k2.Text =
1014                    Tools.byteArrayToStringWithSpaces(key2);
1015                }
1016               , null);
1017            }
1018
1019            // ip_inverse(fk_1(sw(fk_2(ip(ciphertext))))) :
1020
1021            byte[] ip = this.ip(ciphertext);
1022            if (this.mSdes.Presentation.IsVisible)
1023            {
1024                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1025                {
1026                    ((SDESPresentation)mSdes.Presentation).decrypt_txt_plaintext.Text =
1027                    Tools.byteArrayToStringWithSpaces(ciphertext);
1028                    ((SDESPresentation)mSdes.Presentation).decrypt_txt_ip_input.Text =
1029                    Tools.byteArrayToStringWithSpaces(ciphertext);
1030                    ((SDESPresentation)mSdes.Presentation).decrypt_txt_ip_output.Text =
1031                    Tools.byteArrayToStringWithSpaces(ip);
1032                }
1033               , null);
1034            }
1035
1036            byte[] fk2 = fk(ip, key2);
1037            if (this.mSdes.Presentation.IsVisible)
1038            {
1039                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1040                {
1041                    ((SDESPresentation)mSdes.Presentation).decrypt_txt_sw_input.Text =
1042                    Tools.byteArrayToStringWithSpaces(fk2);                 
1043                }
1044               , null);
1045            }
1046
1047            byte[] swtch = sw(fk2); 
1048            if (this.mSdes.Presentation.IsVisible)
1049            {
1050                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1051                {
1052                    ((SDESPresentation)mSdes.Presentation).decrypt_txt_sw_output.Text =
1053                    Tools.byteArrayToStringWithSpaces(swtch);
1054                }
1055               , null);
1056            }
1057
1058            byte[] fk1 = fk(swtch, key1);
1059            if (this.mSdes.Presentation.IsVisible)
1060            {
1061                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1062                {
1063                    ((SDESPresentation)mSdes.Presentation).decrypt_txt_ip_invers_input.Text =
1064                    Tools.byteArrayToStringWithSpaces(fk1);
1065                }
1066               , null);
1067            }
1068
1069            byte[] plaintext = ip_inverse(fk1);
1070            if (this.mSdes.Presentation.IsVisible)
1071            {
1072                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1073                {
1074                    ((SDESPresentation)mSdes.Presentation).decrypt_txt_ip_invers_output.Text =
1075                    Tools.byteArrayToStringWithSpaces(plaintext);
1076                }
1077               , null);
1078            }           
1079
1080            return plaintext;
1081
1082        }//end decrypt
1083
1084        ///<summary>
1085        ///p10-function
1086        ///Permutates the input bytes array of "10 bits" to another by
1087        ///the following rule:
1088        ///
1089        ///src    dest
1090        ///1   -> 3
1091        ///2   -> 5
1092        ///3   -> 2
1093        ///4   -> 7
1094        ///5   -> 4
1095        ///6   -> 10
1096        ///7   -> 1
1097        ///8   -> 9
1098        ///9   -> 8
1099        ///10  -> 6
1100        ///</summary>
1101        ///<param name="bits">byte array of size 10</param>
1102        ///<returns>byte array of size 10</returns>
1103        ///
1104        private byte[] p10(byte[] bits)
1105        {
1106
1107            byte[] p10 = new byte[10];
1108
1109            p10[1 - 1] = bits[3 - 1];
1110            p10[2 - 1] = bits[5 - 1];
1111            p10[3 - 1] = bits[2 - 1];
1112            p10[4 - 1] = bits[7 - 1];
1113            p10[5 - 1] = bits[4 - 1];
1114            p10[6 - 1] = bits[10 - 1];
1115            p10[7 - 1] = bits[1 - 1];
1116            p10[8 - 1] = bits[9 - 1];
1117            p10[9 - 1] = bits[8 - 1];
1118            p10[10 - 1] = bits[6 - 1];
1119
1120            //mSdes.GuiLogMessage("P10 with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(p10), NotificationLevel.Debug);
1121            return p10;
1122
1123        }//end p10
1124
1125        ///<summary>
1126        ///p8-function
1127        ///Permutates the input bytes array of "8 bits" to another by
1128        ///the following rule:
1129        ///
1130        ///src    dest
1131        ///1   -> 6
1132        ///2   -> 3
1133        ///3   -> 7
1134        ///4   -> 4
1135        ///5   -> 8
1136        ///6   -> 5
1137        ///7   -> 10
1138        ///8   -> 9
1139        ///</summary>
1140        ///<param name="bits">byte array of size 10</param>
1141        ///<returns>byte array of size 8</returns>
1142        private byte[] p8(byte[] bits)
1143        {
1144
1145            byte[] p8 = new byte[8];
1146
1147            p8[1 - 1] = bits[6 - 1];
1148            p8[2 - 1] = bits[3 - 1];
1149            p8[3 - 1] = bits[7 - 1];
1150            p8[4 - 1] = bits[4 - 1];
1151            p8[5 - 1] = bits[8 - 1];
1152            p8[6 - 1] = bits[5 - 1];
1153            p8[7 - 1] = bits[10 - 1];
1154            p8[8 - 1] = bits[9 - 1];
1155
1156            //mSdes.GuiLogMessage("P8 with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(p8), NotificationLevel.Debug);
1157            return p8;
1158
1159        }//end p8
1160
1161        ///<summary>
1162        ///ip-function (initial permutation)
1163        ///Permutates the input array of "8 bits" to another by
1164        ///the following rule:
1165        ///
1166        ///src    dest
1167        ///1   -> 2
1168        ///2   -> 6
1169        ///3   -> 3
1170        ///4   -> 1
1171        ///5   -> 4
1172        ///6   -> 8
1173        ///7   -> 5
1174        ///8   -> 7
1175        ///</summary>
1176        ///<param name="bits">byte array of size 8</param>
1177        ///<returns>byte array of size 8</returns>
1178        private byte[] ip(byte[] bits)
1179        {
1180
1181            byte[] ip = new byte[8];
1182
1183            ip[1 - 1] = bits[2 - 1];
1184            ip[2 - 1] = bits[6 - 1];
1185            ip[3 - 1] = bits[3 - 1];
1186            ip[4 - 1] = bits[1 - 1];
1187            ip[5 - 1] = bits[4 - 1];
1188            ip[6 - 1] = bits[8 - 1];
1189            ip[7 - 1] = bits[5 - 1];
1190            ip[8 - 1] = bits[7 - 1];
1191
1192            //mSdes.GuiLogMessage("ip with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(ip), NotificationLevel.Debug);
1193            return ip;
1194
1195        }//end ip
1196
1197        ///<summary>
1198        ///ip^-1-function (initial permutation inverse)
1199        ///Permutates the input array of "8 bits" to another by
1200        ///the following rule:
1201        ///
1202        ///src    dest
1203        ///1   -> 4
1204        ///2   -> 1
1205        ///3   -> 3
1206        ///4   -> 5
1207        ///5   -> 7
1208        ///6   -> 2
1209        ///7   -> 8
1210        ///8   -> 6
1211        ///</summary>
1212        ///<param name="bits">byte array of size 8</param>
1213        ///<returns>byte array of size 8</returns>
1214        private byte[] ip_inverse(byte[] bits)
1215        {
1216
1217            byte[] ip_inverse = new byte[8];
1218
1219            ip_inverse[1 - 1] = bits[4 - 1];
1220            ip_inverse[2 - 1] = bits[1 - 1];
1221            ip_inverse[3 - 1] = bits[3 - 1];
1222            ip_inverse[4 - 1] = bits[5 - 1];
1223            ip_inverse[5 - 1] = bits[7 - 1];
1224            ip_inverse[6 - 1] = bits[2 - 1];
1225            ip_inverse[7 - 1] = bits[8 - 1];
1226            ip_inverse[8 - 1] = bits[6 - 1];
1227
1228            //mSdes.GuiLogMessage("ip_inverse with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(ip_inverse), NotificationLevel.Debug);             
1229            return ip_inverse;
1230
1231        }//end ip_inverse
1232
1233        ///<summary>
1234        ///fk-function
1235        ///
1236        ///combines the following functions:
1237        ///
1238        ///right is the right part of the input array
1239        ///left is the left part of the input array
1240        ///
1241        ///(right | left) := (inputarray))
1242        ///ret := exclusive_or(left,F(right,key)) + right)
1243        ///</summary>
1244        ///<param name="bits">byte array of size 8</param>
1245        ///<param name="key">byte array of size 8</param>
1246        ///<returns>byte array of size 8</returns>
1247        private byte[] fk(byte[] bits, byte[] key)
1248        {
1249            byte[] left = { bits[1 - 1], bits[2 - 1], bits[3 - 1], bits[4 - 1] };
1250            byte[] right = { bits[5 - 1], bits[6 - 1], bits[7 - 1], bits[8 - 1] };
1251
1252            byte[] exclusive_oder = Tools.exclusive_or(left, F(right, key));
1253
1254            byte[] ret = {exclusive_oder[1-1],exclusive_oder[2-1],exclusive_oder[3-1],exclusive_oder[4-1],
1255                                     right[1-1],right[2-1],right[3-1],right[4-1]};
1256
1257            fkstep++;
1258            if (fkstep == 2)
1259                fkstep = 0;
1260
1261            //mSdes.GuiLogMessage("fk with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(ret), NotificationLevel.Debug);
1262            return ret;
1263
1264        }//end fk
1265
1266        ///<summary>
1267        ///ls-1 function
1268        ///</summary>
1269        ///<param name="bits">byte array of size 10</param>
1270        ///<returns>byte array of size 10</returns>
1271        private byte[] ls_1(byte[] bits)
1272        {
1273
1274            byte[] ls_1 = new byte[10];
1275
1276            ls_1[1 - 1] = bits[2 - 1];
1277            ls_1[2 - 1] = bits[3 - 1];
1278            ls_1[3 - 1] = bits[4 - 1];
1279            ls_1[4 - 1] = bits[5 - 1];
1280            ls_1[5 - 1] = bits[1 - 1];
1281            ls_1[6 - 1] = bits[7 - 1];
1282            ls_1[7 - 1] = bits[8 - 1];
1283            ls_1[8 - 1] = bits[9 - 1];
1284            ls_1[9 - 1] = bits[10 - 1];
1285            ls_1[10 - 1] = bits[6 - 1];
1286
1287            //mSdes.GuiLogMessage("ls-1 with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(ls_1), NotificationLevel.Debug);
1288            return ls_1;
1289
1290        }//end ls_1
1291
1292        ///<summary>
1293        ///switch-function
1294        ///
1295        ///switches the left side and the right side of the 8 bit array
1296        ///(left|right) -> (right|left)
1297        ///</summary>
1298        ///<param name="bits">byte array of size 8</param>
1299        ///<returns>byte array of size 8</returns>
1300        private byte[] sw(byte[] bits)
1301        {
1302
1303            byte[] ret = {bits[5-1],bits[6-1],bits[7-1],bits[8-1],
1304                                         bits[1-1],bits[2-1],bits[3-1],bits[4-1]};
1305
1306            //mSdes.GuiLogMessage("sw with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(ret), NotificationLevel.Debug);
1307            return ret;
1308
1309        }//end sw
1310
1311        ///<summary>
1312        ///F-function
1313        ///
1314        ///combines both s-boxes and permutates the return value with p4
1315        ///p4( s0(exclusive_or(ep(number),key) | s1(exclusive_or(ep(number),key) )
1316        ///</summary>
1317        ///<param name="bits">byte array of size 8</param>
1318        ///<param name="bits">key of size 8</param>
1319        ///<returns>byte array of size 8</returns>
1320        private byte[] F(byte[] bits, byte[] key)
1321        {
1322
1323            byte[] ep = this.ep(bits);
1324
1325            byte[] exclusive = Tools.exclusive_or(ep, key);
1326
1327            byte[] s0_input = { exclusive[1 - 1], exclusive[2 - 1], exclusive[3 - 1], exclusive[4 - 1] };
1328            byte[] s0 = sbox_0(s0_input);
1329
1330            byte[] s1_input = { exclusive[5 - 1], exclusive[6 - 1], exclusive[7 - 1], exclusive[8 - 1] };
1331            byte[] s1 = sbox_1(s1_input);
1332
1333            byte[] s0_s1 = { s0[1 - 1], s0[2 - 1], s1[1 - 1], s1[2 - 1] };
1334            byte[] ret = p4(s0_s1);
1335
1336            if (this.mSdes.Presentation.IsVisible)
1337            {
1338                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1339                {
1340                    if (mode == 0 && fkstep == 0)
1341                    {
1342                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_sbox1_output.Text =
1343                        Tools.byteArrayToStringWithSpaces(ret);
1344                    }
1345                    if (mode == 0 && fkstep == 1)
1346                    {
1347                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_sbox2_output.Text =
1348                        Tools.byteArrayToStringWithSpaces(ret);
1349                    }
1350                    if (mode == 1 && fkstep == 0)
1351                    {
1352                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_sbox1_output.Text =
1353                        Tools.byteArrayToStringWithSpaces(ret);
1354                    }
1355                    if (mode == 1 && fkstep == 1)
1356                    {
1357                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_sbox2_output.Text =
1358                        Tools.byteArrayToStringWithSpaces(ret);
1359                    }
1360                }
1361               , null);
1362            }
1363
1364            //mSdes.GuiLogMessage("F with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(key) + " ist " + Tools.intArray2String(ret), NotificationLevel.Debug);
1365            return ret;
1366
1367        }//end F
1368
1369        ///<summary>
1370        ///p4-function
1371        ///Permutates the input array of "4 bits" to another by
1372        ///the following rule:
1373        ///
1374        ///src    dest
1375        ///1   -> 2
1376        ///2   -> 4
1377        ///3   -> 3
1378        ///4   -> 1
1379        ///</summary>
1380        ///<param name="bits">byte array of size 4</param>
1381        ///<returns>byte array of size 4</returns>
1382        private byte[] p4(byte[] bits)
1383        {
1384
1385            byte[] ret = new byte[4];
1386            ret[1 - 1] = bits[2 - 1];
1387            ret[2 - 1] = bits[4 - 1];
1388            ret[3 - 1] = bits[3 - 1];
1389            ret[4 - 1] = bits[1 - 1];
1390
1391            return ret;
1392
1393        }//end p4
1394
1395        ///<summary>
1396        ///ep-function
1397        ///Permutates the input array of "4 bits" to another array of "8 bits" by
1398        ///the following rule:
1399        ///
1400        ///src    dest
1401        ///1   -> 4
1402        ///2   -> 1
1403        ///3   -> 2
1404        ///4   -> 3
1405        ///5   -> 2
1406        ///6   -> 3
1407        ///7   -> 4
1408        ///8   -> 1
1409        ///</summary>
1410         ///<param name="bits">byte array of size 4</param>
1411        ///<returns>byte array of size 8</returns>
1412        private byte[] ep(byte[] bits)
1413        {
1414
1415            byte[] ep = new byte[8];
1416            ep[1 - 1] = bits[4 - 1];
1417            ep[2 - 1] = bits[1 - 1];
1418            ep[3 - 1] = bits[2 - 1];
1419            ep[4 - 1] = bits[3 - 1];
1420            ep[5 - 1] = bits[2 - 1];
1421            ep[6 - 1] = bits[3 - 1];
1422            ep[7 - 1] = bits[4 - 1];
1423            ep[8 - 1] = bits[1 - 1];
1424
1425            if (this.mSdes.Presentation.IsVisible)
1426            {
1427                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1428                {
1429                    if (mode == 0 && fkstep == 0)
1430                    {
1431                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_ep_output.Text =
1432                        Tools.byteArrayToStringWithSpaces(ep);
1433                    }
1434                    if (mode == 0 && fkstep == 1)
1435                    {
1436                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_ep_output1.Text =
1437                        Tools.byteArrayToStringWithSpaces(ep);
1438                    }
1439                    if (mode == 1 && fkstep == 0)
1440                    {
1441                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_ep_output.Text =
1442                        Tools.byteArrayToStringWithSpaces(ep);
1443                    }
1444                    if (mode == 1 && fkstep == 1)
1445                    {
1446                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_ep_output1.Text =
1447                        Tools.byteArrayToStringWithSpaces(ep);
1448                    }
1449                }
1450               , null);
1451            }
1452
1453            return ep;
1454        }
1455
1456        ///<summary>
1457        ///SBox-0
1458        ///
1459        ///S0 =  1 0 3 2
1460        ///      3 2 1 0
1461        ///      0 2 1 3   
1462        ///      3 1 3 2           
1463        ///</summary>
1464        ///<param name="bits">byte array of size 4</param>
1465        ///<returns>byte array of size 2</returns>
1466        private byte[] sbox_0(byte[] bits)
1467        {
1468
1469            int row = 2 * bits[1 - 1] + 1 * bits[4 - 1];
1470            int column = 2 * bits[2 - 1] + 1 * bits[3 - 1];
1471
1472            byte[,][] sbox_0 = new byte[4, 4][]
1473                            {
1474                            {new byte[] {0,1}, new byte[] {0,0}, new byte[] {1,1}, new byte[] {1,0}},
1475                                                {new byte[] {1,1}, new byte[] {1,0}, new byte[] {0,1}, new byte[] {0,0}},
1476                                                {new byte[] {0,0}, new byte[] {1,0}, new byte[] {0,1}, new byte[] {1,1}},
1477                                                {new byte[] {1,1}, new byte[] {0,1}, new byte[] {1,1}, new byte[] {1,0}}
1478                            };
1479
1480            byte[] ret = sbox_0[row, column];
1481
1482            if (this.mSdes.Presentation.IsVisible)
1483            {
1484                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1485                {
1486                    if (mode == 0 && fkstep == 0)
1487                    {
1488                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_s0_1_output.Text =
1489                        Tools.byteArrayToStringWithSpaces(ret);
1490                    }
1491                    if (mode == 0 && fkstep == 1)
1492                    {
1493                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_s0_2_output.Text =
1494                        Tools.byteArrayToStringWithSpaces(ret);
1495                    }
1496                    if (mode == 1 && fkstep == 0)
1497                    {
1498                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_s0_1_output.Text =
1499                        Tools.byteArrayToStringWithSpaces(ret);
1500                    }
1501                    if (mode == 1 && fkstep == 1)
1502                    {
1503                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_s0_2_output.Text =
1504                        Tools.byteArrayToStringWithSpaces(ret);
1505                    }
1506                }
1507               , null);
1508            }
1509
1510            //mSdes.GuiLogMessage("S0 with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(ret), NotificationLevel.Debug);
1511            return ret;
1512
1513        }//end sbox-0
1514
1515
1516        ///<summary>
1517        ///SBox-1
1518        ///
1519        ///S1 =  0 1 2 3
1520        ///      2 0 1 3
1521        ///      3 0 1 0
1522        ///      2 1 0 3
1523        ///</summary>
1524        ///<param name="bits">byte array of size 4</param>
1525        ///<returns>byte array of size 2</returns>
1526        private byte[] sbox_1(byte[] bits)
1527        {
1528
1529            int row = 2 * bits[1 - 1] + 1 * bits[4 - 1];
1530            int column = 2 * bits[2 - 1] + 1 * bits[3 - 1];
1531
1532            byte[,][] sbox_1 = new byte[4, 4][]
1533                            {
1534                            {new byte[] {0,0}, new byte[] {0,1}, new byte[] {1,0}, new byte[] {1,1}},
1535                                                        {new byte[] {1,0}, new byte[] {0,0}, new byte[] {0,1}, new byte[] {1,1}},
1536                                                        {new byte[] {1,1}, new byte[] {0,0}, new byte[] {0,1}, new byte[] {0,0}},
1537                                                        {new byte[] {1,0}, new byte[] {0,1}, new byte[] {0,0}, new byte[] {1,1}}
1538                            };
1539
1540            byte[] ret = sbox_1[row, column];
1541
1542            if (this.mSdes.Presentation.IsVisible)
1543            {
1544                ((SDESPresentation)mSdes.Presentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
1545                {
1546                    if (mode == 0 && fkstep == 0)
1547                    {
1548                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_s1_1_output.Text =
1549                        Tools.byteArrayToStringWithSpaces(ret);
1550                    }
1551                    if (mode == 0 && fkstep == 1)
1552                    {
1553                        ((SDESPresentation)mSdes.Presentation).encrypt_txt_s1_2_output.Text =
1554                        Tools.byteArrayToStringWithSpaces(ret);
1555                    }
1556                    if (mode == 1 && fkstep == 0)
1557                    {
1558                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_s1_1_output.Text =
1559                        Tools.byteArrayToStringWithSpaces(ret);
1560                    }
1561                    if (mode == 1 && fkstep == 1)
1562                    {
1563                        ((SDESPresentation)mSdes.Presentation).decrypt_txt_s1_2_output.Text =
1564                        Tools.byteArrayToStringWithSpaces(ret);
1565                    }
1566                }
1567               , null);
1568            }
1569
1570            //mSdes.GuiLogMessage("S1 with " + Tools.intArray2String(bits) + " is " + Tools.intArray2String(ret), NotificationLevel.Debug);             
1571            return ret;
1572
1573        }//end sbox-1
1574
1575    }
1576
1577    ///<summary>
1578    ///Encapsulates some necessary functions
1579    ///</summary>
1580    public class Tools
1581    {
1582
1583        /// <summary>
1584        /// transforms a byte array into a String with spaces after each byte
1585        /// example:
1586        ///     1,0 => "1 0"
1587        /// </summary>
1588        /// <param name="byt">byt</param>
1589        /// <returns>s</returns>
1590        public static String byteArrayToStringWithSpaces(byte[] byt)
1591        {
1592            String s = "";
1593
1594            foreach (byte b in byt)
1595            {
1596                s = s + b + " ";
1597            }
1598            return s;
1599        }
1600        ///<summary>
1601        ///Converts an byte array to a String
1602        ///</summary>
1603        ///<param name="bits">byte array of size n</param>
1604        ///<returns>String</returns>
1605        public static String byteArray2String(byte[] bits)
1606        {
1607
1608            String ret = "";
1609            for (int i = 0; i < bits.Length; i++)
1610            {
1611                ret += ("" + bits[i]);
1612            }
1613            return ret;
1614
1615        }//end byteArray2String
1616
1617        ///<summary>
1618        ///Converts the given byte array to a printable String
1619        ///
1620        ///example {72, 101, 108, 108, 111} -> "Hello"
1621        ///</summary>
1622        ///<param name="bits">byte array of size n</param>
1623        ///<returns>String</returns>
1624        public static String byteArray2PrintableString(byte[] bits)
1625        {
1626
1627            String ret = "";
1628            for (int i = 0; i < bits.Length; i++)
1629            {
1630                ret += ("" + (char)bits[i]);
1631            }
1632            return ret;
1633
1634        }// byteArray2PrintableString
1635
1636        ///<summary>
1637        ///equals-function
1638        ///
1639        ///returns true if both integer arrays are equal
1640        ///</summary>
1641        ///<param name="a">byte array of size n</param>
1642        ///<param name="b">byte array of size n</param>
1643        ///<returns>bool</returns>
1644        public static bool byteArrays_Equals(byte[] a, byte[] b)
1645        {
1646
1647            for (int i = 0; i < a.Length; i++)
1648            {
1649                if (a[i] != b[i])
1650                {
1651                    return false;
1652                }
1653            }
1654
1655            return true;
1656
1657        }//end byteArrays_Equals       
1658
1659        ///<summary>
1660        ///converts an Byte to an byte array of (0,1)
1661        ///
1662        ///100 -> {1,1,0,0,1,0,0}
1663        ///</summary>
1664        ///<param name="byt">byte array of size n</param>
1665        ///<returns>byte array</returns>
1666        public static byte[] byteToByteArray(byte byt)
1667        {
1668
1669            byte[] bytearray = new byte[8];
1670
1671            for (int i = 7; i >= 0; i--)
1672            {
1673
1674                bytearray[i] = (byte)(byt % 2);
1675                byt = (byte)Math.Floor((double)(byt / 2));
1676
1677            }
1678
1679            return bytearray;
1680
1681        }//end byteTointArray
1682
1683        ///<summary>
1684        ///converts an byte array of (0,1) to an byte
1685        ///
1686        ///{1,1,0,0,1,0,0} -> 100
1687        ///</summary>
1688        ///<param name="bytearray">byte array of size n</param>
1689        ///<returns>byte</returns>
1690        public static byte byteArrayToByte(byte[] bytearray)
1691        {
1692
1693            int byt = 0;
1694
1695            byt = (bytearray[0] * 128)
1696                        + (bytearray[1] * 64)
1697                        + (bytearray[2] * 32)
1698                        + (bytearray[3] * 16)
1699                        + (bytearray[4] * 8)
1700                        + (bytearray[5] * 4)
1701                        + (bytearray[6] * 2)
1702                        + (bytearray[7] * 1);
1703
1704            return (byte)byt;
1705
1706        }//end byteArrayToInteger
1707
1708        ///<summary>
1709        ///Exclusiv-OR function
1710        ///
1711        ///Does a exlusiv-or on two byte arrays
1712        ///
1713        ///example {1,0,1} XOR {1,0,0} -> {0,0,1}
1714        ///</summary>
1715        ///<param name="bitsA">byte array of size n</param>
1716        ///<param name="bitsB">byte array of size n</param>
1717        ///<returns>byte array of size n</returns>
1718        public static byte[] exclusive_or(byte[] bitsA, byte[] bitsB)
1719        {
1720
1721            byte[] exclusive_or_AB = new byte[bitsA.Length];
1722
1723            for (int i = 0; i < bitsA.Length; i++)
1724            {
1725
1726                if ((bitsA[i] == 0 && bitsB[i] == 1) ||
1727                   (bitsA[i] == 1 && bitsB[i] == 0)
1728                )
1729                {
1730                    exclusive_or_AB[i] = 1;
1731                }
1732                else
1733                {
1734                    exclusive_or_AB[i] = 0;
1735                }//end if
1736
1737            }//end for
1738
1739            return exclusive_or_AB;
1740
1741        }//end exclusive_or
1742
1743        ///<summary>
1744        ///converts string to an byte array
1745        ///
1746        ///example "Hello" -> {72, 101, 108, 108, 111}
1747        ///</summary>
1748        ///<param name="s">String</param>
1749        ///<returns>byte array</returns>
1750        public static byte[] stringToByteArray(String s)
1751        {
1752            byte[] bytearray = new byte[s.Length];
1753
1754            for (int i = 0; i < s.Length; i++)
1755            {
1756                bytearray[i] = (byte)s[i];
1757            }
1758
1759            return bytearray;
1760
1761        }// end stringToByteArray
1762
1763        ///<summary>
1764        ///converts a binary string to an byte array
1765        ///
1766        ///example "10010" -> {1, 0, 0, 1, 0}
1767        ///</summary>
1768        ///<param name="s">String</param>
1769        ///<returns>byte array</returns>
1770        public static byte[] stringToBinaryByteArray(String s)
1771        {
1772            byte[] bytearray = new byte[s.Length];
1773
1774            for (int i = 0; i < s.Length; i++)
1775            {
1776                if (s[i] == '1')
1777                {
1778                    bytearray[i] = 1;
1779                }
1780                else if (s[i] == '0')
1781                {
1782                    bytearray[i] = 0;
1783                }
1784                else
1785                {
1786                    throw new Exception("Invalid Character '" + s[i] + "' at position " + i + " in String which represents binary values: " + s);
1787                }
1788            }
1789
1790            return bytearray;
1791
1792        }// end stringToByteArray
1793    }
1794
1795    ///<summary>
1796    ///Encapsulates the CipherBlockChaining algorithm
1797    ///</summary>
1798    public class CipherBlockChaining
1799    {
1800
1801        private SDES mSdes;
1802        private SDES_algorithm mAlgorithm;
1803
1804        /// <summary>
1805        /// Constructs a CipherBlockChaining for SDES
1806        /// </summary>
1807        /// <param name="sdes">plugin</param>
1808        public CipherBlockChaining(SDES sdes)
1809        {
1810            this.mSdes = sdes;
1811            this.mAlgorithm = new SDES_algorithm(sdes);
1812        }
1813
1814        ///<summary>
1815        ///Encrypts the given plaintext with the given key
1816        ///using CipherBlockChaining
1817        ///</summary>
1818        public void encrypt(CryptoolStream inputstream, CryptoolStream outputstream, byte[] key, byte[] vector)
1819        {
1820
1821            byte[] buffer = new byte[1];
1822            int position = 0;
1823
1824            while (!this.mSdes.getStop() && (inputstream.Read(buffer, 0, 1)) > 0)
1825            {
1826                //Step 1 get plaintext symbol
1827                byte symbol = buffer[0];
1828                //Step 2 exclusiv OR with vector
1829                vector = Tools.exclusive_or(vector, Tools.byteToByteArray(symbol));
1830                //Step 3 decrypt vector with key
1831                vector = mAlgorithm.encrypt(vector, key);
1832                //Step 4 store symbol in ciphertext
1833                outputstream.Write(Tools.byteArrayToByte(vector));
1834
1835                if ((int)(inputstream.Position * 100 / inputstream.Length) > position)
1836                {
1837                    position = (int)(inputstream.Position * 100 / inputstream.Length);
1838                    mSdes.ProgressChanged(inputstream.Position, inputstream.Length);
1839                }
1840                outputstream.Flush();
1841            }
1842
1843        }//end encrypt
1844
1845        ///
1846        ///Encrypts the given plaintext with the given key
1847        ///using CipherBlockChaining
1848        ///
1849        /// bytesToUse tells the algorithm how many bytes it has to encrypt
1850        /// bytesToUse = 0 => encrypt all
1851        public byte[] encrypt(byte[] input, byte[] key, byte[] vector, [Optional, DefaultParameterValue(0)] int bytesToUse)
1852        {
1853            int until = input.Length;           
1854
1855            if (bytesToUse < until && bytesToUse > 0)
1856                until = bytesToUse;
1857
1858            byte[] output = new byte[until];
1859
1860            for (int i = 0; i < until; i++)
1861            {
1862                vector = Tools.exclusive_or(vector, Tools.byteToByteArray(input[i]));
1863                vector = mAlgorithm.encrypt(vector, key);
1864                output[i] = Tools.byteArrayToByte(vector);
1865
1866            }//end while
1867           
1868            return output;
1869
1870        }//end encrypt
1871
1872        ///<summary>
1873        ///Decrypts the given plaintext with the given Key
1874        ///using CipherBlockChaining
1875        ///</summary>
1876        public void decrypt(CryptoolStream inputstream, CryptoolStream outputstream, byte[] key, byte[] vector)
1877        {
1878
1879            byte[] buffer = new byte[1];
1880            int position = 0;
1881
1882            while (!this.mSdes.getStop() && (inputstream.Read(buffer, 0, 1)) > 0)
1883            {
1884                //Step 1 get Symbol of Ciphertext
1885                byte symbol = buffer[0];
1886                //Step 2 Decrypt symbol with key and exclusiv-or with vector
1887                outputstream.Write((Tools.byteArrayToByte(Tools.exclusive_or(mAlgorithm.decrypt(Tools.byteToByteArray(symbol), key), vector))));
1888                //Step 3 let vector be the decrypted Symbol
1889                vector = Tools.byteToByteArray(buffer[0]);
1890
1891                if ((int)(inputstream.Position * 100 / inputstream.Length) > position)
1892                {
1893                    position = (int)(inputstream.Position * 100 / inputstream.Length);
1894                    mSdes.ProgressChanged(inputstream.Position, inputstream.Length);
1895                }
1896                outputstream.Flush();
1897            }
1898
1899        }//end decrypt
1900
1901        ///
1902        ///Decrypt the given plaintext with the given key
1903        ///using CipherBlockChaining
1904        ///
1905        /// bytesToUse tells the algorithm how many bytes it has to encrypt
1906        /// bytesToUse = 0 => encrypt all
1907        public byte[] decrypt(byte[] input, byte[] key, byte[] vector, [Optional, DefaultParameterValue(0)] int bytesToUse)
1908        {
1909
1910            int until = input.Length;
1911           
1912            if (bytesToUse < until && bytesToUse > 0)
1913                until = bytesToUse;
1914
1915            byte[] output = new byte[until];
1916
1917            for (int i = 0; i < until; i++)
1918            {
1919                output[i] = (Tools.byteArrayToByte(Tools.exclusive_or(mAlgorithm.decrypt(Tools.byteToByteArray(input[i]), key), vector)));
1920                vector = Tools.byteToByteArray(input[i]);
1921                           
1922            }//end while
1923
1924            return output;
1925
1926        }//end encrypt
1927
1928    }//end class CipherBlockChaining
1929
1930    ///<summary>
1931    ///Encapsulates the ElectronicCodeBook algorithm
1932    ///</summary>
1933    public class ElectronicCodeBook
1934    {
1935
1936        private SDES mSdes;
1937        private SDES_algorithm mAlgorithm;
1938
1939        /// <summary>
1940        /// Constructs a ElectronicCodeBook for SDES
1941        /// </summary>
1942        /// <param name="sdes">plugin</param>
1943        public ElectronicCodeBook(SDES sdes)
1944        {
1945            this.mSdes = sdes;
1946            this.mAlgorithm = new SDES_algorithm(sdes);
1947        }
1948
1949        ///
1950        ///Encrypts the given plaintext with the given key
1951        ///using ElectronicCodeBookMode
1952        ///
1953        public void encrypt(CryptoolStream inputstream, CryptoolStream outputstream, byte[] key)
1954        {
1955
1956            byte[] buffer = new byte[1];
1957            int position = 0;
1958
1959            while (!this.mSdes.getStop() && (inputstream.Read(buffer, 0, 1)) > 0)
1960            {
1961                //Step 1 get plaintext symbol
1962                byte symbol = buffer[0]; ;
1963                //Step 2 encrypt symbol
1964                outputstream.Write(Tools.byteArrayToByte(this.mAlgorithm.encrypt(Tools.byteToByteArray(symbol), key)));
1965
1966                if ((int)(inputstream.Position * 100 / inputstream.Length) > position)
1967                {
1968                    position = (int)(inputstream.Position * 100 / inputstream.Length);
1969                    mSdes.ProgressChanged(inputstream.Position, inputstream.Length);
1970                }
1971                outputstream.Flush();
1972
1973            }//end while
1974
1975        }//end encrypt
1976
1977        ///
1978        ///Encrypts the given plaintext with the given key
1979        ///using ElectronicCodeBookMode
1980        ///
1981        /// bytesToUse tells the algorithm how many bytes it has to encrypt
1982        /// bytesToUse = 0 => encrypt all
1983        public byte[] encrypt(byte[] input, byte[] key, [Optional, DefaultParameterValue(0)] int bytesToUse)
1984        {
1985
1986            int until = input.Length;
1987
1988            if(bytesToUse < until && bytesToUse > 0)
1989                until = bytesToUse;
1990
1991            byte[] output = new byte[until];
1992
1993            for(int i=0;i<until;i++)
1994            {               
1995                //Step 2 encrypt symbol
1996                output[i] = Tools.byteArrayToByte(this.mAlgorithm.encrypt(Tools.byteToByteArray(input[i]), key));
1997
1998            }//end while
1999
2000            return output;
2001
2002        }//end encrypt
2003
2004        ///<summary>
2005        ///Decrypts the given plaintext with the given Key
2006        ///using ElectronicCodeBook mode
2007        ///</summary>
2008        public void decrypt(CryptoolStream inputstream, CryptoolStream outputstream, byte[] key)
2009        {
2010
2011            byte[] buffer = new byte[1];
2012            int position = 0;
2013
2014            while (!this.mSdes.getStop() && (inputstream.Read(buffer, 0, 1)) > 0)
2015            {
2016                //Step 1 get plaintext symbol
2017                byte symbol = buffer[0];
2018                //Step 2 encrypt symbol
2019                outputstream.Write(Tools.byteArrayToByte(this.mAlgorithm.decrypt(Tools.byteToByteArray(symbol), key)));
2020
2021                if ((int)(inputstream.Position * 100 / inputstream.Length) > position)
2022                {
2023                    position = (int)(inputstream.Position * 100 / inputstream.Length);
2024                    mSdes.ProgressChanged(inputstream.Position, inputstream.Length);
2025                }
2026                outputstream.Flush();
2027
2028            }//end while
2029
2030        }//end decrypt
2031
2032        ///
2033        ///Decrypt the given plaintext with the given key
2034        ///using ElectronicCodeBookMode
2035        ///
2036        /// bytesToUse tells the algorithm how many bytes it has to decrypt
2037        /// bytesToUse = 0 => encrypt all
2038        public byte[] decrypt(byte[] input, byte[] key, [Optional, DefaultParameterValue(0)] int bytesToUse)
2039        {
2040            int until = input.Length;
2041
2042            if (bytesToUse < until && bytesToUse > 0)
2043                until = bytesToUse;
2044           
2045            byte[] output = new byte[until];
2046
2047            for (int i = 0; i < until; i++)
2048            {
2049                //Step 2 encrypt symbol
2050                output[i] = Tools.byteArrayToByte(this.mAlgorithm.decrypt(Tools.byteToByteArray(input[i]), key));
2051
2052            }//end while
2053
2054            return output;
2055
2056        }//end encrypt
2057
2058    }//end class ElectronicCodeBook
2059
2060}//end namespace Cryptool.Plugins.Cryptography.Encryption
Note: See TracBrowser for help on using the repository browser.