--- /dev/null
+\feffusing System;
+using System.Security.Cryptography;
+
+namespace Novacoin
+{
+ public class CryptoUtils
+ {
+ public static byte[] PBKDF2_Sha256(int dklen, byte[] password, byte[] salt, int iterationCount)
+ {
+ using (var hmac = new HMACSHA256(password))
+ {
+ int hashLength = hmac.HashSize / 8;
+ if ((hmac.HashSize & 7) != 0)
+ hashLength++;
+ int keyLength = dklen / hashLength;
+ if ((long)dklen > (0xFFFFFFFFL * hashLength) || dklen < 0)
+ throw new ArgumentOutOfRangeException("dklen");
+ if (dklen % hashLength != 0)
+ keyLength++;
+ byte[] extendedkey = new byte[salt.Length + 4];
+ Buffer.BlockCopy(salt, 0, extendedkey, 0, salt.Length);
+ using (var ms = new System.IO.MemoryStream())
+ {
+ for (int i = 0; i < keyLength; i++)
+ {
+ extendedkey[salt.Length] = (byte)(((i + 1) >> 24) & 0xFF);
+ extendedkey[salt.Length + 1] = (byte)(((i + 1) >> 16) & 0xFF);
+ extendedkey[salt.Length + 2] = (byte)(((i + 1) >> 8) & 0xFF);
+ extendedkey[salt.Length + 3] = (byte)(((i + 1)) & 0xFF);
+ byte[] u = hmac.ComputeHash(extendedkey);
+ Array.Clear(extendedkey, salt.Length, 4);
+ byte[] f = u;
+ for (int j = 1; j < iterationCount; j++)
+ {
+ u = hmac.ComputeHash(u);
+ for (int k = 0; k < f.Length; k++)
+ {
+ f[k] ^= u[k];
+ }
+ }
+ ms.Write(f, 0, f.Length);
+ Array.Clear(u, 0, u.Length);
+ Array.Clear(f, 0, f.Length);
+ }
+ byte[] dk = new byte[dklen];
+ ms.Position = 0;
+ ms.Read(dk, 0, dklen);
+ ms.Position = 0;
+ for (long i = 0; i < ms.Length; i++)
+ {
+ ms.WriteByte(0);
+ }
+ Array.Clear(extendedkey, 0, extendedkey.Length);
+ return dk;
+ }
+ }
+ }
+ }
+}
return result.ToArray();
}
-
}
public static byte[] LEBytes(ushort n)
}
return sb.ToString();
}
+
+ public static void UInt16ToBE(ushort n, byte[] bs)
+ {
+ bs[0] = (byte)(n >> 8);
+ bs[1] = (byte)(n);
+ }
+
+ public static ushort BEToUInt16(byte[] bs)
+ {
+ ushort n = (ushort)(bs[0] << 8);
+ n |= (ushort)bs[1];
+ return n;
+ }
+
+ public static ushort BEToUInt16(byte[] bs, int off)
+ {
+ ushort n = (ushort)(bs[off] << 8);
+ n |= (ushort)bs[++off];
+ return n;
+ }
+
+ public static void UInt16ToLE(ushort n, byte[] bs)
+ {
+ bs[0] = (byte)(n);
+ bs[1] = (byte)(n >> 8);
+ }
+
+ public static void UInt16ToLE(ushort n, byte[] bs, int off)
+ {
+ bs[off] = (byte)(n);
+ bs[++off] = (byte)(n >> 8);
+ }
+
+ public static ushort LEToUInt16(byte[] bs)
+ {
+ ushort n = (ushort)bs[0];
+ n |= (ushort)(bs[1] << 8);
+ return n;
+ }
+
+ public static ushort LEToUInt16(byte[] bs, int off)
+ {
+ ushort n = (ushort)bs[off];
+ n |= (ushort)(bs[++off] << 8);
+ return n;
+ }
+
+ public static void UInt32ToBE(uint n, byte[] bs)
+ {
+ bs[0] = (byte)(n >> 24);
+ bs[1] = (byte)(n >> 16);
+ bs[2] = (byte)(n >> 8);
+ bs[3] = (byte)(n);
+ }
+
+ public static void UInt32ToBE(uint n, byte[] bs, int off)
+ {
+ bs[off] = (byte)(n >> 24);
+ bs[++off] = (byte)(n >> 16);
+ bs[++off] = (byte)(n >> 8);
+ bs[++off] = (byte)(n);
+ }
+
+ public static uint BEToUInt32(byte[] bs)
+ {
+ uint n = (uint)bs[0] << 24;
+ n |= (uint)bs[1] << 16;
+ n |= (uint)bs[2] << 8;
+ n |= (uint)bs[3];
+ return n;
+ }
+
+ public static uint BEToUInt32(byte[] bs, int off)
+ {
+ uint n = (uint)bs[off] << 24;
+ n |= (uint)bs[++off] << 16;
+ n |= (uint)bs[++off] << 8;
+ n |= (uint)bs[++off];
+ return n;
+ }
+
+ public static ulong BEToUInt64(byte[] bs)
+ {
+ uint hi = BEToUInt32(bs);
+ uint lo = BEToUInt32(bs, 4);
+ return ((ulong)hi << 32) | (ulong)lo;
+ }
+
+ public static ulong BEToUInt64(byte[] bs, int off)
+ {
+ uint hi = BEToUInt32(bs, off);
+ uint lo = BEToUInt32(bs, off + 4);
+ return ((ulong)hi << 32) | (ulong)lo;
+ }
+
+ public static void UInt64ToBE(ulong n, byte[] bs)
+ {
+ UInt32ToBE((uint)(n >> 32), bs);
+ UInt32ToBE((uint)(n), bs, 4);
+ }
+
+ public static void UInt64ToBE(ulong n, byte[] bs, int off)
+ {
+ UInt32ToBE((uint)(n >> 32), bs, off);
+ UInt32ToBE((uint)(n), bs, off + 4);
+ }
+
+ public static void UInt32ToLE(uint n, byte[] bs)
+ {
+ bs[0] = (byte)(n);
+ bs[1] = (byte)(n >> 8);
+ bs[2] = (byte)(n >> 16);
+ bs[3] = (byte)(n >> 24);
+ }
+
+ public static void UInt32ToLE(uint n, byte[] bs, int off)
+ {
+ bs[off] = (byte)(n);
+ bs[++off] = (byte)(n >> 8);
+ bs[++off] = (byte)(n >> 16);
+ bs[++off] = (byte)(n >> 24);
+ }
+
+ public static uint LEToUInt32(byte[] bs)
+ {
+ uint n = (uint)bs[0];
+ n |= (uint)bs[1] << 8;
+ n |= (uint)bs[2] << 16;
+ n |= (uint)bs[3] << 24;
+ return n;
+ }
+
+ public static uint LEToUInt32(byte[] bs, int off)
+ {
+ uint n = (uint)bs[off];
+ n |= (uint)bs[++off] << 8;
+ n |= (uint)bs[++off] << 16;
+ n |= (uint)bs[++off] << 24;
+ return n;
+ }
+
+ public static ulong LEToUInt64(byte[] bs)
+ {
+ uint lo = LEToUInt32(bs);
+ uint hi = LEToUInt32(bs, 4);
+ return ((ulong)hi << 32) | (ulong)lo;
+ }
+
+ public static ulong LEToUInt64(byte[] bs, int off)
+ {
+ uint lo = LEToUInt32(bs, off);
+ uint hi = LEToUInt32(bs, off + 4);
+ return ((ulong)hi << 32) | (ulong)lo;
+ }
+
+ public static void UInt64ToLE(ulong n, byte[] bs)
+ {
+ UInt32ToLE((uint)(n), bs);
+ UInt32ToLE((uint)(n >> 32), bs, 4);
+ }
+
+ public static void UInt64ToLE(ulong n, byte[] bs, int off)
+ {
+ UInt32ToLE((uint)(n), bs, off);
+ UInt32ToLE((uint)(n >> 32), bs, off + 4);
+ }
+
}
}
<Compile Include="CKeyPair.cs" />
<Compile Include="CNovacoinAddress.cs" />
<Compile Include="CPubKey.cs" />
+ <Compile Include="CryptoUtils.cs" />
<Compile Include="CScriptID.cs" />
<Compile Include="Hash.cs" />
<Compile Include="Interop.cs" />
using System.Collections.Generic;
using System.Linq;
-using System.Security.Cryptography;
-
namespace Novacoin
{
/// <summary>
uint[] V = new uint[(131072 + 63) / sizeof(uint)];
byte[] dataBytes = inputBytes.ToArray();
- byte[] keyBytes1 = PBKDF2Sha256GetBytes(128, dataBytes, dataBytes, 1);
+ byte[] keyBytes1 = CryptoUtils.PBKDF2_Sha256(128, dataBytes, dataBytes, 1);
uint[] X = Interop.ToUInt32Array(keyBytes1);
uint i, j, k;
}
byte[] xBytes = Interop.LEBytes(X);
- byte[] keyBytes2 = PBKDF2Sha256GetBytes(32, dataBytes, xBytes, 1);
+ byte[] keyBytes2 = CryptoUtils.PBKDF2_Sha256(32, dataBytes, xBytes, 1);
return new ScryptHash256(keyBytes2);
}
- private static byte[] PBKDF2Sha256GetBytes(int dklen, byte[] password, byte[] salt, int iterationCount)
- {
- using (var hmac = new HMACSHA256(password))
- {
- int hashLength = hmac.HashSize / 8;
- if ((hmac.HashSize & 7) != 0)
- hashLength++;
- int keyLength = dklen / hashLength;
- if ((long)dklen > (0xFFFFFFFFL * hashLength) || dklen < 0)
- throw new ArgumentOutOfRangeException("dklen");
- if (dklen % hashLength != 0)
- keyLength++;
- byte[] extendedkey = new byte[salt.Length + 4];
- Buffer.BlockCopy(salt, 0, extendedkey, 0, salt.Length);
- using (var ms = new System.IO.MemoryStream())
- {
- for (int i = 0; i < keyLength; i++)
- {
- extendedkey[salt.Length] = (byte)(((i + 1) >> 24) & 0xFF);
- extendedkey[salt.Length + 1] = (byte)(((i + 1) >> 16) & 0xFF);
- extendedkey[salt.Length + 2] = (byte)(((i + 1) >> 8) & 0xFF);
- extendedkey[salt.Length + 3] = (byte)(((i + 1)) & 0xFF);
- byte[] u = hmac.ComputeHash(extendedkey);
- Array.Clear(extendedkey, salt.Length, 4);
- byte[] f = u;
- for (int j = 1; j < iterationCount; j++)
- {
- u = hmac.ComputeHash(u);
- for (int k = 0; k < f.Length; k++)
- {
- f[k] ^= u[k];
- }
- }
- ms.Write(f, 0, f.Length);
- Array.Clear(u, 0, u.Length);
- Array.Clear(f, 0, f.Length);
- }
- byte[] dk = new byte[dklen];
- ms.Position = 0;
- ms.Read(dk, 0, dklen);
- ms.Position = 0;
- for (long i = 0; i < ms.Length; i++)
- {
- ms.WriteByte(0);
- }
- Array.Clear(extendedkey, 0, extendedkey.Length);
- return dk;
- }
- }
- }
-
private static void xor_salsa8(ref uint[] B, int indexB, ref uint[] Bx, int indexBx)
{
uint x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15;