298 lines
7.0 KiB
C#
298 lines
7.0 KiB
C#
using System;
|
|
using sharp.extensions;
|
|
using System.Text;
|
|
using System.Numerics;
|
|
|
|
namespace BigInt
|
|
{
|
|
public class BigIntegerWrapper
|
|
{
|
|
/** Value for Calculations **/
|
|
private System.Numerics.BigInteger value;
|
|
/**
|
|
* Size of BigInteger in bytes that this Number is represented externally
|
|
**/
|
|
private int size;
|
|
|
|
|
|
public BigIntegerWrapper(int size)
|
|
{
|
|
this.size = size;
|
|
this.value = new System.Numerics.BigInteger();
|
|
}
|
|
public BigIntegerWrapper(int size, Int64 v)
|
|
{
|
|
this.size = size;
|
|
this.value = v;
|
|
}
|
|
public BigIntegerWrapper(int size, Int32 v)
|
|
{
|
|
this.size = size;
|
|
this.value = v;
|
|
}
|
|
public BigIntegerWrapper(int size,System.Numerics.BigInteger value){
|
|
this.size = size;
|
|
this.value = value;
|
|
}
|
|
public BigIntegerWrapper(byte[] value)
|
|
{
|
|
this.size = value.Length;
|
|
this.value = new System.Numerics.BigInteger(value);
|
|
}
|
|
|
|
public BigIntegerWrapper Pow3(){
|
|
return new BigIntegerWrapper(this.size,this.value * this.value * this.value);
|
|
}
|
|
|
|
public BigIntegerWrapper Sqrt(){
|
|
return new BigIntegerWrapper(this.size, this.value.Sqrt());
|
|
}
|
|
|
|
|
|
public byte[] getBytes()
|
|
{
|
|
byte[] va = this.value.ToByteArray();
|
|
byte[] r = new byte[this.size];
|
|
int lcopy = va.Length < r.Length ? va.Length : r.Length;
|
|
|
|
Array.Copy( va,r, lcopy );
|
|
r.Fill(value < 0 ? (byte)0xff : (byte)0,lcopy);
|
|
|
|
return r;
|
|
}
|
|
|
|
public byte[] getBytes(Endianess endianess){
|
|
byte[] bytes = getBytes();
|
|
if (endianess != 0.CurrentEndianess()){
|
|
return bytes.Reverse();
|
|
}
|
|
return bytes;
|
|
}
|
|
|
|
public string toHexString()
|
|
{
|
|
return getBytes().toHexString();
|
|
}
|
|
public string toHexString(Endianess endianess)
|
|
{
|
|
return getBytes(endianess).toHexString();
|
|
}
|
|
|
|
public static BigIntegerWrapper fromHexString(string hex){
|
|
return new BigIntegerWrapper(HexString.toBytes(hex));
|
|
}
|
|
|
|
public static BigIntegerWrapper operator +(BigIntegerWrapper a, BigIntegerWrapper b)
|
|
{
|
|
return new BigIntegerWrapper(a.size, a.value + b.value);
|
|
}
|
|
public static BigIntegerWrapper operator -(BigIntegerWrapper a, BigIntegerWrapper b)
|
|
{
|
|
return new BigIntegerWrapper(a.size, a.value - b.value);
|
|
}
|
|
public static BigIntegerWrapper operator /(BigIntegerWrapper a, BigIntegerWrapper b)
|
|
{
|
|
return new BigIntegerWrapper(a.size, a.value / b.value);
|
|
}
|
|
public static BigIntegerWrapper operator *(BigIntegerWrapper a, BigIntegerWrapper b)
|
|
{
|
|
return new BigIntegerWrapper(a.size, a.value * b.value);
|
|
}
|
|
public static BigIntegerWrapper operator %(BigIntegerWrapper a, BigIntegerWrapper b)
|
|
{
|
|
return new BigIntegerWrapper(a.size, a.value % b.value);
|
|
}
|
|
|
|
public static BigIntegerWrapper operator <<(BigIntegerWrapper a,int n)
|
|
{
|
|
return new BigIntegerWrapper(a.size, a.value << n);
|
|
}
|
|
public static BigIntegerWrapper operator >>(BigIntegerWrapper a, int n)
|
|
{
|
|
return new BigIntegerWrapper(a.size, a.value >> n);
|
|
}
|
|
|
|
|
|
public static implicit operator BigIntegerWrapper(Int32 v)
|
|
{
|
|
return new BigIntegerWrapper(v.GetBytes());
|
|
}
|
|
public static implicit operator BigIntegerWrapper(UInt32 v)
|
|
{
|
|
return new BigIntegerWrapper(v.GetBytes());
|
|
}
|
|
public static implicit operator BigIntegerWrapper(Int64 v)
|
|
{
|
|
return new BigIntegerWrapper(v.GetBytes());
|
|
}
|
|
public static implicit operator BigIntegerWrapper(UInt64 v)
|
|
{
|
|
return new BigIntegerWrapper(v.GetBytes());
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
/*
|
|
UInt32[] value;
|
|
|
|
public BigInteger(int bits)
|
|
{
|
|
this.value = new UInt32[(bits + 0x1F) >> 5];
|
|
}
|
|
public BigInteger(UInt32[] initialValue)
|
|
{
|
|
this.value = initialValue.Segment(0);
|
|
}
|
|
public BigInteger(BigInteger initialValue)
|
|
{
|
|
this.value = initialValue.value.Segment(0);
|
|
}
|
|
|
|
public UInt32 this[int n] {
|
|
get { return (this.value.Length > n) ? this.value[n] : 0; }
|
|
}
|
|
|
|
|
|
public override string ToString()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
foreach (UInt32 seg in this.value.Reverse()){
|
|
sb.Append(seg.GetBytes(Endianess.BigEndian).toHexString());
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
|
|
|
|
public static BigInteger operator +(BigInteger a, UInt32 b)
|
|
{
|
|
UInt32[] result = new UInt32[a.value.Length];
|
|
UInt32 c = 0;
|
|
|
|
result[0] = add(a[0], b, ref c);
|
|
for (int n = 1; n < result.Length; n++)
|
|
{
|
|
result[n] = add(a[n], ref c);
|
|
}
|
|
|
|
return new BigInteger(result);
|
|
}
|
|
public static BigInteger operator +(BigInteger a,BigInteger b){
|
|
UInt32[] result = new UInt32[ getBufferSize(a,b) ];
|
|
UInt32 c = 0;
|
|
|
|
for (int n = 0; n < result.Length; n++){
|
|
result[n] = add(a[n], b[n], ref c);
|
|
}
|
|
|
|
return new BigInteger(result);
|
|
}
|
|
|
|
public static BigInteger operator -(BigInteger a, UInt32 b)
|
|
{
|
|
UInt32[] result = new UInt32[a.value.Length];
|
|
UInt32 c = 0;
|
|
|
|
result[0] = sub(a[0], b, ref c);
|
|
for (int n = 1; n < result.Length; n++)
|
|
{
|
|
result[n] = sub(a[n], ref c);
|
|
}
|
|
|
|
return new BigInteger(result);
|
|
}
|
|
public static BigInteger operator -(BigInteger a, BigInteger b)
|
|
{
|
|
UInt32[] result = new UInt32[getBufferSize(a, b)];
|
|
UInt32 c = 0;
|
|
|
|
for (int n = 0; n < result.Length; n++)
|
|
{
|
|
result[n] = add(a[n], b[n], ref c);
|
|
}
|
|
|
|
return new BigInteger(result);
|
|
}
|
|
|
|
public static BigInteger operator <<(BigInteger a,int n){
|
|
BigInteger b = new BigInteger(a);
|
|
UInt32 c = 0;
|
|
int step = n >> 5;
|
|
n &= 0x1F;
|
|
|
|
for (int i = step; i < (b.value.Length); i++){
|
|
b.value[i] = shl(b.value[i - step], n, ref c);
|
|
}
|
|
for (int i = 0; i < (step); i++)
|
|
{
|
|
b.value[i] = 0;
|
|
}
|
|
return b;
|
|
}
|
|
|
|
public static BigInteger operator >>(BigInteger a, int n)
|
|
{
|
|
BigInteger b = new BigInteger(a);
|
|
UInt32 c = 0;
|
|
|
|
for (int i = b.value.Length; i > 0; i--)
|
|
{
|
|
b.value[i-1] = shr(b.value[i-1], n, ref c);
|
|
}
|
|
|
|
return b;
|
|
}
|
|
|
|
private static UInt32 add(UInt32 a, UInt32 b, ref UInt32 carry)
|
|
{
|
|
UInt64 ui64 = (UInt64)carry + (UInt64)a + (UInt64)b;
|
|
carry = (UInt32)(ui64 >> 32);
|
|
return (UInt32)(ui64 & 0xffffffff);
|
|
}
|
|
private static UInt32 add(UInt32 a, ref UInt32 carry)
|
|
{
|
|
UInt64 ui64 = (UInt64)carry + (UInt64)a;
|
|
carry = (UInt32)(ui64 >> 32);
|
|
return (UInt32)(ui64 & 0xffffffff);
|
|
}
|
|
|
|
private static UInt32 sub(UInt32 a, UInt32 b, ref UInt32 carry)
|
|
{
|
|
UInt64 ui64 = (UInt64)a - (UInt64)b - (UInt64)carry;
|
|
carry = (ui64 & (1UL << 63)) != 0 ? (UInt32)1 : (UInt32)0;
|
|
return (UInt32)(ui64 & 0xffffffff);
|
|
}
|
|
private static UInt32 sub(UInt32 a, ref UInt32 carry)
|
|
{
|
|
UInt64 ui64 = (UInt64)a - (UInt64)carry;
|
|
carry = (ui64 & (1UL << 63)) != 0 ? (UInt32)1 : (UInt32)0;
|
|
return (UInt32)(ui64 & 0xffffffff);
|
|
}
|
|
|
|
private static UInt32 shl(UInt32 a, int n, ref UInt32 carry)
|
|
{
|
|
UInt64 result = (UInt64)((UInt64)a << n) | carry;
|
|
carry = (UInt32)(result >> 32);
|
|
return (UInt32)result;
|
|
}
|
|
private static UInt32 shr(UInt32 a, int n, ref UInt32 carry)
|
|
{
|
|
UInt64 result = (UInt64)((UInt64)a << (32 - n)) | ((UInt64)carry << 32);
|
|
carry = (UInt32)result;
|
|
return (UInt32)(result >> 32);
|
|
}
|
|
|
|
|
|
private static int getBufferSize(BigInteger a){
|
|
return a.value.Length;
|
|
}
|
|
private static int getBufferSize(BigInteger a,BigInteger b)
|
|
{
|
|
return a.value.Length > b.value.Length ? a.value.Length : b.value.Length;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|