public class Interop
{
/// <summary>
+ /// Convert array of unsigned integers to array of bytes.
+ /// </summary>
+ /// <param name="values">Array of unsigned integer values.</param>
+ /// <returns>Byte array</returns>
+ public static byte[] LEBytes(uint[] values)
+ {
+ var result = new byte[values.Length * sizeof(uint)];
+ Buffer.BlockCopy(values, 0, result, 0, result.Length);
+
+ return result;
+ }
+
+ /// <summary>
+ /// Convert byte array to array of unsigned integers.
+ /// </summary>
+ /// <param name="bytes">Byte array.</param>
+ /// <returns>Array of integers</returns>
+ public static uint[] ToUInt32Array(byte[] bytes)
+ {
+ var result = new uint[bytes.Length / sizeof(uint)];
+ Buffer.BlockCopy(bytes, 0, result, 0, bytes.Length);
+
+ return result;
+ }
+
+ /// <summary>
/// Reverse byte array
/// </summary>
/// <param name="source">Source array</param>
var V = new uint[(131072 + 63) / sizeof(uint)];
var keyBytes1 = CryptoUtils.PBKDF2_Sha256(128, (byte[])inputBytes, (byte[])inputBytes, 1);
- var X = ToUInt32Array(keyBytes1);
+ var X = Interop.ToUInt32Array(keyBytes1);
for (var i = 0; i < 1024; i++)
{
xor_salsa8(ref X, 16, ref X, 0);
}
- var xBytes = LEBytes(X);
+ var xBytes = Interop.LEBytes(X);
var keyBytes2 = CryptoUtils.PBKDF2_Sha256(32, (byte[])inputBytes, xBytes, 1);
return new ScryptHash256(keyBytes2);
B[indexB + 14] += x14;
B[indexB + 15] += x15;
}
-
- /// <summary>
- /// Convert array of unsigned integers to array of bytes.
- /// </summary>
- /// <param name="values">Array of unsigned integer values.</param>
- /// <returns>Byte array</returns>
- private static byte[] LEBytes(uint[] values)
- {
- var result = new byte[values.Length * sizeof(uint)];
- Buffer.BlockCopy(values, 0, result, 0, result.Length);
-
- return result;
- }
-
- /// <summary>
- /// Convert byte array to array of unsigned integers.
- /// </summary>
- /// <param name="bytes">Byte array.</param>
- /// <returns>Array of integers</returns>
- private static uint[] ToUInt32Array(byte[] bytes)
- {
- var result = new uint[bytes.Length / sizeof(uint)];
- Buffer.BlockCopy(bytes, 0, result, 0, bytes.Length);
-
- return result;
- }
-
}
}
using System;
+using System.Diagnostics.Contracts;
namespace Novacoin
{
+ /// <summary>
+ /// Base class for uint256 and uint160.
+ /// </summary>
public class base_uint : IComparable<base_uint>, IEquatable<base_uint>
{
- protected int nWidth;
+ protected readonly int nWidth;
protected uint[] pn;
public double getDouble()
}
}
-
public static bool operator !(base_uint a)
{
for (int i = 0; i < a.nWidth; i++)
return true;
}
- public static base_uint operator ~(base_uint a)
- {
- var ret = new base_uint();
- for (int i = 0; i < a.nWidth; i++)
- {
- ret.pn[i] = ~a.pn[i];
- }
- return ret;
- }
-
- public static base_uint operator -(base_uint a)
- {
- var ret = new base_uint();
- for (int i = 0; i < a.nWidth; i++)
- {
- ret.pn[i] = ~a.pn[i];
- }
- ret++;
- return ret;
- }
-
-
- public static base_uint operator ++(base_uint a)
- {
- int i = 0;
- while (++a.pn[i] == 0 && i < a.nWidth - 1)
- {
- i++;
- }
- return a;
- }
-
- public static base_uint operator --(base_uint a)
- {
- int i = 0;
- while (--a.pn[i] == uint.MaxValue && i < a.nWidth - 1)
- {
- i++;
- }
- return a;
- }
-
- public static base_uint operator ^(base_uint a, base_uint b)
- {
- var result = new base_uint();
- result.pn = new uint[a.nWidth];
- for (int i = 0; i < result.nWidth; i++)
- {
- result.pn[i] = a.pn[i] ^ b.pn[i];
- }
- return result;
- }
-
- public static base_uint operator +(base_uint a, base_uint b)
- {
- var result = new base_uint();
- ulong carry = 0;
- for (int i = 0; i < result.nWidth; i++)
- {
- ulong n = carry + a.pn[i] + b.pn[i];
- result.pn[i] = (uint)(n & 0xffffffff);
- carry = n >> 32;
- }
- return result;
- }
-
- public static base_uint operator -(base_uint a, base_uint b)
- {
- return a + (-b);
- }
-
- public static base_uint operator &(base_uint a, base_uint b)
- {
- var result = new base_uint();
- result.pn = new uint[a.nWidth];
- for (int i = 0; i < result.nWidth; i++)
- {
- result.pn[i] = a.pn[i] & b.pn[i];
- }
- return result;
- }
-
- public static base_uint operator |(base_uint a, base_uint b)
- {
- var result = new base_uint();
- result.pn = new uint[a.nWidth];
- for (int i = 0; i < result.nWidth; i++)
- {
- result.pn[i] = a.pn[i] | b.pn[i];
- }
- return result;
- }
public static bool operator <(base_uint a, base_uint b)
{
{
return false;
}
+
if (a.pn[1] != (uint)(b >> 32))
{
return false;
}
+
for (int i = 2; i < a.nWidth; i++)
{
if (a.pn[i] != 0)
public static implicit operator byte[] (base_uint a)
{
- var result = new byte[a.nWidth];
- for (int i = 0; i < a.nWidth; i++)
- {
- Buffer.BlockCopy(BitConverter.GetBytes(a.pn[i]), 0, result, 4 * i, 4);
- }
- return result;
+ return Interop.LEBytes(a.pn);
}
private static bool ArraysEqual(uint[] a, uint[] b)
{
- if (a.Length != b.Length)
- {
- return false;
- }
+ Contract.Requires<ArgumentException>(a.Length == b.Length, "Array length mismatch.");
+
for (int i = 0; i < a.Length; i++)
{
if (a[i] != b[i])
{
return Equals(o as base_uint);
}
+
+ public override string ToString()
+ {
+ return Interop.ToHex(Interop.ReverseBytes(this));
+ }
}
}
\feffusing System;
using System.Collections.Generic;
+using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
{
public class uint160 : base_uint
{
+ new protected readonly int nWidth = 5;
+
+ public uint160()
+ {
+ pn = new uint[nWidth];
+
+ for (int i = 0; i < nWidth; i++)
+ {
+ pn[i] = 0;
+ }
+ }
+
+ public uint160(uint160 b)
+ {
+ pn = new uint[nWidth];
+
+ for (int i = 0; i < nWidth; i++)
+ {
+ pn[i] = b.pn[i];
+ }
+ }
+
+
+ public uint160(ulong n)
+ {
+ pn = new uint[nWidth];
+
+ pn[0] = (uint)n;
+ pn[1] = (uint)(n >> 32);
+ for (int i = 2; i < nWidth; i++)
+ {
+ pn[i] = 0;
+ }
+ }
+
+ public uint160(byte[] bytes)
+ {
+ Contract.Requires<ArgumentException>(bytes.Length == 20, "Incorrect array length");
+
+ pn = Interop.ToUInt32Array(bytes);
+ }
+
+ public uint160(string hex)
+ {
+ Contract.Requires<ArgumentException>(hex.Length == 40, "Incorrect string");
+
+ var bytes = Interop.ReverseBytes(Interop.HexToArray(hex));
+ pn = Interop.ToUInt32Array(bytes);
+ }
+
+ public static uint160 operator ~(uint160 a)
+ {
+ var ret = new uint160();
+ for (int i = 0; i < a.nWidth; i++)
+ {
+ ret.pn[i] = ~a.pn[i];
+ }
+ return ret;
+ }
+
+ public static uint160 operator -(uint160 a)
+ {
+ var ret = new uint160();
+ for (int i = 0; i < a.nWidth; i++)
+ {
+ ret.pn[i] = ~a.pn[i];
+ }
+ ret++;
+ return ret;
+ }
+
+
+ public static uint160 operator ++(uint160 a)
+ {
+ int i = 0;
+ while (++a.pn[i] == 0 && i < a.nWidth - 1)
+ {
+ i++;
+ }
+ return a;
+ }
+
+ public static uint160 operator --(uint160 a)
+ {
+ int i = 0;
+ while (--a.pn[i] == uint.MaxValue && i < a.nWidth - 1)
+ {
+ i++;
+ }
+ return a;
+ }
+
+ public static uint160 operator ^(uint160 a, uint160 b)
+ {
+ var result = new uint160();
+ result.pn = new uint[a.nWidth];
+ for (int i = 0; i < result.nWidth; i++)
+ {
+ result.pn[i] = a.pn[i] ^ b.pn[i];
+ }
+ return result;
+ }
+
+ public static uint160 operator +(uint160 a, uint160 b)
+ {
+ var result = new uint160();
+ ulong carry = 0;
+ for (int i = 0; i < result.nWidth; i++)
+ {
+ ulong n = carry + a.pn[i] + b.pn[i];
+ result.pn[i] = (uint)(n & 0xffffffff);
+ carry = n >> 32;
+ }
+ return result;
+ }
+
+ public static uint160 operator +(uint160 a, ulong b)
+ {
+ return a + new uint160(b);
+ }
+
+ public static uint160 operator -(uint160 a, uint160 b)
+ {
+ return a + (-b);
+ }
+
+ public static uint160 operator -(uint160 a, ulong b)
+ {
+ return a - new uint160(b);
+ }
+
+ public static uint160 operator &(uint160 a, uint160 b)
+ {
+ var result = new uint160();
+ result.pn = new uint[a.nWidth];
+ for (int i = 0; i < result.nWidth; i++)
+ {
+ result.pn[i] = a.pn[i] & b.pn[i];
+ }
+ return result;
+ }
+
+ public static uint160 operator |(uint160 a, uint160 b)
+ {
+ var result = new uint160();
+ result.pn = new uint[a.nWidth];
+ for (int i = 0; i < result.nWidth; i++)
+ {
+ result.pn[i] = a.pn[i] | b.pn[i];
+ }
+ return result;
+ }
+
+ public static uint160 operator <<(uint160 a, int shift)
+ {
+ var result = new uint160();
+ int k = shift / 32;
+ shift = shift % 32;
+
+ for (int i = 0; i < a.nWidth; i++)
+ {
+ if (i + k + 1 < a.nWidth && shift != 0)
+ {
+ result.pn[i + k + 1] |= (a.pn[i] >> (32 - shift));
+ }
+
+ if (i + k < a.nWidth)
+ {
+ result.pn[i + k] |= (a.pn[i] << shift);
+ }
+ }
+
+ return result;
+ }
+
+ public static uint160 operator >>(uint160 a, int shift)
+ {
+ var result = new uint160();
+ int k = shift / 32;
+ shift = shift % 32;
+
+ for (int i = 0; i < a.nWidth; i++)
+ {
+ if (i - k - 1 >= 0 && shift != 0)
+ {
+ result.pn[i - k - 1] |= (a.pn[i] << (32 - shift));
+ }
+
+ if (i - k >= 0)
+ {
+ result.pn[i - k] |= (a.pn[i] >> shift);
+ }
+ }
+
+ return result;
+ }
}
}
\feffusing System;
using System.Collections.Generic;
+using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
{
public class uint256 : base_uint
{
+ new public readonly int nWidth = 8;
+
+ public uint256()
+ {
+ pn = new uint[nWidth];
+
+ for (int i = 0; i < nWidth; i++)
+ {
+ pn[i] = 0;
+ }
+ }
+
+ public uint256(uint256 b)
+ {
+ pn = new uint[nWidth];
+
+ for (int i = 0; i < nWidth; i++)
+ {
+ pn[i] = b.pn[i];
+ }
+ }
+
+
+ public uint256(ulong n)
+ {
+ pn = new uint[nWidth];
+
+ pn[0] = (uint)n;
+ pn[1] = (uint)(n >> 32);
+ for (int i = 2; i < nWidth; i++)
+ {
+ pn[i] = 0;
+ }
+ }
+
+ public uint256(byte[] bytes)
+ {
+ Contract.Requires<ArgumentException>(bytes.Length == 32, "Incorrect array length");
+
+ pn = Interop.ToUInt32Array(bytes);
+ }
+
+ public uint256(string hex)
+ {
+ Contract.Requires<ArgumentException>(hex.Length == 64, "Incorrect string");
+
+ var bytes = Interop.ReverseBytes(Interop.HexToArray(hex));
+ pn = Interop.ToUInt32Array(bytes);
+ }
+
+
+ public static uint256 operator ~(uint256 a)
+ {
+ var ret = new uint256();
+ for (int i = 0; i < a.nWidth; i++)
+ {
+ ret.pn[i] = ~a.pn[i];
+ }
+ return ret;
+ }
+
+ public static uint256 operator -(uint256 a)
+ {
+ var ret = new uint256();
+ for (int i = 0; i < a.nWidth; i++)
+ {
+ ret.pn[i] = ~a.pn[i];
+ }
+ ret++;
+ return ret;
+ }
+
+
+ public static uint256 operator ++(uint256 a)
+ {
+ int i = 0;
+ while (++a.pn[i] == 0 && i < a.nWidth - 1)
+ {
+ i++;
+ }
+ return a;
+ }
+
+ public static uint256 operator --(uint256 a)
+ {
+ int i = 0;
+ while (--a.pn[i] == uint.MaxValue && i < a.nWidth - 1)
+ {
+ i++;
+ }
+ return a;
+ }
+
+ public static uint256 operator ^(uint256 a, uint256 b)
+ {
+ var result = new uint256();
+ result.pn = new uint[a.nWidth];
+ for (int i = 0; i < result.nWidth; i++)
+ {
+ result.pn[i] = a.pn[i] ^ b.pn[i];
+ }
+ return result;
+ }
+
+ public static uint256 operator +(uint256 a, uint256 b)
+ {
+ var result = new uint256();
+ ulong carry = 0;
+ for (int i = 0; i < result.nWidth; i++)
+ {
+ ulong n = carry + a.pn[i] + b.pn[i];
+ result.pn[i] = (uint)(n & 0xffffffff);
+ carry = n >> 32;
+ }
+ return result;
+ }
+
+ public static uint256 operator +(uint256 a, ulong b)
+ {
+ return a + new uint256(b);
+ }
+
+ public static uint256 operator -(uint256 a, uint256 b)
+ {
+ return a + (-b);
+ }
+
+ public static uint256 operator -(uint256 a, ulong b)
+ {
+ return a - new uint256(b);
+ }
+
+ public static uint256 operator &(uint256 a, uint256 b)
+ {
+ var result = new uint256();
+ result.pn = new uint[a.nWidth];
+ for (int i = 0; i < result.nWidth; i++)
+ {
+ result.pn[i] = a.pn[i] & b.pn[i];
+ }
+ return result;
+ }
+
+ public static uint256 operator |(uint256 a, uint256 b)
+ {
+ var result = new uint256();
+ result.pn = new uint[a.nWidth];
+ for (int i = 0; i < result.nWidth; i++)
+ {
+ result.pn[i] = a.pn[i] | b.pn[i];
+ }
+ return result;
+ }
+
+ public static uint256 operator <<(uint256 a, int shift)
+ {
+ var result = new uint256();
+ int k = shift / 32;
+ shift = shift % 32;
+
+ for (int i = 0; i < a.nWidth; i++)
+ {
+ if (i + k + 1 < a.nWidth && shift != 0)
+ {
+ result.pn[i + k + 1] |= (a.pn[i] >> (32 - shift));
+ }
+
+ if (i + k < a.nWidth)
+ {
+ result.pn[i + k] |= (a.pn[i] << shift);
+ }
+ }
+
+ return result;
+ }
+
+ public static uint256 operator >>(uint256 a, int shift)
+ {
+ var result = new uint256();
+ int k = shift / 32;
+ shift = shift % 32;
+
+ for (int i = 0; i < a.nWidth; i++)
+ {
+ if (i - k - 1 >= 0 && shift != 0)
+ {
+ result.pn[i - k - 1] |= (a.pn[i] << (32 - shift));
+ }
+
+ if (i - k >= 0)
+ {
+ result.pn[i - k] |= (a.pn[i] >> shift);
+ }
+ }
+
+ return result;
+ }
}
}
Console.WriteLine("{0} != {1} : {2}", hash1.ToString(), hash2.ToString(), hash1 != hash2);
Console.WriteLine("{0} == {1} : {2}\n", hash2.ToString(), hash3.ToString(), hash2 == hash3);
-
+
/*
/// Pre-09854c5 revisions were affected by integer overflow bug, this issue was caused by incorrect deserialization of input value. Below you can see an example, broken transaction and its normal version.
Console.WriteLine(txNoBug);
*/
-
+ /*
+ var test1 = new uint256("0000000000021173331e7742b51afe6c853158a8881f7ad871f4391a7ddcfa4e");
+ var test2 = new uint256("0000000000093bf84cea580ede01206c3ffc75487ec46771e533e38d9bda972d");
+
+ Console.WriteLine(test1 < test2);
+ Console.WriteLine(test1 > test2);
+ Console.WriteLine(test1 == test2);
+ Console.WriteLine(test1 != test2);
+
+ Console.WriteLine(test1 - 1);
+ Console.WriteLine(test1 + 1);
+
+ Console.WriteLine(test1 << 32);
+ Console.WriteLine(test1 >> 32);
+
+ Output:
+
+ False
+ False
+ True
+ False
+ 0000000000021173331e7742b51afe6c853158a8881f7ad871f4391a7ddcfa4d
+ 0000000000021173331e7742b51afe6c853158a8881f7ad871f4391a7ddcfa4f
+ 00021173331e7742b51afe6c853158a8881f7ad871f4391a7ddcfa4e00000000
+ 000000000000000000021173331e7742b51afe6c853158a8881f7ad871f4391a
+ */
+
Console.WriteLine("Reading the block file...");
var bs = new CBlockStore();
bs.ParseBlockFile();
-
Console.ReadLine();
}