From cdc8e0cc8db6ac6f1817010a37b4aa048cb418c3 Mon Sep 17 00:00:00 2001 From: Harald Wolff Date: Thu, 18 Mar 2021 19:38:09 +0100 Subject: [PATCH] Initial Commit --- .gitignore | 40 + big.impl/Makefile | 12 + big.impl/bigint.c | 232 +++++ big.impl/bigint.o | Bin 0 -> 5736 bytes big.impl/libbigint.so | Bin 0 -> 15920 bytes ln.biginteger.sln | 48 + ln.biginteger.test/UnitTest1.cs | 84 ++ ln.biginteger.test/ln.biginteger.test.csproj | 17 + ln.biginteger/BigInteger.cs | 899 +++++++++++++++++++ ln.biginteger/NumericsExtensions.cs | 36 + ln.biginteger/libbigint.so | Bin 0 -> 16400 bytes ln.biginteger/ln.biginteger.csproj | 13 + 12 files changed, 1381 insertions(+) create mode 100644 .gitignore create mode 100644 big.impl/Makefile create mode 100644 big.impl/bigint.c create mode 100644 big.impl/bigint.o create mode 100755 big.impl/libbigint.so create mode 100644 ln.biginteger.sln create mode 100644 ln.biginteger.test/UnitTest1.cs create mode 100644 ln.biginteger.test/ln.biginteger.test.csproj create mode 100644 ln.biginteger/BigInteger.cs create mode 100644 ln.biginteger/NumericsExtensions.cs create mode 100755 ln.biginteger/libbigint.so create mode 100644 ln.biginteger/ln.biginteger.csproj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4e82d27 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# Autosave files +*~ + +# build +[Oo]bj/ +[Bb]in/ +packages/ +TestResults/ + +# globs +Makefile.in +*.DS_Store +*.sln.cache +*.suo +*.cache +*.pidb +*.userprefs +*.usertasks +config.log +config.make +config.status +aclocal.m4 +install-sh +autom4te.cache/ +*.user +*.tar.gz +tarballs/ +test-results/ +Thumbs.db + +# Mac bundle stuff +*.dmg +*.app + +# resharper +*_Resharper.* +*.Resharper + +# dotCover +*.dotCover diff --git a/big.impl/Makefile b/big.impl/Makefile new file mode 100644 index 0000000..68717e3 --- /dev/null +++ b/big.impl/Makefile @@ -0,0 +1,12 @@ + +OBJECTS=bigint.o +CFLAGS=-fPIC + +all: distribute + +distribute: ../ln.biginteger/libbigint.so + +../ln.biginteger/libbigint.so: $(OBJECTS) + gcc -shared -o ../ln.biginteger/libbigint.so $(OBJECTS) + + diff --git a/big.impl/bigint.c b/big.impl/bigint.c new file mode 100644 index 0000000..fe02b95 --- /dev/null +++ b/big.impl/bigint.c @@ -0,0 +1,232 @@ +#include +#include + +uint32_t one[] = { 1 }; + +int32_t max(int32_t a,int32_t b) +{ + return a>b ? a : b; +} + +int32_t big_get_length(uint32_t *op, int32_t length) +{ + for (; length > 1; length--){ + if ( + ((op[length-1] != 0) || ((op[length-2] & (1<<31))!=0)) && ((op[length-1] != 0xFFFFFFFF) || ((op[length-2] & (1<<31))==0)) + ){ + break; + } + } + return length; +} + +int32_t big_sign(uint32_t *op, int32_t length) +{ + if ((length == 1) && (op[0] == 0)) + return 0; + else if ((op[length-1] & 0x80000000) != 0) + return -1; + else + return 1; +} + +int32_t big_log2(uint32_t *op, int32_t length) +{ + if (big_sign(op, length) < 0) + { + for (int n = (length << 5)-1; n > 0; n--) + { + if ((op[(n - 1) >> 5] & (1 << ((n - 1) & 0x1F))) == 0) + { + return 1 - n; + } + } + return 0; + } else { + for (int n = length << 5; n > 0; n--) + { + if ((op[(n - 1) >> 5] & (1 << ((n - 1) & 0x1F))) != 0) + { + return n - 1; + } + } + return 0; + } +} + +int32_t big_cmp(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length_b) +{ + int l = max(length_a, length_b); + for (int n=l-1; n >= 0; n--) + { + int a = n < length_a ? op_a[n] : 0; + int b = n < length_b ? op_b[n] : 0; + + if (a < b) + return -1; + else if (a > b) + return 1; + } + return 0; +} + +void big_shl(uint32_t *op, int32_t length, int32_t n) +{ + if (n > 0) + { + int step = n >> 5; + n &= 0x1F; + + for (int i = length; i > 0; i--) + { + int b1 = i - 1 - step; + int b2 = b1 - 1; + + if (b1 >= 0){ + op[i - 1] = (op[b1] << n); + if ((n != 0)&&(b2 >= 0)) + { + op[i - 1] |= ((op[b2] >> (32 - n))); + } + } else { + op[i - 1] = 0; + } + } + } +} + +void big_shr(uint32_t *op, int32_t length, int32_t n) +{ + if (n > 0) + { + int32_t s = big_sign(op, length); + int step = n >> 5; + n &= 0x1F; + + for (int i = 0; i < length; i++) + { + int b1 = i + step; + int b2 = b1 + 1; + + if (b1 < length) + { + op[i] = (op[b1] >> n); + if ((b2 == length) && (s)){ + op[i] |= ((0xffffffff << (32 - n))); + } else if ((n != 0) && (b2 < length)) + { + op[i] |= ((op[b2] << (32 - n))); + } + } else { + op[i] = s ? 0xFFFFFFFF : 0; + } + } + } +} + + +void big_add(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length_b) +{ + uint64_t c = 0; + + for (int n=0;n>= 32; + + if ((c == 0) && (n > length_b)) + break; + } +} +void big_sub(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length_b) +{ + uint64_t c = 0; + + for (int n=0;n>= 32; + + if ((c == 0) && (n > length_b)) + break; + } +} + +void big_twos(uint32_t *op, int32_t length) +{ + for (int n=0;n>= 32; + } + } + } +} + +void big_divmod(uint32_t* op_a, int32_t length_a, uint32_t* op_b, int32_t length_b) +{ + int sign_a = big_sign(op_a, length_a); + int sign_b = big_sign(op_b, length_b); + + uint32_t dividend[length_a]; + uint32_t divisor[length_a]; + + memset( divisor, 0x00, sizeof(divisor) ); + + memcpy( dividend, op_a, length_a << 2); + memcpy( divisor, op_b, length_b << 2); + + memset( op_a, 0x00, length_a << 2); + + if (sign_a < 0) + big_twos( dividend, length_a); + if (sign_b < 0) + big_twos( divisor, length_a); + + int lg2a, lg2b, shift; + + lg2a = big_log2(dividend, length_a); + lg2b = big_log2(divisor, length_a); + shift = lg2a - lg2b; + + if (shift > 0) + big_shl(divisor, length_a, shift); + + for (int n = 0; n <= (shift); n++) + { + big_shl(op_a, length_a, 1); + + if (big_cmp( divisor, length_a, dividend, length_a ) <= 0) + { + op_a[0] |= 1; + big_sub( dividend, length_a, divisor, length_a ); + } + + big_shr( divisor, length_b, 1); + } + + if ((sign_a < 0) != (sign_b < 0)) + big_twos(op_a, length_a); + if (sign_a < 0) + big_twos(dividend, length_a); + + memcpy( op_b, dividend, length_b << 2); +} diff --git a/big.impl/bigint.o b/big.impl/bigint.o new file mode 100644 index 0000000000000000000000000000000000000000..090c7739c7841937ed47e24632c5f255cf79f18a GIT binary patch literal 5736 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 literal 0 HcmV?d00001 diff --git a/ln.biginteger.sln b/ln.biginteger.sln new file mode 100644 index 0000000..3da26b7 --- /dev/null +++ b/ln.biginteger.sln @@ -0,0 +1,48 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.biginteger", "ln.biginteger\ln.biginteger.csproj", "{25072D31-5A85-4114-8C11-37299240E494}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.biginteger.test", "ln.biginteger.test\ln.biginteger.test.csproj", "{4AB1ADA7-ACB3-4790-90F0-2813FC56408A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {25072D31-5A85-4114-8C11-37299240E494}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {25072D31-5A85-4114-8C11-37299240E494}.Debug|Any CPU.Build.0 = Debug|Any CPU + {25072D31-5A85-4114-8C11-37299240E494}.Debug|x64.ActiveCfg = Debug|Any CPU + {25072D31-5A85-4114-8C11-37299240E494}.Debug|x64.Build.0 = Debug|Any CPU + {25072D31-5A85-4114-8C11-37299240E494}.Debug|x86.ActiveCfg = Debug|Any CPU + {25072D31-5A85-4114-8C11-37299240E494}.Debug|x86.Build.0 = Debug|Any CPU + {25072D31-5A85-4114-8C11-37299240E494}.Release|Any CPU.ActiveCfg = Release|Any CPU + {25072D31-5A85-4114-8C11-37299240E494}.Release|Any CPU.Build.0 = Release|Any CPU + {25072D31-5A85-4114-8C11-37299240E494}.Release|x64.ActiveCfg = Release|Any CPU + {25072D31-5A85-4114-8C11-37299240E494}.Release|x64.Build.0 = Release|Any CPU + {25072D31-5A85-4114-8C11-37299240E494}.Release|x86.ActiveCfg = Release|Any CPU + {25072D31-5A85-4114-8C11-37299240E494}.Release|x86.Build.0 = Release|Any CPU + {4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Debug|x64.ActiveCfg = Debug|Any CPU + {4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Debug|x64.Build.0 = Debug|Any CPU + {4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Debug|x86.ActiveCfg = Debug|Any CPU + {4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Debug|x86.Build.0 = Debug|Any CPU + {4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Release|Any CPU.Build.0 = Release|Any CPU + {4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Release|x64.ActiveCfg = Release|Any CPU + {4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Release|x64.Build.0 = Release|Any CPU + {4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Release|x86.ActiveCfg = Release|Any CPU + {4AB1ADA7-ACB3-4790-90F0-2813FC56408A}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/ln.biginteger.test/UnitTest1.cs b/ln.biginteger.test/UnitTest1.cs new file mode 100644 index 0000000..e6449ec --- /dev/null +++ b/ln.biginteger.test/UnitTest1.cs @@ -0,0 +1,84 @@ +using NUnit.Framework; + +namespace ln.biginteger.test +{ + public class Tests + { + [SetUp] + public void Setup() + { + } + + [Test] + public void Test_01_BigInteger() + { + Assert.AreEqual(1, BigInteger.Zero.GetLength()); + Assert.AreEqual(1, BigInteger.One.GetLength()); + Assert.AreEqual(2, new BigInteger(long.MaxValue).GetLength()); + Assert.AreEqual(2, new BigInteger(long.MinValue).GetLength()); + Assert.AreEqual(1, new BigInteger((long)1234).GetLength()); + + Assert.AreEqual(BigInteger.One, BigInteger.MinusOne.Twos()); + Assert.AreEqual(BigInteger.MinusOne, BigInteger.One.Twos()); + Assert.AreEqual(BigInteger.Zero, BigInteger.Zero.Twos()); + + Assert.IsTrue(BigInteger.Zero.IsZero); + Assert.IsFalse(BigInteger.One.IsZero); + + Assert.AreEqual(BigInteger.One, BigInteger.Zero.Add(BigInteger.One)); + Assert.AreEqual(BigInteger.One, BigInteger.One.Add(BigInteger.Zero)); + Assert.AreNotEqual(BigInteger.Zero, BigInteger.Zero.Add(BigInteger.One)); + + Assert.AreEqual(BigInteger.Zero, BigInteger.One.Sub(BigInteger.One)); + Assert.AreEqual(BigInteger.One, BigInteger.One.Sub(BigInteger.Zero)); + + BigInteger bi5 = new BigInteger(5 << 24); + BigInteger bi15 = new BigInteger(15 << 24 ); + BigInteger bi75 = new BigInteger(75L << 48 ); + BigInteger bi75b = bi5.Mul(bi15); + + Assert.AreEqual(bi75, bi75b); + Assert.AreEqual(new BigInteger(5), bi5 >> 24); + + + + + + Assert.Pass(); + } + + [Test] + public void Test_20_Converter() + { + foreach (string hexdigits in new string[]{ + "44BBCCDD", + "FFFFFFFF", + "1122334455667788", + "778899AABBCCDDEE" + }) + TestImplHexConvert(hexdigits); + } + + public void TestImplHexConvert(string hexdigits) + { + BigInteger bi = BigInteger.FromHexString(hexdigits); + string rehexed = bi.ToHexString(); + Assert.AreEqual(hexdigits, rehexed); + } + + + struct TestVector + { + public uint[] a,b,c; + + public TestVector(uint[] a,uint[] b, uint[] c) + { + this.a = a; + this.b = b; + this.c = c; + } + + + } + } +} \ No newline at end of file diff --git a/ln.biginteger.test/ln.biginteger.test.csproj b/ln.biginteger.test/ln.biginteger.test.csproj new file mode 100644 index 0000000..5db5206 --- /dev/null +++ b/ln.biginteger.test/ln.biginteger.test.csproj @@ -0,0 +1,17 @@ + + + + netcoreapp5.0 + + false + + + + + + + + + + + diff --git a/ln.biginteger/BigInteger.cs b/ln.biginteger/BigInteger.cs new file mode 100644 index 0000000..58a5961 --- /dev/null +++ b/ln.biginteger/BigInteger.cs @@ -0,0 +1,899 @@ +using System; +using System.Globalization; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; + +namespace ln.biginteger +{ + public class BigInteger : IComparable + { + public static readonly BigInteger Zero = new BigInteger(); + public static readonly BigInteger One = new BigInteger(1); + public static readonly BigInteger MinusOne = new BigInteger(-1); + + UInt32[] bits; + + public BigInteger() + { + this.bits = new UInt32[1]; + } + public BigInteger(UInt32 ui) + { + this.bits = new uint[]{ ui }; + } + public BigInteger(Int32 i) + { + this.bits = new uint[]{ (uint)i }; + } + + public BigInteger(UInt64 i) + { + this.bits = new uint[]{ + (uint)(i & 0xFFFFFFFF), + (uint)(i >> 32), + 0 + }; + Reduce(); + } + public BigInteger(Int64 i) + { + this.bits = new uint[]{ + (uint)(i & 0xFFFFFFFF), + (uint)(i >> 32) + }; + Reduce(); + } + + public BigInteger(UInt32[] rawbits) + { + bits = rawbits; + if (!Reduce()) + bits = (UInt32[])bits.Clone(); + } + + private bool Reduce() + { + Int32 rl = GetLength(); + if (bits.Length > rl) + { + UInt32[] newbits = new uint[rl]; + Array.Copy(bits, newbits, rl); + bits = newbits; + return true; + } + return false; + } + + public Int32 GetByteCount() => big_get_length(bits) << 2; + public Int32 GetBitLength() => big_get_length(bits) << 5; + public Int32 GetLength() => big_get_length(bits); + + public int CompareTo(BigInteger other) => big_cmp(bits, bits.Length, other.bits, other.bits.Length); + + + public Int32 Sign { + get { + if ((bits.Length == 1) && (bits[0] == 0)) + return 0; + else if ((bits[bits.Length-1] & 0x80000000) != 0) + return -1; + else + return 1; + } + } + + public bool IsZero => ((bits.Length == 1) && (bits[0] == 0)); + + + public BigInteger Add(BigInteger bi2) + { + UInt32[] r = new uint[max(bits.Length, bi2.bits.Length)+1]; + Array.Copy(bits,r,bits.Length); + big_add(r, r.Length, bi2.bits, bi2.bits.Length); + return new BigInteger(r); + } + public BigInteger Sub(BigInteger bi2) + { + UInt32[] r = new uint[max(bits.Length, bi2.bits.Length)+1]; + Array.Copy(bits,r,bits.Length); + big_sub(r, r.Length, bi2.bits, bi2.bits.Length); + return new BigInteger(r); + } + // public BigInteger Sub(BigInteger bi2) + // { + // UInt32[] r = new uint[max(bits.Length, bi2.bits.Length)+1]; + // Array.Copy(bits,r,bits.Length); + + // UInt32[] r2 = (uint[])bi2.bits.Clone(); + // big_twos(r2, r2.Length); + + // big_add(r, r.Length, r2, r2.Length); + // return new BigInteger(r); + // } + + public BigInteger Mul(BigInteger bi2) + { + UInt32[] r = new uint[bits.Length + bi2.bits.Length]; + big_smul(bits, bits.Length, bi2.bits, bi2.bits.Length, r); + return new BigInteger(r); + } + + public BigInteger DivMod(BigInteger divisor,out BigInteger remainder) + { + UInt32[] quotient = (uint[])bits.Clone(); + UInt32[] d = (uint[])divisor.bits.Clone(); + + big_divmod( quotient, quotient.Length, d, d.Length); + + remainder = new BigInteger(d); + return new BigInteger(quotient); + } + public BigInteger Div(BigInteger divisor) + { + UInt32[] quotient = (uint[])bits.Clone(); + UInt32[] d = (uint[])divisor.bits.Clone(); + + big_divmod( quotient, quotient.Length, d, d.Length); + + return new BigInteger(quotient); + } + public BigInteger Mod(BigInteger divisor) + { + UInt32[] quotient = (uint[])bits.Clone(); + UInt32[] d = (uint[])divisor.bits.Clone(); + + big_divmod( quotient, quotient.Length, d, d.Length); + + return new BigInteger(d); + } + + + + public BigInteger Ones() + { + UInt32[] r = (UInt32[])bits.Clone(); + for (int n=0;n= 0; n--) + { + for (int m=3; m>=0; m--) + { + byte tb = (byte)((bits[n] >> (m*8)) & 0xff); + if (nonzero || (tb!=0)) + { + nonzero = true; + ms.WriteByte(tb); + } + } + } + + return ms.ToArray(); + } + + + public static BigInteger operator+(BigInteger bi1,BigInteger bi2) => bi1.Add(bi2); + public static BigInteger operator-(BigInteger bi1,BigInteger bi2) => bi1.Sub(bi2); + + public static BigInteger operator<<(BigInteger bi, int n) => bi.ShiftLeft(n); + public static BigInteger operator>>(BigInteger bi, int n) => bi.ShiftRight(n); + + + + + + + + public static BigInteger FromHexString(string hex) + { + hex = hex.ToUpper(); + int length = (hex.Length+7) >> 3; + UInt32[] bits = new uint[length]; + int n; + + for (n=hex.Length-8; n>=0; n -= 8) + bits[length - 1 - (n >> 3)] = uint.Parse(hex.Substring(n,8), NumberStyles.HexNumber); + if (n > -8) + bits[length - 1] = uint.Parse(hex.Substring(0, 8 + n), NumberStyles.HexNumber); + + return new BigInteger(bits); + } + + public string ToHexString() + { + byte[] bytes = ToByteArray(); + StringBuilder sb = new StringBuilder(); + foreach (byte by in bytes) + sb.AppendFormat("{0:X2}", by); + return sb.ToString(); + } + + + + // public BigInteger(UInt32[] value) + // { + // this.bits = value; + // } + + + + + // public BigInteger(byte[] ivalue) + // { + // UInt32[] v = new UInt32[(ivalue.Length + 3) >> 2]; + // ivalue = ivalue.Segment(0, v.Length << 2); + + // for (int n = 0; n < v.Length; n++) + // { + // v[n] = BitConverter.ToUInt32(ivalue, n << 2); + // } + // this.bits = BigIntMath.reduceSigned(v); + // } + // public BigInteger(BigInteger src) + // { + // this.bits = src.bits; + // } + + // public bool IsZero => BigIntMath.isZero(bits); + // public int Sign => BigIntMath.isZero(bits) ? 0 : BigIntMath.sign(bits) ? -1 : 1; + + // public int GetByteCount() => bits.Length * 4; + // public int GetBitLength() => BigIntMath.log2(bits); + + // public byte[] ToByteArray() => bits.GetBytes(); + + // public void TryWriteBytes(Span s,out int bytesWritten) + // { + // byte[] sb = ToByteArray(); + // for (bytesWritten = 0; bytesWritten < sb.Length; bytesWritten++) + // s[bytesWritten] = sb[bytesWritten]; + // } + + // public int Log2(){ + // return BigIntMath.log2(bits); + // } + + // public static BigInteger ModPow(BigInteger i,int n,BigInteger modulus) + // { + // BigInteger r = BigInteger.One; + // while (n-- > 0) + // { + // r *= i; + // r %= modulus; + // } + // return r; + // } + + // public BigInteger Pow(int n) + // { + // if (n == 0) + // { + // return One; + // } + // else if (n == 1) + // { + // return this; + // } + // else if (n > 1) + // { + // BigInteger result = this; + // n--; + // while ((n--) > 0) + // { + // result = (result * this); + // } + // return result; + // } + // throw new ArgumentException("Integer.Pow(n): not implemented for negative exponent"); + // } + + // public BigInteger Ones() + // { + // UInt32[] result = BigIntMath.ones(bits); + // return new BigInteger(result); + // } + + // public BigInteger Twos() + // { + // UInt32[] result = BigIntMath.twos(bits); + // return new BigInteger(result); + // } + + + // public static BigInteger fromHexString(string hex) => Parse(hex, 16); + + // public override string ToString() + // { + // return String.Format("[{0}: Sign: {2,5} / {1}]", this.GetType().Name, ToString(16), Sign ); + // } + + // public string ToString(string format) + // { + // if (format.Equals("X")) + // return ToString(16); + // return ToString(10); + // } + + // public string ToString(int radix) => ToString(radix, -1); + // public string ToString(int radix, int length) + // { + // if ((radix < 2) || (radix > 36)) + // throw new ArgumentOutOfRangeException(nameof(radix)); + + // uint[] v = bits.Segment(0); + // uint[] r = new uint[]{ (uint)radix }; + + // StringBuilder sb = new StringBuilder(); + + // while ((!BigIntMath.isZero(v)) && ((length-- )!=0)) + // { + // uint[] x = BigIntMath.sdivmod(ref v, r); + // if (v[0] < 10) + // sb.Append((char)('0' + v[0])); + // else + // sb.Append((char)(55 + v[0])); + // v = x; + // } + + // char[] result = new char[sb.Length]; + // sb.CopyTo(0, result, 0, sb.Length); + // Array.Reverse(result); + // return new string(result); + // } + + // public static BigInteger Parse(string input) => Parse(input, 10); + + // public static BigInteger Parse(string input, NumberStyles numberStyles) + // { + // if ((numberStyles & (NumberStyles.HexNumber | NumberStyles.AllowHexSpecifier)) != 0) + // return Parse(input, 16); + // return Parse(input, 10); + // } + + // public static BigInteger Parse(string input, int radix) + // { + // BigInteger v = 0; + // bool sign = false; + + // if (input[0] == '-') + // { + // sign = true; + // input = input.Substring(1); + // } + + // foreach (char d in input) + // { + // int n = d - '0'; + // if (n > 9) + // n = d - 55; + + // v *= radix; + // v += n; + // } + + // if (sign) + // v = v.Twos(); + + // return v; + // } + + + + // private BigInteger __op_add(BigInteger b) + // { + // int width = (bits.Length > b.bits.Length ? bits.Length : b.bits.Length) + 1; + // UInt32[] v = BigIntMath.extendSigned(bits, width); + // UInt32[] vb = BigIntMath.extendSigned(b.bits, width); + // return new BigInteger(BigIntMath.reduceSigned(BigIntMath.add(v,vb))); + // } + // private BigInteger __op_sub(BigInteger b) + // { + // int width = (bits.Length > b.bits.Length ? bits.Length : b.bits.Length) + 1; + // UInt32[] v = BigIntMath.extendSigned(bits, width); + // UInt32[] vb = BigIntMath.extendSigned(b.bits, width); + // return new BigInteger(BigIntMath.reduceSigned(BigIntMath.sub(v,vb))); + // } + + // private int __op_cmp(BigInteger b) + // { + // return BigIntMath.cmp(bits, b.bits); + // } + + // private BigInteger __op_div(BigInteger b) + // { + // UInt32[] result = BigIntMath.sdiv(bits, b.bits); + // return new BigInteger(result); + // } + + // private BigInteger __op_mod(BigInteger b) + // { + // UInt32[] result = BigIntMath.smod(bits, b.bits); + // return new BigInteger(result); + // } + + // private BigInteger __op_mul(BigInteger b) + // { + // UInt32[] value = BigIntMath.smul(bits, b.bits); + // return new BigInteger(value); + // } + + // private BigInteger __op_new(uint[] value) + // { + // return new BigInteger(value); + // } + + // private BigInteger __op_shl(int b) + // { + // UInt32[] value = BigIntMath.extendSigned(bits, bits.Length + ((b + 31) >> 5)); + // BigIntMath.shl(value,b); + // return new BigInteger(value); + // } + + // private BigInteger __op_shr(int b) + // { + // UInt32[] value = bits.Segment(0); + // BigIntMath.shr(value, b); + // return new BigInteger(value); + // } + + // public static implicit operator BigInteger(int i) + // { + // return new BigInteger(new UInt32[]{(UInt32)i}); + // } + + + + // public static BigInteger operator +(BigInteger a, BigInteger b) + // { + // return a.__op_add(b); + // } + // public static BigInteger operator -(BigInteger a, BigInteger b) + // { + // return a.__op_sub(b); + // } + // public static BigInteger operator *(BigInteger a, BigInteger b) + // { + // return a.__op_mul(b); + // } + + // public static BigInteger operator /(BigInteger a, BigInteger b) + // { + // return a.__op_div(b); + // } + // public static BigInteger operator %(BigInteger a, BigInteger b) + // { + // return a.__op_mod(b); + // } + + // public static bool operator <(BigInteger a, BigInteger b) + // { + // return a.__op_cmp(b) < 0; + // } + // public static bool operator >(BigInteger a, BigInteger b) + // { + // return a.__op_cmp(b) > 0; + // } + // public static bool operator ==(BigInteger a, BigInteger b) + // { + // if ((object)a == (object)b) + // { + // return true; + // } + // if (((object)a == null) || ((object)b == null)) + // { + // return false; + // } + // return a.__op_cmp(b) == 0; + // } + // public static bool operator !=(BigInteger a, BigInteger b) + // { + // return a.__op_cmp(b) != 0; + // } + + // public static BigInteger operator <<(BigInteger a, int b) + // { + // return a.__op_shl(b); + // } + // public static BigInteger operator >>(BigInteger a, int b) + // { + // return a.__op_shr(b); + // } + + // public override bool Equals(object obj) => (obj is BigInteger other) && (this == other); + // public override int GetHashCode() => ToByteArray().CreateHashCode(); + + + + + + + + /*** Native Implementations ***/ + + + + + + + // public BigInteger(UInt32[] value) + // { + // this.bits = value; + // } + + + + + // public BigInteger(byte[] ivalue) + // { + // UInt32[] v = new UInt32[(ivalue.Length + 3) >> 2]; + // ivalue = ivalue.Segment(0, v.Length << 2); + + // for (int n = 0; n < v.Length; n++) + // { + // v[n] = BitConverter.ToUInt32(ivalue, n << 2); + // } + // this.bits = BigIntMath.reduceSigned(v); + // } + // public BigInteger(BigInteger src) + // { + // this.bits = src.bits; + // } + + // public bool IsZero => BigIntMath.isZero(bits); + // public int Sign => BigIntMath.isZero(bits) ? 0 : BigIntMath.sign(bits) ? -1 : 1; + + // public int GetByteCount() => bits.Length * 4; + // public int GetBitLength() => BigIntMath.log2(bits); + + // public byte[] ToByteArray() => bits.GetBytes(); + + // public void TryWriteBytes(Span s,out int bytesWritten) + // { + // byte[] sb = ToByteArray(); + // for (bytesWritten = 0; bytesWritten < sb.Length; bytesWritten++) + // s[bytesWritten] = sb[bytesWritten]; + // } + + // public int Log2(){ + // return BigIntMath.log2(bits); + // } + + // public static BigInteger ModPow(BigInteger i,int n,BigInteger modulus) + // { + // BigInteger r = BigInteger.One; + // while (n-- > 0) + // { + // r *= i; + // r %= modulus; + // } + // return r; + // } + + // public BigInteger Pow(int n) + // { + // if (n == 0) + // { + // return One; + // } + // else if (n == 1) + // { + // return this; + // } + // else if (n > 1) + // { + // BigInteger result = this; + // n--; + // while ((n--) > 0) + // { + // result = (result * this); + // } + // return result; + // } + // throw new ArgumentException("Integer.Pow(n): not implemented for negative exponent"); + // } + + // public BigInteger Ones() + // { + // UInt32[] result = BigIntMath.ones(bits); + // return new BigInteger(result); + // } + + // public BigInteger Twos() + // { + // UInt32[] result = BigIntMath.twos(bits); + // return new BigInteger(result); + // } + + + // public static BigInteger fromHexString(string hex) => Parse(hex, 16); + + // public override string ToString() + // { + // return String.Format("[{0}: Sign: {2,5} / {1}]", this.GetType().Name, ToString(16), Sign ); + // } + + // public string ToString(string format) + // { + // if (format.Equals("X")) + // return ToString(16); + // return ToString(10); + // } + + // public string ToString(int radix) => ToString(radix, -1); + // public string ToString(int radix, int length) + // { + // if ((radix < 2) || (radix > 36)) + // throw new ArgumentOutOfRangeException(nameof(radix)); + + // uint[] v = bits.Segment(0); + // uint[] r = new uint[]{ (uint)radix }; + + // StringBuilder sb = new StringBuilder(); + + // while ((!BigIntMath.isZero(v)) && ((length-- )!=0)) + // { + // uint[] x = BigIntMath.sdivmod(ref v, r); + // if (v[0] < 10) + // sb.Append((char)('0' + v[0])); + // else + // sb.Append((char)(55 + v[0])); + // v = x; + // } + + // char[] result = new char[sb.Length]; + // sb.CopyTo(0, result, 0, sb.Length); + // Array.Reverse(result); + // return new string(result); + // } + + // public static BigInteger Parse(string input) => Parse(input, 10); + + // public static BigInteger Parse(string input, NumberStyles numberStyles) + // { + // if ((numberStyles & (NumberStyles.HexNumber | NumberStyles.AllowHexSpecifier)) != 0) + // return Parse(input, 16); + // return Parse(input, 10); + // } + + // public static BigInteger Parse(string input, int radix) + // { + // BigInteger v = 0; + // bool sign = false; + + // if (input[0] == '-') + // { + // sign = true; + // input = input.Substring(1); + // } + + // foreach (char d in input) + // { + // int n = d - '0'; + // if (n > 9) + // n = d - 55; + + // v *= radix; + // v += n; + // } + + // if (sign) + // v = v.Twos(); + + // return v; + // } + + + + // private BigInteger __op_add(BigInteger b) + // { + // int width = (bits.Length > b.bits.Length ? bits.Length : b.bits.Length) + 1; + // UInt32[] v = BigIntMath.extendSigned(bits, width); + // UInt32[] vb = BigIntMath.extendSigned(b.bits, width); + // return new BigInteger(BigIntMath.reduceSigned(BigIntMath.add(v,vb))); + // } + // private BigInteger __op_sub(BigInteger b) + // { + // int width = (bits.Length > b.bits.Length ? bits.Length : b.bits.Length) + 1; + // UInt32[] v = BigIntMath.extendSigned(bits, width); + // UInt32[] vb = BigIntMath.extendSigned(b.bits, width); + // return new BigInteger(BigIntMath.reduceSigned(BigIntMath.sub(v,vb))); + // } + + // private int __op_cmp(BigInteger b) + // { + // return BigIntMath.cmp(bits, b.bits); + // } + + // private BigInteger __op_div(BigInteger b) + // { + // UInt32[] result = BigIntMath.sdiv(bits, b.bits); + // return new BigInteger(result); + // } + + // private BigInteger __op_mod(BigInteger b) + // { + // UInt32[] result = BigIntMath.smod(bits, b.bits); + // return new BigInteger(result); + // } + + // private BigInteger __op_mul(BigInteger b) + // { + // UInt32[] value = BigIntMath.smul(bits, b.bits); + // return new BigInteger(value); + // } + + // private BigInteger __op_new(uint[] value) + // { + // return new BigInteger(value); + // } + + // private BigInteger __op_shl(int b) + // { + // UInt32[] value = BigIntMath.extendSigned(bits, bits.Length + ((b + 31) >> 5)); + // BigIntMath.shl(value,b); + // return new BigInteger(value); + // } + + // private BigInteger __op_shr(int b) + // { + // UInt32[] value = bits.Segment(0); + // BigIntMath.shr(value, b); + // return new BigInteger(value); + // } + + // public static implicit operator BigInteger(int i) + // { + // return new BigInteger(new UInt32[]{(UInt32)i}); + // } + + + + // public static BigInteger operator +(BigInteger a, BigInteger b) + // { + // return a.__op_add(b); + // } + // public static BigInteger operator -(BigInteger a, BigInteger b) + // { + // return a.__op_sub(b); + // } + // public static BigInteger operator *(BigInteger a, BigInteger b) + // { + // return a.__op_mul(b); + // } + + // public static BigInteger operator /(BigInteger a, BigInteger b) + // { + // return a.__op_div(b); + // } + // public static BigInteger operator %(BigInteger a, BigInteger b) + // { + // return a.__op_mod(b); + // } + + // public static bool operator <(BigInteger a, BigInteger b) + // { + // return a.__op_cmp(b) < 0; + // } + // public static bool operator >(BigInteger a, BigInteger b) + // { + // return a.__op_cmp(b) > 0; + // } + // public static bool operator ==(BigInteger a, BigInteger b) + // { + // if ((object)a == (object)b) + // { + // return true; + // } + // if (((object)a == null) || ((object)b == null)) + // { + // return false; + // } + // return a.__op_cmp(b) == 0; + // } + // public static bool operator !=(BigInteger a, BigInteger b) + // { + // return a.__op_cmp(b) != 0; + // } + + // public static BigInteger operator <<(BigInteger a, int b) + // { + // return a.__op_shl(b); + // } + // public static BigInteger operator >>(BigInteger a, int b) + // { + // return a.__op_shr(b); + // } + + // public override bool Equals(object obj) => (obj is BigInteger other) && (this == other); + // public override int GetHashCode() => ToByteArray().CreateHashCode(); + + + + + + + + /*** Native Implementations ***/ + [DllImport("libbigint")] + public static extern Int32 big_get_length(UInt32[] bits, Int32 length); + public static Int32 big_get_length(UInt32[] bits) => big_get_length(bits, bits.Length); + + [DllImport("libbigint")] + public static extern void big_add(UInt32[] op_a, Int32 length_a, UInt32[] op_b, Int32 length_b); + [DllImport("libbigint")] + public static extern void big_sub(UInt32[] op_a, Int32 length_a, UInt32[] op_b, Int32 length_b); + + [DllImport("libbigint")] + public static extern void big_twos(UInt32[] bits, Int32 length); + [DllImport("libbigint")] + public static extern void big_shl(UInt32[] bits, Int32 length, Int32 n); + [DllImport("libbigint")] + public static extern void big_shr(UInt32[] bits, Int32 length, Int32 n); + + + [DllImport("libbigint")] + public static extern Int32 big_cmp(UInt32[] op_a, Int32 length_a, UInt32[] op_b, Int32 length_b); + + + [DllImport("libbigint")] + public static extern void big_smul(UInt32[] op_a, Int32 length_a, UInt32[] op_b, Int32 length_b, UInt32[] result); + [DllImport("libbigint")] + public static extern void big_divmod(UInt32[] op_a, Int32 length_a, UInt32[] op_b, Int32 length_b); + + + private int max(int a,int b) => a > b ? a : b; + + } +} diff --git a/ln.biginteger/NumericsExtensions.cs b/ln.biginteger/NumericsExtensions.cs new file mode 100644 index 0000000..503db67 --- /dev/null +++ b/ln.biginteger/NumericsExtensions.cs @@ -0,0 +1,36 @@ +using System; +using System.Numerics; + +namespace BigInt +{ + public static class NumericsExtensions + { + public static System.Numerics.BigInteger Sqrt(this System.Numerics.BigInteger n) + { + if (n == 0) return 0; + if (n > 0) + { + int bitLength = Convert.ToInt32(Math.Ceiling(System.Numerics.BigInteger.Log(n, 2))); + System.Numerics.BigInteger root = System.Numerics.BigInteger.One << (bitLength / 2); + + while (!isSqrt(n, root)) + { + root += n / root; + root /= 2; + } + + return root; + } + + throw new ArithmeticException("NaN"); + } + + private static Boolean isSqrt(System.Numerics.BigInteger n, System.Numerics.BigInteger root) + { + System.Numerics.BigInteger lowerBound = root * root; + System.Numerics.BigInteger upperBound = (root + 1) * (root + 1); + + return (n >= lowerBound && n < upperBound); + } + } +} diff --git a/ln.biginteger/libbigint.so b/ln.biginteger/libbigint.so new file mode 100755 index 0000000000000000000000000000000000000000..84ceda2d5c4409301d3f9cc071c8a5de59c362e2 GIT binary patch literal 16400 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 b?dps)#F9J~d%ME+&9tziOxVQvpKt$vKl+?O literal 0 HcmV?d00001 diff --git a/ln.biginteger/ln.biginteger.csproj b/ln.biginteger/ln.biginteger.csproj new file mode 100644 index 0000000..108ceec --- /dev/null +++ b/ln.biginteger/ln.biginteger.csproj @@ -0,0 +1,13 @@ + + + + netcoreapp5.0 + + + + + PreserveNewest + + + +