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

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

keysearcher opencl fix

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