Initial Commit

master
Harald Wolff 2017-10-17 21:49:51 +02:00
commit a54b28ed97
12 changed files with 1758 additions and 0 deletions

40
.gitignore vendored 100644
View File

@ -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

55
BigInt.csproj 100644
View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E745E261-9E3E-4401-B3BA-78B38753A82E}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>BigInt</RootNamespace>
<AssemblyName>BigInteger</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Numerics" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="BigIntegerWrapper.cs" />
<Compile Include="NumericsExtensions.cs" />
<Compile Include="UInteger.cs" />
<Compile Include="FixedWidthUBigInteger.cs" />
<Compile Include="IntField.cs" />
<Compile Include="BigUIntMath.cs" />
<Compile Include="UInt256.cs" />
<Compile Include="IUInteger.cs" />
<Compile Include="IntBase.cs" />
<Compile Include="Euclid.cs" />
<Compile Include="Integer.cs" />
<Compile Include="BigIntMath.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\sharp-extensions\sharp.extensions.csproj">
<Project>{97CA3CA9-98B3-4492-B072-D7A5995B68E9}</Project>
<Name>sharp.extensions</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

456
BigIntMath.cs 100644
View File

@ -0,0 +1,456 @@
using System;
using sharp.extensions;
namespace BigInt
{
public static class BigIntMath
{
/* Public Interface */
public static bool sign(UInt32[] value){
return (value[value.Length - 1] & (1 << 31)) != 0;
}
public static int log2(UInt32[] value)
{
switch (sign(value)){
case false:
for (int n = value.Length << 5; n > 0; n--)
{
if ((value[(n - 1) >> 5] & (1 << ((n - 1) & 0x1F))) != 0)
{
return n - 1;
}
}
return 0;
case true:
for (int n = (value.Length << 5)-1; n > 0; n--)
{
if ((value[(n - 1) >> 5] & (1 << ((n - 1) & 0x1F))) == 0)
{
return 1 - n;
}
}
return 0;
}
return 0;
}
public static bool isZero(UInt32[] value){
foreach (UInt32 v in value){
if (v != 0){
return false;
}
}
return true;
}
public static UInt32[] ones(UInt32[] value){
UInt32[] result = value.Segment(0);
for (int n = 0; n < result.Length;n++){
result[n] ^= 0xffffffff;
}
return result;
}
public static UInt32[] twos(UInt32[] value){
UInt32[] result = ones(value);
UInt32[] one = new UInt32[]{1};
result = add(result, one);
return result;
}
/**
* Extend signed integer to higher width
**/
public static UInt32[] extendSigned(UInt32[] value,int width){
UInt32[] result = value.Segment(0).Extend(width);
if (sign(value))
{
for (int n = value.Length; n < width; n++)
{
result[n] = 0xFFFFFFFF;
}
}
return result;
}
public static void extendEqualSigned(ref UInt32[] a, ref UInt32[] b){
int width = a.Length > b.Length ? a.Length : b.Length;
a = extendSigned(a, width);
b = extendSigned(b, width);
}
public static UInt32[] signedFromUnsigned(UInt32[] value){
int lg2 = log2(value);
int vlen = value.Length;
if (lg2 < 0){
lg2 = 34 - lg2;
if ((lg2 % 32)==0){
vlen++;
}
}
return value.Extend(vlen);
}
/**
* Reduce signed integer to smallest width, needed to represent its value
**/
public static UInt32[] reduceSigned(UInt32[] value){
int lg2 = log2(value);
if (lg2 < 0){
lg2 = 0 - lg2;
}
lg2 >>= 5;
lg2++;
if (value.Length != lg2){
return value.Segment(0, lg2);
}
return value;
}
/**
* Reduce unsigned integer to smallest width, needed to represent its value
**/
public static UInt32[] reduceUnsigned(UInt32[] value)
{
int lg2 = log2(value);
if (lg2 < 0){
lg2 = value.Length;
} else {
lg2 >>= 5;
lg2++;
}
if (lg2 < 1)
{
lg2 = 1;
}
if (value.Length != lg2)
{
return value.Segment(0, lg2);
}
return value;
}
public static UInt32[] add(UInt32[] a, UInt32[] b)
{
UInt32 c = 0;
a = a.Segment(0);
extendEqualSigned(ref a, ref b);
for (int n = 0; n < a.Length; n++)
{
a[n] = add(a[n], b[n], ref c);
}
return a;
}
public static UInt32[] sub(UInt32[] a, UInt32[] b)
{
UInt32 c = 0;
a = a.Segment(0);
extendEqualSigned(ref a, ref b);
for (int n = 0; n < a.Length; n++)
{
a[n] = sub(a[n], b[n], ref c);
}
return a;
}
public static UInt32[] umul(UInt32[] a, UInt32[] b)
{
UInt32[] result = new UInt32[a.Length + b.Length];
for (int l1 = 0; l1 < a.Length; l1++)
{
for (int l2 = 0; l2 < (b.Length); l2++)
{
int target = l1 + l2;
UInt64 ui64 = ((UInt64)a[l1] * b[l2]);
for (int ct = target; (ct < result.Length) && (ui64 != 0); ct++){
ui64 += result[ct];
result[ct] = (UInt32)ui64;
ui64 >>= 32;
}
}
}
return result;
}
public static UInt32[] smul(UInt32[] a, UInt32[] b)
{
a = extendSigned(a, a.Length << 1);
b = extendSigned(b, b.Length << 1);
UInt32[] result = new UInt32[(a.Length + b.Length)>>1];
for (int l1 = 0; l1 < a.Length; l1++)
{
for (int l2 = 0; l2 < (b.Length); l2++)
{
int target = l1 + l2;
UInt64 ui64 = ((UInt64)a[l1] * b[l2]);
for (int ct = target; (ct < result.Length) && (ui64 != 0); ct++)
{
ui64 += result[ct];
result[ct] = (UInt32)ui64;
ui64 >>= 32;
}
}
}
return result;
}
/**
* @brief Calulate a / b. (unsigned values)
* @returns Result of division.
**/
public static UInt32[] udiv(UInt32[] a,UInt32[] b){
return udivmod(ref a, b);
}
public static UInt32[] umod(UInt32[] a,UInt32[] b){
UInt32[] m = a.Segment(0);
udivmod(ref m,b);
return m;
}
public static UInt32[] udivmod(ref UInt32[] _a, UInt32[] b)
{
UInt32[] a = _a;
if (cmp(a, b) < 0)
{
return new UInt32[a.Length];
}
UInt32[] result = new UInt32[a.Length];
UInt32[] d = b.Segment(0).Extend(a.Length);
int lg2a, lg2b, shift;
lg2a = log2(a);
lg2b = log2(d);
shift = lg2a - lg2b;
if (shift > 0)
{
shl(d, shift);
}
for (int n = 0; n <= (shift); n++)
{
shl(result, 1);
if (cmp(d, a) <= 0)
{
result[0] |= 1;
a = sub(a, d);
}
shr(d, 1);
}
_a = a;
return result;
}
/**
* @brief Calulate a / b. (unsigned values)
* @returns Result of division. a[] will contain reminder.
**/
public static UInt32[] sdiv(UInt32[] a, UInt32[] b)
{
return sdivmod(ref a, b);
}
public static UInt32[] smod(UInt32[] a, UInt32[] b)
{
UInt32[] m = a.Segment(0);
sdivmod(ref m, b);
return m;
}
/**
* sdivmod ( a , b )
*
* Calculate Quotient and Reminder of a / b using signed integer arithmetics
* returns quotient
* leaves reminder in <param name="a">
*
**/
public static UInt32[] sdivmod(ref UInt32[] a, UInt32[] b)
{
bool sgna, sgnb;
sgna = sign(a);
sgnb = sign(b);
Console.WriteLine("sdivmod(): a = {0}",a.getBytes().Reverse().toHexString());
Console.WriteLine("sdivmod(): b = {0}",b.getBytes().Reverse().toHexString());
if (sgna){
a = twos(a);
}
if (sgnb){
b = twos(b);
}
UInt32[] result = udivmod(ref a, b);
if (sgna != sgnb){
result = twos(result);
}
if (sgna){
a = twos(a);
}
Console.WriteLine("sdivmod(): result = {0}",result.getBytes().Reverse().toHexString());
Console.WriteLine("sdivmod(): reminder = {0}",a.getBytes().Reverse().toHexString());
return result;
}
/**
* @brief Logical Shift Left
**/
public static void shl(UInt32[] a, int n)
{
if (n > 0)
{
int step = n >> 5;
n &= 0x1F;
for (int i = a.Length; i > 0; i--)
{
int b1 = i - 1 - step;
int b2 = b1 - 1;
if (b1 >= 0){
a[i - 1] = (a[b1] << n);
if ((n != 0)&&(b2 >= 0))
{
a[i - 1] |= ((a[b2] >> (32 - n)));
}
} else {
a[i - 1] = 0;
}
}
}
}
/**
* @brief Logical Shift Right
**/
public static void shr(UInt32[] a, int n)
{
if (n > 0)
{
bool s = sign(a);
int step = n >> 5;
n &= 0x1F;
for (int i = 0; i < a.Length; i++)
{
int b1 = i + step;
int b2 = b1 + 1;
if (b1 < a.Length)
{
a[i] = (a[b1] >> n);
if ((b2 == a.Length) && (s)){
a[i] |= ((0xffffffff << (32 - n)));
} else if ((n != 0) && (b2 < a.Length))
{
a[i] |= ((a[b2] << (32 - n)));
}
} else {
a[i] = s ? 0xFFFFFFFF : 0;
}
}
}
}
/**
* @brief Compare
* @returns Negative Value if a<b, Positive Value if a>b,0 if equal
**/
public static int cmp(UInt32[] a, UInt32[] b)
{
a = a.Segment(0);
b = b.Segment(0);
extendEqualSigned(ref a, ref b);
UInt32[] result = sub(a, b);
if (isZero(result))
{
return 0;
}
else if (sign(result))
{
return -1;
}
else
{
return 1;
}
}
/* Helper Functions */
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);
}
}
}

View File

@ -0,0 +1,297 @@
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;
}
}
}
*/

233
BigUIntMath.cs 100644
View File

@ -0,0 +1,233 @@
using System;
using sharp.extensions;
namespace BigInt
{
public static class BigUIntMath
{
/* Public Interface */
public static void add(UInt32[] a, UInt32[] b)
{
UInt32 c = 0;
for (int n = 0; n < a.Length; n++)
{
a[n] = add(a[n], (n < b.Length) ? b[n] : 0, ref c);
}
}
public static void sub(UInt32[] a, UInt32[] b)
{
UInt32 c = 0;
for (int n = 0; n < a.Length; n++)
{
a[n] = sub(a[n], (n < b.Length) ? b[n] : 0, ref c);
}
}
public static UInt32[] mul(UInt32[] a, UInt32[] b)
{
UInt32[] result = new UInt32[a.Length + b.Length];
for (int l1 = 0; l1 < a.Length; l1++)
{
for (int l2 = 0; l2 < (b.Length); l2++)
{
int target = l1 + l2;
UInt64 ui64 = ((UInt64)a[l1] * b[l2]);
for (int ct = target; (ct < result.Length) && (ui64 != 0); ct++){
ui64 += result[ct];
result[ct] = (UInt32)ui64;
ui64 >>= 32;
}
}
}
return result;
}
/**
* @brief Calulate a / b.
* @returns Result of division. a[] will contain reminder.
**/
public static UInt32[] div(UInt32[] a, UInt32[] b)
{
if (cmp(a, b) < 0)
{
return new UInt32[a.Length];
}
UInt32[] result = new UInt32[a.Length];
UInt32[] d = b.Segment(0).Extend(a.Length);
int lg2a, lg2b, shift;
lg2a = log2(a);
lg2b = log2(d);
shift = lg2a - lg2b;
if (shift > 0)
{
shl(d, shift);
}
for (int n = 0; n <= (shift); n++)
{
shl(result, 1);
if (cmp(d, a) <= 0)
{
result[0] |= 1;
sub(a, d);
}
shr(d, 1);
}
return result;
}
public static int log2(UInt32[] a)
{
for (int n = a.Length << 5; n > 0; n--)
{
if ((a[(n - 1) >> 5] & (1 << ((n - 1) & 0x1F))) != 0)
{
return n - 1;
}
}
return 0;
}
/**
* @brief Logical Shift Left
**/
public static void shl(UInt32[] a, int n)
{
if (n > 0)
{
int step = n >> 5;
n &= 0x1F;
for (int i = a.Length; i > 0; i--)
{
int b1 = i - 1 - step;
int b2 = b1 - 1;
if (b1 >= 0){
a[i - 1] = (a[b1] << n);
if ((n != 0)&&(b2 >= 0))
{
a[i - 1] |= ((a[b2] >> (32 - n)));
}
} else {
a[i - 1] = 0;
}
}
}
}
/**
* @brief Logical Shift Right
**/
public static void shr(UInt32[] a, int n)
{
if (n > 0)
{
int step = n >> 5;
n &= 0x1F;
for (int i = 0; i < a.Length; i++)
{
int b1 = i + step;
int b2 = b1 + 1;
if (b1 < a.Length)
{
a[i] = (a[b1] >> n);
if ((n != 0) && (b2 < a.Length))
{
a[i] |= ((a[b2] << (32 - n)));
}
}
else
{
a[i] = 0;
}
}
}
}
/**
* @brief Compare
* @returns Negative Value if a<b, Positive Value if a>b,0 if equal
**/
public static int cmp(UInt32[] a, UInt32[] b)
{
int start = a.Length > b.Length ? a.Length : b.Length;
for (int n = start; n > 0; n--)
{
Int64 diff = (n <= a.Length ? (Int64)a[n - 1] : 0) - (n <= b.Length ? (Int64)b[n - 1] : 0);
if (diff != 0)
{
return (diff < 0) ? -1 : 1;
}
}
return 0;
}
/* Helper Functions */
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);
}
}
}

72
Euclid.cs 100644
View File

@ -0,0 +1,72 @@
using System;
using sharp.extensions;
namespace BigInt
{
public static class Euclid
{
public static Tripple<Integer> extended(Integer a, Integer b)
{
if (b.isZero()){
if (a != Integer.ONE){
throw new ArgumentException("Euclid found GCD>1!");
}
return new Tripple<Integer>(a, Integer.ONE, Integer.ZERO);
}
Tripple<Integer> r = extended(b, a % b);
return new Tripple<Integer>(r.X,r.Z,r.Y - ((a / b) * r.Z) );
}
/**
* Implementation of inverse() like found at
* https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm (14 Oct 2017)
**/
public static Integer inverse(Integer a,Integer m){
Integer one, zero;
rt act, next, future;
one = Integer.ONE;
zero = Integer.ZERO;
act = new rt(m, zero);
next = new rt(a, one);
while (!next.r.isZero())
{
Integer q = act.r / next.r;
future = new rt(
act.r - (q * next.r),
act.t - (q * next.t)
);
Console.WriteLine("EUCLID: q = {0}",q);
Console.WriteLine("EUCLID: act: r = {0} / t = {1}",act.r,act.t);
Console.WriteLine("EUCLID: next: r = {0} / t = {1}",next.r,next.t);
Console.WriteLine("EUCLID: future: r = {0} / t = {1}",future.r,future.t);
act = next;
next = future;
}
if (act.r > one){
return null;
}
if (act.t < 0){
act.t += m;
}
return act.t;
}
private struct rt {
public Integer r, t;
public rt(Integer r,Integer t){
this.r = r;
this.t = t;
}
}
}
}

51
IntBase.cs 100644
View File

@ -0,0 +1,51 @@
using System;
using System.CodeDom;
using System.Dynamic;
using sharp.extensions;
namespace BigInt
{
public abstract class IntBase
{
protected UInt32[] rawValue;
public UInt32[] RawValue
{
get { return this.rawValue; }
protected set
{
this.rawValue = value;
}
}
public byte[] getBytes()
{
byte[] b = new byte[this.RawValue.Length << 2];
for (int n = 0; n < this.RawValue.Length; n++)
{
b.Insert(this.RawValue[n].GetBytes(), n << 2);
}
return b;
}
public bool this[int bit]
{
get { return ((this.RawValue[bit >> 5] & (1 << (bit & 0x1F))) != 0); }
}
public bool isZero(){
return BigIntMath.isZero(rawValue);
}
public string toHexString()
{
return getBytes().Reverse().toHexString();
}
public override string ToString()
{
return String.Format("[{0}: {1}]",this.GetType().Name,toHexString());
}
}
}

30
IntField.cs 100644
View File

@ -0,0 +1,30 @@
using System;
using System.Linq.Expressions;
namespace BigInt
{
public class IntField
{
public static IntField Default { get; set; } = null; // new IntField(UBigInteger.ZERO.Resize(256) - 1);
public UInteger FieldModulo { get; private set; }
public int FieldWidth { get; private set; }
public IntField(UInteger p,int width){
this.FieldWidth = width;
this.FieldModulo = p;
}
public IntField(UInteger p){
this.FieldModulo = p;
this.FieldWidth = p.RawValue.Length << 5;
}
public UInteger Fit(UInteger value){
return value % FieldModulo;
}
public override string ToString(){
return String.Format("[IntField p={0}]",this.FieldModulo);
}
}
}

226
Integer.cs 100644
View File

@ -0,0 +1,226 @@
using System;
using sharp.extensions;
namespace BigInt
{
public class Integer: IntBase
{
public static readonly Integer ZERO = new Integer();
public static readonly Integer ONE = new Integer(new UInt32[] { 1 });
public Integer()
{
this.RawValue = new UInt32[1];
}
public Integer(UInt32[] value)
{
this.RawValue = BigIntMath.reduceSigned(value);
}
public Integer(byte[] ivalue)
{
UInt32[] v = new UInt32[(ivalue.Length + 3) >> 2];
ivalue = ivalue.Extend(v.Length << 2);
for (int n = 0; n < v.Length; n++)
{
v[n] = BitConverter.ToUInt32(ivalue, n << 2);
}
this.RawValue = BigIntMath.reduceSigned(v);
}
public Integer(UInt32[] value, IntField field)
{
this.RawValue = BigIntMath.reduceSigned(value);
}
public Integer(Integer src)
{
this.RawValue = src.RawValue;
}
public bool Sign(){
return BigIntMath.sign(rawValue);
}
public int Log2(){
return BigIntMath.log2(rawValue);
}
public Integer Pow(int n)
{
if (n == 0)
{
return ONE;
}
else if (n == 1)
{
return this;
}
else if (n > 1)
{
Integer result = this;
n--;
while ((n--) > 0)
{
result = (result * this);
}
return result;
}
throw new ArgumentException("Integer.Pow(n): not implemented for negative exponent");
}
public Integer Ones()
{
UInt32[] result = BigIntMath.ones(rawValue);
return new Integer(result);
}
public Integer Twos()
{
UInt32[] result = BigIntMath.twos(rawValue);
return new Integer(result);
}
public static Integer fromHexString(string hex)
{
return new Integer(HexString.toBytes(hex).Reverse());
}
public override string ToString()
{
return String.Format("[{0}: Sign: {2,5} / {1}]", this.GetType().Name, toHexString(), Sign() );
}
private Integer __op_add(Integer b)
{
int width = (rawValue.Length > b.RawValue.Length ? rawValue.Length : b.RawValue.Length) + 1;
UInt32[] v = BigIntMath.extendSigned(rawValue, width);
UInt32[] vb = BigIntMath.extendSigned(b.RawValue, width);
return new Integer(BigIntMath.reduceSigned(BigIntMath.add(v,vb)));
}
private Integer __op_sub(Integer b)
{
int width = (rawValue.Length > b.RawValue.Length ? rawValue.Length : b.RawValue.Length) + 1;
UInt32[] v = BigIntMath.extendSigned(rawValue, width);
UInt32[] vb = BigIntMath.extendSigned(b.RawValue, width);
return new Integer(BigIntMath.reduceSigned(BigIntMath.sub(v,vb)));
}
private int __op_cmp(Integer b)
{
return BigIntMath.cmp(rawValue, b.RawValue);
}
private Integer __op_div(Integer b)
{
UInt32[] result = BigIntMath.sdiv(rawValue, b.RawValue);
return new Integer(result);
}
private Integer __op_mod(Integer b)
{
return null;
}
private Integer __op_mul(Integer b)
{
UInt32[] value = BigIntMath.smul(rawValue, b.RawValue);
return new Integer(value);
}
private Integer __op_new(uint[] value)
{
return new Integer(value);
}
private Integer __op_shl(int b)
{
UInt32[] value = BigIntMath.extendSigned(rawValue, RawValue.Length + ((b + 31) >> 5));
BigIntMath.shl(value,b);
return new Integer(value);
}
private Integer __op_shr(int b)
{
UInt32[] value = rawValue.Segment(0);
BigIntMath.shr(value, b);
return new Integer(value);
}
public static implicit operator Integer(UInteger ui)
{
return new Integer( BigIntMath.signedFromUnsigned( ui.RawValue ));
}
public static implicit operator Integer(int i)
{
return new Integer(new UInt32[]{(UInt32)i});
}
public static Integer operator +(Integer a, Integer b)
{
return a.__op_add(b);
}
public static Integer operator -(Integer a, Integer b)
{
return a.__op_sub(b);
}
public static Integer operator *(Integer a, Integer b)
{
return a.__op_mul(b);
}
public static Integer operator *(Integer a, UInt32 b)
{
Integer bb = new Integer(new UInt32[] { b });
return a.__op_mul(bb);
}
public static Integer operator /(Integer a, Integer b)
{
return a.__op_div(b);
}
public static Integer operator %(Integer a, Integer b)
{
return a.__op_mod(b);
}
public static bool operator <(Integer a, Integer b)
{
return a.__op_cmp(b) < 0;
}
public static bool operator >(Integer a, Integer b)
{
return a.__op_cmp(b) > 0;
}
public static bool operator ==(Integer a, Integer 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 !=(Integer a, Integer b)
{
return a.__op_cmp(b) != 0;
}
public static Integer operator <<(Integer a, int b)
{
return a.__op_shl(b);
}
public static Integer operator >>(Integer a, int b)
{
return a.__op_shr(b);
}
}
}

View File

@ -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);
}
}
}

View File

@ -0,0 +1,26 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("BigInteger")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

236
UInteger.cs 100644
View File

@ -0,0 +1,236 @@
using System;
using sharp.extensions;
using System.Text;
using System.CodeDom;
namespace BigInt
{
public class UInteger: IntBase
{
public static readonly UInteger ZERO = new UInteger();
public static readonly UInteger ONE = new UInteger(new UInt32[] { 1 });
public UInteger()
{
this.RawValue = new UInt32[1];
}
public UInteger(UInt32[] value)
{
this.RawValue = BigIntMath.reduceUnsigned(value);
}
public UInteger(byte[] ivalue)
{
UInt32[] v = new UInt32[(ivalue.Length + 3) >> 2];
ivalue = ivalue.Extend(v.Length << 2);
for (int n = 0; n < v.Length; n++)
{
v[n] = BitConverter.ToUInt32(ivalue, n << 2);
}
this.RawValue = BigIntMath.reduceUnsigned(v);
}
public UInteger(UInt32[] value, IntField field)
{
this.RawValue = BigIntMath.reduceUnsigned(value);
}
public UInteger(UInteger src)
{
this.RawValue = src.RawValue;
}
public int Log2()
{
int lg2 = BigIntMath.log2(rawValue);
return lg2 < 0 ? rawValue.Length << 32 : lg2;
}
public UInteger Pow(int n)
{
if (n == 0)
{
return ONE;
}
else if (n == 1)
{
return this;
}
else if (n > 1)
{
UInteger result = this;
n--;
while ((n--) > 0)
{
result = (result * this);
}
return result;
}
throw new ArgumentException("Integer.Pow(n): not implemented for negative exponent");
}
public UInteger Ones()
{
UInt32[] result = BigIntMath.ones(rawValue);
return new UInteger(result);
}
public UInteger Twos()
{
UInt32[] result = BigIntMath.twos(rawValue);
return new UInteger(result);
}
public static UInteger fromHexString(string hex)
{
return new UInteger(HexString.toBytes(hex).Reverse());
}
private UInteger __op_new(uint[] value)
{
return new UInteger(value);
}
private UInteger __op_add(UInteger b)
{
UInt32[] result = RawValue.Segment(0).Extend(b.RawValue.Length);
BigUIntMath.add(result,b.RawValue);
return new UInteger(result);
}
private UInteger __op_sub(UInteger b)
{
UInt32[] result = RawValue.Segment(0).Extend(b.RawValue.Length);
BigUIntMath.sub(result,b.RawValue);
return new UInteger(result);
}
private UInteger __op_mul(UInteger b)
{
return new UInteger(BigUIntMath.mul(this.RawValue,b.RawValue));
}
private UInteger __op_div(UInteger b)
{
return new UInteger(BigUIntMath.div(this.RawValue.Segment(0), b.RawValue));
}
private UInteger __op_mod(UInteger b)
{
UInt32[] result = RawValue.Segment(0);
BigUIntMath.div(result,b.RawValue);
return new UInteger(result);
}
private UInteger __op_shl(int b)
{
UInt32[] v = this.RawValue.Segment(0);
v = v.Extend(v.Length + ((b + 31) >> 5));
BigUIntMath.shl(v, b);
UInteger r = new UInteger(v);
return r;
}
private UInteger __op_shr(int b)
{
UInteger result = new UInteger(this);
BigUIntMath.shr(result.RawValue,b);
return result;
}
private int __op_cmp(UInteger b)
{
return BigUIntMath.cmp(this.RawValue,b.RawValue);
}
public static implicit operator UInteger(int n)
{
return new UInteger(new UInt32[] { (UInt32)n });
}
public static implicit operator UInteger(uint n)
{
return new UInteger(new UInt32[] { n });
}
public static implicit operator UInteger(UInt64 n)
{
return new UInteger(new UInt32[] { (UInt32)n, (UInt32)(n >> 32) });
}
public static implicit operator UInteger(Integer ui)
{
return new UInteger(ui.RawValue);
}
public static UInteger operator +(UInteger a, UInteger b)
{
return a.__op_add(b);
}
public static UInteger operator -(UInteger a, UInteger b)
{
return a.__op_sub(b);
}
public static UInteger operator *(UInteger a, UInteger b)
{
return a.__op_mul(b);
}
public static UInteger operator *(UInteger a, UInt32 b)
{
UInteger bb = a.__op_new(new UInt32[] { b });
return a.__op_mul(bb);
}
public static UInteger operator /(UInteger a, UInteger b)
{
return a.__op_div(b);
}
public static UInteger operator %(UInteger a, UInteger b)
{
return a.__op_mod(b);
}
public static bool operator <(UInteger a, UInteger b)
{
return a.__op_cmp(b) < 0;
}
public static bool operator >(UInteger a, UInteger b)
{
return a.__op_cmp(b) > 0;
}
public static bool operator ==(UInteger a, UInteger 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 !=(UInteger a, UInteger b)
{
return a.__op_cmp(b) != 0;
}
public static UInteger operator <<(UInteger a, int b)
{
return a.__op_shl(b);
}
public static UInteger operator >>(UInteger a, int b)
{
return a.__op_shr(b);
}
public override bool Equals(object obj)
{
if (typeof(IntBase).IsInstanceOfType(obj)){
IntBase ib = (IntBase)obj;
return BigIntMath.cmp(rawValue, ib.RawValue) == 0;
}
return false;
}
}
}