summary refs log tree commit diff
path: root/crypto/test
diff options
context:
space:
mode:
authorTim Whittington <bc@whittington.net.nz>2013-10-10 12:47:44 +1300
committerTim Whittington <bc@whittington.net.nz>2013-10-10 12:56:38 +1300
commit4e0d67b4ddcee08a49e8922159eebc6d11f2ae6d (patch)
tree4851e73d038fa4eea1429999820faf749ed17cbe /crypto/test
parentfixed line endings (diff)
downloadBouncyCastle.NET-ed25519-4e0d67b4ddcee08a49e8922159eebc6d11f2ae6d.tar.xz
Port reduced round Salsa20, registerised Salsa20 core, XSalsa20 and ChaCha from bc-java.
Diffstat (limited to 'crypto/test')
-rw-r--r--crypto/test/src/crypto/test/ChaChaTest.cs318
-rw-r--r--crypto/test/src/crypto/test/RegressionTest.cs4
-rw-r--r--crypto/test/src/crypto/test/Salsa20Test.cs69
-rw-r--r--crypto/test/src/crypto/test/XSalsa20Test.cs183
4 files changed, 567 insertions, 7 deletions
diff --git a/crypto/test/src/crypto/test/ChaChaTest.cs b/crypto/test/src/crypto/test/ChaChaTest.cs
new file mode 100644
index 000000000..fea88ca85
--- /dev/null
+++ b/crypto/test/src/crypto/test/ChaChaTest.cs
@@ -0,0 +1,318 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Crypto.Engines;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Crypto.Tests
+{
+	/**
+	 * ChaCha Test
+	 * <p>
+	 * Test cases generated using ref version of ChaCha20 in estreambench-20080905.
+	 */
+	[TestFixture]
+	public class ChaChaTest
+		: SimpleTest
+	{
+		private static readonly byte[] zeroes = Hex.Decode(
+			"00000000000000000000000000000000"
+			+ "00000000000000000000000000000000"
+			+ "00000000000000000000000000000000"
+			+ "00000000000000000000000000000000");
+
+		private static readonly string set1v0_0 =
+			"FBB87FBB8395E05DAA3B1D683C422046"
+			+ "F913985C2AD9B23CFC06C1D8D04FF213"
+			+ "D44A7A7CDB84929F915420A8A3DC58BF"
+			+ "0F7ECB4B1F167BB1A5E6153FDAF4493D";
+
+		private static readonly string set1v0_192 =
+			"D9485D55B8B82D792ED1EEA8E93E9BC1"
+			+ "E2834AD0D9B11F3477F6E106A2F6A5F2"
+			+ "EA8244D5B925B8050EAB038F58D4DF57"
+			+ "7FAFD1B89359DAE508B2B10CBD6B488E";
+
+		private static readonly string set1v0_256 =
+			"08661A35D6F02D3D9ACA8087F421F7C8"
+			+ "A42579047D6955D937925BA21396DDD4"
+			+ "74B1FC4ACCDCAA33025B4BCE817A4FBF"
+			+ "3E5D07D151D7E6FE04934ED466BA4779";
+
+		private static readonly string set1v0_448 =
+			"A7E16DD38BA48CCB130E5BE9740CE359"
+			+ "D631E91600F85C8A5D0785A612D1D987"
+			+ "90780ACDDC26B69AB106CCF6D866411D"
+			+ "10637483DBF08CC5591FD8B3C87A3AE0";
+
+		private static readonly string set1v9_0 =
+			"A276339F99316A913885A0A4BE870F06"
+			+ "91E72B00F1B3F2239F714FE81E88E00C"
+			+ "BBE52B4EBBE1EA15894E29658C4CB145"
+			+ "E6F89EE4ABB045A78514482CE75AFB7C";
+
+		private static readonly string set1v9_192 =
+			"0DFB9BD4F87F68DE54FBC1C6428FDEB0"
+			+ "63E997BE8490C9B7A4694025D6EBA2B1"
+			+ "5FE429DB82A7CAE6AAB22918E8D00449"
+			+ "6FB6291467B5AE81D4E85E81D8795EBB";
+
+		private static readonly string set1v9_256 =
+			"546F5BB315E7F71A46E56D4580F90889"
+			+ "639A2BA528F757CF3B048738BA141AF3"
+			+ "B31607CB21561BAD94721048930364F4"
+			+ "B1227CFEB7CDECBA881FB44903550E68";
+
+		private static readonly string set1v9_448 =
+			"6F813586E76691305A0CF048C0D8586D"
+			+ "C89460207D8B230CD172398AA33D19E9"
+			+ "2D24883C3A9B0BB7CD8C6B2668DB142E"
+			+ "37A97948A7A01498A21110297984CD20";
+
+		private static readonly string set6v0_0 =
+			"57459975BC46799394788DE80B928387"
+			+ "862985A269B9E8E77801DE9D874B3F51"
+			+ "AC4610B9F9BEE8CF8CACD8B5AD0BF17D"
+			+ "3DDF23FD7424887EB3F81405BD498CC3";
+
+		private static readonly string set6v0_65472 =
+			"EF9AEC58ACE7DB427DF012B2B91A0C1E"
+			+ "8E4759DCE9CDB00A2BD59207357BA06C"
+			+ "E02D327C7719E83D6348A6104B081DB0"
+			+ "3908E5186986AE41E3AE95298BB7B713";
+
+		private static readonly string set6v0_65536 =
+			"17EF5FF454D85ABBBA280F3A94F1D26E"
+			+ "950C7D5B05C4BB3A78326E0DC5731F83"
+			+ "84205C32DB867D1B476CE121A0D7074B"
+			+ "AA7EE90525D15300F48EC0A6624BD0AF";
+
+		private static readonly string set6v1_0 =
+			"92A2508E2C4084567195F2A1005E552B"
+			+ "4874EC0504A9CD5E4DAF739AB553D2E7"
+			+ "83D79C5BA11E0653BEBB5C116651302E"
+			+ "8D381CB728CA627B0B246E83942A2B99";
+
+		private static readonly string set6v1_65472 =
+			"E1974EC3063F7BD0CBA58B1CE34BC874"
+			+ "67AAF5759B05EA46682A5D4306E5A76B"
+			+ "D99A448DB8DE73AF97A73F5FBAE2C776"
+			+ "35040464524CF14D7F08D4CE1220FD84";
+
+		private static readonly string set6v1_65536 =
+			"BE3436141CFD62D12FF7D852F80C1344"
+			+ "81F152AD0235ECF8CA172C55CA8C031B"
+			+ "2E785D773A988CA8D4BDA6FAE0E493AA"
+			+ "71DCCC4C894D1F106CAC62A9FC0A9607";
+
+		// ChaCha12
+		private static readonly string chacha12_set1v0_0 =
+			"36CF0D56E9F7FBF287BC5460D95FBA94"
+			+ "AA6CBF17D74E7C784DDCF7E0E882DDAE"
+			+ "3B5A58243EF32B79A04575A8E2C2B73D"
+			+ "C64A52AA15B9F88305A8F0CA0B5A1A25";
+
+		private static readonly string chacha12_set1v0_192 =
+			"83496792AB68FEC75ADB16D3044420A4"
+			+ "A00A6E9ADC41C3A63DBBF317A8258C85"
+			+ "A9BC08B4F76B413A4837324AEDF8BC2A"
+			+ "67D53C9AB9E1C5BC5F379D48DF9AF730";
+
+		private static readonly string chacha12_set1v0_256 = 
+			"BAA28ED593690FD760ADA07C95E3B888"
+			+ "4B4B64E488CA7A2D9BDC262243AB9251"
+			+ "394C5037E255F8BCCDCD31306C508FFB"
+			+ "C9E0161380F7911FCB137D46D9269250";
+
+		private static readonly string chacha12_set1v0_448 =
+			"B7ECFB6AE0B51915762FE1FD03A14D0C"
+			+ "9E54DA5DC76EB16EBA5313BC535DE63D"
+			+ "C72D7F9F1874E301E99C8531819F4E37"
+			+ "75793F6A5D19C717FA5C78A39EB804A6";
+
+		// ChaCha8
+		private static readonly string chacha8_set1v0_0 =
+			"BEB1E81E0F747E43EE51922B3E87FB38"
+			+ "D0163907B4ED49336032AB78B67C2457"
+			+ "9FE28F751BD3703E51D876C017FAA435"
+			+ "89E63593E03355A7D57B2366F30047C5";
+
+		private static readonly string chacha8_set1v0_192 =
+			"33B8B7CA8F8E89F0095ACE75A379C651"
+			+ "FD6BDD55703C90672E44C6BAB6AACDD8"
+			+ "7C976A87FD264B906E749429284134C2"
+			+ "38E3B88CF74A68245B860D119A8BDF43";
+
+		private static readonly string chacha8_set1v0_256 =
+			"F7CA95BF08688BD3BE8A27724210F9DC"
+			+ "16F32AF974FBFB09E9F757C577A245AB"
+			+ "F35F824B70A4C02CB4A8D7191FA8A5AD"
+			+ "6A84568743844703D353B7F00A8601F4";
+
+		private static readonly string chacha8_set1v0_448 =
+			"7B4117E8BFFD595CD8482270B08920FB"
+			+ "C9B97794E1809E07BB271BF07C861003"
+			+ "4C38DBA6ECA04E5474F399A284CBF6E2"
+			+ "7F70142E604D0977797DE5B58B6B25E0";
+
+		public override string Name
+		{
+			get { return "ChaCha"; }
+		}
+
+		public override void PerformTest()
+		{
+			chachaTest1(20, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
+					set1v0_0, set1v0_192,  set1v0_256,  set1v0_448);
+			chachaTest1(20, new ParametersWithIV(new KeyParameter(Hex.Decode("00400000000000000000000000000000")), Hex.Decode("0000000000000000")),
+					set1v9_0, set1v9_192,  set1v9_256,  set1v9_448);
+			chachaTest1(12, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
+		            chacha12_set1v0_0, chacha12_set1v0_192,  chacha12_set1v0_256,  chacha12_set1v0_448);
+			chachaTest1(8, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
+		            chacha8_set1v0_0, chacha8_set1v0_192,  chacha8_set1v0_256,  chacha8_set1v0_448);
+			chachaTest2(new ParametersWithIV(new KeyParameter(Hex.Decode("0053A6F94C9FF24598EB3E91E4378ADD3083D6297CCF2275C81B6EC11467BA0D")), Hex.Decode("0D74DB42A91077DE")),
+					set6v0_0, set6v0_65472, set6v0_65536);
+			chachaTest2(new ParametersWithIV(new KeyParameter(Hex.Decode("0558ABFE51A4F74A9DF04396E93C8FE23588DB2E81D4277ACD2073C6196CBF12")), Hex.Decode("167DE44BB21980E7")),
+					set6v1_0, set6v1_65472, set6v1_65536);
+			reinitBug();
+		}
+
+		private void chachaTest1(
+			int rounds,
+			ICipherParameters	parameters,
+			string				v0,
+			string				v192,
+			string				v256,
+			string				v448)
+		{
+			IStreamCipher salsa = new ChaChaEngine(rounds);
+			byte[]       buf = new byte[64];
+
+			salsa.Init(true, parameters);
+
+			for (int i = 0; i != 7; i++)
+			{
+				salsa.ProcessBytes(zeroes, 0, 64, buf, 0);
+				switch (i)
+				{
+				case 0:
+					if (!AreEqual(buf, Hex.Decode(v0)))
+					{
+						mismatch("v0/" + rounds, v0, buf);
+					}
+					break;
+				case 3:
+					if (!AreEqual(buf, Hex.Decode(v192)))
+					{
+						mismatch("v192/" + rounds, v192, buf);
+					}
+					break;
+				case 4:
+					if (!AreEqual(buf, Hex.Decode(v256)))
+					{
+						mismatch("v256/" + rounds, v256, buf);
+					}
+					break;
+				default:
+					// ignore
+					break;
+				}
+			}
+
+			for (int i = 0; i != 64; i++)
+			{
+				buf[i] = salsa.ReturnByte(zeroes[i]);
+			}
+
+			if (!AreEqual(buf, Hex.Decode(v448)))
+			{
+				mismatch("v448", v448, buf);
+			}       
+		}
+
+		private void chachaTest2(
+			ICipherParameters	parameters,
+			string				v0,
+			string				v65472,
+			string				v65536)
+		{
+			IStreamCipher salsa = new ChaChaEngine();
+			byte[]       buf = new byte[64];
+
+			salsa.Init(true, parameters);
+
+			for (int i = 0; i != 1025; i++)
+			{
+				salsa.ProcessBytes(zeroes, 0, 64, buf, 0);
+				switch (i)
+				{
+				case 0:
+					if (!AreEqual(buf, Hex.Decode(v0)))
+					{
+						mismatch("v0", v0, buf);
+					}
+					break;
+				case 1023:
+					if (!AreEqual(buf, Hex.Decode(v65472)))
+					{
+						mismatch("v65472", v65472, buf);
+					}
+					break;
+				case 1024:
+					if (!AreEqual(buf, Hex.Decode(v65536)))
+					{
+						mismatch("v65536", v65536, buf);
+					}
+					break;
+				default:
+					// ignore
+					break;
+				}
+			}
+		}
+
+		private void mismatch(
+			string	name,
+			string	expected,
+			byte[]	found)
+		{
+			Fail("mismatch on " + name, expected, Hex.ToHexString(found));
+		}
+
+		private void reinitBug()
+		{
+			KeyParameter key = new KeyParameter(Hex.Decode("80000000000000000000000000000000"));
+			ParametersWithIV parameters = new ParametersWithIV(key, Hex.Decode("0000000000000000"));
+
+			IStreamCipher chacha = new ChaChaEngine();
+
+			chacha.Init(true, parameters);
+
+			try
+			{
+				chacha.Init(true, key);
+				Fail("ChaCha should throw exception if no IV in Init");
+			}
+			catch (ArgumentException)
+			{
+			}
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new ChaChaTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/crypto/test/RegressionTest.cs b/crypto/test/src/crypto/test/RegressionTest.cs
index 687e9ee4f..3a21f3656 100644
--- a/crypto/test/src/crypto/test/RegressionTest.cs
+++ b/crypto/test/src/crypto/test/RegressionTest.cs
@@ -94,7 +94,9 @@ namespace Org.BouncyCastle.Crypto.Tests
             new Rfc3211WrapTest(),
             new SeedTest(),
             new NaccacheSternTest(),
-            new Salsa20Test(),
+			new Salsa20Test(),
+			new XSalsa20Test(),
+			new ChaChaTest(),
             new CMacTest(),
             new EaxTest(),
             new GcmTest(),
diff --git a/crypto/test/src/crypto/test/Salsa20Test.cs b/crypto/test/src/crypto/test/Salsa20Test.cs
index 9e7549ae7..b4dc1ef2b 100644
--- a/crypto/test/src/crypto/test/Salsa20Test.cs
+++ b/crypto/test/src/crypto/test/Salsa20Test.cs
@@ -106,6 +106,58 @@ namespace Org.BouncyCastle.Crypto.Tests
 			+ "C945A6CC69A6A17367BC03431A86B3ED"
 			+ "04B0245B56379BF997E25800AD837D7D";
 
+		// Salsa20/12
+
+		private static readonly string salsa12_set1v0_0 = 
+			"FC207DBFC76C5E1774961E7A5AAD0906"
+			+ "9B2225AC1CE0FE7A0CE77003E7E5BDF8"
+			+ "B31AF821000813E6C56B8C1771D6EE70"
+			+ "39B2FBD0A68E8AD70A3944B677937897";
+
+		private static readonly string salsa12_set1v0_192 = 
+			"4B62A4881FA1AF9560586510D5527ED4"
+			+ "8A51ECAFA4DECEEBBDDC10E9918D44AB"
+			+ "26B10C0A31ED242F146C72940C6E9C37"
+			+ "53F641DA84E9F68B4F9E76B6C48CA5AC";
+
+		private static readonly string salsa12_set1v0_256 = 
+			"F52383D9DEFB20810325F7AEC9EADE34"
+			+ "D9D883FEE37E05F74BF40875B2D0BE79"
+			+ "ED8886E5BFF556CEA8D1D9E86B1F68A9"
+			+ "64598C34F177F8163E271B8D2FEB5996";
+
+		private static readonly string salsa12_set1v0_448 =
+			"A52ED8C37014B10EC0AA8E05B5CEEE12"
+			+ "3A1017557FB3B15C53E6C5EA8300BF74"
+			+ "264A73B5315DC821AD2CAB0F3BB2F152"
+			+ "BDAEA3AEE97BA04B8E72A7B40DCC6BA4";
+
+		// Salsa20/8
+
+		private static readonly string salsa8_set1v0_0 =
+			"A9C9F888AB552A2D1BBFF9F36BEBEB33"
+			+ "7A8B4B107C75B63BAE26CB9A235BBA9D"
+			+ "784F38BEFC3ADF4CD3E266687EA7B9F0"
+			+ "9BA650AE81EAC6063AE31FF12218DDC5";
+
+		private static readonly string salsa8_set1v0_192 =
+			"BB5B6BB2CC8B8A0222DCCC1753ED4AEB"
+			+ "23377ACCBD5D4C0B69A8A03BB115EF71"
+			+ "871BC10559080ACA7C68F0DEF32A80DD"
+			+ "BAF497259BB76A3853A7183B51CC4B9F";
+
+		private static readonly string salsa8_set1v0_256 =
+			"4436CDC0BE39559F5E5A6B79FBDB2CAE"
+			+ "4782910F27FFC2391E05CFC78D601AD8"
+			+ "CD7D87B074169361D997D1BED9729C0D"
+			+ "EB23418E0646B7997C06AA84E7640CE3";
+
+		private static readonly string salsa8_set1v0_448 =
+			"BEE85903BEA506B05FC04795836FAAAC"
+			+ "7F93F785D473EB762576D96B4A65FFE4"
+			+ "63B34AAE696777FC6351B67C3753B89B"
+			+ "A6B197BD655D1D9CA86E067F4D770220";
+
 		public override string Name
 		{
 			get { return "Salsa20"; }
@@ -113,10 +165,14 @@ namespace Org.BouncyCastle.Crypto.Tests
 
 		public override void PerformTest()
 		{
-			salsa20Test1(new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
+			salsa20Test1(20, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
 					set1v0_0, set1v0_192,  set1v0_256,  set1v0_448);
-			salsa20Test1(new ParametersWithIV(new KeyParameter(Hex.Decode("00400000000000000000000000000000")), Hex.Decode("0000000000000000")),
+			salsa20Test1(20, new ParametersWithIV(new KeyParameter(Hex.Decode("00400000000000000000000000000000")), Hex.Decode("0000000000000000")),
 					set1v9_0, set1v9_192,  set1v9_256,  set1v9_448);
+			salsa20Test1(12, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
+		             salsa12_set1v0_0, salsa12_set1v0_192,  salsa12_set1v0_256,  salsa12_set1v0_448);
+			salsa20Test1(8, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
+		             salsa8_set1v0_0, salsa8_set1v0_192,  salsa8_set1v0_256,  salsa8_set1v0_448);
 			salsa20Test2(new ParametersWithIV(new KeyParameter(Hex.Decode("0053A6F94C9FF24598EB3E91E4378ADD3083D6297CCF2275C81B6EC11467BA0D")), Hex.Decode("0D74DB42A91077DE")),
 					set6v0_0, set6v0_65472, set6v0_65536);
 			salsa20Test2(new ParametersWithIV(new KeyParameter(Hex.Decode("0558ABFE51A4F74A9DF04396E93C8FE23588DB2E81D4277ACD2073C6196CBF12")), Hex.Decode("167DE44BB21980E7")),
@@ -125,13 +181,14 @@ namespace Org.BouncyCastle.Crypto.Tests
 		}
 
 		private void salsa20Test1(
+			int rounds,
 			ICipherParameters	parameters,
 			string				v0,
 			string				v192,
 			string				v256,
 			string				v448)
 		{
-			IStreamCipher salsa = new Salsa20Engine();
+			IStreamCipher salsa = new Salsa20Engine(rounds);
 			byte[]       buf = new byte[64];
 
 			salsa.Init(true, parameters);
@@ -144,19 +201,19 @@ namespace Org.BouncyCastle.Crypto.Tests
 				case 0:
 					if (!AreEqual(buf, Hex.Decode(v0)))
 					{
-						mismatch("v0", v0, buf);
+						mismatch("v0/" + rounds, v0, buf);
 					}
 					break;
 				case 3:
 					if (!AreEqual(buf, Hex.Decode(v192)))
 					{
-						mismatch("v192", v192, buf);
+						mismatch("v192/" + rounds, v192, buf);
 					}
 					break;
 				case 4:
 					if (!AreEqual(buf, Hex.Decode(v256)))
 					{
-						mismatch("v256", v256, buf);
+						mismatch("v256/" + rounds, v256, buf);
 					}
 					break;
 				default:
diff --git a/crypto/test/src/crypto/test/XSalsa20Test.cs b/crypto/test/src/crypto/test/XSalsa20Test.cs
new file mode 100644
index 000000000..74ed04e88
--- /dev/null
+++ b/crypto/test/src/crypto/test/XSalsa20Test.cs
@@ -0,0 +1,183 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Crypto.Engines;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Crypto.Tests
+{
+	/**
+	* XSalsa20 Test
+	*/
+	[TestFixture]
+	public class XSalsa20Test 
+		: SimpleTest
+	{
+		private class TestCase
+		{
+
+			private byte[] key;
+			private byte[] iv;
+			private byte[] plaintext;
+			private byte[] ciphertext;
+
+			public TestCase(String key, string iv, string plaintext, string ciphertext)
+			{
+				this.key = Hex.Decode(key);
+				this.iv = Hex.Decode(iv);
+				this.plaintext = Hex.Decode(plaintext);
+				this.ciphertext = Hex.Decode(ciphertext);
+			}
+
+			public byte[] Key
+			{
+				get { return key; }
+			}
+
+			public byte[] Iv
+			{
+				get { return iv; }
+			}
+
+			public byte[] Plaintext
+			{
+				get { return plaintext; }
+			}
+
+			public byte[] Ciphertext
+			{
+				get { return ciphertext; }
+			}
+		}
+
+		// Test cases generated by naclcrypto-20090308, as used by cryptopp
+		private static readonly TestCase[] TEST_CASES = new TestCase[] {
+			new TestCase(
+				"a6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff88030",
+				"9e645a74e9e0a60d8243acd9177ab51a1beb8d5a2f5d700c",
+				"093c5e5585579625337bd3ab619d615760d8c5b224a85b1d0efe0eb8a7ee163abb0376529fcc09bab506c618e13ce777d82c3ae9d1a6f972d4160287cbfe60bf2130fc0a6ff6049d0a5c8a82f429231f008082e845d7e189d37f9ed2b464e6b919e6523a8c1210bd52a02a4c3fe406d3085f5068d1909eeeca6369abc981a42e87fe665583f0ab85ae71f6f84f528e6b397af86f6917d9754b7320dbdc2fea81496f2732f532ac78c4e9c6cfb18f8e9bdf74622eb126141416776971a84f94d156beaf67aecbf2ad412e76e66e8fad7633f5b6d7f3d64b5c6c69ce29003c6024465ae3b89be78e915d88b4b5621d",
+				"b2af688e7d8fc4b508c05cc39dd583d6714322c64d7f3e63147aede2d9534934b04ff6f337b031815cd094bdbc6d7a92077dce709412286822ef0737ee47f6b7ffa22f9d53f11dd2b0a3bb9fc01d9a88f9d53c26e9365c2c3c063bc4840bfc812e4b80463e69d179530b25c158f543191cff993106511aa036043bbc75866ab7e34afc57e2cce4934a5faae6eabe4f221770183dd060467827c27a354159a081275a291f69d946d6fe28ed0b9ce08206cf484925a51b9498dbde178ddd3ae91a8581b91682d860f840782f6eea49dbb9bd721501d2c67122dea3b7283848c5f13e0c0de876bd227a856e4de593a3"),
+			new TestCase(
+				"9e1da239d155f52ad37f75c7368a536668b051952923ad44f57e75ab588e475a",
+				"af06f17859dffa799891c4288f6635b5c5a45eee9017fd72",
+				"feac9d54fc8c115ae247d9a7e919dd76cfcbc72d32cae4944860817cbdfb8c04e6b1df76a16517cd33ccf1acda9206389e9e318f5966c093cfb3ec2d9ee2de856437ed581f552f26ac2907609df8c613b9e33d44bfc21ff79153e9ef81a9d66cc317857f752cc175fd8891fefebb7d041e6517c3162d197e2112837d3bc4104312ad35b75ea686e7c70d4ec04746b52ff09c421451459fb59f",
+				"2c261a2f4e61a62e1b27689916bf03453fcbc97bb2af6f329391ef063b5a219bf984d07d70f602d85f6db61474e9d9f5a2deecb4fcd90184d16f3b5b5e168ee03ea8c93f3933a22bc3d1a5ae8c2d8b02757c87c073409052a2a8a41e7f487e041f9a49a0997b540e18621cad3a24f0a56d9b19227929057ab3ba950f6274b121f193e32e06e5388781a1cb57317c0ba6305e910961d01002f0"),
+			new TestCase("d5c7f6797b7e7e9c1d7fd2610b2abf2bc5a7885fb3ff78092fb3abe8986d35e2",
+	             "744e17312b27969d826444640e9c4a378ae334f185369c95",
+	             "7758298c628eb3a4b6963c5445ef66971222be5d1a4ad839715d1188071739b77cc6e05d5410f963a64167629757",
+	             "27b8cfe81416a76301fd1eec6a4d99675069b2da2776c360db1bdfea7c0aa613913e10f7a60fec04d11e65f2d64e"),
+			new TestCase(
+				"737d7811ce96472efed12258b78122f11deaec8759ccbd71eac6bbefa627785c",
+				"6fb2ee3dda6dbd12f1274f126701ec75c35c86607adb3edd",
+				"501325fb2645264864df11faa17bbd58312b77cad3d94ac8fb8542f0eb653ad73d7fce932bb874cb89ac39fc47f8267cf0f0c209f204b2d8578a3bdf461cb6a271a468bebaccd9685014ccbc9a73618c6a5e778a21cc8416c60ad24ddc417a130d53eda6dfbfe47d09170a7be1a708b7b5f3ad464310be36d9a2a95dc39e83d38667e842eb6411e8a23712297b165f690c2d7ca1b1346e3c1fccf5cafd4f8be0",
+				"6724c372d2e9074da5e27a6c54b2d703dc1d4c9b1f8d90f00c122e692ace7700eadca942544507f1375b6581d5a8fb39981c1c0e6e1ff2140b082e9ec016fce141d5199647d43b0b68bfd0fea5e00f468962c7384dd6129aea6a3fdfe75abb210ed5607cef8fa0e152833d5ac37d52e557b91098a322e76a45bbbcf4899e790618aa3f4c2e5e0fc3de93269a577d77a5502e8ea02f717b1dd2df1ec69d8b61ca"),
+			new TestCase(
+				"760158da09f89bbab2c99e6997f9523a95fcef10239bcca2573b7105f6898d34",
+				"43636b2cc346fc8b7c85a19bf507bdc3dafe953b88c69dba",
+				"d30a6d42dff49f0ed039a306bae9dec8d9e88366cc19e8c3642fd58fa0794ebf8029d949730339b0823a51f0f49f0d2c71f1051c1e0e2c86941f172789cdb1b0107413e70f982ff9761877bb526ef1c3eb1106a948d60ef21bd35d32cfd64f89b79ed63ecc5cca56246af736766f285d8e6b0da9cb1cd21020223ffacc5a32",
+				"c815b6b79b64f9369aec8dce8c753df8a50f2bc97c70ce2f014db33a65ac5816bac9e30ac08bdded308c65cb87e28e2e71b677dc25c5a6499c1553555daf1f55270a56959dffa0c66f24e0af00951ec4bb59ccc3a6c5f52e0981647e53e439313a52c40fa7004c855b6e6eb25b212a138e843a9ba46edb2a039ee82a263abe"),
+			new TestCase(
+				"27ba7e81e7edd4e71be53c07ce8e633138f287e155c7fa9e84c4ad804b7fa1b9",
+				"ea05f4ebcd2fb6b000da0612861ba54ff5c176fb601391aa",
+				"e09ff5d2cb050d69b2d42494bde5825238c756d6991d99d7a20d1ef0b83c371c89872690b2fc11d5369f4fc4971b6d3d6c078aef9b0f05c0e61ab89c025168054defeb03fef633858700c58b1262ce011300012673e893e44901dc18eee3105699c44c805897bdaf776af1833162a21a",
+				"a23e7ef93c5d0667c96d9e404dcbe6be62026fa98f7a3ff9ba5d458643a16a1cef7272dc6097a9b52f35983557c77a11b314b4f7d5dc2cca15ee47616f861873cbfed1d32372171a61e38e447f3cf362b3abbb2ed4170d89dcb28187b7bfd206a3e026f084a7e0ed63d319de6bc9afc0"),
+			new TestCase("6799d76e5ffb5b4920bc2768bafd3f8c16554e65efcf9a16f4683a7a06927c11",
+	             "61ab951921e54ff06d9b77f313a4e49df7a057d5fd627989", "472766", "8fd7df"),
+			new TestCase(
+				"f68238c08365bb293d26980a606488d09c2f109edafa0bbae9937b5cc219a49c",
+				"5190b51e9b708624820b5abdf4e40fad1fb950ad1adc2d26",
+				"47ec6b1f73c4b7ff5274a0bfd7f45f864812c85a12fbcb3c2cf8a3e90cf66ccf2eacb521e748363c77f52eb426ae57a0c6c78f75af71284569e79d1a92f949a9d69c4efc0b69902f1e36d7562765543e2d3942d9f6ff5948d8a312cff72c1afd9ea3088aff7640bfd265f7a9946e606abc77bcedae6bddc75a0dba0bd917d73e3bd1268f727e0096345da1ed25cf553ea7a98fea6b6f285732de37431561ee1b3064887fbcbd71935e02",
+				"36160e88d3500529ba4edba17bc24d8cfaca9a0680b3b1fc97cf03f3675b7ac301c883a68c071bc54acdd3b63af4a2d72f985e51f9d60a4c7fd481af10b2fc75e252fdee7ea6b6453190617dcc6e2fe1cd56585fc2f0b0e97c5c3f8ad7eb4f31bc4890c03882aac24cc53acc1982296526690a220271c2f6e326750d3fbda5d5b63512c831f67830f59ac49aae330b3e0e02c9ea0091d19841f1b0e13d69c9fbfe8a12d6f30bb734d9d2"),
+			new TestCase(
+				"45b2bd0de4ed9293ec3e26c4840faaf64b7d619d51e9d7a2c7e36c83d584c3df",
+				"546c8c5d6be8f90952cab3f36d7c1957baaa7a59abe3d7e5",
+				"5007c8cd5b3c40e17d7fe423a87ae0ced86bec1c39dc07a25772f3e96dabd56cd3fd7319f6c9654925f2d87087a700e1b130da796895d1c9b9acd62b266144067d373ed51e787498b03c52faad16bb3826fa511b0ed2a19a8663f5ba2d6ea7c38e7212e9697d91486c49d8a000b9a1935d6a7ff7ef23e720a45855481440463b4ac8c4f6e7062adc1f1e1e25d3d65a31812f58a71160",
+				"8eacfba568898b10c0957a7d44100685e8763a71a69a8d16bc7b3f88085bb9a2f09642e4d09a9f0ad09d0aad66b22610c8bd02ff6679bb92c2c026a216bf425c6be35fb8dae7ff0c72b0efd6a18037c70eed0ca90062a49a3c97fdc90a8f9c2ea536bfdc41918a7582c9927fae47efaa3dc87967b7887dee1bf071734c7665901d9105dae2fdf66b4918e51d8f4a48c60d19fbfbbcba"),
+			new TestCase(
+				"fe559c9a282beb40814d016d6bfcb2c0c0d8bf077b1110b8703a3ce39d70e0e1",
+				"b076200cc7011259805e18b304092754002723ebec5d6200",
+				"6db65b9ec8b114a944137c821fd606be75478d928366d5284096cdef782fcff7e8f59cb8ffcda979757902c5ffa6bc477ceaa4cb5d5ea76f94d91e833f823a6bc78f1055dfa6a97bea8965c1cde67a668e001257334a585727d9e0f7c1a06e88d3d25a4e6d9096c968bf138e116a3ebeffd4bb4808adb1fd698164ba0a35c709a47f16f1f4435a2345a9194a00b95abd51851d505809a6077da9baca5831afff31578c487ee68f2767974a98a7e803aac788da98319c4ea8eaa3d394855651f484cef543f537e35158ee29",
+				"4dce9c8f97a028051b0727f34e1b9ef21f06f0760f36e71713204027902090ba2bb6b13436ee778d9f50530efbd7a32b0d41443f58ccaee781c7b716d3a96fdec0e3764ed7959f34c3941278591ea033b5cbadc0f1916032e9bebbd1a8395b83fb63b1454bd775bd20b3a2a96f951246ac14daf68166ba62f6cbff8bd121ac9498ff8852fd2be975df52b5daef3829d18eda42e715022dcbf930d0a789ee6a146c2c7088c35773c63c06b4af4559856ac199ced86863e4294707825337c5857970eb7fddeb263781309011"),
+			new TestCase(
+				"0ae10012d7e56614b03dcc89b14bae9242ffe630f3d7e35ce8bbb97bbc2c92c3",
+				"f96b025d6cf46a8a12ac2af1e2aef1fb83590adadaa5c5ea",
+				"ea0f354e96f12bc72bbaa3d12b4a8ed879b042f0689878f46b651cc4116d6f78409b11430b3aaa30b2076891e8e1fa528f2fd169ed93dc9f84e24409eec2101daf4d057be2492d11de640cbd7b355ad29fb70400fffd7cd6d425abeeb732a0eaa4330af4c656252c4173deab653eb85c58462d7ab0f35fd12b613d29d473d330310dc323d3c66348bbdbb68a326324657cae7b77a9e34358f2cec50c85609e73056856796e3be8d62b6e2fe9f953",
+				"e8abd48924b54e5b80866be7d4ebe5cf4274cafff08b39cb2d40a8f0b472398aedc776e0793812fbf1f60078635d2ed86b15efcdba60411ee23b07233592a44ec31b1013ce8964236675f8f183aef885e864f2a72edf4215b5338fa2b54653dfa1a8c55ce5d95cc605b9b311527f2e3463ffbec78a9d1d65dabad2f338769c9f43f133a791a11c7eca9af0b771a4ac32963dc8f631a2c11217ac6e1b9430c1aae1ceebe22703f429998a8fb8c641"),
+			new TestCase(
+				"082c539bc5b20f97d767cd3f229eda80b2adc4fe49c86329b5cd6250a9877450",
+				"845543502e8b64912d8f2c8d9fffb3c69365686587c08d0c",
+				"a96bb7e910281a6dfad7c8a9c370674f0ceec1ad8d4f0de32f9ae4a23ed329e3d6bc708f876640a229153ac0e7281a8188dd77695138f01cda5f41d5215fd5c6bdd46d982cb73b1efe2997970a9fdbdb1e768d7e5db712068d8ba1af6067b5753495e23e6e1963af012f9c7ce450bf2de619d3d59542fb55f3",
+				"835da74fc6de08cbda277a7966a07c8dcd627e7b17adde6d930b6581e3124b8baad096f693991fedb1572930601fc7709541839b8e3ffd5f033d2060d999c6c6e3048276613e648000acb5212cc632a916afce290e20ebdf612d08a6aa4c79a74b070d3f872a861f8dc6bb07614db515d363349d3a8e3336a3"),
+			new TestCase("3d02bff3375d403027356b94f514203737ee9a85d2052db3e4e5a217c259d18a",
+	             "74216c95031895f48c1dba651555ebfa3ca326a755237025",
+	             "0d4b0f54fd09ae39baa5fa4baccf2e6682e61b257e01f42b8f",
+	             "16c4006c28365190411eb1593814cf15e74c22238f210afc3d"),
+			new TestCase(
+				"ad1a5c47688874e6663a0f3fa16fa7efb7ecadc175c468e5432914bdb480ffc6",
+				"e489eed440f1aae1fac8fb7a9825635454f8f8f1f52e2fcc",
+				"aa6c1e53580f03a9abb73bfdadedfecada4c6b0ebe020ef10db745e54ba861caf65f0e40dfc520203bb54d29e0a8f78f16b3f1aa525d6bfa33c54726e59988cfbec78056",
+				"02fe84ce81e178e7aabdd3ba925a766c3c24756eefae33942af75e8b464556b5997e616f3f2dfc7fce91848afd79912d9fb55201b5813a5a074d2c0d4292c1fd441807c5"),
+			new TestCase(
+				"053a02bedd6368c1fb8afc7a1b199f7f7ea2220c9a4b642a6850091c9d20ab9c",
+				"c713eea5c26dad75ad3f52451e003a9cb0d649f917c89dde",
+				"8f0a8a164760426567e388840276de3f95cb5e3fadc6ed3f3e4fe8bc169d9388804dcb94b6587dbb66cb0bd5f87b8e98b52af37ba290629b858e0e2aa7378047a26602",
+				"516710e59843e6fbd4f25d0d8ca0ec0d47d39d125e9dad987e0518d49107014cb0ae405e30c2eb3794750bca142ce95e290cf95abe15e822823e2e7d3ab21bc8fbd445"),
+			new TestCase(
+				"5b14ab0fbed4c58952548a6cb1e0000cf4481421f41288ea0aa84add9f7deb96",
+				"54bf52b911231b952ba1a6af8e45b1c5a29d97e2abad7c83",
+				"37fb44a675978b560ff9a4a87011d6f3ad2d37a2c3815b45a3c0e6d1b1d8b1784cd468927c2ee39e1dccd4765e1c3d676a335be1ccd6900a45f5d41a317648315d8a8c24adc64eb285f6aeba05b9029586353d303f17a807658b9ff790474e1737bd5fdc604aeff8dfcaf1427dcc3aacbb0256badcd183ed75a2dc52452f87d3c1ed2aa583472b0ab91cda20614e9b6fdbda3b49b098c95823cc72d8e5b717f2314b0324e9ce",
+				"ae6deb5d6ce43d4b09d0e6b1c0e9f46157bcd8ab50eaa3197ff9fa2bf7af649eb52c68544fd3adfe6b1eb316f1f23538d470c30dbfec7e57b60cbcd096c782e7736b669199c8253e70214cf2a098fda8eac5da79a9496a3aae754d03b17c6d70d1027f42bf7f95ce3d1d9c338854e158fcc803e4d6262fb639521e47116ef78a7a437ca9427ba645cd646832feab822a208278e45e93e118d780b988d65397eddfd7a819526e"),
+			new TestCase(
+				"d74636e3413a88d85f322ca80fb0bd650bd0bf0134e2329160b69609cd58a4b0",
+				"efb606aa1d9d9f0f465eaa7f8165f1ac09f5cb46fecf2a57",
+				"f85471b75f6ec81abac2799ec09e98e280b2ffd64ca285e5a0109cfb31ffab2d617b2c2952a2a8a788fc0da2af7f530758f74f1ab56391ab5ff2adbcc5be2d6c7f49fbe8118104c6ff9a23c6dfe52f57954e6a69dcee5db06f514f4a0a572a9a8525d961dae72269b987189d465df6107119c7fa790853e063cba0fab7800ca932e258880fd74c33c784675bedad0e7c09e9cc4d63dd5e9713d5d4a0196e6b562226ac31b4f57c04f90a181973737ddc7e80f364112a9fbb435ebdbcabf7d490ce52",
+				"b2b795fe6c1d4c83c1327e015a67d4465fd8e32813575cbab263e20ef05864d2dc17e0e4eb81436adfe9f638dcc1c8d78f6b0306baf938e5d2ab0b3e05e735cc6fff2d6e02e3d60484bea7c7a8e13e23197fea7b04d47d48f4a4e5944174539492800d3ef51e2ee5e4c8a0bdf050c2dd3dd74fce5e7e5c37364f7547a11480a3063b9a0a157b15b10a5a954de2731ced055aa2e2767f0891d4329c426f3808ee867bed0dc75b5922b7cfb895700fda016105a4c7b7f0bb90f029f6bbcb04ac36ac16") };
+
+		public override string Name
+		{
+			get { return "XSalsa20"; }
+		}
+
+		public override void PerformTest()
+		{
+			for (int i = 0; i < TEST_CASES.Length; i++)
+			{
+				performTest(i, TEST_CASES[i]);
+			}
+		}
+
+		private void performTest(int number, TestCase testCase)
+		{
+			byte[] plaintext = testCase.Plaintext;
+			byte[] output = new byte[plaintext.Length];
+
+			XSalsa20Engine engine = new XSalsa20Engine();
+			engine.Init(false, new ParametersWithIV(new KeyParameter(testCase.Key), testCase.Iv));
+
+			engine.ProcessBytes(testCase.Plaintext, 0, testCase.Plaintext.Length, output, 0);
+
+			if (!Arrays.AreEqual(testCase.Ciphertext, output))
+			{
+				Fail("mismatch on " + number, Hex.ToHexString(testCase.Ciphertext), Hex.ToHexString(output));
+			}
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new XSalsa20Test());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}