Merge pull request #3135 from kumpera/enable_conc_gc_on_mainline_archs
[mono.git] / mcs / class / Mono.Security.Win32 / Test / Mono.Security.Cryptography / SHA1Test.cs
1 //
2 // SHA1Test.cs - NUnit Test Cases for SHA1 (FIPS186)
3 //
4 // Author:
5 //      Sebastien Pouliot (spouliot@motus.com)
6 //
7 // (C) 2002 Motus Technologies Inc. (http://www.motus.com)
8 //
9
10 using System;
11 using System.IO;
12 using System.Security.Cryptography;
13 using System.Text;
14
15 using Mono.Security.Cryptography;
16 using NUnit.Framework;
17
18 namespace MonoTests.Security.Cryptography {
19
20 // References:
21 // a.   FIPS PUB 180-1: Secure Hash Standard
22 //      http://csrc.nist.gov/publications/fips/fips180-1/fip180-1.txt
23
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 {
27
28         protected SHA1 hash;
29
30         // because most crypto stuff works with byte[] buffers
31         static public void AssertEquals (string msg, byte[] array1, byte[] array2) 
32         {
33                 if ((array1 == null) && (array2 == null))
34                         return;
35                 if (array1 == null)
36                         Assert.Fail (msg + " -> First array is NULL");
37                 if (array2 == null)
38                         Assert.Fail (msg + " -> Second array is NULL");
39
40                 bool a = (array1.Length == array2.Length);
41                 if (a) {
42                         for (int i = 0; i < array1.Length; i++) {
43                                 if (array1 [i] != array2 [i]) {
44                                         a = false;
45                                         break;
46                                 }
47                         }
48                 }
49                 msg += " -> Expected " + BitConverter.ToString (array1, 0);
50                 msg += " is different than " + BitConverter.ToString (array2, 0);
51                 Assert.IsTrue (a, msg);
52         }
53
54         [SetUp]
55         protected void SetUp () 
56         {
57                 hash = new Mono.Security.Cryptography.SHA1CryptoServiceProvider ();
58         }
59
60         // none of those values changes for a particuliar implementation of SHA1
61         [Test]
62         public void TestStaticInfo () 
63         {
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);
72         }
73
74         // First test, we hash the string "abc"
75         [Test]
76         public void FIPS186_Test1 () 
77         {
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");
81         
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);
88         }
89
90         // Second test, we hash the string "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
91         [Test]
92         public void FIPS186_Test2 () 
93         {
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");
97         
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);
104         }
105
106         // Third test, we hash 1,000,000 times the character "a"
107         [Test]
108         [Ignore("Much too long - must implements blocks")]
109         public void FIPS186_Test3 () 
110         {
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
116         
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);
123         }
124
125         public void FIPS186_a (string testName, SHA1 hash, byte[] input, byte[] result) 
126         {
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
131                 hash.Initialize ();
132         }
133
134         public void FIPS186_b (string testName, SHA1 hash, byte[] input, byte[] result) 
135         {
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
140                 hash.Initialize ();
141         }
142
143         public void FIPS186_c (string testName, SHA1 hash, byte[] input, byte[] result) 
144         {
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
150                 hash.Initialize ();
151         }
152
153         public void FIPS186_d (string testName, SHA1 hash, byte[] input, byte[] result) 
154         {
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
160                 hash.Initialize ();
161         }
162
163         public void FIPS186_e (string testName, SHA1 hash, byte[] input, byte[] result) 
164         {
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
173                 hash.Initialize ();
174         }
175 }
176
177 }