From eefd828ada9c7563c063b4e92343d87f57363a14 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Thu, 5 Feb 2015 05:03:44 +0000 Subject: [PATCH] Added workaround so SHA3 works under Mono, and enabling SHA3 --- SharpHash/Checksums/SHA3Context.cs | 92 ++++++++++++++++++++++++++++-- SharpHash/Program.cs | 16 +++--- SharpHash/SharpHash.csproj | 6 +- SharpHash/packages.config | 5 -- 4 files changed, 99 insertions(+), 20 deletions(-) delete mode 100644 SharpHash/packages.config diff --git a/SharpHash/Checksums/SHA3Context.cs b/SharpHash/Checksums/SHA3Context.cs index 0faf324..29aa9d0 100644 --- a/SharpHash/Checksums/SHA3Context.cs +++ b/SharpHash/Checksums/SHA3Context.cs @@ -22,6 +22,7 @@ using System.Text; using System.IO; using SHA3; +using System; namespace SharpHash.Checksums { @@ -30,14 +31,14 @@ namespace SharpHash.Checksums /// public class SHA3Context { - SHA3Unmanaged _sha3Provider; + SHA3WorkaroundForMono _sha3Provider; /// /// Initializes the SHA3 hash provider /// public void Init() { - _sha3Provider = new SHA3Unmanaged(512); + _sha3Provider = new SHA3WorkaroundForMono(512); } /// @@ -64,7 +65,7 @@ namespace SharpHash.Checksums /// public byte[] Final() { - _sha3Provider.TransformFinalBlock(new byte[0], 0, 0); + _sha3Provider.WorkaroundTransformFinalBlock(new byte[0], 0, 0); return _sha3Provider.Hash; } @@ -73,7 +74,7 @@ namespace SharpHash.Checksums /// public string End() { - _sha3Provider.TransformFinalBlock(new byte[0], 0, 0); + _sha3Provider.WorkaroundTransformFinalBlock(new byte[0], 0, 0); StringBuilder sha3Output = new StringBuilder(); for (int i = 0; i < _sha3Provider.Hash.Length; i++) @@ -142,5 +143,88 @@ namespace SharpHash.Checksums return Data(data, (uint)data.Length, out hash); } } + + // This is a workaround for Mono + // Mono calls Initialize() on HashAlgorithm.cs, making SHA3.Hash be null + // .NET Framework does not + // + // This snippet then does detect if running under Mono, if so it is doing + // the same code, but without that call. + // Under .NET Framework, just calls base(). + // + // Following snippet: + // + // System.Security.Cryptography.HashAlgorithm.cs + // + // Authors: + // Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu) + // Sebastien Pouliot (sebastien@ximian.com) + // + // Copyright 2001 by Matthew S. Ford. + // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com) + // Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com) + // + // Permission is hereby granted, free of charge, to any person obtaining + // a copy of this software and associated documentation files (the + // "Software"), to deal in the Software without restriction, including + // without limitation the rights to use, copy, modify, merge, publish, + // distribute, sublicense, and/or sell copies of the Software, and to + // permit persons to whom the Software is furnished to do so, subject to + // the following conditions: + // + // The above copyright notice and this permission notice shall be + // included in all copies or substantial portions of the Software. + // + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + // + public class SHA3WorkaroundForMono : SHA3Managed + { + public SHA3WorkaroundForMono(int hashBitLength) : base (hashBitLength) + { } + + public byte[] WorkaroundTransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount) + { + // Check for Mono + Type t = Type.GetType ("Mono.Runtime"); + + // Not under Mono + if (t == null) + { + return base.TransformFinalBlock(inputBuffer, inputOffset, inputCount); + } + // Under Mono + else + { + if (inputBuffer == null) + throw new ArgumentNullException("inputBuffer"); + if (inputCount < 0) + throw new ArgumentException("inputCount"); + // ordered to avoid possible integer overflow + if (inputOffset > inputBuffer.Length - inputCount) + { + throw new ArgumentException("inputOffset + inputCount", + "Overflow"); + } + + byte[] outputBuffer = new byte [inputCount]; + + // note: other exceptions are handled by Buffer.BlockCopy + Buffer.BlockCopy(inputBuffer, inputOffset, outputBuffer, 0, inputCount); + + HashCore(inputBuffer, inputOffset, inputCount); + HashValue = HashFinal(); + // Offending line + //Initialize (); + + return outputBuffer; + } + } + } } diff --git a/SharpHash/Program.cs b/SharpHash/Program.cs index 8a6e51e..2c5d6b7 100644 --- a/SharpHash/Program.cs +++ b/SharpHash/Program.cs @@ -160,9 +160,9 @@ namespace SharpHash Checksums.SHA512Context sha512Context = new Checksums.SHA512Context(); sha512Context.Init(); -// Console.WriteLine("Initializing SHA3-512..."); -// Checksums.SHA3Context sha3Context = new Checksums.SHA3Context(); -// sha3Context.Init(); + Console.WriteLine("Initializing SHA3-512..."); + Checksums.SHA3Context sha3Context = new Checksums.SHA3Context(); + sha3Context.Init(); Console.WriteLine("Initializing SpamSum..."); Checksums.SpamSumContext spamsumContext = new Checksums.SpamSumContext(); @@ -190,7 +190,7 @@ namespace SharpHash sha256Context.Update(dataBuffer); sha384Context.Update(dataBuffer); sha512Context.Update(dataBuffer); -// sha3Context.Update(dataBuffer); + sha3Context.Update(dataBuffer); spamsumContext.Update(dataBuffer); } @@ -209,7 +209,7 @@ namespace SharpHash sha256Context.Update(dataBuffer); sha384Context.Update(dataBuffer); sha512Context.Update(dataBuffer); -// sha3Context.Update(dataBuffer); + sha3Context.Update(dataBuffer); spamsumContext.Update(dataBuffer); } else @@ -229,7 +229,7 @@ namespace SharpHash sha256Context.Update(dataBuffer); sha384Context.Update(dataBuffer); sha512Context.Update(dataBuffer); -// sha3Context.Update(dataBuffer); + sha3Context.Update(dataBuffer); spamsumContext.Update(dataBuffer); } @@ -245,7 +245,7 @@ namespace SharpHash byte[] sha256Hash = sha256Context.Final(); byte[] sha384Hash = sha384Context.Final(); byte[] sha512Hash = sha512Context.Final(); -// byte[] sha3Hash = sha3Context.Final(); + byte[] sha3Hash = sha3Context.Final(); string spamsumHash = spamsumContext.End(); Console.WriteLine(); @@ -270,7 +270,7 @@ namespace SharpHash Console.WriteLine("SHA2-256: {0}", stringify(sha256Hash)); Console.WriteLine("SHA2-384: {0}", stringify(sha384Hash)); Console.WriteLine("SHA2-512: {0}", stringify(sha512Hash)); -// Console.WriteLine("SHA3-512: {0}", stringify(sha3Hash)); + Console.WriteLine("SHA3-512: {0}", stringify(sha3Hash)); Console.WriteLine("SpamSum: {0}", spamsumHash); fileStream.Close(); diff --git a/SharpHash/SharpHash.csproj b/SharpHash/SharpHash.csproj index 35f0059..1b91042 100644 --- a/SharpHash/SharpHash.csproj +++ b/SharpHash/SharpHash.csproj @@ -31,8 +31,8 @@ - - ..\packages\SHA3.0.9.2\lib\net40\SHA3.dll + + ..\packages\SHA3.0.9.2\lib\net40\SHA3Managed.dll @@ -67,7 +67,6 @@ - README.md @@ -77,5 +76,6 @@ LICENSE + \ No newline at end of file diff --git a/SharpHash/packages.config b/SharpHash/packages.config deleted file mode 100644 index 7ef15db..0000000 --- a/SharpHash/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file