dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnetlib/tests/runtime/System/Security/Cryptog


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnetlib/tests/runtime/System/Security/Cryptography CryptoTestCase.cs,NONE,1.1 Makefile,NONE,1.1 TestAES.cs,NONE,1.1 TestCryptography.cs,NONE,1.1 TestDES.cs,NONE,1.1 TestMD5.cs,NONE,1.1 TestRC2.cs,NONE,1.1 TestSHA1.cs,NONE,1.1 TestSHA256.cs,NONE,1.1 TestSHA384.cs,NONE,1.1 TestSHA512.cs,NONE,1.1 TestTripleDES.cs,NONE,1.1
Date: Thu, 21 Nov 2002 19:17:51 -0500

Update of 
/cvsroot/dotgnu-pnet/pnetlib/tests/runtime/System/Security/Cryptography
In directory 
subversions:/tmp/cvs-serv21403/tests/runtime/System/Security/Cryptography

Added Files:
        CryptoTestCase.cs Makefile TestAES.cs TestCryptography.cs 
        TestDES.cs TestMD5.cs TestRC2.cs TestSHA1.cs TestSHA256.cs 
        TestSHA384.cs TestSHA512.cs TestTripleDES.cs 
Log Message:


Test the behaviour of some of the cryptographic algorithms.


--- NEW FILE ---
/*
 * CryptoTestCase.cs - encapsulate a cryptographic algorithm test case.
 *
 * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using CSUnit;
using System;
using System.Reflection;
using System.Text;
using System.Security.Cryptography;

public class CryptoTestCase : TestCase
{

        // Constructor.
        public CryptoTestCase(String name)
                        : base(name)
                        {
                                // Nothing to do here.  
                        }

        // Set up for the tests.
        protected override void Setup()
                        {
                                // Nothing to do here.
                        }

        // Clean up after the tests.
        protected override void Cleanup()
                        {
                                // Nothing to do here.
                        }
        
        // Determine if two byte blocks are identical.
        public static bool IdenticalBlock(byte[] block1, int offset1,
                                                                          
byte[] block2, int offset2,
                                                                          int 
length)
                        {
                                while(length > 0)
                                {
                                        if(block1[offset1++] != 
block2[offset2++])
                                        {
                                                return false;
                                        }
                                        --length;
                                }
                                return true;
                        }

        // Run a symmetric algorithm test.
        protected void RunSymmetric(SymmetricAlgorithm alg, byte[] key,
                                                                byte[] 
plaintext, byte[] expected)
                        {
                                // Set up the algorithm the way we want.
                                alg.Mode = CipherMode.ECB;
                                alg.Padding = PaddingMode.None;

                                // Create an encryptor and run the test 
forwards.
                                ICryptoTransform encryptor = 
alg.CreateEncryptor(key, null);
                                byte[] output = new byte [plaintext.Length * 2];
                                byte[] tail;
                                int len = encryptor.TransformBlock
                                                (plaintext, 0, plaintext.Length,
                                                 output, 0);
                                AssertEquals("ECB encrypt length mismatch",
                                                         len, expected.Length);
                                tail = encryptor.TransformFinalBlock
                                                (plaintext, 0, 0);
                                AssertNotNull("ECB encrypt tail should be 
non-null");
                                AssertEquals("ECB encrypt tail should be zero 
length",
                                                         tail.Length, 0);
                                if(!IdenticalBlock(expected, 0, output, 0,
                                                                   
expected.Length))
                                {
                                        Fail("did not encrypt to the expected 
output");
                                }

                                // Create a decryptor and run the test 
backwards.
                                ICryptoTransform decryptor = 
alg.CreateDecryptor(key, null);
                                len = decryptor.TransformBlock
                                                (expected, 0, expected.Length, 
output, 0);
                                AssertEquals("ECB decrypt length mismatch",
                                                         len, expected.Length);
                                tail = decryptor.TransformFinalBlock
                                                (expected, 0, 0);
                                AssertNotNull("ECB decrypt tail should be 
non-null");
                                AssertEquals("ECB decrypt tail should be zero 
length",
                                                         tail.Length, 0);
                                if(!IdenticalBlock(plaintext, 0, output, 0,
                                                                   
plaintext.Length))
                                {
                                        Fail("did not decrypt to the original 
plaintext");
                                }
                        }
        protected void RunSymmetric(String name, byte[] key,
                                                                byte[] 
plaintext, byte[] expected)
                        {
                                int index = name.IndexOf(':');
                                if(index != -1)
                                {
                                        // Use the default algorithm.
                                        Type type = 
Type.GetType("System.Security.Cryptography." +
                                                                                
         name.Substring(0, index),
                                                                                
         false, false);
                                        Object[] args;
                                        if((index + 1) < name.Length)
                                        {
                                                args = new Object [1];
                                                args[0] = name.Substring(index 
+ 1);
                                        }
                                        else
                                        {
                                                args = new Object [0];
                                        }
                                        SymmetricAlgorithm alg = 
(SymmetricAlgorithm)
                                                (type.InvokeMember("Create",
                                                                                
   BindingFlags.DeclaredOnly |
                                                                                
   BindingFlags.Static |
                                                                                
   BindingFlags.Public |
                                                                                
   BindingFlags.InvokeMethod,
                                                                                
   null, null, args));
                                        AssertEquals("default key size is 
wrong",
                                                     alg.KeySize, key.Length * 
8);
                                        RunSymmetric(alg, key, plaintext, 
expected);
                                }
                                else
                                {
                                        // Use the specified algorithm.
                                        
RunSymmetric(SymmetricAlgorithm.Create(name), key,
                                                                 plaintext, 
expected);
                                }
                        }

        // Run a hash algorithm test.
        protected void RunHash(HashAlgorithm alg, String value, byte[] expected)
                        {
                                // Make sure that the hash size is what we 
expect.
                                AssertEquals("hash size is incorrect",
                                                         alg.HashSize, 
expected.Length * 8);

                                // Convert the string form of the input into a 
byte array.
                                byte[] input = Encoding.ASCII.GetBytes(value);

                                // Get the hash value over the input.
                                byte[] hash = alg.ComputeHash(input);

                                // Compare the hash with the expected value.
                                AssertNotNull("returned hash was null", hash);
                                AssertEquals("hash length is wrong", 
hash.Length,
                                                         expected.Length);
                                if(!IdenticalBlock(hash, 0, expected, 0, 
expected.Length))
                                {
                                        Fail("incorrect hash value produced");
                                }
                        }
        protected void RunHash(String name, String value, byte[] expected)
                        {
                                int index = name.IndexOf(':');
                                if(index != -1)
                                {
                                        // Use the default algorithm.
                                        Type type = 
Type.GetType("System.Security.Cryptography." +
                                                                                
         name.Substring(0, index),
                                                                                
         false, false);
                                        Object[] args;
                                        if((index + 1) < name.Length)
                                        {
                                                args = new Object [1];
                                                args[0] = name.Substring(index 
+ 1);
                                        }
                                        else
                                        {
                                                args = new Object [0];
                                        }
                                        HashAlgorithm alg = (HashAlgorithm)
                                                (type.InvokeMember("Create",
                                                                                
   BindingFlags.DeclaredOnly |
                                                                                
   BindingFlags.Static |
                                                                                
   BindingFlags.Public |
                                                                                
   BindingFlags.InvokeMethod,
                                                                                
   null, null, args));
                                        RunHash(alg, value, expected);
                                }
                                else
                                {
                                        // Use the specified algorithm.
                                        RunHash(HashAlgorithm.Create(name), 
value, expected);
                                }
                        }

}; // CryptoTestCase

--- NEW FILE ---

all:
        (cd ../../..;make)

check:
        (cd ../../..;make check)

--- NEW FILE ---
/*
 * TestAES.cs - Test the AES algorithm.
 *
 * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using CSUnit;
using System;
using System.Security.Cryptography;

public class TestAES : CryptoTestCase
{

        // Constructor.
        public TestAES(String name)
                        : base(name)
                        {
                                // Nothing to do here.  
                        }

        // 128-bit test vectors.
        private static readonly byte[] aes128Key =
                {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
        private static readonly byte[] aes128Plaintext =
                {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
                 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
        private static readonly byte[] aes128Expected =
                {0x69, 0xC4, 0xE0, 0xD8, 0x6A, 0x7B, 0x04, 0x30,
                 0xD8, 0xCD, 0xB7, 0x80, 0x70, 0xB4, 0xC5, 0x5A};

        // 192-bit test vectors.
        private static readonly byte[] aes192Key =
                {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
                 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
        private static readonly byte[] aes192Plaintext =
                {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
                 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
        private static readonly byte[] aes192Expected =
                {0xDD, 0xA9, 0x7C, 0xA4, 0x86, 0x4C, 0xDF, 0xE0,
                 0x6E, 0xAF, 0x70, 0xA0, 0xEC, 0x0D, 0x71, 0x91};

        // 256-bit test vectors.
        private static readonly byte[] aes256Key =
                {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
                 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
                 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
        private static readonly byte[] aes256Plaintext =
                {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
                 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
        private static readonly byte[] aes256Expected =
                {0x8E, 0xA2, 0xB7, 0xCA, 0x51, 0x67, 0x45, 0xBF,
                 0xEA, 0xFC, 0x49, 0x90, 0x4B, 0x49, 0x60, 0x89};

        // Test the default AES implementation.
        public void TestAESDefault()
                        {
                                RunSymmetric("Rijndael:", aes128Key, 
aes128Plaintext,
                                                         aes128Expected);
                        }

        // Test a 128-bit key.
        public void TestAES128()
                        {
                                RunSymmetric("Rijndael", aes128Key,
                                                         aes128Plaintext, 
aes128Expected);
                        }

        // Test a 192-bit key.
        public void TestAES192()
                        {
                                RunSymmetric("Rijndael", aes192Key,
                                                         aes192Plaintext, 
aes192Expected);
                        }

        // Test a 256-bit key.
        public void TestAES256()
                        {
                                RunSymmetric("Rijndael", aes256Key,
                                                         aes256Plaintext, 
aes256Expected);
                        }

        // Test that the algorithm specific class cannot return
        // an object of another algorithm.
        public void TestAESCreateOther()
                        {
                                try
                                {
                                        Rijndael.Create("DES");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                        }

}; // TestAES

--- NEW FILE ---
/*
 * TestCryptography.cs - Tests for the "System.Security.Cryptography" namespace.
 *
 * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using CSUnit;
using System;

public class TestCryptography
{

        public static TestSuite Suite()
                        {
                                TestSuite suite = new TestSuite("Cryptography 
Tests");
                                suite.AddTests(typeof(TestAES));
                                suite.AddTests(typeof(TestDES));
                                suite.AddTests(typeof(TestRC2));
                                suite.AddTests(typeof(TestTripleDES));
                                suite.AddTests(typeof(TestMD5));
                                suite.AddTests(typeof(TestSHA1));
                                suite.AddTests(typeof(TestSHA256));
                                suite.AddTests(typeof(TestSHA384));
                                suite.AddTests(typeof(TestSHA512));
                                return suite;
                        }

}; // class TestCryptography

--- NEW FILE ---
/*
 * TestDES.cs - Test the DES algorithm.
 *
 * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using CSUnit;
using System;
using System.Security.Cryptography;

public class TestDES : CryptoTestCase
{

        // Constructor.
        public TestDES(String name)
                        : base(name)
                        {
                                // Nothing to do here.  
                        }

        // First test vector.
        private static readonly byte[] desKey1 =
                {0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A};
        private static readonly byte[] desPlaintext1 =
                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        private static readonly byte[] desExpected1 =
                {0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02};

        // Second test vector.
        private static readonly byte[] desKey2 =
                {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
        private static readonly byte[] desPlaintext2 =
                {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        private static readonly byte[] desExpected2 =
                {0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00};

        // Third test vector.
        private static readonly byte[] desKey3 =
                {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
        private static readonly byte[] desPlaintext3 =
                {0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        private static readonly byte[] desExpected3 =
                {0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19};

        // Fourth test vector.
        private static readonly byte[] desKey4 =
                {0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
        private static readonly byte[] desPlaintext4 =
                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        private static readonly byte[] desExpected4 =
                {0x95, 0xA8, 0xD7, 0x28, 0x13, 0xDA, 0xA9, 0x4D};

        // Fifth test vector.
        private static readonly byte[] desKey5 =
                {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
        private static readonly byte[] desPlaintext5 =
                {0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74};
        private static readonly byte[] desExpected5 =
                {0x3f, 0xa4, 0x0e, 0x8a, 0x98, 0x4d, 0x48, 0x15};

        // Test the default DES implementation.
        public void TestDESDefault()
                        {
                                RunSymmetric("DES:", desKey1, desPlaintext1,
                                                         desExpected1);
                        }

        // Test the various key vectors.
        public void TestDESKey1()
                        {
                                RunSymmetric("DES", desKey1, desPlaintext1,
                                                         desExpected1);
                        }
        public void TestDESKey2()
                        {
                                RunSymmetric("DES", desKey2, desPlaintext2,
                                                         desExpected2);
                        }
        public void TestDESKey3()
                        {
                                RunSymmetric("DES", desKey3, desPlaintext3,
                                                         desExpected3);
                        }
        public void TestDESKey4()
                        {
                                RunSymmetric("DES", desKey4, desPlaintext4,
                                                         desExpected4);
                        }
        public void TestDESKey5()
                        {
                                RunSymmetric("DES", desKey5, desPlaintext5,
                                                         desExpected5);
                        }

        // Test that the algorithm specific class cannot return
        // an object of another algorithm.
        public void TestDESCreateOther()
                        {
                                try
                                {
                                        DES.Create("RC2");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                                try
                                {
                                        DES.Create("TripleDES");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                        }

        // Check that a key is weak.
        private void CheckWeak(String name, byte[] key)
                        {
                                if(!DES.IsWeakKey(key))
                                {
                                        Fail(name + ": key wasn't recognized as 
weak");
                                }
                                DES alg = DES.Create();
                                try
                                {
                                        alg.Key = key;
                                        Fail(name + ": key was supposed to be 
detected as weak");
                                }
                                catch(CryptographicException)
                                {
                                        // Success
                                }
                        }

        // Check that a key is non-weak.
        private void CheckNonWeak(String name, byte[] key)
                        {
                                CheckNonWeak(name, key, false);
                        }
        private void CheckNonWeak(String name, byte[] key, bool suppressCreate)
                        {
                                if(DES.IsWeakKey(key))
                                {
                                        Fail(name + "key was recognized as 
weak");
                                }
                                if(!suppressCreate)
                                {
                                        DES alg = DES.Create();
                                        try
                                        {
                                                alg.Key = key;
                                        }
                                        catch(CryptographicException)
                                        {
                                                Fail(name +
                                                         ": key was not 
supposed to be detected as weak");
                                        }
                                }
                        }

        // Check that a key is semi-weak.
        private void CheckSemiWeak(String name, byte[] key)
                        {
                                if(!DES.IsSemiWeakKey(key))
                                {
                                        Fail(name + ": key wasn't recognized as 
semi-weak");
                                }
                                DES alg = DES.Create();
                                try
                                {
                                        alg.Key = key;
                                        Fail(name +
                                                 ": key was supposed to be 
detected as semi-weak");
                                }
                                catch(CryptographicException)
                                {
                                        // Success
                                }
                        }

        // Check that a key is non-semi-weak.
        private void CheckNonSemiWeak(String name, byte[] key)
                        {
                                CheckNonSemiWeak(name, key, false);
                        }
        private void CheckNonSemiWeak(String name, byte[] key, bool 
suppressCreate)
                        {
                                if(DES.IsSemiWeakKey(key))
                                {
                                        Fail(name + "key was recognized as 
semi-weak");
                                }
                                if(!suppressCreate)
                                {
                                        DES alg = DES.Create();
                                        try
                                        {
                                                alg.Key = key;
                                        }
                                        catch(CryptographicException)
                                        {
                                                Fail(name +
                                                 ": key was not supposed to be 
detected as semi-weak");
                                        }
                                }
                        }

        // Test for weak and semi-weak keys.
        public void TestDESWeak()
                        {
                                // These keys are weak.
                                CheckWeak("weak1", new byte[]
                                        {0x01, 0x01, 0x01, 0x01,  0x01, 0x01, 
0x01, 0x01});
                                CheckWeak("weak2", new byte[]
                                        {0x1F, 0x1F, 0x1F, 0x1F,  0x0E, 0x0E, 
0x0E, 0x0E});
                                CheckWeak("weak3", new byte[]
                                        {0xE0, 0xE0, 0xE0, 0xE0,  0xF1, 0xF1, 
0xF1, 0xF1});
                                CheckWeak("weak4", new byte[]
                                        {0xFE, 0xFE, 0xFE, 0xFE,  0xFE, 0xFE, 
0xFE, 0xFE});

                                // Test a semi-weak key.
                                CheckNonWeak("weak5", new byte[]
                                        {0x01, 0xFE, 0x01, 0xFE,  0x01, 0xFE, 
0x01, 0xFE}, true);

                                // Test a normal key.
                                CheckNonWeak("weak6", new byte[]
                                        {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 
0xcd, 0xef});
                        }
        public void TestDESSemiWeak()
                        {
                                // These keys are semi-weak.
                                CheckSemiWeak("semi1", new byte[]
                                        {0x01, 0xFE, 0x01, 0xFE,  0x01, 0xFE, 
0x01, 0xFE});
                                CheckSemiWeak("semi2", new byte[]
                                        {0xFE, 0x01, 0xFE, 0x01,  0xFE, 0x01, 
0xFE, 0x01});
                                CheckSemiWeak("semi3", new byte[]
                                        {0x1F, 0xE0, 0x1F, 0xE0,  0x0E, 0xF1, 
0x0E, 0xF1});
                                CheckSemiWeak("semi4", new byte[]
                                        {0xE0, 0x1F, 0xE0, 0x1F,  0xF1, 0x0E, 
0xF1, 0x0E});
                                CheckSemiWeak("semi5", new byte[]
                                        {0x01, 0xE0, 0x01, 0xE0,  0x01, 0xF1, 
0x01, 0xF1});
                                CheckSemiWeak("semi6", new byte[]
                                        {0xE0, 0x01, 0xE0, 0x01,  0xF1, 0x01, 
0xF1, 0x01});
                                CheckSemiWeak("semi7", new byte[]
                                        {0x1F, 0xFE, 0x1F, 0xFE,  0x0E, 0xFE, 
0x0E, 0xFE});
                                CheckSemiWeak("semi8", new byte[]
                                        {0xFE, 0x1F, 0xFE, 0x1F,  0xFE, 0x0E, 
0xFE, 0x0E});
                                CheckSemiWeak("semi9", new byte[]
                                        {0x01, 0x1F, 0x01, 0x1F,  0x01, 0x0E, 
0x01, 0x0E});
                                CheckSemiWeak("semi10", new byte[]
                                        {0x1F, 0x01, 0x1F, 0x01,  0x0E, 0x01, 
0x0E, 0x01});
                                CheckSemiWeak("semi11", new byte[]
                                        {0xE0, 0xFE, 0xE0, 0xFE,  0xF1, 0xFE, 
0xF1, 0xFE});
                                CheckSemiWeak("semi12", new byte[]
                                        {0xFE, 0xE0, 0xFE, 0xE0,  0xFE, 0xF1, 
0xFE, 0xF1});

                                // Test a weak key.
                                CheckNonSemiWeak("semi13", new byte[]
                                        {0xE0, 0xE0, 0xE0, 0xE0,  0xF1, 0xF1, 
0xF1, 0xF1}, true);

                                // Test a normal key.
                                CheckNonSemiWeak("semi14", new byte[]
                                        {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 
0xcd, 0xef});
                        }

}; // TestDES

--- NEW FILE ---
/*
 * TestMD5.cs - Test the MD5 algorithm.
 *
 * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using CSUnit;
using System;
using System.Security.Cryptography;

public class TestMD5 : CryptoTestCase
{

        // Constructor.
        public TestMD5(String name)
                        : base(name)
                        {
                                // Nothing to do here.  
                        }

        // First test vector.
        private static readonly String md5Value1 =
                "";
        private static readonly byte[] md5Expected1 =
                {0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
                 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E};

        // Second test vector.
        private static readonly String md5Value2 =
                "a";
        private static readonly byte[] md5Expected2 =
                {0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
                 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61};

        // Third test vector.
        private static readonly String md5Value3 =
                "abc";
        private static readonly byte[] md5Expected3 =
                {0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
                 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72};

        // Fourth test vector.
        private static readonly String md5Value4 =
                "message digest";
        private static readonly byte[] md5Expected4 =
                {0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
                 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0};

        // Fifth test vector.
        private static readonly String md5Value5 =
                "abcdefghijklmnopqrstuvwxyz";
        private static readonly byte[] md5Expected5 =
                {0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
                 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B};

        // Sixth test vector.
        private static readonly String md5Value6 =
                
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        private static readonly byte[] md5Expected6 =
                {0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
                 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F};

        // Seventh test vector.
        private static readonly String md5Value7 =
                
"123456789012345678901234567890123456789012345678901234567890123456" +
                "78901234567890";
        private static readonly byte[] md5Expected7 =
                {0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
                 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A};

        // Test the default MD5 implementation.
        public void TestMD5Default()
                        {
                                RunHash("MD5:", md5Value1, md5Expected1);
                        }

        // Test the various vectors.
        public void TestMD5Value1()
                        {
                                RunHash("MD5", md5Value1, md5Expected1);
                        }
        public void TestMD5Value2()
                        {
                                RunHash("MD5", md5Value2, md5Expected2);
                        }
        public void TestMD5Value3()
                        {
                                RunHash("MD5", md5Value3, md5Expected3);
                        }
        public void TestMD5Value4()
                        {
                                RunHash("MD5", md5Value4, md5Expected4);
                        }
        public void TestMD5Value5()
                        {
                                RunHash("MD5", md5Value5, md5Expected5);
                        }
        public void TestMD5Value6()
                        {
                                RunHash("MD5", md5Value6, md5Expected6);
                        }
        public void TestMD5Value7()
                        {
                                RunHash("MD5", md5Value7, md5Expected7);
                        }

        // Test that the algorithm specific class cannot return
        // an object of another algorithm.
        public void TestMD5CreateOther()
                        {
                                try
                                {
                                        MD5.Create("DES");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                                try
                                {
                                        MD5.Create("SHA1");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                        }

}; // TestMD5

--- NEW FILE ---
/*
 * TestRC2.cs - Test the RC2 algorithm.
 *
 * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using CSUnit;
using System;
using System.Security.Cryptography;

public class TestRC2 : CryptoTestCase
{

        // Constructor.
        public TestRC2(String name)
                        : base(name)
                        {
                                // Nothing to do here.  
                        }

        // First test vector.
        private static readonly byte[] rc2Key1 =
                {0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f,
                 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2};
        private static readonly byte[] rc2Plaintext1 =
                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        private static readonly byte[] rc2Expected1 =
                {0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6};

        // Test the default RC2 implementation.
        public void TestRC2Default()
                        {
                                RunSymmetric("RC2:", rc2Key1, rc2Plaintext1,
                                                         rc2Expected1);
                        }

        // Test the first key vector.
        public void TestRC2Key1()
                        {
                                RunSymmetric("RC2", rc2Key1, rc2Plaintext1,
                                                         rc2Expected1);
                        }

        // Test that the algorithm specific class cannot return
        // an object of another algorithm.
        public void TestRC2CreateOther()
                        {
                                try
                                {
                                        RC2.Create("DES");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                        }

}; // TestRC2

--- NEW FILE ---
/*
 * TestSHA1.cs - Test the SHA1 algorithm.
 *
 * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using CSUnit;
using System;
using System.Security.Cryptography;

public class TestSHA1 : CryptoTestCase
{

        // Constructor.
        public TestSHA1(String name)
                        : base(name)
                        {
                                // Nothing to do here.  
                        }

        // First test vector.
        private static readonly String shaValue1 =
                "abc";
        private static readonly byte[] shaExpected1 =
                {0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
                 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D};

        // Second test vector.
        private static readonly String shaValue2 =
                "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
        private static readonly byte[] shaExpected2 =
                {0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
                 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1};

        // Test the default SHA1 implementation.
        public void TestSHA1Default()
                        {
                                RunHash("SHA1:", shaValue1, shaExpected1);
                        }

        // Test the various vectors.
        public void TestSHA1Value1()
                        {
                                RunHash("SHA1", shaValue1, shaExpected1);
                        }
        public void TestSHA1Value2()
                        {
                                RunHash("SHA1", shaValue2, shaExpected2);
                        }

        // Test that the algorithm specific class cannot return
        // an object of another algorithm.
        public void TestSHA1CreateOther()
                        {
                                try
                                {
                                        SHA1.Create("DES");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                                try
                                {
                                        SHA1.Create("MD5");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                        }

}; // TestSHA1

--- NEW FILE ---
/*
 * TestSHA256.cs - Test the SHA256 algorithm.
 *
 * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using CSUnit;
using System;
using System.Security.Cryptography;

public class TestSHA256 : CryptoTestCase
{

        // Constructor.
        public TestSHA256(String name)
                        : base(name)
                        {
                                // Nothing to do here.  
                        }

        // First test vector.
        private static readonly String shaValue1 =
                "abc";
        private static readonly byte[] shaExpected1 =
                {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
                 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
                 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
                 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};

        // Second test vector.
        private static readonly String shaValue2 =
                "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
        private static readonly byte[] shaExpected2 =
                {0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
                 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
                 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
                 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1};

        // Test the default SHA256 implementation.
        public void TestSHA256Default()
                        {
                                RunHash("SHA256:", shaValue1, shaExpected1);
                        }

        // Test the various vectors.
        public void TestSHA256Value1()
                        {
                                RunHash("SHA256", shaValue1, shaExpected1);
                        }
        public void TestSHA256Value2()
                        {
                                RunHash("SHA256", shaValue2, shaExpected2);
                        }

        // Test that the algorithm specific class cannot return
        // an object of another algorithm.
        public void TestSHA256CreateOther()
                        {
                                try
                                {
                                        SHA256.Create("DES");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                                try
                                {
                                        SHA256.Create("SHA1");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                        }

}; // TestSHA256

--- NEW FILE ---
/*
 * TestSHA384.cs - Test the SHA384 algorithm.
 *
 * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using CSUnit;
using System;
using System.Security.Cryptography;

public class TestSHA384 : CryptoTestCase
{

        // Constructor.
        public TestSHA384(String name)
                        : base(name)
                        {
                                // Nothing to do here.  
                        }

        // First test vector.
        private static readonly String shaValue1 =
                "abc";
        private static readonly byte[] shaExpected1 =
                {0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
                 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
                 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
                 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
                 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
                 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7};

        // Second test vector.
        private static readonly String shaValue2 =
                "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" +
                "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
        private static readonly byte[] shaExpected2 =
                {0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
                 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
                 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
                 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
                 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
                 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39};

        // Test the default SHA384 implementation.
        public void TestSHA384Default()
                        {
                                RunHash("SHA384:", shaValue1, shaExpected1);
                        }

        // Test the various vectors.
        public void TestSHA384Value1()
                        {
                                RunHash("SHA384", shaValue1, shaExpected1);
                        }
        public void TestSHA384Value2()
                        {
                                RunHash("SHA384", shaValue2, shaExpected2);
                        }

        // Test that the algorithm specific class cannot return
        // an object of another algorithm.
        public void TestSHA384CreateOther()
                        {
                                try
                                {
                                        SHA384.Create("DES");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                                try
                                {
                                        SHA384.Create("SHA1");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                        }

}; // TestSHA384

--- NEW FILE ---
/*
 * TestSHA512.cs - Test the SHA512 algorithm.
 *
 * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using CSUnit;
using System;
using System.Security.Cryptography;

public class TestSHA512 : CryptoTestCase
{

        // Constructor.
        public TestSHA512(String name)
                        : base(name)
                        {
                                // Nothing to do here.  
                        }

        // First test vector.
        private static readonly String shaValue1 =
                "abc";
        private static readonly byte[] shaExpected1 =
                {0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
                 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
                 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
                 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
                 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
                 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
                 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
                 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f};

        // Second test vector.
        private static readonly String shaValue2 =
                "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" +
                "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
        private static readonly byte[] shaExpected2 =
                {0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
                 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
                 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
                 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
                 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
                 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
                 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
                 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09};

        // Test the default SHA512 implementation.
        public void TestSHA512Default()
                        {
                                RunHash("SHA512:", shaValue1, shaExpected1);
                        }

        // Test the various vectors.
        public void TestSHA512Value1()
                        {
                                RunHash("SHA512", shaValue1, shaExpected1);
                        }
        public void TestSHA512Value2()
                        {
                                RunHash("SHA512", shaValue2, shaExpected2);
                        }

        // Test that the algorithm specific class cannot return
        // an object of another algorithm.
        public void TestSHA512CreateOther()
                        {
                                try
                                {
                                        SHA512.Create("DES");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                                try
                                {
                                        SHA512.Create("SHA1");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                        }

}; // TestSHA512

--- NEW FILE ---
/*
 * TestTripleDES.cs - Test the TripleDES algorithm.
 *
 * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using CSUnit;
using System;
using System.Security.Cryptography;

public class TestTripleDES : CryptoTestCase
{

        // Constructor.
        public TestTripleDES(String name)
                        : base(name)
                        {
                                // Nothing to do here.  
                        }

        // Keys to use to help test TripleDES.
        private static readonly byte[] des3Key1 =
                {0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A,
                 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
        private static readonly byte[] des3Key2 =
                {0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A,
                 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};

        // Sample plaintexts.
        private static readonly byte[] des3Plaintext1 =
                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        private static readonly byte[] des3Plaintext2 =
                {0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A};

        // Extract a sub-key.
        private static byte[] SubKey(byte[] key, int offset, int length)
                        {
                                byte[] sub = new byte [length];
                                Array.Copy(key, offset, sub, 0, length);
                                return sub;
                        }

        // Check a TripleDES instance against a particular key and plaintext.
        // We do this by comparing against what DES would do, if applied 
manually.
        // This assumes that DES has already been tested and found to be OK.
        private static void CheckTripleDES(TripleDES alg, byte[] key,
                                                                           
byte[] plaintext)
                        {
                                // Set up the algorithm the way we want.
                                alg.Mode = CipherMode.ECB;
                                alg.Padding = PaddingMode.None;

                                // Create an encryptor and determine the output 
ciphertext.
                                ICryptoTransform encryptor = 
alg.CreateEncryptor(key, null);
                                byte[] ciphertext = new byte [plaintext.Length 
* 2];
                                byte[] tail;
                                int len = encryptor.TransformBlock
                                                (plaintext, 0, plaintext.Length,
                                                 ciphertext, 0);
                                AssertEquals("ECB encrypt length mismatch",
                                                         len, plaintext.Length);
                                tail = encryptor.TransformFinalBlock
                                                (plaintext, 0, 0);
                                AssertNotNull("ECB encrypt tail should be 
non-null");
                                AssertEquals("ECB encrypt tail should be zero 
length",
                                                         tail.Length, 0);

                                // Create a decryptor and run the test 
backwards.
                                ICryptoTransform decryptor = 
alg.CreateDecryptor(key, null);
                                byte[] original = new byte [plaintext.Length * 
2];
                                len = decryptor.TransformBlock
                                                (ciphertext, 0, 
plaintext.Length, original, 0);
                                AssertEquals("ECB decrypt length mismatch",
                                                         len, plaintext.Length);
                                tail = decryptor.TransformFinalBlock
                                                (ciphertext, 0, 0);
                                AssertNotNull("ECB decrypt tail should be 
non-null");
                                AssertEquals("ECB decrypt tail should be zero 
length",
                                                         tail.Length, 0);
                                if(!IdenticalBlock(plaintext, 0, original, 0,
                                                                   
plaintext.Length))
                                {
                                        Fail("did not decrypt to the original 
plaintext");
                                }

                                // Now see what DES would say on the same input 
to make
                                // sure that TripleDES is giving the correct 
behaviour.
                                DES des = DES.Create();
                                des.Mode = CipherMode.ECB;
                                des.Padding = PaddingMode.None;
                                ICryptoTransform encrypt1;
                                ICryptoTransform decrypt2;
                                ICryptoTransform encrypt3;
                                if(key.Length == 16)
                                {
                                        encrypt1 = 
des.CreateEncryptor(SubKey(key, 0, 8), null);
                                        decrypt2 = 
des.CreateDecryptor(SubKey(key, 8, 8), null);
                                        encrypt3 = 
des.CreateEncryptor(SubKey(key, 0, 8), null);
                                }
                                else
                                {
                                        encrypt1 = 
des.CreateEncryptor(SubKey(key, 0, 8), null);
                                        decrypt2 = 
des.CreateDecryptor(SubKey(key, 8, 8), null);
                                        encrypt3 = 
des.CreateEncryptor(SubKey(key, 16, 8), null);
                                }
                                byte[] block = new byte [plaintext.Length];
                                encrypt1.TransformBlock
                                                (plaintext, 0, 
plaintext.Length, block, 0);
                                tail = encrypt1.TransformFinalBlock
                                                (plaintext, 0, 0);
                                decrypt2.TransformBlock
                                                (block, 0, plaintext.Length, 
block, 0);
                                tail = decrypt2.TransformFinalBlock
                                                (block, 0, 0);
                                encrypt3.TransformBlock
                                                (block, 0, plaintext.Length, 
block, 0);
                                tail = encrypt3.TransformFinalBlock
                                                (block, 0, 0);
                                if(!IdenticalBlock(ciphertext, 0, block, 0, 
plaintext.Length))
                                {
                                        Fail("TripleDES does not have the 
correct behaviour");
                                }
                        }

        // Test the TripleDES implementation.
        public void TestTripleDES()
                        {
                                CheckTripleDES(TripleDES.Create(), des3Key1, 
des3Plaintext1);
                                CheckTripleDES(TripleDES.Create(), des3Key1, 
des3Plaintext2);
                                CheckTripleDES(TripleDES.Create(), des3Key2, 
des3Plaintext1);
                                CheckTripleDES(TripleDES.Create(), des3Key2, 
des3Plaintext2);
                        }

        // Test that the algorithm specific class cannot return
        // an object of another algorithm.
        public void TestTripleDESCreateOther()
                        {
                                try
                                {
                                        TripleDES.Create("RC2");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                                try
                                {
                                        TripleDES.Create("DES");
                                        Fail();
                                }
                                catch(InvalidCastException)
                                {
                                        // Success case.
                                }
                        }

}; // TestTripleDES





reply via email to

[Prev in Thread] Current Thread [Next in Thread]