2 using System.Collections.Generic;
3 using System.Diagnostics.Contracts;
6 using System.Threading.Tasks;
11 public class uint256 : base_uint
13 new public readonly int nWidth = 8;
18 pn = new uint[nWidth];
20 for (int i = 0; i < nWidth; i++)
26 public uint256(uint256 b)
29 pn = new uint[nWidth];
31 for (int i = 0; i < nWidth; i++)
38 public uint256(ulong n)
41 pn = new uint[nWidth];
44 pn[1] = (uint)(n >> 32);
45 for (int i = 2; i < nWidth; i++)
51 public uint256(byte[] bytes)
53 Contract.Requires<ArgumentException>(bytes.Length == 32, "Incorrect array length");
56 pn = Interop.ToUInt32Array(bytes);
59 public uint256(string hex)
61 Contract.Requires<ArgumentException>(hex.Length == 64, "Incorrect string");
64 var bytes = Interop.ReverseBytes(Interop.HexToArray(hex));
65 pn = Interop.ToUInt32Array(bytes);
69 /// Compact representation of unsigned 256bit numbers.
71 /// N = (-1^sign) * m * 256^(exp-3)
73 /// http://bitcoin.stackexchange.com/questions/30467/what-are-the-equations-to-convert-between-bits-and-difficulty
79 int nSize = (bits + 7) / 8;
82 nCompact = ((uint)GetLow64()) << 8 * (3 - nSize);
85 uint256 bn = this >> 8 * (nSize - 3);
86 nCompact = (uint)bn.GetLow64();
89 if ((nCompact & 0x00800000) != 0)
95 Contract.Assert((nCompact & ~0x007fffff) == 0);
96 Contract.Assert(nSize < 256);
98 nCompact |= (uint)nSize << 24;
104 int nSize = (int)value >> 24;
105 uint nWord = value & 0x007fffff;
111 nWord >>= 8 * (3 - nSize);
112 i = new uint256(nWord);
116 i = new uint256(nWord);
117 i <<= 8 * (nSize - 3);
124 private void SetBytes(byte[] bytes)
126 pn = Interop.ToUInt32Array(Interop.ReverseBytes(bytes));
129 public static uint256 operator ~(uint256 a)
131 var ret = new uint256();
132 for (int i = 0; i < a.nWidth; i++)
134 ret.pn[i] = ~a.pn[i];
139 public static uint256 operator -(uint256 a)
141 var ret = new uint256();
142 for (int i = 0; i < a.nWidth; i++)
144 ret.pn[i] = ~a.pn[i];
151 public static uint256 operator ++(uint256 a)
154 while (++a.pn[i] == 0 && i < a.nWidth - 1)
161 public static uint256 operator --(uint256 a)
164 while (--a.pn[i] == uint.MaxValue && i < a.nWidth - 1)
171 public static uint256 operator ^(uint256 a, uint256 b)
173 var result = new uint256();
174 result.pn = new uint[a.nWidth];
175 for (int i = 0; i < result.nWidth; i++)
177 result.pn[i] = a.pn[i] ^ b.pn[i];
182 public static uint256 operator +(uint256 a, uint256 b)
184 var result = new uint256();
186 for (int i = 0; i < result.nWidth; i++)
188 ulong n = carry + a.pn[i] + b.pn[i];
189 result.pn[i] = (uint)(n & 0xffffffff);
195 public static uint256 operator +(uint256 a, ulong b)
197 return a + new uint256(b);
200 public static uint256 operator -(uint256 a, uint256 b)
205 public static uint256 operator -(uint256 a, ulong b)
207 return a - new uint256(b);
210 public static uint256 operator &(uint256 a, uint256 b)
212 var result = new uint256();
213 result.pn = new uint[a.nWidth];
214 for (int i = 0; i < result.nWidth; i++)
216 result.pn[i] = a.pn[i] & b.pn[i];
221 public static uint256 operator |(uint256 a, uint256 b)
223 var result = new uint256();
224 result.pn = new uint[a.nWidth];
225 for (int i = 0; i < result.nWidth; i++)
227 result.pn[i] = a.pn[i] | b.pn[i];
232 public static uint256 operator <<(uint256 a, int shift)
234 var result = new uint256();
238 for (int i = 0; i < a.nWidth; i++)
240 if (i + k + 1 < a.nWidth && shift != 0)
242 result.pn[i + k + 1] |= (a.pn[i] >> (32 - shift));
245 if (i + k < a.nWidth)
247 result.pn[i + k] |= (a.pn[i] << shift);
254 public static uint256 operator >>(uint256 a, int shift)
256 var result = new uint256();
260 for (int i = 0; i < a.nWidth; i++)
262 if (i - k - 1 >= 0 && shift != 0)
264 result.pn[i - k - 1] |= (a.pn[i] << (32 - shift));
269 result.pn[i - k] |= (a.pn[i] >> shift);