Redefine uint160.nWidth, uint160.pn, uint256.nWidth and uint256.pn as protected prope...
[NovacoinLibrary.git] / Novacoin / uint160.cs
1 \feffusing System;
2 using System.Collections.Generic;
3 using System.Diagnostics.Contracts;
4 using System.Linq;
5 using System.Text;
6 using System.Threading.Tasks;
7
8 namespace Novacoin
9 {
10     public class uint160 : base_uint
11     {
12         new protected int nWidth
13         {
14             get { return base.nWidth; }
15             private set { base.nWidth = value; }
16         }
17         new protected uint[] pn
18         {
19             get { return base.pn; }
20             private set { base.pn = value; }
21         }
22
23         public uint160()
24         {
25             nWidth = 5;
26             pn = new uint[nWidth];
27         }
28
29         public uint160(uint160 b) : this()
30         {
31             for (int i = 0; i < nWidth; i++)
32             {
33                 pn[i] = b.pn[i];
34             }
35         }
36
37
38         public uint160(ulong n) : this()
39         {
40             pn[0] = (uint)n;
41             pn[1] = (uint)(n >> 32);
42             for (int i = 2; i < nWidth; i++)
43             {
44                 pn[i] = 0;
45             }
46         }
47
48         public uint160(byte[] bytes) : this()
49         {
50             Contract.Requires<ArgumentException>(bytes.Length == 20, "Incorrect array length");
51             pn = Interop.ToUInt32Array(bytes);
52         }
53
54         public uint160(string hex) : this()
55         {
56             Contract.Requires<ArgumentException>(hex.Length == 40, "Incorrect string");
57             var bytes = Interop.ReverseBytes(Interop.HexToArray(hex));
58             pn = Interop.ToUInt32Array(bytes);
59         }
60
61         public static uint160 operator ~(uint160 a)
62         {
63             var ret = new uint160();
64             for (int i = 0; i < a.nWidth; i++)
65             {
66                 ret.pn[i] = ~a.pn[i];
67             }
68             return ret;
69         }
70
71         public static uint160 operator -(uint160 a)
72         {
73             var ret = new uint160();
74             for (int i = 0; i < a.nWidth; i++)
75             {
76                 ret.pn[i] = ~a.pn[i];
77             }
78             ret++;
79             return ret;
80         }
81
82
83         public static uint160 operator ++(uint160 a)
84         {
85             int i = 0;
86             while (++a.pn[i] == 0 && i < a.nWidth - 1)
87             {
88                 i++;
89             }
90             return a;
91         }
92
93         public static uint160 operator --(uint160 a)
94         {
95             int i = 0;
96             while (--a.pn[i] == uint.MaxValue && i < a.nWidth - 1)
97             {
98                 i++;
99             }
100             return a;
101         }
102
103         public static uint160 operator ^(uint160 a, uint160 b)
104         {
105             var result = new uint160();
106             result.pn = new uint[a.nWidth];
107             for (int i = 0; i < result.nWidth; i++)
108             {
109                 result.pn[i] = a.pn[i] ^ b.pn[i];
110             }
111             return result;
112         }
113
114         public static uint160 operator +(uint160 a, uint160 b)
115         {
116             var result = new uint160();
117             ulong carry = 0;
118             for (int i = 0; i < result.nWidth; i++)
119             {
120                 ulong n = carry + a.pn[i] + b.pn[i];
121                 result.pn[i] = (uint)(n & 0xffffffff);
122                 carry = n >> 32;
123             }
124             return result;
125         }
126
127         public static uint160 operator +(uint160 a, ulong b)
128         {
129             return a + new uint160(b);
130         }
131
132         public static uint160 operator -(uint160 a, uint160 b)
133         {
134             return a + (-b);
135         }
136
137         public static uint160 operator -(uint160 a, ulong b)
138         {
139             return a - new uint160(b);
140         }
141
142         public static uint160 operator &(uint160 a, uint160 b)
143         {
144             var result = new uint160();
145             result.pn = new uint[a.nWidth];
146             for (int i = 0; i < result.nWidth; i++)
147             {
148                 result.pn[i] = a.pn[i] & b.pn[i];
149             }
150             return result;
151         }
152
153         public static uint160 operator |(uint160 a, uint160 b)
154         {
155             var result = new uint160();
156             result.pn = new uint[a.nWidth];
157             for (int i = 0; i < result.nWidth; i++)
158             {
159                 result.pn[i] = a.pn[i] | b.pn[i];
160             }
161             return result;
162         }
163
164         public static uint160 operator <<(uint160 a, int shift)
165         {
166             var result = new uint160();
167             int k = shift / 32;
168             shift = shift % 32;
169
170             for (int i = 0; i < a.nWidth; i++)
171             {
172                 if (i + k + 1 < a.nWidth && shift != 0)
173                 {
174                     result.pn[i + k + 1] |= (a.pn[i] >> (32 - shift));
175                 }
176
177                 if (i + k < a.nWidth)
178                 {
179                     result.pn[i + k] |= (a.pn[i] << shift);
180                 }
181             }
182
183             return result;
184         }
185
186         public static uint160 operator >>(uint160 a, int shift)
187         {
188             var result = new uint160();
189             int k = shift / 32;
190             shift = shift % 32;
191
192             for (int i = 0; i < a.nWidth; i++)
193             {
194                 if (i - k - 1 >= 0 && shift != 0)
195                 {
196                     result.pn[i - k - 1] |= (a.pn[i] << (32 - shift));
197                 }
198
199                 if (i - k >= 0)
200                 {
201                     result.pn[i - k] |= (a.pn[i] >> shift);
202                 }
203             }
204
205             return result;
206         }
207     }
208 }