-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add code for scrypt miner (unoptimized)
- Loading branch information
1 parent
6b460da
commit 0dd1c41
Showing
8 changed files
with
1,248 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
Oops, something went wrong.