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

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

Added code to generate openCL bruteforce code in KeySearcher.
Not used yet, so don't try it

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