X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=Novacoin%2Fbase_uint.cs;h=072111f620af3eedd6ffbd8a1efffd250aac85e6;hb=241856f1328f7d900260976c18c29f67c7cebc80;hp=b7eb7f90ab48913b3be3ac3389e385ee974ed22a;hpb=534af8e0f785ed0854becde62732e9fcc0a36fe4;p=NovacoinLibrary.git diff --git a/Novacoin/base_uint.cs b/Novacoin/base_uint.cs index b7eb7f9..072111f 100644 --- a/Novacoin/base_uint.cs +++ b/Novacoin/base_uint.cs @@ -18,10 +18,15 @@ using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; namespace Novacoin { - public class base_uint : IComparable, IEquatable + /// + /// Base class for uint256 and uint160. + /// + public class base_uint : IComparable, IEquatable, IEqualityComparer { protected int nWidth; protected uint[] pn; @@ -50,120 +55,54 @@ namespace Novacoin return pn[0]; } + /// + /// Total size in bytes. + /// public int Size { get { - return nWidth; + return nWidth * sizeof(uint); } } - - public static bool operator !(base_uint a) + /// + /// Zero or the position of highest non-zero bit plus one. + /// + protected int bits { - for (int i = 0; i < a.nWidth; i++) + get { - if (a.pn[i] != 0) + for (int pos = nWidth - 1; pos >= 0; pos--) { - return false; + if (pn[pos]!=0) + { + for (int bits = 31; bits > 0; bits--) + { + if ((pn[pos] & 1 << bits)!=0) + return 32 * pos + bits + 1; + } + return 32 * pos + 1; + } } + return 0; } - 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) + public static bool 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]; + if (a.pn[i] != 0) + { + return false; + } } - return result; + return true; } - 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; - } + #region Comparison operations public static bool operator <(base_uint a, base_uint b) { for (int i = a.nWidth - 1; i >= 0; i--) @@ -227,7 +166,9 @@ namespace Novacoin } return true; } + #endregion + #region Equality operators public static bool operator ==(base_uint a, base_uint b) { if (object.ReferenceEquals(a, b)) @@ -251,10 +192,12 @@ namespace Novacoin { return false; } + if (a.pn[1] != (uint)(b >> 32)) { return false; } + for (int i = 2; i < a.nWidth; i++) { if (a.pn[i] != 0) @@ -274,33 +217,43 @@ namespace Novacoin { return (!(a == b)); } - + #endregion + + #region Cast oerations + /// + /// True cast operator + /// + /// + /// public static bool operator true(base_uint a) { return (a != 0); } + /// + /// False cast operator. + /// + /// Value + /// Boolean result public static bool operator false(base_uint a) { return (a == 0); } + /// + /// Imlicit byte[] cast operator. + /// + /// Value 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); } + #endregion private static bool ArraysEqual(uint[] a, uint[] b) { - if (a.Length != b.Length) - { - return false; - } + Contract.Requires(a.Length == b.Length, "Array length mismatch."); + for (int i = 0; i < a.Length; i++) { if (a[i] != b[i]) @@ -311,19 +264,26 @@ namespace Novacoin return true; } - public override int GetHashCode() + + #region IEqualityComparer + public bool Equals(base_uint a, base_uint b) { - int hash = 17; - unchecked + if (object.ReferenceEquals(a, b)) { - foreach (var element in pn) - { - hash = hash * 31 + element.GetHashCode(); - } + return true; } - return hash; + + return ArraysEqual(a.pn, b.pn); + } + + public int GetHashCode(base_uint a) + { + return a.GetHashCode(); } + #endregion + + #region IComparable public int CompareTo(base_uint item) { if (this > item) @@ -337,7 +297,9 @@ namespace Novacoin return 0; } + #endregion + #region IEquatable public bool Equals(base_uint a) { if (a == null) @@ -348,9 +310,28 @@ namespace Novacoin return ArraysEqual(pn, a.pn); } + public override int GetHashCode() + { + int hash = 17; + unchecked + { + foreach (var element in pn) + { + hash = hash * 31 + element.GetHashCode(); + } + } + return hash; + } + public override bool Equals(object o) { return Equals(o as base_uint); } + #endregion + + public override string ToString() + { + return Interop.ToHex(Interop.ReverseBytes(this)); + } } }