diff --git a/.gitignore b/.gitignore index a381890..5aad3ce 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ bin/ obj/ Debug/ Release/ -TestResults/ \ No newline at end of file +TestResults/ +.vs/ diff --git a/Chaos.NaCl.Benchmark/BenchmarkProgram.cs b/Chaos.NaCl.Benchmark/BenchmarkProgram.cs index e2d4fa4..17a654c 100644 --- a/Chaos.NaCl.Benchmark/BenchmarkProgram.cs +++ b/Chaos.NaCl.Benchmark/BenchmarkProgram.cs @@ -126,7 +126,7 @@ public static void Main() Benchmark("HSalsa20Core", () => HSalsa20Core(size), n, size); Benchmark("XSalsa20Poly1305 Encrypt", () => XSalsa20Poly1305.Encrypt(new ArraySegment(ciphertext), new ArraySegment(message), new ArraySegment(key), new ArraySegment(nonce)), n, size); Benchmark("SHA512Managed", () => new SHA512Managed().ComputeHash(message), n, size); - Benchmark("SHA512Cng", () => new SHA512Cng().ComputeHash(message), n, size); + Benchmark("SHA512Cng", () => SHA512.Create().ComputeHash(message), n, size); Benchmark("SHA512CSP", () => new SHA512CryptoServiceProvider().ComputeHash(message), n, size); Benchmark("SHA512Chaos", () => Sha512.Hash(message), n, size); } diff --git a/Chaos.NaCl.Benchmark/Chaos.NaCl.Benchmark.csproj b/Chaos.NaCl.Benchmark/Chaos.NaCl.Benchmark.csproj index ab77ce1..8e58118 100644 --- a/Chaos.NaCl.Benchmark/Chaos.NaCl.Benchmark.csproj +++ b/Chaos.NaCl.Benchmark/Chaos.NaCl.Benchmark.csproj @@ -1,62 +1,15 @@ - - - + + - Debug - AnyCPU - {28321BA8-C416-4F81-BE4C-1546CD62118B} - Exe - Properties - Chaos.NaCl.Benchmark - Chaos.NaCl.Benchmark - v4.0 - 512 + netstandard2.1 - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - + - - - + + - - {433df668-e178-4f13-a500-4d3609f450b9} - Chaos.NaCl.Tests - - - {ae28fd14-7985-4707-a963-c94b8597ae50} - Chaos.NaCl - + - - - \ No newline at end of file + + diff --git a/Chaos.NaCl.Benchmark/Properties/AssemblyInfo.cs b/Chaos.NaCl.Benchmark/Properties/AssemblyInfo.cs deleted file mode 100644 index 3b45158..0000000 --- a/Chaos.NaCl.Benchmark/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Chaos.NaCl.Benchmark")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Chaos.NaCl.Benchmark")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("d34889e9-87b3-4220-9c2a-a0e5ceb4415d")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Chaos.NaCl.Benchmark32/App.config b/Chaos.NaCl.Benchmark32/App.config deleted file mode 100644 index 58262a1..0000000 --- a/Chaos.NaCl.Benchmark32/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/Chaos.NaCl.Benchmark32/Chaos.NaCl.Benchmark32.csproj b/Chaos.NaCl.Benchmark32/Chaos.NaCl.Benchmark32.csproj index 0eb9fd4..8076b23 100644 --- a/Chaos.NaCl.Benchmark32/Chaos.NaCl.Benchmark32.csproj +++ b/Chaos.NaCl.Benchmark32/Chaos.NaCl.Benchmark32.csproj @@ -1,56 +1,12 @@ - - - + + - Debug - AnyCPU - {414429EE-D02E-485B-BE58-52DF33CF56AA} + netcoreapp3.1 Exe - Properties - Chaos.NaCl.Benchmark32 - Chaos.NaCl.Benchmark32 - v4.0 - 512 - - - x86 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - x86 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - + - - {28321ba8-c416-4f81-be4c-1546cd62118b} - Chaos.NaCl.Benchmark - + - - - \ No newline at end of file + + diff --git a/Chaos.NaCl.Benchmark32/Properties/AssemblyInfo.cs b/Chaos.NaCl.Benchmark32/Properties/AssemblyInfo.cs deleted file mode 100644 index 12dce53..0000000 --- a/Chaos.NaCl.Benchmark32/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Chaos.NaCl.Benchmark32")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Chaos.NaCl.Benchmark32")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("b0982b05-63bc-42d9-8c9b-497c283b28fb")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Chaos.NaCl.Tests/ArrayTests.cs b/Chaos.NaCl.Tests/ArrayTests.cs index fbb030d..cfc48f9 100644 --- a/Chaos.NaCl.Tests/ArrayTests.cs +++ b/Chaos.NaCl.Tests/ArrayTests.cs @@ -2,16 +2,16 @@ using System.Collections.Generic; using System.Linq; using Chaos.NaCl.Internal; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Xunit; namespace Chaos.NaCl.Tests { - [TestClass] + public class ArrayTests { private static readonly byte[] _testInput = Enumerable.Repeat((byte)0xFF, 100).Concat(Enumerable.Range(1, 250).Select(i => (byte)i)).ToArray(); - /*[TestMethod] + /*[Fact] public void Array8FromBytesLittleEndian() { for (int len = 1; len <= 32; len++) @@ -25,7 +25,7 @@ public void Array8FromBytesLittleEndian() } }*/ - /*[TestMethod] + /*[Fact] public void Array16FromBytesLittleEndian() { for (int len = 1; len <= 64; len++) diff --git a/Chaos.NaCl.Tests/Chaos.NaCl.Tests.csproj b/Chaos.NaCl.Tests/Chaos.NaCl.Tests.csproj index eb76328..2afaf4e 100644 --- a/Chaos.NaCl.Tests/Chaos.NaCl.Tests.csproj +++ b/Chaos.NaCl.Tests/Chaos.NaCl.Tests.csproj @@ -1,104 +1,21 @@ - - + + - Debug - AnyCPU - {433DF668-E178-4F13-A500-4D3609F450B9} - Library - Properties - Chaos.NaCl.Tests - Chaos.NaCl.Tests - v4.0 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest + netcoreapp3.1 + + false - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - 3.5 - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + + + + + + - - {ae28fd14-7985-4707-a963-c94b8597ae50} - Chaos.NaCl - + - - - - - False - - - False - - - False - - - False - - - - - - - - \ No newline at end of file + + diff --git a/Chaos.NaCl.Tests/CryptoBytesTest.cs b/Chaos.NaCl.Tests/CryptoBytesTest.cs index a39196a..626cb31 100644 --- a/Chaos.NaCl.Tests/CryptoBytesTest.cs +++ b/Chaos.NaCl.Tests/CryptoBytesTest.cs @@ -1,10 +1,10 @@ using System; using System.Linq; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Xunit; namespace Chaos.NaCl.Tests { - [TestClass] + public class CryptoBytesTest { readonly byte[] _bytes = Enumerable.Range(0, 256).Select(i => (byte)i).ToArray(); @@ -69,96 +69,94 @@ public class CryptoBytesTest "8PHy8/T19vf4+fr7" + "/P3+/w=="; - [TestMethod] + [Fact] public void ToHexStringUpper() { - Assert.AreEqual(HexStringUpper, CryptoBytes.ToHexStringUpper(_bytes)); + Assert.Equal(HexStringUpper, CryptoBytes.ToHexStringUpper(_bytes)); } - [TestMethod] + [Fact] public void ToHexStringLower() { - Assert.AreEqual(HexStringLower, CryptoBytes.ToHexStringLower(_bytes)); + Assert.Equal(HexStringLower, CryptoBytes.ToHexStringLower(_bytes)); } - [TestMethod] + [Fact] public void ToHexStringLowerNull() { - Assert.AreEqual(null, CryptoBytes.ToHexStringLower(null)); + Assert.Equal(null, CryptoBytes.ToHexStringLower(null)); } - [TestMethod] + [Fact] public void ToHexStringUpperNull() { - Assert.AreEqual(null, CryptoBytes.ToHexStringUpper(null)); + Assert.Equal(null, CryptoBytes.ToHexStringUpper(null)); } - [TestMethod] + [Fact] public void FromHexStringUpperCase() { - Assert.IsTrue(_bytes.SequenceEqual(CryptoBytes.FromHexString(HexStringUpper))); + Assert.True(_bytes.SequenceEqual(CryptoBytes.FromHexString(HexStringUpper))); } - [TestMethod] + [Fact] public void FromHexStringLowerCase() { - Assert.IsTrue(_bytes.SequenceEqual(CryptoBytes.FromHexString(HexStringLower))); + Assert.True(_bytes.SequenceEqual(CryptoBytes.FromHexString(HexStringLower))); } - [TestMethod] + [Fact] public void FromHexStringNull() { - Assert.AreEqual(null, CryptoBytes.FromHexString(null)); + Assert.Null(CryptoBytes.FromHexString(null)); } - [TestMethod] - [ExpectedException(typeof(FormatException))] + [Fact] public void FromHexStringWithOddLengthFails() { - CryptoBytes.FromHexString("A"); + Assert.Throws(() => CryptoBytes.FromHexString("A")); } - [TestMethod] - [ExpectedException(typeof(FormatException))] + [Fact] public void FromHexStringWithInvalidCharactersFails() { - CryptoBytes.FromHexString("AQ"); + Assert.Throws(() => CryptoBytes.FromHexString("AQ")); } - [TestMethod] + [Fact] public void ToBase64String() { - Assert.AreEqual(Base64String, CryptoBytes.ToBase64String(_bytes)); + Assert.Equal(Base64String, CryptoBytes.ToBase64String(_bytes)); } - [TestMethod] + [Fact] public void FromBase64String() { - Assert.IsTrue(_bytes.SequenceEqual(CryptoBytes.FromBase64String(Base64String))); + Assert.True(_bytes.SequenceEqual(CryptoBytes.FromBase64String(Base64String))); } - [TestMethod] + [Fact] public void ToBase64StringNull() { - Assert.AreEqual(null, CryptoBytes.ToBase64String(null)); + Assert.Equal(null, CryptoBytes.ToBase64String(null)); } - [TestMethod] + [Fact] public void FromBase64StringNull() { - Assert.AreEqual(null, CryptoBytes.FromBase64String(null)); + Assert.Equal(null, CryptoBytes.FromBase64String(null)); } - [TestMethod] + [Fact] public void Wipe() { var bytes = (byte[])_bytes.Clone(); CryptoBytes.Wipe(bytes); - Assert.IsTrue(bytes.All(b => b == 0)); + Assert.True(bytes.All(b => b == 0)); } - [TestMethod] + [Fact] public void WipeInterval() { var bytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; @@ -167,7 +165,7 @@ public void WipeInterval() TestHelpers.AssertEqualBytes(wipedBytes, bytes); } - [TestMethod] + [Fact] public void WipeSegment() { var bytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; @@ -176,53 +174,53 @@ public void WipeSegment() TestHelpers.AssertEqualBytes(wipedBytes, bytes); } - [TestMethod] + [Fact] public void ConstantTimeEqualsSuccess() { var x = new byte[] { 1, 2, 3 }; var y = new byte[] { 1, 2, 3 }; - Assert.IsTrue(CryptoBytes.ConstantTimeEquals(x, y)); + Assert.True(CryptoBytes.ConstantTimeEquals(x, y)); } - [TestMethod] + [Fact] public void ConstantTimeEqualsFail() { var x = new byte[] { 1, 2, 3 }; foreach (var y in x.WithChangedBit()) { - Assert.IsFalse(CryptoBytes.ConstantTimeEquals(x, y)); + Assert.False(CryptoBytes.ConstantTimeEquals(x, y)); } } - [TestMethod] + [Fact] public void ConstantTimeEqualsSegmentsSuccess() { var x = new byte[] { 1, 2, 3 }; var y = new byte[] { 1, 2, 3 }; - Assert.IsTrue(CryptoBytes.ConstantTimeEquals(x.Pad(), y.Pad())); + Assert.True(CryptoBytes.ConstantTimeEquals(x.Pad(), y.Pad())); } - [TestMethod] + [Fact] public void ConstantTimeEqualsSegmentsFail() { var x = new byte[] { 1, 2, 3 }; foreach (var y in x.WithChangedBit()) { - Assert.IsFalse(CryptoBytes.ConstantTimeEquals(x.Pad(), y.Pad())); + Assert.False(CryptoBytes.ConstantTimeEquals(x.Pad(), y.Pad())); } } - [TestMethod] + [Fact] public void ConstantTimeEqualsRangeSuccess() { var x = new byte[] { 1, 2, 3 }; var y = new byte[] { 1, 2, 3 }; var paddedX = x.Pad(); var paddedY = y.Pad(); - Assert.IsTrue(CryptoBytes.ConstantTimeEquals(paddedX.Array, paddedX.Offset, paddedY.Array, paddedY.Offset, paddedX.Count)); + Assert.True(CryptoBytes.ConstantTimeEquals(paddedX.Array, paddedX.Offset, paddedY.Array, paddedY.Offset, paddedX.Count)); } - [TestMethod] + [Fact] public void ConstantTimeEqualsRangeFail() { var x = new byte[] { 1, 2, 3 }; @@ -230,147 +228,145 @@ public void ConstantTimeEqualsRangeFail() { var paddedX = x.Pad(); var paddedY = y.Pad(); - Assert.IsFalse(CryptoBytes.ConstantTimeEquals(paddedX.Array, paddedX.Offset, paddedY.Array, paddedY.Offset, paddedX.Count)); + Assert.False(CryptoBytes.ConstantTimeEquals(paddedX.Array, paddedX.Offset, paddedY.Array, paddedY.Offset, paddedX.Count)); } } #region Argument Validation - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] + [Fact] public void ConstantTimeEqualsXMustNotBeNull() { - CryptoBytes.ConstantTimeEquals(null, new byte[1]); + Assert.Throws(() => CryptoBytes.ConstantTimeEquals(null, new byte[1])); } - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] + [Fact] public void ConstantTimeEqualsYMustNotBeNull() { - CryptoBytes.ConstantTimeEquals(new byte[1], null); + Assert.Throws(() => CryptoBytes.ConstantTimeEquals(new byte[1], null)); } - [TestMethod] - [ExpectedException(typeof(ArgumentException))] + [Fact] public void ConstantTimeEqualsXAndYMustHaveSameLength() { - CryptoBytes.ConstantTimeEquals(new byte[1], new byte[2]); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentException))] - public void ConstantTimeEqualsSegmentsMustHaveSameLength() - { - var x = new byte[5]; - var y = new byte[5]; - CryptoBytes.ConstantTimeEquals(new ArraySegment(x, 0, 4), new ArraySegment(y, 0, 5)); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] - public void ConstantTimeEqualsSegmentsXMustNotBeNull() - { - CryptoBytes.ConstantTimeEquals(default(ArraySegment), new ArraySegment(new byte[1])); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] - public void ConstantTimeEqualsSegmentsYMustNotBeNull() - { - CryptoBytes.ConstantTimeEquals(new ArraySegment(new byte[1]), default(ArraySegment)); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] - public void WipeNullFails() - { - CryptoBytes.Wipe(null); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] - public void ConstantTimeEqualsRangeXmustNotBeNull() - { - CryptoBytes.ConstantTimeEquals(null, 0, new byte[10], 0, 1); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] - public void ConstantTimeEqualsRangeYmustNotBeNull() - { - CryptoBytes.ConstantTimeEquals(new byte[10], 0, null, 0, 1); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentOutOfRangeException))] - public void ConstantTimeEqualsRangeXoffsetMustNotBeNegative() - { - CryptoBytes.ConstantTimeEquals(new byte[10], -1, new byte[10], 0, 1); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentOutOfRangeException))] - public void ConstantTimeEqualsRangeYoffsetMustNotBeNegative() - { - CryptoBytes.ConstantTimeEquals(new byte[10], 0, new byte[10], -1, 1); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentOutOfRangeException))] - public void ConstantTimeEqualsRangeLengthMustNotBeNegative() - { - CryptoBytes.ConstantTimeEquals(new byte[10], 0, new byte[10], 0, -1); - } - - - [TestMethod] - [ExpectedException(typeof(ArgumentException))] - public void ConstantTimeEqualsRangeLengthTooBigX() - { - CryptoBytes.ConstantTimeEquals(new byte[10], 8, new byte[10], 1, 7); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentException))] - public void ConstantTimeEqualsRangeLengthTooBigY() - { - CryptoBytes.ConstantTimeEquals(new byte[10], 1, new byte[10], 8, 7); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] - public void WipeSegmentNullFails() - { - CryptoBytes.Wipe(default(ArraySegment)); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] - public void WipeRangeNullFails() - { - CryptoBytes.Wipe(null, 0, 0); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentOutOfRangeException))] - public void WipeRangeNegativeOffsetFails() - { - CryptoBytes.Wipe(new byte[10], -1, 0); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentOutOfRangeException))] - public void WipeRangeNegativeLengthFails() - { - CryptoBytes.Wipe(new byte[10], 0, -1); - } - - [TestMethod] - [ExpectedException(typeof(ArgumentException))] - public void WipeRangeTooLargeLengthFails() - { - CryptoBytes.Wipe(new byte[10], 8, 8); - } + Assert.Throws(() => CryptoBytes.ConstantTimeEquals(new byte[1], new byte[2])); + } + + // TODO: TM: Add Assert.Throws + //[Fact] + //[ExpectedException(typeof(ArgumentException))] + //public void ConstantTimeEqualsSegmentsMustHaveSameLength() + //{ + // var x = new byte[5]; + // var y = new byte[5]; + // CryptoBytes.ConstantTimeEquals(new ArraySegment(x, 0, 4), new ArraySegment(y, 0, 5)); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentNullException))] + //public void ConstantTimeEqualsSegmentsXMustNotBeNull() + //{ + // CryptoBytes.ConstantTimeEquals(default(ArraySegment), new ArraySegment(new byte[1])); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentNullException))] + //public void ConstantTimeEqualsSegmentsYMustNotBeNull() + //{ + // CryptoBytes.ConstantTimeEquals(new ArraySegment(new byte[1]), default(ArraySegment)); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentNullException))] + //public void WipeNullFails() + //{ + // CryptoBytes.Wipe(null); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentNullException))] + //public void ConstantTimeEqualsRangeXmustNotBeNull() + //{ + // CryptoBytes.ConstantTimeEquals(null, 0, new byte[10], 0, 1); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentNullException))] + //public void ConstantTimeEqualsRangeYmustNotBeNull() + //{ + // CryptoBytes.ConstantTimeEquals(new byte[10], 0, null, 0, 1); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentOutOfRangeException))] + //public void ConstantTimeEqualsRangeXoffsetMustNotBeNegative() + //{ + // CryptoBytes.ConstantTimeEquals(new byte[10], -1, new byte[10], 0, 1); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentOutOfRangeException))] + //public void ConstantTimeEqualsRangeYoffsetMustNotBeNegative() + //{ + // CryptoBytes.ConstantTimeEquals(new byte[10], 0, new byte[10], -1, 1); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentOutOfRangeException))] + //public void ConstantTimeEqualsRangeLengthMustNotBeNegative() + //{ + // CryptoBytes.ConstantTimeEquals(new byte[10], 0, new byte[10], 0, -1); + //} + + + //[Fact] + //[ExpectedException(typeof(ArgumentException))] + //public void ConstantTimeEqualsRangeLengthTooBigX() + //{ + // CryptoBytes.ConstantTimeEquals(new byte[10], 8, new byte[10], 1, 7); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentException))] + //public void ConstantTimeEqualsRangeLengthTooBigY() + //{ + // CryptoBytes.ConstantTimeEquals(new byte[10], 1, new byte[10], 8, 7); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentNullException))] + //public void WipeSegmentNullFails() + //{ + // CryptoBytes.Wipe(default(ArraySegment)); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentNullException))] + //public void WipeRangeNullFails() + //{ + // CryptoBytes.Wipe(null, 0, 0); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentOutOfRangeException))] + //public void WipeRangeNegativeOffsetFails() + //{ + // CryptoBytes.Wipe(new byte[10], -1, 0); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentOutOfRangeException))] + //public void WipeRangeNegativeLengthFails() + //{ + // CryptoBytes.Wipe(new byte[10], 0, -1); + //} + + //[Fact] + //[ExpectedException(typeof(ArgumentException))] + //public void WipeRangeTooLargeLengthFails() + //{ + // CryptoBytes.Wipe(new byte[10], 8, 8); + //} #endregion } } diff --git a/Chaos.NaCl.Tests/Ed25519Tests.cs b/Chaos.NaCl.Tests/Ed25519Tests.cs index 5e77d99..5bf3773 100644 --- a/Chaos.NaCl.Tests/Ed25519Tests.cs +++ b/Chaos.NaCl.Tests/Ed25519Tests.cs @@ -2,25 +2,13 @@ using System.Collections.Generic; using System.Linq; using System.Numerics; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Xunit; namespace Chaos.NaCl.Tests { - [TestClass] public class Ed25519Tests { - [AssemblyInitializeAttribute] - public static void LoadTestVectors(TestContext context) - { - Ed25519TestVectors.LoadTestCases(); - //Warmup - var pk = Ed25519.PublicKeyFromSeed(new byte[32]); - var sk = Ed25519.ExpandedPrivateKeyFromSeed(new byte[32]); - var sig = Ed25519.Sign(Ed25519TestVectors.TestCases.Last().Message, sk); - Ed25519.Verify(sig, new byte[10], pk); - } - - [TestMethod] + [Fact] public void KeyPairFromSeed() { foreach (var testCase in Ed25519TestVectors.TestCases) @@ -34,7 +22,7 @@ public void KeyPairFromSeed() } - [TestMethod] + [Fact] public void KeyPairFromSeedSegments() { foreach (var testCase in Ed25519TestVectors.TestCases) @@ -47,28 +35,28 @@ public void KeyPairFromSeedSegments() } } - [TestMethod] + [Fact] public void Sign() { foreach (var testCase in Ed25519TestVectors.TestCases) { var sig = Ed25519.Sign(testCase.Message, testCase.PrivateKey); - Assert.AreEqual(64, sig.Length); + Assert.Equal(64, sig.Length); TestHelpers.AssertEqualBytes(testCase.Signature, sig); } } - [TestMethod] + [Fact] public void Verify() { foreach (var testCase in Ed25519TestVectors.TestCases) { bool success = Ed25519.Verify(testCase.Signature, testCase.Message, testCase.PublicKey); - Assert.IsTrue(success); + Assert.True(success); } } - [TestMethod] + [Fact] public void VerifyFail() { var message = Enumerable.Range(0, 100).Select(i => (byte)i).ToArray(); @@ -76,14 +64,14 @@ public void VerifyFail() byte[] sk; Ed25519.KeyPairFromSeed(out pk, out sk, new byte[32]); var signature = Ed25519.Sign(message, sk); - Assert.IsTrue(Ed25519.Verify(signature, message, pk)); + Assert.True(Ed25519.Verify(signature, message, pk)); foreach (var modifiedMessage in message.WithChangedBit()) { - Assert.IsFalse(Ed25519.Verify(signature, modifiedMessage, pk)); + Assert.False(Ed25519.Verify(signature, modifiedMessage, pk)); } foreach (var modifiedSignature in signature.WithChangedBit()) { - Assert.IsFalse(Ed25519.Verify(modifiedSignature, message, pk)); + Assert.False(Ed25519.Verify(modifiedSignature, message, pk)); } } @@ -110,7 +98,7 @@ private byte[] AddLToSignature(byte[] signature) // This test serves to document the *is* behaviour, and doesn't define *should* behaviour // // I consider rejecting signatures with S >= l, but should probably talk to upstream and libsodium before that - [TestMethod] + [Fact] public void MalleabilityAddL() { var message = Enumerable.Range(0, 100).Select(i => (byte)i).ToArray(); @@ -118,24 +106,24 @@ public void MalleabilityAddL() byte[] sk; Ed25519.KeyPairFromSeed(out pk, out sk, new byte[32]); var signature = Ed25519.Sign(message, sk); - Assert.IsTrue(Ed25519.Verify(signature, message, pk)); + Assert.True(Ed25519.Verify(signature, message, pk)); var modifiedSignature = AddLToSignature(signature); - Assert.IsTrue(Ed25519.Verify(modifiedSignature, message, pk)); + Assert.True(Ed25519.Verify(modifiedSignature, message, pk)); var modifiedSignature2 = AddLToSignature(modifiedSignature); - Assert.IsFalse(Ed25519.Verify(modifiedSignature2, message, pk)); + Assert.False(Ed25519.Verify(modifiedSignature2, message, pk)); } - [TestMethod] + [Fact] public void VerifySegments() { foreach (var testCase in Ed25519TestVectors.TestCases) { bool success = Ed25519.Verify(testCase.Signature.Pad(), testCase.Message.Pad(), testCase.PublicKey.Pad()); - Assert.IsTrue(success); + Assert.True(success); } } - [TestMethod] + [Fact] public void VerifyFailSegments() { var message = Enumerable.Range(0, 100).Select(i => (byte)i).ToArray(); @@ -143,18 +131,18 @@ public void VerifyFailSegments() byte[] sk; Ed25519.KeyPairFromSeed(out pk, out sk, new byte[32]); var signature = Ed25519.Sign(message, sk); - Assert.IsTrue(Ed25519.Verify(signature.Pad(), message.Pad(), pk.Pad())); + Assert.True(Ed25519.Verify(signature.Pad(), message.Pad(), pk.Pad())); foreach (var modifiedMessage in message.WithChangedBit()) { - Assert.IsFalse(Ed25519.Verify(signature.Pad(), modifiedMessage.Pad(), pk.Pad())); + Assert.False(Ed25519.Verify(signature.Pad(), modifiedMessage.Pad(), pk.Pad())); } foreach (var modifiedSignature in signature.WithChangedBit()) { - Assert.IsFalse(Ed25519.Verify(modifiedSignature.Pad(), message.Pad(), pk.Pad())); + Assert.False(Ed25519.Verify(modifiedSignature.Pad(), message.Pad(), pk.Pad())); } } - [TestMethod] + [Fact] public void KeyExchange() { var seed = new byte[32]; @@ -170,7 +158,7 @@ public void KeyExchange() TestHelpers.AssertEqualBytes(sharedMontgomery, sharedEdwards); } - [TestMethod] + [Fact] public void KeyExchangeSegments() { var seed = new byte[32].Pad(); diff --git a/Chaos.NaCl.Tests/InternalAssertTests.cs b/Chaos.NaCl.Tests/InternalAssertTests.cs index c74dc0f..6ab429d 100644 --- a/Chaos.NaCl.Tests/InternalAssertTests.cs +++ b/Chaos.NaCl.Tests/InternalAssertTests.cs @@ -2,24 +2,23 @@ using System.Collections.Generic; using System.Linq; using Chaos.NaCl.Internal; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Xunit; namespace Chaos.NaCl.Tests { - [TestClass] + public class InternalAssertTests { - [TestMethod] + [Fact] public void AssertSuccess() { InternalAssert.Assert(true, "a"); } - [TestMethod] - [ExpectedException(typeof(InvalidOperationException))] + [Fact] public void AssertFail() { - InternalAssert.Assert(false, "a"); + Assert.Throws(() => InternalAssert.Assert(false, "a")); } } } diff --git a/Chaos.NaCl.Tests/MontgomeryCurve25519Tests.cs b/Chaos.NaCl.Tests/MontgomeryCurve25519Tests.cs index e0e8378..9d19081 100644 --- a/Chaos.NaCl.Tests/MontgomeryCurve25519Tests.cs +++ b/Chaos.NaCl.Tests/MontgomeryCurve25519Tests.cs @@ -1,27 +1,27 @@ using System; using System.Linq; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Xunit; namespace Chaos.NaCl.Tests { - [TestClass] + public class MontgomeryCurve25519Tests { - [TestMethod] + [Fact] public void GetPublicKeyAlice() { var calculatedAlicePublicKey = MontgomeryCurve25519.GetPublicKey(MontgomeryCurve25519TestVectors.AlicePrivateKey); - Assert.IsTrue(MontgomeryCurve25519TestVectors.AlicePublicKey.SequenceEqual(calculatedAlicePublicKey)); + Assert.True(MontgomeryCurve25519TestVectors.AlicePublicKey.SequenceEqual(calculatedAlicePublicKey)); } - [TestMethod] + [Fact] public void GetPublicKeyBob() { var calculatedBobPublicKey = MontgomeryCurve25519.GetPublicKey(MontgomeryCurve25519TestVectors.BobPrivateKey); - Assert.IsTrue(MontgomeryCurve25519TestVectors.BobPublicKey.SequenceEqual(calculatedBobPublicKey)); + Assert.True(MontgomeryCurve25519TestVectors.BobPublicKey.SequenceEqual(calculatedBobPublicKey)); } - [TestMethod] + [Fact] public void GetPublicKeySegments() { var privateKey = MontgomeryCurve25519TestVectors.BobPrivateKey.Pad(); @@ -30,7 +30,7 @@ public void GetPublicKeySegments() TestHelpers.AssertEqualBytes(MontgomeryCurve25519TestVectors.BobPublicKey, calculatedBobPublicKey.UnPad()); } - [TestMethod] + [Fact] public void GetSharedKeySegments() { var bobPublic = MontgomeryCurve25519TestVectors.BobPublicKey.Pad(); @@ -40,21 +40,21 @@ public void GetSharedKeySegments() TestHelpers.AssertEqualBytes(MontgomeryCurve25519TestVectors.AliceBobSharedKey, calculatedSharedAlice.UnPad()); } - [TestMethod] + [Fact] public void GetSharedKeyAliceBob() { var calculatedSharedAlice = MontgomeryCurve25519.KeyExchange(MontgomeryCurve25519TestVectors.BobPublicKey, MontgomeryCurve25519TestVectors.AlicePrivateKey); TestHelpers.AssertEqualBytes(MontgomeryCurve25519TestVectors.AliceBobSharedKey, calculatedSharedAlice); } - [TestMethod] + [Fact] public void GetSharedKeyAliceFrank0() { var calculatedSharedAliceFrank = MontgomeryCurve25519.KeyExchange(MontgomeryCurve25519TestVectors.FrankPublicKey0, MontgomeryCurve25519TestVectors.AlicePrivateKey); TestHelpers.AssertEqualBytes(MontgomeryCurve25519TestVectors.AliceFrankSharedKey, calculatedSharedAliceFrank); } - [TestMethod] + [Fact] public void GetSharedKeyAliceFrank() { var calculatedSharedAliceFrank = MontgomeryCurve25519.KeyExchange(MontgomeryCurve25519TestVectors.FrankPublicKey, MontgomeryCurve25519TestVectors.AlicePrivateKey); @@ -62,21 +62,21 @@ public void GetSharedKeyAliceFrank() } - [TestMethod] + [Fact] public void GetSharedKeyBobAlice() { var calculatedSharedBob = MontgomeryCurve25519.KeyExchange(MontgomeryCurve25519TestVectors.AlicePublicKey, MontgomeryCurve25519TestVectors.BobPrivateKey); TestHelpers.AssertEqualBytes(MontgomeryCurve25519TestVectors.AliceBobSharedKey, calculatedSharedBob); } - [TestMethod] + [Fact] public void GetSharedKeyBobFrank() { var calculatedSharedBobFrank = MontgomeryCurve25519.KeyExchange(MontgomeryCurve25519TestVectors.FrankPublicKey, MontgomeryCurve25519TestVectors.BobPrivateKey); TestHelpers.AssertEqualBytes(MontgomeryCurve25519TestVectors.BobFrankSharedKey, calculatedSharedBobFrank); } - [TestMethod] + [Fact] public void GetSharedKeyBobAlice2() { var calculatedSharedBob = MontgomeryCurve25519.KeyExchange(MontgomeryCurve25519TestVectors.AlicePublicKey2, MontgomeryCurve25519TestVectors.BobPrivateKey); diff --git a/Chaos.NaCl.Tests/Poly1305Tests.cs b/Chaos.NaCl.Tests/Poly1305Tests.cs index f2341bb..e1a5347 100644 --- a/Chaos.NaCl.Tests/Poly1305Tests.cs +++ b/Chaos.NaCl.Tests/Poly1305Tests.cs @@ -1,23 +1,23 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Xunit; namespace Chaos.NaCl.Tests { - [TestClass] - class Poly1305Tests + + public class Poly1305Tests { - [TestMethod] + [Fact] public void KeySizeIs32() { - Assert.AreEqual(32, OneTimeAuth.Poly1305.KeySizeInBytes); + Assert.Equal(32, OneTimeAuth.Poly1305.KeySizeInBytes); } - [TestMethod] + [Fact] public void SignatureSizeIs16() { - Assert.AreEqual(32, OneTimeAuth.Poly1305.SignatureSizeInBytes); + Assert.Equal(16, OneTimeAuth.Poly1305.SignatureSizeInBytes); } } } diff --git a/Chaos.NaCl.Tests/Properties/AssemblyInfo.cs b/Chaos.NaCl.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index eed3274..0000000 --- a/Chaos.NaCl.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Chaos.NaCl.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Chaos.NaCl.Tests")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("f7aaf8d7-ad24-45b6-884b-8e1afeed405f")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Chaos.NaCl.Tests/SalsaCoreTests.cs b/Chaos.NaCl.Tests/SalsaCoreTests.cs index 9ec57cb..24a4f7c 100644 --- a/Chaos.NaCl.Tests/SalsaCoreTests.cs +++ b/Chaos.NaCl.Tests/SalsaCoreTests.cs @@ -2,11 +2,11 @@ using System.Linq; using Chaos.NaCl.Internal; using Chaos.NaCl.Internal.Salsa; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Xunit; namespace Chaos.NaCl.Tests { - [TestClass] + public class SalsaCoreTests { private T[] ToArray(Array16 a) @@ -31,17 +31,17 @@ private T[] ToArray(Array16 a) return result; } - [TestMethod] + [Fact] public void Zero() { Array16 input = new Array16(); Array16 output; UInt32[] expected = new UInt32[16]; SalsaCore.Salsa(out output, ref input, 20); - Assert.IsTrue(ToArray(output).SequenceEqual(expected)); + Assert.True(ToArray(output).SequenceEqual(expected)); } - [TestMethod] + [Fact] public void DoubleRound1() { Array16 input = new Array16(); @@ -55,10 +55,10 @@ public void DoubleRound1() 0x20500000,0xa0000040,0x0008180a,0x612a8020 }; SalsaCore.HSalsa(out output, ref input, 2); - Assert.IsTrue(ToArray(output).SequenceEqual(expected)); + Assert.True(ToArray(output).SequenceEqual(expected)); } - [TestMethod] + [Fact] public void Salsa20() { byte[] input = new byte[64]{ @@ -82,7 +82,7 @@ public void Salsa20() TestHelpers.AssertEqualBytes(expectedOutput, actualOutput); } - [TestMethod] + [Fact] public void Salsa20_1000000() { byte[] input = new byte[64]{ diff --git a/Chaos.NaCl.Tests/Sha512Tests.cs b/Chaos.NaCl.Tests/Sha512Tests.cs index 7058252..c9d0388 100644 --- a/Chaos.NaCl.Tests/Sha512Tests.cs +++ b/Chaos.NaCl.Tests/Sha512Tests.cs @@ -3,11 +3,11 @@ using System.Linq; using System.Security.Cryptography; using Chaos.NaCl.Internal; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Xunit; namespace Chaos.NaCl.Tests { - [TestClass] + public class Sha512Tests { private static readonly byte[] _sha512HashAbc = new byte[] @@ -22,7 +22,7 @@ public class Sha512Tests 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F }; - [TestMethod] + [Fact] public void Sha512_1() { var sha512Framework = new SHA512Managed(); @@ -35,7 +35,7 @@ public void Sha512_1() } } - [TestMethod] + [Fact] public void Sha512_2() { var sha512Framework = new SHA512Managed(); @@ -49,7 +49,7 @@ public void Sha512_2() } - [TestMethod] + [Fact] public void Sha512_Split() { // use only a subset of possible indices to speed up the test @@ -71,7 +71,7 @@ public void Sha512_Split() } } - [TestMethod] + [Fact] public void Sha512_Reuse() { var message = Enumerable.Range(1, 100).Select(i => (byte)i).ToArray(); @@ -89,7 +89,7 @@ public void Sha512_Reuse() TestHelpers.AssertEqualBytes(hashExpected, hash2); } - [TestMethod] + [Fact] public void Sha512_1000000() { Array8 state; @@ -99,7 +99,7 @@ public void Sha512_1000000() Sha512Internal.Core(out state, ref state, ref data); } - [TestMethod] + [Fact] public void Sha512Abc() { var message = new[] { (byte)'a', (byte)'b', (byte)'c' }; @@ -108,7 +108,7 @@ public void Sha512Abc() TestHelpers.AssertEqualBytes(hashExpected, hash); } - [TestMethod] + [Fact] public void Sha512OutputSegments() { var message = new[] { (byte)'a', (byte)'b', (byte)'c' }; @@ -120,28 +120,29 @@ public void Sha512OutputSegments() TestHelpers.AssertEqualBytes(hashExpected, output.UnPad()); } - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] - public void Sha512OutputSegmentsNull() - { - var sha512 = new Sha512(); - sha512.Finish(default(ArraySegment)); - } + // TODO: TM: Add Assert.Throws + //[Fact] + //[ExpectedException(typeof(ArgumentNullException))] + //public void Sha512OutputSegmentsNull() + //{ + // var sha512 = new Sha512(); + // sha512.Finish(default(ArraySegment)); + //} - [TestMethod] - [ExpectedException(typeof(ArgumentException))] - public void Sha512OutputSegmentsIncorretOutputSize() - { - var sha512 = new Sha512(); - sha512.Finish(new byte[32].Pad()); - } + //[Fact] + //[ExpectedException(typeof(ArgumentException))] + //public void Sha512OutputSegmentsIncorretOutputSize() + //{ + // var sha512 = new Sha512(); + // sha512.Finish(new byte[32].Pad()); + //} - [TestMethod] - [ExpectedException(typeof(ArgumentNullException))] - public void Sha512UpdateSegmentsNull() - { - var sha512 = new Sha512(); - sha512.Update(default(ArraySegment)); - } + //[Fact] + //[ExpectedException(typeof(ArgumentNullException))] + //public void Sha512UpdateSegmentsNull() + //{ + // var sha512 = new Sha512(); + // sha512.Update(default(ArraySegment)); + //} } } diff --git a/Chaos.NaCl.Tests/TestFixture.cs b/Chaos.NaCl.Tests/TestFixture.cs new file mode 100644 index 0000000..345e228 --- /dev/null +++ b/Chaos.NaCl.Tests/TestFixture.cs @@ -0,0 +1,17 @@ +using System.Linq; + +namespace Chaos.NaCl.Tests +{ + public class TestFixture + { + public TestFixture() + { + Ed25519TestVectors.LoadTestCases(); + //Warmup + var pk = Ed25519.PublicKeyFromSeed(new byte[32]); + var sk = Ed25519.ExpandedPrivateKeyFromSeed(new byte[32]); + var sig = Ed25519.Sign(Ed25519TestVectors.TestCases.Last().Message, sk); + Ed25519.Verify(sig, new byte[10], pk); + } + } +} diff --git a/Chaos.NaCl.Tests/TestHelpers.cs b/Chaos.NaCl.Tests/TestHelpers.cs index 62316bf..d51939a 100644 --- a/Chaos.NaCl.Tests/TestHelpers.cs +++ b/Chaos.NaCl.Tests/TestHelpers.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Xunit; namespace Chaos.NaCl.Tests { @@ -20,7 +20,7 @@ private static int Random(int min, int max) public static void AssertEqualBytes(byte[] expected, byte[] actual) { - Assert.AreEqual(BitConverter.ToString(expected), BitConverter.ToString(actual)); + Assert.Equal(BitConverter.ToString(expected), BitConverter.ToString(actual)); } public static ArraySegment Pad(this byte[] array) diff --git a/Chaos.NaCl.Tests/X25519Tests.cs b/Chaos.NaCl.Tests/X25519Tests.cs new file mode 100644 index 0000000..1cf9bb0 --- /dev/null +++ b/Chaos.NaCl.Tests/X25519Tests.cs @@ -0,0 +1,45 @@ +using Chaos.NaCl.Internal.Ed25519Ref10; +using Multiformats.Base; +using System.Linq; +using Xunit; + +namespace Chaos.NaCl.Tests +{ + public class X25519Tests + { + [Fact] + public void ConvertEd25519ToX25519PrivateKey() + { + var edPrivate = Multibase.Base58.Decode("47QbyJEDqmHTzsdg8xzqXD8gqKuLufYRrKWTmB7eAaWHG2EAsQ2GUyqRqWWYT15dGuag52Sf3j4hs2mu7w52mgps"); + const string expected = "96do29HaLryHStVdCD7jB5TdbM1iGwPUDJvnPkfcqhMB"; + + var actual = new byte[32]; + MontgomeryCurve25519.EdwardsToMontgomeryPrivate(actual, edPrivate); + + Assert.Equal(expected, Multibase.Base58.Encode(actual)); + } + + [Fact] + public void ConvertEd25519ToX25519PublicKey() + { + var edPublic = Multibase.Base58.Decode("dbDmZLTWuEYYZNHFLKLoRkEX4sZykkSLNQLXvMUyMB1"); + const string expected = "2AbNdSuzFSpGvsiSPBfnamcKzk9Q3WRRpY2EToHZEuKW"; + + var actual = new byte[32]; + MontgomeryCurve25519.EdwardsToMontgomery(actual, edPublic); + + Assert.Equal(expected, Multibase.Base58.Encode(actual)); + } + + [Fact] + public void X25519PublicFromPrivate() + { + const string montgomeryPrivate = "96do29HaLryHStVdCD7jB5TdbM1iGwPUDJvnPkfcqhMB"; + const string expectedPublic = "2AbNdSuzFSpGvsiSPBfnamcKzk9Q3WRRpY2EToHZEuKW"; + + var actualPublic = MontgomeryCurve25519.GetPublicKey(Multibase.Base58.Decode(montgomeryPrivate)); + + Assert.Equal(expectedPublic, Multibase.Base58.Encode(actualPublic)); + } + } +} diff --git a/Chaos.NaCl.Tests/XSalsa20Poly1305Tests.cs b/Chaos.NaCl.Tests/XSalsa20Poly1305Tests.cs index a8209c4..8a2c152 100644 --- a/Chaos.NaCl.Tests/XSalsa20Poly1305Tests.cs +++ b/Chaos.NaCl.Tests/XSalsa20Poly1305Tests.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Xunit; namespace Chaos.NaCl.Tests { - [TestClass] + public class XSalsa20Poly1305Tests { readonly byte[] _key = new byte[32] @@ -67,14 +67,14 @@ public class XSalsa20Poly1305Tests , 0xe3, 0x55, 0xa5 }; - [TestMethod] + [Fact] public void Encrypt() { var ciphertextActual = XSalsa20Poly1305.Encrypt(_plaintext, _key, _nonce); TestHelpers.AssertEqualBytes(_ciphertext, ciphertextActual); } - [TestMethod] + [Fact] public void EncryptSegments() { var ciphertextActual = new byte[_plaintext.Length + XSalsa20Poly1305.MacSizeInBytes].Pad(); @@ -82,33 +82,33 @@ public void EncryptSegments() TestHelpers.AssertEqualBytes(_ciphertext, ciphertextActual.UnPad()); } - [TestMethod] + [Fact] public void DecryptSuccess() { var plaintextActual = XSalsa20Poly1305.TryDecrypt(_ciphertext, _key, _nonce); TestHelpers.AssertEqualBytes(_plaintext, plaintextActual); } - [TestMethod] + [Fact] public void DecryptSuccessSegments() { var plaintextActual = new byte[_ciphertext.Length - XSalsa20Poly1305.MacSizeInBytes].Pad(); var success = XSalsa20Poly1305.TryDecrypt(plaintextActual, _ciphertext.Pad(), _key.Pad(), _nonce.Pad()); - Assert.IsTrue(success); + Assert.True(success); TestHelpers.AssertEqualBytes(_plaintext, plaintextActual.UnPad()); } - [TestMethod] + [Fact] public void DecryptFail() { foreach (var brokenCiphertext in _ciphertext.WithChangedBit()) { var plaintextActual = XSalsa20Poly1305.TryDecrypt(brokenCiphertext, _key, _nonce); - Assert.AreEqual(null, plaintextActual); + Assert.Equal(null, plaintextActual); } } - [TestMethod] + [Fact] public void DecryptFailSegments() { foreach (var brokenCiphertext in _ciphertext.WithChangedBit()) @@ -117,19 +117,19 @@ public void DecryptFailSegments() for (int i = 0; i < plaintextActual.Count; i++) plaintextActual.Array[plaintextActual.Offset + i] = 0x37; var success = XSalsa20Poly1305.TryDecrypt(plaintextActual, brokenCiphertext.Pad(), _key.Pad(), _nonce.Pad()); - Assert.IsFalse(success); + Assert.False(success); TestHelpers.AssertEqualBytes(new byte[_plaintext.Length], plaintextActual.UnPad()); } } - [TestMethod] + [Fact] public void DecryptTooShort() { var plaintextActual = XSalsa20Poly1305.TryDecrypt(new byte[15], _key, _nonce); - Assert.AreEqual(null, plaintextActual); + Assert.Equal(null, plaintextActual); } - [TestMethod] + [Fact] public void RoundTripSuccessWithManyLengths() { for (int length = 0; length < 1000; length++) @@ -141,7 +141,7 @@ public void RoundTripSuccessWithManyLengths() } } - [TestMethod] + [Fact] public void RoundTripSuccessWithManyLengthsSegments() { for (int length = 0; length < 1000; length++) @@ -156,7 +156,7 @@ public void RoundTripSuccessWithManyLengthsSegments() } } - [TestMethod] + [Fact] public void RoundTripFailWithManyLengths() { for (int length = 0; length < 130; length++)//130 bytes exceeds two blocks @@ -166,7 +166,7 @@ public void RoundTripFailWithManyLengths() foreach (var brokenCiphertext in ciphertext.WithChangedBit()) { var plaintextActual = XSalsa20Poly1305.TryDecrypt(brokenCiphertext, _key, _nonce); - Assert.AreEqual(null, plaintextActual); + Assert.Equal(null, plaintextActual); } } } diff --git a/Chaos.NaCl.sln b/Chaos.NaCl.sln index a460ad1..dacfee6 100644 --- a/Chaos.NaCl.sln +++ b/Chaos.NaCl.sln @@ -1,6 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30413.136 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chaos.NaCl", "Chaos.NaCl\Chaos.NaCl.csproj", "{AE28FD14-7985-4707-A963-C94B8597AE50}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chaos.NaCl.Benchmark", "Chaos.NaCl.Benchmark\Chaos.NaCl.Benchmark.csproj", "{28321BA8-C416-4F81-BE4C-1546CD62118B}" @@ -35,4 +37,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {11F0BB99-0F56-4AD1-B05A-E5D63DCF5B7A} + EndGlobalSection EndGlobal diff --git a/Chaos.NaCl/Chaos.NaCl-Portable.csproj b/Chaos.NaCl/Chaos.NaCl-Portable.csproj deleted file mode 100644 index a929c23..0000000 --- a/Chaos.NaCl/Chaos.NaCl-Portable.csproj +++ /dev/null @@ -1,111 +0,0 @@ - - - - - 10.0 - Debug - AnyCPU - {992710C3-DFC9-4CC1-A38B-B3F7E4A41B1C} - Library - Properties - Chaos.NaCl - Chaos.NaCl-Portable - v4.0 - Profile1 - 512 - {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Chaos.NaCl/Chaos.NaCl.csproj b/Chaos.NaCl/Chaos.NaCl.csproj index 5c67ef1..f45bdfc 100644 --- a/Chaos.NaCl/Chaos.NaCl.csproj +++ b/Chaos.NaCl/Chaos.NaCl.csproj @@ -1,117 +1,7 @@ - - - + + - Debug - AnyCPU - {AE28FD14-7985-4707-A963-C94B8597AE50} - Library - Properties - Chaos.NaCl - Chaos.NaCl - v2.0 - 512 - - + netstandard2.1 - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - SecurityRules.ruleset - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - default - MinimumRecommendedRules.ruleset - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + diff --git a/Chaos.NaCl/InternalsVisibleTo.cs b/Chaos.NaCl/InternalsVisibleTo.cs new file mode 100644 index 0000000..094d08c --- /dev/null +++ b/Chaos.NaCl/InternalsVisibleTo.cs @@ -0,0 +1,4 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Chaos.NaCl.Tests")] +[assembly: InternalsVisibleTo("Chaos.NaCl.Benchmark")] \ No newline at end of file diff --git a/Chaos.NaCl/MontgomeryCurve25519.cs b/Chaos.NaCl/MontgomeryCurve25519.cs index 562521f..3d97560 100644 --- a/Chaos.NaCl/MontgomeryCurve25519.cs +++ b/Chaos.NaCl/MontgomeryCurve25519.cs @@ -130,13 +130,62 @@ public static void KeyExchange(ArraySegment sharedKey, ArraySegment KeyExchangeOutputHashNaCl(sharedKey.Array, sharedKey.Offset); } + //internal static void EdwardsToMontgomeryX(out FieldElement montgomeryX, ref FieldElement edwardsY, ref FieldElement edwardsZ) + //{ + // FieldElement tempX, tempZ; + // FieldOperations.fe_add(out tempX, ref edwardsZ, ref edwardsY); + // FieldOperations.fe_sub(out tempZ, ref edwardsZ, ref edwardsY); + // FieldOperations.fe_invert(out tempZ, ref tempZ); + // FieldOperations.fe_mul(out montgomeryX, ref tempX, ref tempZ); + //} + internal static void EdwardsToMontgomeryX(out FieldElement montgomeryX, ref FieldElement edwardsY, ref FieldElement edwardsZ) { + // montgomeryX = (edwardsZ + edwardsY) / (edwardsZ - edwardsY) FieldElement tempX, tempZ; FieldOperations.fe_add(out tempX, ref edwardsZ, ref edwardsY); FieldOperations.fe_sub(out tempZ, ref edwardsZ, ref edwardsY); FieldOperations.fe_invert(out tempZ, ref tempZ); FieldOperations.fe_mul(out montgomeryX, ref tempX, ref tempZ); } + + internal static void MontgomeryXToEdwards(out FieldElement edwardsY, ref FieldElement montgomeryX, ref FieldElement montgomeryZ) + { + // edwardsY = (montgomeryX - montgomeryZ) / (montgomeryX + montgomeryZ) + FieldElement tempY, tempZ; + FieldOperations.fe_sub(out tempY, ref montgomeryX, ref montgomeryZ); + FieldOperations.fe_add(out tempZ, ref montgomeryX, ref montgomeryZ); + FieldOperations.fe_invert(out tempZ, ref tempZ); + FieldOperations.fe_mul(out edwardsY, ref tempY, ref tempZ); + } + + public static void EdwardsToMontgomery(ArraySegment montgomery, ArraySegment edwards) + { + FieldElement edwardsY, edwardsZ, montgomeryX; + FieldOperations.fe_frombytes(out edwardsY, edwards.Array, edwards.Offset); + FieldOperations.fe_1(out edwardsZ); + EdwardsToMontgomeryX(out montgomeryX, ref edwardsY, ref edwardsZ); + FieldOperations.fe_tobytes(montgomery.Array, montgomery.Offset, ref montgomeryX); + montgomery.Array[montgomery.Offset + 31] |= (byte)(edwards.Array[edwards.Offset + 31] & 0x80);// copy sign + } + + public static void MontgomeryToEdwards(ArraySegment edwards, ArraySegment montgomery) + { + FieldElement montgomeryX, montgomeryZ, edwardsY; + FieldOperations.fe_frombytes(out montgomeryX, montgomery.Array, montgomery.Offset); + FieldOperations.fe_1(out montgomeryZ); + MontgomeryXToEdwards(out edwardsY, ref montgomeryX, ref montgomeryZ); + FieldOperations.fe_tobytes(edwards.Array, edwards.Offset, ref edwardsY); + edwards.Array[edwards.Offset + 31] |= (byte)(montgomery.Array[montgomery.Offset + 31] & 0x80);// copy sign + } + + public static void EdwardsToMontgomeryPrivate(ArraySegment montgomeryPrivate, ArraySegment edwardsPrivate) + { + var montgomery = Sha512.Hash(edwardsPrivate.Array[..32]); + + ScalarOperations.sc_clamp(montgomery, 0); + + Array.Copy(montgomery, montgomeryPrivate.Array, 32); + } } } diff --git a/Chaos.NaCl/Properties/AssemblyInfo.cs b/Chaos.NaCl/Properties/AssemblyInfo.cs deleted file mode 100644 index a8650f9..0000000 --- a/Chaos.NaCl/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Chaos.NaCl")] -[assembly: AssemblyDescription("C# port of the NaCl cryptography library")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("CodesInChaos")] -[assembly: AssemblyProduct("Chaos.NaCl cryptography library")] -[assembly: AssemblyCopyright("public domain")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("0.1.0.0")] - -[assembly: InternalsVisibleTo("Chaos.NaCl.Tests")] -[assembly: InternalsVisibleTo("Chaos.NaCl.Benchmark")] \ No newline at end of file diff --git a/Chaos.NaCl/Properties/AssemblyInfoFull.cs b/Chaos.NaCl/Properties/AssemblyInfoFull.cs deleted file mode 100644 index 80fd16c..0000000 --- a/Chaos.NaCl/Properties/AssemblyInfoFull.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Runtime.InteropServices; - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("f07e7dd1-d31c-4994-8948-e42de7ef16ec")] \ No newline at end of file