Click here to Skip to main content
15,885,985 members
Articles / Desktop Programming / Windows Forms

Strong and Fast Data Encryption with the CAST-128 Algorithm

Rate me:
Please Sign up or sign in to vote.
4.63/5 (13 votes)
27 May 2006CPOL7 min read 110.7K   3.9K   70  
An effective implementation of the CAST-128 algorithm (ECB and CBC modes).
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Security.Cryptography;
using System.IO;

using Aced.Cryptography;

namespace CastEncryptor_Demo
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		private System.Windows.Forms.Button checkUpButton;
		private System.Windows.Forms.Label testStatusLabel;
		private System.Windows.Forms.Button generateKeyButton;
		private System.Windows.Forms.Label keyLabel;
		private System.Windows.Forms.GroupBox groupBox1;
		private System.Windows.Forms.GroupBox groupBox2;
		private System.Windows.Forms.Button encSourceButton;
		private System.Windows.Forms.Button encDestButton;
		private System.Windows.Forms.Button encProceedButton;
		private System.Windows.Forms.Button decSourceButton;
		private System.Windows.Forms.Button decDestButton;
		private System.Windows.Forms.Button decProceedButton;
		private System.Windows.Forms.Label encStatusLabel;
		private System.Windows.Forms.Label decStatusLabel;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.Label encSourceLabel;
		private System.Windows.Forms.Label encDestLabel;
		private System.Windows.Forms.Label decDestLabel;
		private System.Windows.Forms.Label decSourceLabel;
		private System.Windows.Forms.Label label6;
		private System.Windows.Forms.Label label7;
		private System.Windows.Forms.Label label4;
		private System.Windows.Forms.Label label5;
		private System.Windows.Forms.Label label10;
		private System.Windows.Forms.Label label11;
		private System.Windows.Forms.OpenFileDialog openFileDialog1;
		private System.Windows.Forms.SaveFileDialog saveFileDialog1;
		private System.Windows.Forms.ComboBox encMethodCombo;
		private System.Windows.Forms.ComboBox decMethodCombo;
		private System.Windows.Forms.Label encHashLabel;
		private System.Windows.Forms.Label decHashLabel;
		private System.Windows.Forms.Label label1;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public Form1()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.checkUpButton = new System.Windows.Forms.Button();
			this.testStatusLabel = new System.Windows.Forms.Label();
			this.generateKeyButton = new System.Windows.Forms.Button();
			this.keyLabel = new System.Windows.Forms.Label();
			this.groupBox1 = new System.Windows.Forms.GroupBox();
			this.encHashLabel = new System.Windows.Forms.Label();
			this.label5 = new System.Windows.Forms.Label();
			this.encMethodCombo = new System.Windows.Forms.ComboBox();
			this.label4 = new System.Windows.Forms.Label();
			this.encDestLabel = new System.Windows.Forms.Label();
			this.encSourceLabel = new System.Windows.Forms.Label();
			this.label3 = new System.Windows.Forms.Label();
			this.label2 = new System.Windows.Forms.Label();
			this.encStatusLabel = new System.Windows.Forms.Label();
			this.encProceedButton = new System.Windows.Forms.Button();
			this.encDestButton = new System.Windows.Forms.Button();
			this.encSourceButton = new System.Windows.Forms.Button();
			this.groupBox2 = new System.Windows.Forms.GroupBox();
			this.decHashLabel = new System.Windows.Forms.Label();
			this.label10 = new System.Windows.Forms.Label();
			this.decMethodCombo = new System.Windows.Forms.ComboBox();
			this.label11 = new System.Windows.Forms.Label();
			this.decDestLabel = new System.Windows.Forms.Label();
			this.decSourceLabel = new System.Windows.Forms.Label();
			this.label6 = new System.Windows.Forms.Label();
			this.label7 = new System.Windows.Forms.Label();
			this.decStatusLabel = new System.Windows.Forms.Label();
			this.decProceedButton = new System.Windows.Forms.Button();
			this.decDestButton = new System.Windows.Forms.Button();
			this.decSourceButton = new System.Windows.Forms.Button();
			this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
			this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
			this.label1 = new System.Windows.Forms.Label();
			this.groupBox1.SuspendLayout();
			this.groupBox2.SuspendLayout();
			this.SuspendLayout();
			// 
			// checkUpButton
			// 
			this.checkUpButton.Location = new System.Drawing.Point(24, 16);
			this.checkUpButton.Name = "checkUpButton";
			this.checkUpButton.Size = new System.Drawing.Size(372, 23);
			this.checkUpButton.TabIndex = 0;
			this.checkUpButton.Text = "Check Up The CAST-128 Algorithm With Test Vectors From RFC 2144";
			this.checkUpButton.Click += new System.EventHandler(this.checkUpButton_Click);
			// 
			// testStatusLabel
			// 
			this.testStatusLabel.Location = new System.Drawing.Point(416, 20);
			this.testStatusLabel.Name = "testStatusLabel";
			this.testStatusLabel.Size = new System.Drawing.Size(104, 16);
			this.testStatusLabel.TabIndex = 1;
			this.testStatusLabel.Text = "<status>";
			this.testStatusLabel.TextAlign = System.Drawing.ContentAlignment.TopRight;
			// 
			// generateKeyButton
			// 
			this.generateKeyButton.Location = new System.Drawing.Point(24, 56);
			this.generateKeyButton.Name = "generateKeyButton";
			this.generateKeyButton.Size = new System.Drawing.Size(188, 23);
			this.generateKeyButton.TabIndex = 2;
			this.generateKeyButton.Text = "Use New GUID As Encryption Key";
			this.generateKeyButton.Click += new System.EventHandler(this.generateKeyButton_Click);
			// 
			// keyLabel
			// 
			this.keyLabel.Location = new System.Drawing.Point(300, 60);
			this.keyLabel.Name = "keyLabel";
			this.keyLabel.Size = new System.Drawing.Size(220, 16);
			this.keyLabel.TabIndex = 4;
			this.keyLabel.Text = "00000000-0000-0000-0000-000000000000";
			this.keyLabel.TextAlign = System.Drawing.ContentAlignment.TopRight;
			// 
			// groupBox1
			// 
			this.groupBox1.Controls.Add(this.encHashLabel);
			this.groupBox1.Controls.Add(this.label5);
			this.groupBox1.Controls.Add(this.encMethodCombo);
			this.groupBox1.Controls.Add(this.label4);
			this.groupBox1.Controls.Add(this.encDestLabel);
			this.groupBox1.Controls.Add(this.encSourceLabel);
			this.groupBox1.Controls.Add(this.label3);
			this.groupBox1.Controls.Add(this.label2);
			this.groupBox1.Controls.Add(this.encStatusLabel);
			this.groupBox1.Controls.Add(this.encProceedButton);
			this.groupBox1.Controls.Add(this.encDestButton);
			this.groupBox1.Controls.Add(this.encSourceButton);
			this.groupBox1.Location = new System.Drawing.Point(24, 92);
			this.groupBox1.Name = "groupBox1";
			this.groupBox1.Size = new System.Drawing.Size(496, 128);
			this.groupBox1.TabIndex = 5;
			this.groupBox1.TabStop = false;
			this.groupBox1.Text = "File Encryption";
			// 
			// encHashLabel
			// 
			this.encHashLabel.Location = new System.Drawing.Point(272, 100);
			this.encHashLabel.Name = "encHashLabel";
			this.encHashLabel.Size = new System.Drawing.Size(216, 16);
			this.encHashLabel.TabIndex = 11;
			this.encHashLabel.Text = "<hash value>";
			this.encHashLabel.TextAlign = System.Drawing.ContentAlignment.TopRight;
			// 
			// label5
			// 
			this.label5.Location = new System.Drawing.Point(212, 100);
			this.label5.Name = "label5";
			this.label5.Size = new System.Drawing.Size(60, 16);
			this.label5.TabIndex = 10;
			this.label5.Text = "MD5 Hash:";
			// 
			// encMethodCombo
			// 
			this.encMethodCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
			this.encMethodCombo.Items.AddRange(new object[] {
																"CAST-128",
																"AES-128 (Rijndael)",
																"AES-256 (Rijndael)",
																"TripleDES"});
			this.encMethodCombo.Location = new System.Drawing.Point(68, 96);
			this.encMethodCombo.Name = "encMethodCombo";
			this.encMethodCombo.Size = new System.Drawing.Size(128, 21);
			this.encMethodCombo.TabIndex = 9;
			// 
			// label4
			// 
			this.label4.Location = new System.Drawing.Point(12, 100);
			this.label4.Name = "label4";
			this.label4.Size = new System.Drawing.Size(56, 16);
			this.label4.TabIndex = 8;
			this.label4.Text = "Method:";
			// 
			// encDestLabel
			// 
			this.encDestLabel.Location = new System.Drawing.Point(104, 40);
			this.encDestLabel.Name = "encDestLabel";
			this.encDestLabel.Size = new System.Drawing.Size(388, 16);
			this.encDestLabel.TabIndex = 7;
			this.encDestLabel.Text = "<file name>";
			// 
			// encSourceLabel
			// 
			this.encSourceLabel.Location = new System.Drawing.Point(104, 20);
			this.encSourceLabel.Name = "encSourceLabel";
			this.encSourceLabel.Size = new System.Drawing.Size(388, 16);
			this.encSourceLabel.TabIndex = 6;
			this.encSourceLabel.Text = "<file name>";
			// 
			// label3
			// 
			this.label3.Location = new System.Drawing.Point(12, 40);
			this.label3.Name = "label3";
			this.label3.Size = new System.Drawing.Size(92, 16);
			this.label3.TabIndex = 5;
			this.label3.Text = "Destination File:";
			// 
			// label2
			// 
			this.label2.Location = new System.Drawing.Point(12, 20);
			this.label2.Name = "label2";
			this.label2.Size = new System.Drawing.Size(92, 16);
			this.label2.TabIndex = 4;
			this.label2.Text = "Source File:";
			// 
			// encStatusLabel
			// 
			this.encStatusLabel.Location = new System.Drawing.Point(396, 68);
			this.encStatusLabel.Name = "encStatusLabel";
			this.encStatusLabel.Size = new System.Drawing.Size(92, 16);
			this.encStatusLabel.TabIndex = 3;
			this.encStatusLabel.Text = "<status>";
			this.encStatusLabel.TextAlign = System.Drawing.ContentAlignment.TopRight;
			// 
			// encProceedButton
			// 
			this.encProceedButton.Location = new System.Drawing.Point(276, 64);
			this.encProceedButton.Name = "encProceedButton";
			this.encProceedButton.Size = new System.Drawing.Size(116, 23);
			this.encProceedButton.TabIndex = 2;
			this.encProceedButton.Text = "Perform Encryption";
			this.encProceedButton.Click += new System.EventHandler(this.encProceedButton_Click);
			// 
			// encDestButton
			// 
			this.encDestButton.Location = new System.Drawing.Point(132, 64);
			this.encDestButton.Name = "encDestButton";
			this.encDestButton.Size = new System.Drawing.Size(140, 23);
			this.encDestButton.TabIndex = 1;
			this.encDestButton.Text = "Assign Destination File...";
			this.encDestButton.Click += new System.EventHandler(this.encDestButton_Click);
			// 
			// encSourceButton
			// 
			this.encSourceButton.Location = new System.Drawing.Point(8, 64);
			this.encSourceButton.Name = "encSourceButton";
			this.encSourceButton.Size = new System.Drawing.Size(120, 23);
			this.encSourceButton.TabIndex = 0;
			this.encSourceButton.Text = "Assign Source File...";
			this.encSourceButton.Click += new System.EventHandler(this.encSourceButton_Click);
			// 
			// groupBox2
			// 
			this.groupBox2.Controls.Add(this.decHashLabel);
			this.groupBox2.Controls.Add(this.label10);
			this.groupBox2.Controls.Add(this.decMethodCombo);
			this.groupBox2.Controls.Add(this.label11);
			this.groupBox2.Controls.Add(this.decDestLabel);
			this.groupBox2.Controls.Add(this.decSourceLabel);
			this.groupBox2.Controls.Add(this.label6);
			this.groupBox2.Controls.Add(this.label7);
			this.groupBox2.Controls.Add(this.decStatusLabel);
			this.groupBox2.Controls.Add(this.decProceedButton);
			this.groupBox2.Controls.Add(this.decDestButton);
			this.groupBox2.Controls.Add(this.decSourceButton);
			this.groupBox2.Location = new System.Drawing.Point(24, 236);
			this.groupBox2.Name = "groupBox2";
			this.groupBox2.Size = new System.Drawing.Size(496, 128);
			this.groupBox2.TabIndex = 6;
			this.groupBox2.TabStop = false;
			this.groupBox2.Text = "File Decryption";
			// 
			// decHashLabel
			// 
			this.decHashLabel.Location = new System.Drawing.Point(272, 100);
			this.decHashLabel.Name = "decHashLabel";
			this.decHashLabel.Size = new System.Drawing.Size(216, 16);
			this.decHashLabel.TabIndex = 15;
			this.decHashLabel.Text = "<hash value>";
			this.decHashLabel.TextAlign = System.Drawing.ContentAlignment.TopRight;
			// 
			// label10
			// 
			this.label10.Location = new System.Drawing.Point(212, 100);
			this.label10.Name = "label10";
			this.label10.Size = new System.Drawing.Size(60, 16);
			this.label10.TabIndex = 14;
			this.label10.Text = "MD5 Hash:";
			// 
			// decMethodCombo
			// 
			this.decMethodCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
			this.decMethodCombo.Items.AddRange(new object[] {
																"CAST-128",
																"AES-128 (Rijndael)",
																"AES-256 (Rijndael)",
																"TripleDES"});
			this.decMethodCombo.Location = new System.Drawing.Point(68, 96);
			this.decMethodCombo.Name = "decMethodCombo";
			this.decMethodCombo.Size = new System.Drawing.Size(128, 21);
			this.decMethodCombo.TabIndex = 13;
			// 
			// label11
			// 
			this.label11.Location = new System.Drawing.Point(12, 100);
			this.label11.Name = "label11";
			this.label11.Size = new System.Drawing.Size(56, 16);
			this.label11.TabIndex = 12;
			this.label11.Text = "Method:";
			// 
			// decDestLabel
			// 
			this.decDestLabel.Location = new System.Drawing.Point(104, 40);
			this.decDestLabel.Name = "decDestLabel";
			this.decDestLabel.Size = new System.Drawing.Size(388, 16);
			this.decDestLabel.TabIndex = 11;
			this.decDestLabel.Text = "<file name>";
			// 
			// decSourceLabel
			// 
			this.decSourceLabel.Location = new System.Drawing.Point(104, 20);
			this.decSourceLabel.Name = "decSourceLabel";
			this.decSourceLabel.Size = new System.Drawing.Size(388, 16);
			this.decSourceLabel.TabIndex = 10;
			this.decSourceLabel.Text = "<file name>";
			// 
			// label6
			// 
			this.label6.Location = new System.Drawing.Point(12, 40);
			this.label6.Name = "label6";
			this.label6.Size = new System.Drawing.Size(92, 16);
			this.label6.TabIndex = 9;
			this.label6.Text = "Destination File:";
			// 
			// label7
			// 
			this.label7.Location = new System.Drawing.Point(12, 20);
			this.label7.Name = "label7";
			this.label7.Size = new System.Drawing.Size(92, 16);
			this.label7.TabIndex = 8;
			this.label7.Text = "Source File:";
			// 
			// decStatusLabel
			// 
			this.decStatusLabel.Location = new System.Drawing.Point(396, 68);
			this.decStatusLabel.Name = "decStatusLabel";
			this.decStatusLabel.Size = new System.Drawing.Size(92, 16);
			this.decStatusLabel.TabIndex = 3;
			this.decStatusLabel.Text = "<status>";
			this.decStatusLabel.TextAlign = System.Drawing.ContentAlignment.TopRight;
			// 
			// decProceedButton
			// 
			this.decProceedButton.Location = new System.Drawing.Point(276, 64);
			this.decProceedButton.Name = "decProceedButton";
			this.decProceedButton.Size = new System.Drawing.Size(116, 23);
			this.decProceedButton.TabIndex = 2;
			this.decProceedButton.Text = "Perform Decryption";
			this.decProceedButton.Click += new System.EventHandler(this.decProceedButton_Click);
			// 
			// decDestButton
			// 
			this.decDestButton.Location = new System.Drawing.Point(132, 64);
			this.decDestButton.Name = "decDestButton";
			this.decDestButton.Size = new System.Drawing.Size(140, 23);
			this.decDestButton.TabIndex = 1;
			this.decDestButton.Text = "Assign Destination File...";
			this.decDestButton.Click += new System.EventHandler(this.decDestButton_Click);
			// 
			// decSourceButton
			// 
			this.decSourceButton.Location = new System.Drawing.Point(8, 64);
			this.decSourceButton.Name = "decSourceButton";
			this.decSourceButton.Size = new System.Drawing.Size(120, 23);
			this.decSourceButton.TabIndex = 0;
			this.decSourceButton.Text = "Assign Source File...";
			this.decSourceButton.Click += new System.EventHandler(this.decSourceButton_Click);
			// 
			// openFileDialog1
			// 
			this.openFileDialog1.Filter = "All Files|*.*";
			this.openFileDialog1.Title = "Select The Source File";
			// 
			// saveFileDialog1
			// 
			this.saveFileDialog1.Filter = "All Files|*.*";
			this.saveFileDialog1.Title = "Select The Destination File";
			// 
			// label1
			// 
			this.label1.Location = new System.Drawing.Point(224, 60);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(76, 16);
			this.label1.TabIndex = 7;
			this.label1.Text = "Encrypt. Key:";
			this.label1.TextAlign = System.Drawing.ContentAlignment.TopRight;
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 14);
			this.ClientSize = new System.Drawing.Size(542, 379);
			this.Controls.Add(this.label1);
			this.Controls.Add(this.groupBox2);
			this.Controls.Add(this.groupBox1);
			this.Controls.Add(this.keyLabel);
			this.Controls.Add(this.generateKeyButton);
			this.Controls.Add(this.testStatusLabel);
			this.Controls.Add(this.checkUpButton);
			this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204)));
			this.MaximizeBox = false;
			this.Name = "Form1";
			this.Text = "CastEncryptor Test Application";
			this.Load += new System.EventHandler(this.Form1_Load);
			this.groupBox1.ResumeLayout(false);
			this.groupBox2.ResumeLayout(false);
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new Form1());
		}

		public static void ChangeEndian(byte[] bytes)
		{
			int index = 0;
			while (index < bytes.Length)
			{
				byte b = bytes[index];
				bytes[index] = bytes[index + 3];
				bytes[index + 3] = b;
				b = bytes[index + 1];
				bytes[index + 1] = bytes[index + 2];
				bytes[index + 2] = b;
				index += 4;
			}
		}

		private void AssertEquals(byte[] x, byte[] vector)
		{
			for (int i = 0; i < vector.Length; i++)
				if (x[i] != vector[i])
					throw new Exception("Test Failed !");
		}

		private void SimpleTest()
		{
			byte[] key = new byte[]
			{
				0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
				0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A
			};
			byte[] plaintext = new byte[]
			{
				0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
			};
			ChangeEndian(key);
			int[] scheduledKey = AcedCast5.ScheduleKey(key);
			byte[] ct = (byte[])plaintext.Clone();
			ChangeEndian(ct);
			AcedCast5.EncryptECB(scheduledKey, ct, 0);
			ChangeEndian(ct);
			AssertEquals(ct, new byte[]
			{
				0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2
			});
			byte[] dt = (byte[])ct.Clone();
			ChangeEndian(dt);
			AcedCast5.DecryptECB(scheduledKey, dt, 0);
			ChangeEndian(dt);
			AssertEquals(dt, new byte[]
			{
				0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
			});
			testStatusLabel.Text = "< 1 test passed >";
			MessageBox.Show("Single Plaintext-Key-Ciphertext Test passed successfully.",
				"CAST-128 Algorithm Tests");
		}

		private void FullTest()
		{
			testStatusLabel.Text = "Please wait...";
			Application.DoEvents();
			byte[] a = new byte[]
			{
				0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
				0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A
			};
			byte[] b = new byte[]
			{
				0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
				0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A
			};
			int[] key = new int[32];
			ChangeEndian(a);
			ChangeEndian(b);
			long L = DateTime.UtcNow.Ticks;
			for (int i = 0; i < 1000000; i++)
			{
				AcedCast5.ScheduleKey(b, key);
				AcedCast5.EncryptECB(key, a, 0);
				AcedCast5.EncryptECB(key, a, 8);
				AcedCast5.ScheduleKey(a, key);
				AcedCast5.EncryptECB(key, b, 0);
				AcedCast5.EncryptECB(key, b, 8);
			}
			L = (DateTime.UtcNow.Ticks - L) / 10000;
			ChangeEndian(a);
			ChangeEndian(b);
			AssertEquals(a, new byte[]
			{
				0xEE, 0xA9, 0xD0, 0xA2, 0x49, 0xFD, 0x3B, 0xA6,
				0xB3, 0x43, 0x6F, 0xB8, 0x9D, 0x6D, 0xCA, 0x92
			});
			AssertEquals(b, new byte[]
			{
				0xB2, 0xC9, 0x5E, 0xB0, 0x0C, 0x31, 0xAD, 0x71,
				0x80, 0xAC, 0x05, 0xB8, 0xE8, 0x3D, 0x69, 0x6E
			});
			testStatusLabel.Text = "< 2 tests passed >";
			MessageBox.Show("Full Maintenance Encryption Test passed in " + L.ToString() + " ms.",
				"CAST-128 Algorithm Tests");
			testStatusLabel.Text = "Please wait...";
			Application.DoEvents();
			ChangeEndian(a);
			ChangeEndian(b);
			L = DateTime.UtcNow.Ticks;
			for (int i = 0; i < 1000000; i++)
			{
				AcedCast5.ScheduleKey(a, key);
				AcedCast5.DecryptECB(key, b, 8);
				AcedCast5.DecryptECB(key, b, 0);
				AcedCast5.ScheduleKey(b, key);
				AcedCast5.DecryptECB(key, a, 8);
				AcedCast5.DecryptECB(key, a, 0);
			}
			L = (DateTime.UtcNow.Ticks - L) / 10000;
			ChangeEndian(a);
			ChangeEndian(b);
			AssertEquals(a, new byte[]
			{
				0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
				0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A
			});
			AssertEquals(b, a);
			testStatusLabel.Text = "< 3 tests passed >";
			MessageBox.Show("Full Maintenance Decryption Test passed in " + L.ToString() + " ms.",
				"CAST-128 Algorithm Tests");
		}

		private void checkUpButton_Click(object sender, System.EventArgs e)
		{
			SimpleTest();
			FullTest();
		}

		private Guid _key = Guid.Empty;
		private string _encSourceFileName;
		private string _encDestFileName;
		private string _decSourceFileName;
		private string _decDestFileName;

		private void EncryptCAST()
		{
			encStatusLabel.Text = "Please wait...";
			Application.DoEvents();

			long L = DateTime.UtcNow.Ticks;
			FileStream inFile = new FileStream(_encSourceFileName, FileMode.Open, FileAccess.Read);
			FileStream outFile = new FileStream(_encDestFileName, FileMode.Create, FileAccess.Write);
			byte[] buffer = new byte[0x40000];
			long x = inFile.Length;
			outFile.WriteByte(99); // a format check mark
			outFile.WriteByte((byte)x);
			outFile.WriteByte((byte)(x >> 8));
			outFile.WriteByte((byte)(x >> 16));
			outFile.WriteByte((byte)(x >> 24));
			outFile.WriteByte((byte)(x >> 32));

			int[] schKey = AcedCast5.ScheduleKey(_key.ToByteArray());
			long iv = AcedCast5.GetOrdinaryIV(schKey);
			while (x >= 0x40000)
			{
				inFile.Read(buffer, 0, 0x40000);
				iv = AcedCast5.EncryptCBC(schKey, buffer, 0, 0x40000, iv);
				outFile.Write(buffer, 0, 0x40000);
				x -= 0x40000;
			}
			if (x > 0)
			{
				int len = (int)x;
				inFile.Read(buffer, 0, len);
				while ((len & 7) != 0)
				{
					buffer[len] = 0;
					len++;
				}
				AcedCast5.EncryptCBC(schKey, buffer, 0, len, iv);
				outFile.Write(buffer, 0, len);
			}
			outFile.Close();
			inFile.Close();
			L = (DateTime.UtcNow.Ticks - L) / 10000;

			encStatusLabel.Text = "Done in " + L.ToString() + " ms.";
		}

		private void DecryptCAST()
		{
			decStatusLabel.Text = "Please wait...";
			Application.DoEvents();

			long L = DateTime.UtcNow.Ticks;
			FileStream inFile = new FileStream(_decSourceFileName, FileMode.Open, FileAccess.Read);
			if (inFile.ReadByte() != 99)
			{
				decStatusLabel.Text = "Wrong File !";
				inFile.Close();
				return;
			}
			long x = inFile.ReadByte();
			x |= ((long)inFile.ReadByte()) << 8;
			x |= ((long)inFile.ReadByte()) << 16;
			x |= ((long)inFile.ReadByte()) << 24;
			x |= ((long)inFile.ReadByte()) << 32;

			FileStream outFile = new FileStream(_decDestFileName, FileMode.Create, FileAccess.Write);
			byte[] buffer = new byte[0x40000];

			int[] schKey = AcedCast5.ScheduleKey(_key.ToByteArray());
			long iv = AcedCast5.GetOrdinaryIV(schKey);
			while (x >= 0x40000)
			{
				inFile.Read(buffer, 0, 0x40000);
				iv = AcedCast5.DecryptCBC(schKey, buffer, 0, 0x40000, iv);
				outFile.Write(buffer, 0, 0x40000);
				x -= 0x40000;
			}
			if (x > 0)
			{
				int len = ((int)x + 7) & 0x3FFF8;
				inFile.Read(buffer, 0, len);
				AcedCast5.DecryptCBC(schKey, buffer, 0, len, iv);
				outFile.Write(buffer, 0, (int)x);
			}
			outFile.Close();
			inFile.Close();
			L = (DateTime.UtcNow.Ticks - L) / 10000;

			decHashLabel.Text = GetFileHash(_decDestFileName);
			decStatusLabel.Text = "Done in " + L.ToString() + " ms.";
		}

		private byte[] _lastKey;
		private byte[] _lastIV;

		private void EncryptAES(int keySize)
		{
			encStatusLabel.Text = "Please wait...";
			Application.DoEvents();

			RijndaelManaged myRijndael = new RijndaelManaged();
			myRijndael.KeySize = keySize;
			myRijndael.GenerateKey();
			myRijndael.GenerateIV();
			_lastKey = myRijndael.Key;
			_lastIV = myRijndael.IV;

			long L = DateTime.UtcNow.Ticks;
			FileStream inFile = new FileStream(_encSourceFileName, FileMode.Open, FileAccess.Read);
			FileStream outFile = new FileStream(_encDestFileName, FileMode.Create, FileAccess.Write);

			long x = inFile.Length;
			outFile.WriteByte(99); // a format check mark
			outFile.WriteByte((byte)x);
			outFile.WriteByte((byte)(x >> 8));
			outFile.WriteByte((byte)(x >> 16));
			outFile.WriteByte((byte)(x >> 24));
			outFile.WriteByte((byte)(x >> 32));

			ICryptoTransform encryptor = myRijndael.CreateEncryptor(_lastKey, _lastIV);
			CryptoStream csEncrypt = new CryptoStream(outFile, encryptor, CryptoStreamMode.Write);
			byte[] buffer = new byte[0x40000];
			while (x >= 0x40000)
			{
				inFile.Read(buffer, 0, 0x40000);
				csEncrypt.Write(buffer, 0, 0x40000);
				x -= 0x40000;
			}
			if (x > 0)
			{
				inFile.Read(buffer, 0, (int)x);
				csEncrypt.Write(buffer, 0, (int)x);
			}
			csEncrypt.FlushFinalBlock();
			csEncrypt.Close();
			outFile.Close();
			inFile.Close();
			L = (DateTime.UtcNow.Ticks - L) / 10000;
			myRijndael.Clear();

			encStatusLabel.Text = "Done in " + L.ToString() + " ms.";
		}

		private void DecryptAES(int keySize)
		{
			decStatusLabel.Text = "Please wait...";
			Application.DoEvents();

			RijndaelManaged myRijndael = new RijndaelManaged();
			myRijndael.KeySize = keySize;

			long L = DateTime.UtcNow.Ticks;
			FileStream inFile = new FileStream(_decSourceFileName, FileMode.Open, FileAccess.Read);
			if (inFile.ReadByte() != 99)
			{
				decStatusLabel.Text = "Wrong File !";
				inFile.Close();
				return;
			}
			long x = inFile.ReadByte();
			x |= ((long)inFile.ReadByte()) << 8;
			x |= ((long)inFile.ReadByte()) << 16;
			x |= ((long)inFile.ReadByte()) << 24;
			x |= ((long)inFile.ReadByte()) << 32;

			ICryptoTransform decryptor = myRijndael.CreateDecryptor(_lastKey, _lastIV);
			CryptoStream csDecrypt = new CryptoStream(inFile, decryptor, CryptoStreamMode.Read);

			FileStream outFile = new FileStream(_decDestFileName, FileMode.Create, FileAccess.Write);
			byte[] buffer = new byte[0x40000];

			int[] schKey = AcedCast5.ScheduleKey(_key.ToByteArray());
			long iv = AcedCast5.GetOrdinaryIV(schKey);
			while (x >= 0x40000)
			{
				csDecrypt.Read(buffer, 0, 0x40000);
				outFile.Write(buffer, 0, 0x40000);
				x -= 0x40000;
			}
			if (x > 0)
			{
				csDecrypt.Read(buffer, 0, (int)x);
				outFile.Write(buffer, 0, (int)x);
			}
			csDecrypt.Close();
			outFile.Close();
			inFile.Close();
			L = (DateTime.UtcNow.Ticks - L) / 10000;
			myRijndael.Clear();

			decHashLabel.Text = GetFileHash(_decDestFileName);
			decStatusLabel.Text = "Done in " + L.ToString() + " ms.";
		}

		private void EncryptTripleDES()
		{
			encStatusLabel.Text = "Please wait...";
			Application.DoEvents();

			TripleDESCryptoServiceProvider myTripleDES = new TripleDESCryptoServiceProvider();
			myTripleDES.GenerateKey();
			myTripleDES.GenerateIV();
			_lastKey = myTripleDES.Key;
			_lastIV = myTripleDES.IV;

			long L = DateTime.UtcNow.Ticks;
			FileStream inFile = new FileStream(_encSourceFileName, FileMode.Open, FileAccess.Read);
			FileStream outFile = new FileStream(_encDestFileName, FileMode.Create, FileAccess.Write);

			long x = inFile.Length;
			outFile.WriteByte(99); // a format check mark
			outFile.WriteByte((byte)x);
			outFile.WriteByte((byte)(x >> 8));
			outFile.WriteByte((byte)(x >> 16));
			outFile.WriteByte((byte)(x >> 24));
			outFile.WriteByte((byte)(x >> 32));

			ICryptoTransform encryptor = myTripleDES.CreateEncryptor(_lastKey, _lastIV);
			CryptoStream csEncrypt = new CryptoStream(outFile, encryptor, CryptoStreamMode.Write);
			byte[] buffer = new byte[0x40000];
			while (x >= 0x40000)
			{
				inFile.Read(buffer, 0, 0x40000);
				csEncrypt.Write(buffer, 0, 0x40000);
				x -= 0x40000;
			}
			if (x > 0)
			{
				inFile.Read(buffer, 0, (int)x);
				csEncrypt.Write(buffer, 0, (int)x);
			}
			csEncrypt.FlushFinalBlock();
			csEncrypt.Close();
			outFile.Close();
			inFile.Close();
			L = (DateTime.UtcNow.Ticks - L) / 10000;
			myTripleDES.Clear();

			encStatusLabel.Text = "Done in " + L.ToString() + " ms.";
		}

		private void DecryptTripleDES()
		{
			decStatusLabel.Text = "Please wait...";
			Application.DoEvents();

			TripleDESCryptoServiceProvider myTripleDES = new TripleDESCryptoServiceProvider();

			long L = DateTime.UtcNow.Ticks;
			FileStream inFile = new FileStream(_decSourceFileName, FileMode.Open, FileAccess.Read);
			if (inFile.ReadByte() != 99)
			{
				decStatusLabel.Text = "Wrong File !";
				inFile.Close();
				return;
			}
			long x = inFile.ReadByte();
			x |= ((long)inFile.ReadByte()) << 8;
			x |= ((long)inFile.ReadByte()) << 16;
			x |= ((long)inFile.ReadByte()) << 24;
			x |= ((long)inFile.ReadByte()) << 32;

			ICryptoTransform decryptor = myTripleDES.CreateDecryptor(_lastKey, _lastIV);
			CryptoStream csDecrypt = new CryptoStream(inFile, decryptor, CryptoStreamMode.Read);

			FileStream outFile = new FileStream(_decDestFileName, FileMode.Create, FileAccess.Write);
			byte[] buffer = new byte[0x40000];

			int[] schKey = AcedCast5.ScheduleKey(_key.ToByteArray());
			long iv = AcedCast5.GetOrdinaryIV(schKey);
			while (x >= 0x40000)
			{
				csDecrypt.Read(buffer, 0, 0x40000);
				outFile.Write(buffer, 0, 0x40000);
				x -= 0x40000;
			}
			if (x > 0)
			{
				csDecrypt.Read(buffer, 0, (int)x);
				outFile.Write(buffer, 0, (int)x);
			}
			csDecrypt.Close();
			outFile.Close();
			inFile.Close();
			L = (DateTime.UtcNow.Ticks - L) / 10000;
			myTripleDES.Clear();

			decHashLabel.Text = GetFileHash(_decDestFileName);
			decStatusLabel.Text = "Done in " + L.ToString() + " ms.";
		}

		private string GetFileHash(string fileName)
		{
			FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
			MD5 md5 = new MD5CryptoServiceProvider();
			byte[] hash = md5.ComputeHash(fs);
			fs.Close();
			md5.Clear();
			return (new Guid(hash)).ToString();
		}

		private void generateKeyButton_Click(object sender, System.EventArgs e)
		{
			_key = Guid.NewGuid();
			keyLabel.Text = _key.ToString();
		}

		private void encSourceButton_Click(object sender, System.EventArgs e)
		{
			if (openFileDialog1.ShowDialog() == DialogResult.OK)
			{
				_encSourceFileName = openFileDialog1.FileName;
				encSourceLabel.Text = _encSourceFileName;
				encHashLabel.Text = GetFileHash(_encSourceFileName);
			}
		}

		private void encDestButton_Click(object sender, System.EventArgs e)
		{
			if (saveFileDialog1.ShowDialog() == DialogResult.OK)
			{
				_encDestFileName = saveFileDialog1.FileName;
				encDestLabel.Text = _encDestFileName;
			}
		}

		private void decSourceButton_Click(object sender, System.EventArgs e)
		{
			if (openFileDialog1.ShowDialog() == DialogResult.OK)
			{
				_decSourceFileName = openFileDialog1.FileName;
				decSourceLabel.Text = _decSourceFileName;
			}
		}

		private void decDestButton_Click(object sender, System.EventArgs e)
		{
			if (saveFileDialog1.ShowDialog() == DialogResult.OK)
			{
				_decDestFileName = saveFileDialog1.FileName;
				decDestLabel.Text = _decDestFileName;
			}
		}

		private void encProceedButton_Click(object sender, System.EventArgs e)
		{
			if (_encSourceFileName != null && _encDestFileName != null)
				switch (encMethodCombo.SelectedIndex)
				{
					case 0:
						EncryptCAST();
						break;
					case 1:
						EncryptAES(128);
						break;
					case 2:
						EncryptAES(256);
						break;
					case 3:
						EncryptTripleDES();
						break;
				}
		}

		private void decProceedButton_Click(object sender, System.EventArgs e)
		{
			if (_decSourceFileName != null && _decDestFileName != null)
				switch (decMethodCombo.SelectedIndex)
				{
					case 0:
						DecryptCAST();
						break;
					case 1:
						DecryptAES(128);
						break;
					case 2:
						DecryptAES(256);
						break;
					case 3:
						DecryptTripleDES();
						break;
				}
		}

		private void Form1_Load(object sender, System.EventArgs e)
		{
			encMethodCombo.SelectedIndex = 0;
			decMethodCombo.SelectedIndex = 0;
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Russian Federation Russian Federation
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions