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

Last change on this file since 1157 was 1157, checked in by Arno Wacker, 12 years ago

AnotherEditor

  • Yet another Invoke during a single log message changed into BeginInvoke

IControlEncryption

  • Removed obsolete signature

CryptoolStream

  • Added a try-catch when deleting a file. An exception occurs when the file is locked. Clearly, in this case there not much one can do.. the file remains on the disk. Waiting for CStream...

AES, DES, SDES

  • Cleanup of IControl interface and general code cleanup
  • Fixed compatibility with KeySearcher - now all three should work again. (However, kind of slow)

StreamToStringConverter

  • Updated license

Sample update

  • KeySearcher-Sample-DES.cte, KeySearcher-Sample-DES.cte, KeySearcher-Sample-SDES.cte: Compatibility with IControl changes and slight rearrangement.
  • P2P-DES-BruteforceManger.cte, P2P-DES-BruteforceWorker.cte: Compatibility

New binaries

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