2 // SHA1Test.cs - NUnit Test Cases for SHA1 (FIPS186)
5 // Sebastien Pouliot (spouliot@motus.com)
7 // (C) 2002 Motus Technologies Inc. (http://www.motus.com)
12 using System.Security.Cryptography;
15 using Mono.Security.Cryptography;
16 using NUnit.Framework;
18 namespace MonoTests.Security.Cryptography {
21 // a. FIPS PUB 180-1: Secure Hash Standard
22 // http://csrc.nist.gov/publications/fips/fips180-1/fip180-1.txt
24 // we inherit from SHA1Test because all SHA1 implementation must return the
25 // same results (hence should run a common set of unit tests).
26 public class SHA1Test {
30 // because most crypto stuff works with byte[] buffers
31 static public void AssertEquals (string msg, byte[] array1, byte[] array2)
33 if ((array1 == null) && (array2 == null))
36 Assert.Fail (msg + " -> First array is NULL");
38 Assert.Fail (msg + " -> Second array is NULL");
40 bool a = (array1.Length == array2.Length);
42 for (int i = 0; i < array1.Length; i++) {
43 if (array1 [i] != array2 [i]) {
49 msg += " -> Expected " + BitConverter.ToString (array1, 0);
50 msg += " is different than " + BitConverter.ToString (array2, 0);
51 Assert.IsTrue (a, msg);
55 protected void SetUp ()
57 hash = new Mono.Security.Cryptography.SHA1CryptoServiceProvider ();
60 // none of those values changes for a particuliar implementation of SHA1
62 public void TestStaticInfo ()
64 // test all values static for SHA1
65 string className = hash.ToString ();
66 Assert.AreEqual (className + ".HashSize", 160, hash.HashSize);
67 Assert.AreEqual (className + ".InputBlockSize", 1, hash.InputBlockSize);
68 Assert.AreEqual (className + ".OutputBlockSize", 1, hash.OutputBlockSize);
69 Assert.AreEqual (className + ".CanReuseTransform", true, hash.CanReuseTransform);
70 Assert.AreEqual (className + ".CanTransformMultipleBlocks", true, hash.CanTransformMultipleBlocks);
71 Assert.AreEqual (className + ".ToString()", "Mono.Security.Cryptography.SHA1CryptoServiceProvider", className);
74 // First test, we hash the string "abc"
76 public void FIPS186_Test1 ()
78 string className = hash.ToString ();
79 byte[] result = { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d };
80 byte[] input = Encoding.Default.GetBytes ("abc");
82 string testName = className + " 1";
83 FIPS186_a (testName, hash, input, result);
84 FIPS186_b (testName, hash, input, result);
85 FIPS186_c (testName, hash, input, result);
86 FIPS186_d (testName, hash, input, result);
87 FIPS186_e (testName, hash, input, result);
90 // Second test, we hash the string "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
92 public void FIPS186_Test2 ()
94 string className = hash.ToString ();
95 byte[] result = { 0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e, 0xba, 0xae, 0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5, 0xe5, 0x46, 0x70, 0xf1 };
96 byte[] input = Encoding.Default.GetBytes ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
98 string testName = className + " 2";
99 FIPS186_a (testName, hash, input, result);
100 FIPS186_b (testName, hash, input, result);
101 FIPS186_c (testName, hash, input, result);
102 FIPS186_d (testName, hash, input, result);
103 FIPS186_e (testName, hash, input, result);
106 // Third test, we hash 1,000,000 times the character "a"
108 [Ignore("Much too long - must implements blocks")]
109 public void FIPS186_Test3 ()
111 string className = hash.ToString ();
112 byte[] result = { 0x34, 0xaa, 0x97, 0x3c, 0xd4, 0xc4, 0xda, 0xa4, 0xf6, 0x1e, 0xeb, 0x2b, 0xdb, 0xad, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6f };
113 byte[] input = new byte [1000000];
114 for (int i = 0; i < 1000000; i++)
115 input[i] = 0x61; // a
117 string testName = className + " 3";
118 FIPS186_a (testName, hash, input, result);
119 FIPS186_b (testName, hash, input, result);
120 FIPS186_c (testName, hash, input, result);
121 FIPS186_d (testName, hash, input, result);
122 FIPS186_e (testName, hash, input, result);
125 public void FIPS186_a (string testName, SHA1 hash, byte[] input, byte[] result)
127 byte[] output = hash.ComputeHash (input);
128 AssertEquals (testName + ".a.1", result, output);
129 AssertEquals (testName + ".a.2", result, hash.Hash);
130 // required or next operation will still return old hash
134 public void FIPS186_b (string testName, SHA1 hash, byte[] input, byte[] result)
136 byte[] output = hash.ComputeHash (input, 0, input.Length);
137 AssertEquals (testName + ".b.1", result, output);
138 AssertEquals (testName + ".b.2", result, hash.Hash);
139 // required or next operation will still return old hash
143 public void FIPS186_c (string testName, SHA1 hash, byte[] input, byte[] result)
145 MemoryStream ms = new MemoryStream (input);
146 byte[] output = hash.ComputeHash (ms);
147 AssertEquals (testName + ".c.1", result, output);
148 AssertEquals (testName + ".c.2", result, hash.Hash);
149 // required or next operation will still return old hash
153 public void FIPS186_d (string testName, SHA1 hash, byte[] input, byte[] result)
155 byte[] output = hash.TransformFinalBlock (input, 0, input.Length);
156 // LAMESPEC or FIXME: TransformFinalBlock doesn't return HashValue !
157 // AssertEquals( testName + ".d.1", result, output );
158 AssertEquals (testName + ".d", result, hash.Hash);
159 // required or next operation will still return old hash
163 public void FIPS186_e (string testName, SHA1 hash, byte[] input, byte[] result)
165 byte[] copy = new byte [input.Length];
166 for (int i=0; i < input.Length - 1; i++)
167 hash.TransformBlock (input, i, 1, copy, i);
168 byte[] output = hash.TransformFinalBlock (input, input.Length - 1, 1);
169 // LAMESPEC or FIXME: TransformFinalBlock doesn't return HashValue !
170 // AssertEquals (testName + ".e.1", result, output);
171 AssertEquals (testName + ".e", result, hash.Hash);
172 // required or next operation will still return old hash