2 using System.Collections.Generic;
3 using System.Diagnostics.Contracts;
6 using System.Threading.Tasks;
11 public class uint256 : base_uint
13 new protected int nWidth {
14 get { return base.nWidth; }
15 private set { base.nWidth = value; }
17 new protected uint[] pn {
18 get { return base.pn; }
19 private set { base.pn = value; }
25 pn = new uint[nWidth];
28 public uint256(uint256 b) : this()
30 for (int i = 0; i < nWidth; i++)
36 public uint256(ulong n) : this()
39 pn[1] = (uint)(n >> 32);
40 for (int i = 2; i < nWidth; i++)
46 public uint256(byte[] bytes) : this()
48 Contract.Requires<ArgumentException>(bytes.Length == 32, "Incorrect array length");
50 pn = Interop.ToUInt32Array(bytes);
53 public uint256(string hex) : this()
55 Contract.Requires<ArgumentException>(hex.Length == 64, "Incorrect string");
57 var bytes = Interop.ReverseBytes(Interop.HexToArray(hex));
58 pn = Interop.ToUInt32Array(bytes);
62 /// Compact representation of unsigned 256bit numbers.
64 /// N = (-1^sign) * m * 256^(exp-3)
66 /// http://bitcoin.stackexchange.com/questions/30467/what-are-the-equations-to-convert-between-bits-and-difficulty
72 int nSize = (bits + 7) / 8;
75 nCompact = ((uint)GetLow64()) << 8 * (3 - nSize);
78 uint256 bn = this >> 8 * (nSize - 3);
79 nCompact = (uint)bn.GetLow64();
82 if ((nCompact & 0x00800000) != 0)
88 Contract.Assert((nCompact & ~0x007fffff) == 0);
89 Contract.Assert(nSize < 256);
91 nCompact |= (uint)nSize << 24;
97 int nSize = (int)value >> 24;
98 uint nWord = value & 0x007fffff;
104 nWord >>= 8 * (3 - nSize);
105 i = new uint256(nWord);
109 i = new uint256(nWord);
110 i <<= 8 * (nSize - 3);
117 private void SetBytes(byte[] bytes)
119 pn = Interop.ToUInt32Array(Interop.ReverseBytes(bytes));
122 public static uint256 operator ~(uint256 a)
124 var ret = new uint256();
125 for (int i = 0; i < a.nWidth; i++)
127 ret.pn[i] = ~a.pn[i];
132 public static uint256 operator -(uint256 a)
134 var ret = new uint256();
135 for (int i = 0; i < a.nWidth; i++)
137 ret.pn[i] = ~a.pn[i];
144 public static uint256 operator ++(uint256 a)
147 while (++a.pn[i] == 0 && i < a.nWidth - 1)
154 public static uint256 operator --(uint256 a)
157 while (--a.pn[i] == uint.MaxValue && i < a.nWidth - 1)
164 public static uint256 operator ^(uint256 a, uint256 b)
166 var result = new uint256();
167 result.pn = new uint[a.nWidth];
168 for (int i = 0; i < result.nWidth; i++)
170 result.pn[i] = a.pn[i] ^ b.pn[i];
175 public static uint256 operator +(uint256 a, uint256 b)
177 var result = new uint256();
179 for (int i = 0; i < result.nWidth; i++)
181 ulong n = carry + a.pn[i] + b.pn[i];
182 result.pn[i] = (uint)(n & 0xffffffff);
188 public static uint256 operator +(uint256 a, ulong b)
190 return a + new uint256(b);
193 public static uint256 operator -(uint256 a, uint256 b)
198 public static uint256 operator -(uint256 a, ulong b)
200 return a - new uint256(b);
203 public static uint256 operator &(uint256 a, uint256 b)
205 var result = new uint256();
206 result.pn = new uint[a.nWidth];
207 for (int i = 0; i < result.nWidth; i++)
209 result.pn[i] = a.pn[i] & b.pn[i];
214 public static uint256 operator |(uint256 a, uint256 b)
216 var result = new uint256();
217 result.pn = new uint[a.nWidth];
218 for (int i = 0; i < result.nWidth; i++)
220 result.pn[i] = a.pn[i] | b.pn[i];
225 public static uint256 operator <<(uint256 a, int shift)
227 var result = new uint256();
231 for (int i = 0; i < a.nWidth; i++)
233 if (i + k + 1 < a.nWidth && shift != 0)
235 result.pn[i + k + 1] |= (a.pn[i] >> (32 - shift));
238 if (i + k < a.nWidth)
240 result.pn[i + k] |= (a.pn[i] << shift);
247 public static uint256 operator >>(uint256 a, int shift)
249 var result = new uint256();
253 for (int i = 0; i < a.nWidth; i++)
255 if (i - k - 1 >= 0 && shift != 0)
257 result.pn[i - k - 1] |= (a.pn[i] << (32 - shift));
262 result.pn[i - k] |= (a.pn[i] >> shift);