Skip to content

Commit

Permalink
Add code for scrypt miner (unoptimized)
Browse files Browse the repository at this point in the history
  • Loading branch information
Coding-Enthusiast committed Jul 7, 2019
1 parent 6b460da commit 0dd1c41
Show file tree
Hide file tree
Showing 8 changed files with 1,248 additions and 10 deletions.
143 changes: 143 additions & 0 deletions LearnMining/Cryptography/HmacSha.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace LearnMining.Cryptography
{
// https://tools.ietf.org/html/rfc2104
public class HmacSha : IHmacFunction
{
public HmacSha(IHashFunction shaBasedHashFunction)
{
if (shaBasedHashFunction == null)
throw new ArgumentNullException(nameof(shaBasedHashFunction), "Hash function can not be null.");

Hash = shaBasedHashFunction;
}

public HmacSha(IHashFunction shaBasedHashFunction, byte[] key)
{
if (shaBasedHashFunction == null)
throw new ArgumentNullException(nameof(shaBasedHashFunction), "Hash function can not be null.");

Hash = shaBasedHashFunction; // Note: hash needs to be set first or setkey will throw null exception.
Key = key;
}



public IHashFunction Hash { get; set; }
public int BlockSize => Hash.BlockByteSize;
public int OutputSize => Hash.HashByteSize;
byte[] opad, ipad;

private byte[] _keyValue;
public byte[] Key
{
get => _keyValue;
set
{
if (value == null)
throw new ArgumentNullException("Key can not be null.");


if (value.Length > Hash.BlockByteSize)
{
_keyValue = Hash.ComputeHash(value);
}
else
{
_keyValue = value.CloneByteArray();
}

// Now set pads
opad = new byte[Hash.BlockByteSize];
ipad = new byte[Hash.BlockByteSize];
unsafe
{
// Note (kp = _keyValue) can't assign to first item because key might be empty array which will throw an excpetion
fixed (byte* kp = _keyValue, op = &opad[0], ip = &ipad[0])
{
for (int i = 0; i < _keyValue.Length; i++)
{
op[i] = (byte)(kp[i] ^ 0x5c);
ip[i] = (byte)(kp[i] ^ 0x36);
}
for (int i = _keyValue.Length; i < opad.Length; i++)
{
op[i] = 0 ^ 0x5c;
ip[i] = 0 ^ 0x36;
}
}
}
}
}


// TODO: check behavior in case key was set (or other ctor with key was called) and then this function was called!
// there might be some issue with pad
public byte[] ComputeHash(byte[] data, byte[] key)
{
if (data == null)
throw new ArgumentNullException(nameof(data), "Data can not be null.");

Key = key; // This will check null, set _keyValue properly and initializes pads

return Hash.ComputeHash(opad.ConcatFast(Hash.ComputeHash(ipad.ConcatFast(data))));
}


/// <summary>
/// <see cref="ComputeHash(byte[], byte[])"/>
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public byte[] ComputeHash(byte[] data)
{
if (disposedValue)
throw new ObjectDisposedException($"{nameof(HmacSha)} instance was disposed.");
if (data == null)
throw new ArgumentNullException(nameof(data), "Data can not be null.");
if (_keyValue == null)
throw new ArgumentNullException(nameof(Key), "Key must be set before calling this function");

// Pads are already set
return Hash.ComputeHash(opad.ConcatFast(Hash.ComputeHash(ipad.ConcatFast(data))));
}





#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls

protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
if (_keyValue != null)
Array.Clear(_keyValue, 0, _keyValue.Length);
_keyValue = null;

if (Hash != null)
Hash.Dispose();
Hash = null;
}

disposedValue = true;
}
}

/// <summary>
/// Releases all resources used by the current instance of the <see cref="HmacSha"/> class.
/// </summary>
public void Dispose()
{
Dispose(true);
}
#endregion
}
}
30 changes: 30 additions & 0 deletions LearnMining/Cryptography/IHashFunction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;

namespace LearnMining.Cryptography
{
public interface IHashFunction : IDisposable
{
/// <summary>
/// Indicates whether the hash function should be performed twice on message.
/// For example Double SHA256 that bitcoin uses.
/// </summary>
bool IsDouble { get; set; }

/// <summary>
/// Size of the hash result in bytes.
/// </summary>
int HashByteSize { get; }

/// <summary>
/// Size of the blocks used in each round.
/// </summary>
int BlockByteSize { get; }

/// <summary>
/// Computes the hash value for the specified byte array.
/// </summary>
/// <param name="data">The byte array to compute hash for</param>
/// <returns>The computed hash</returns>
byte[] ComputeHash(byte[] data);
}
}
45 changes: 45 additions & 0 deletions LearnMining/Cryptography/IHmacFunction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;

namespace LearnMining.Cryptography
{
public interface IHmacFunction : IDisposable
{
/// <summary>
/// Underlying hash function
/// </summary>
IHashFunction Hash { get; set; }

/// <summary>
/// Size of the blocks
/// </summary>
int BlockSize { get; }

/// <summary>
/// Size of the hash result in bytes.
/// </summary>
int OutputSize { get; }

/// <summary>
/// Key to use in HMAC function
/// </summary>
byte[] Key { get; set; }

/// <summary>
/// Computes HMAC hash of a given byte array with the specified hash function and the specified key data.
/// <para/> * This function is useful for computing hash multiple times each with a differet key.
/// </summary>
/// <param name="data">The byte array to compute hash for</param>
/// <param name="key">The secret key used for HMAC encryption.
/// Key size is best chosen based on recommended size for each function.</param>
/// <returns>The computed hash</returns>
byte[] ComputeHash(byte[] data, byte[] key);

/// <summary>
/// Computes HMAC hash of a given byte array with the specified hash function with the key that was specified in constructor.
/// <para/> * This function is useful for computing hash multiple times with the same key.
/// </summary>
/// <param name="data">The byte array to compute hash for</param>
/// <returns>The computed hash</returns>
byte[] ComputeHash(byte[] data);
}
}
Loading

0 comments on commit 0dd1c41

Please sign in to comment.