init commit
This commit is contained in:
@@ -0,0 +1,417 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Math.Raw;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Math.EC;
|
||||
|
||||
public class FpFieldElement : AbstractFpFieldElement
|
||||
{
|
||||
private readonly BigInteger q;
|
||||
|
||||
private readonly BigInteger r;
|
||||
|
||||
private readonly BigInteger x;
|
||||
|
||||
public override string FieldName => "Fp";
|
||||
|
||||
public override int FieldSize => q.BitLength;
|
||||
|
||||
public BigInteger Q => q;
|
||||
|
||||
internal static BigInteger CalculateResidue(BigInteger p)
|
||||
{
|
||||
int bitLength = p.BitLength;
|
||||
if (bitLength >= 96)
|
||||
{
|
||||
BigInteger bigInteger = p.ShiftRight(bitLength - 64);
|
||||
if (bigInteger.LongValue == -1)
|
||||
{
|
||||
return BigInteger.One.ShiftLeft(bitLength).Subtract(p);
|
||||
}
|
||||
if ((bitLength & 7) == 0)
|
||||
{
|
||||
return BigInteger.One.ShiftLeft(bitLength << 1).Divide(p).Negate();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
[Obsolete("Use ECCurve.FromBigInteger to construct field elements")]
|
||||
public FpFieldElement(BigInteger q, BigInteger x)
|
||||
: this(q, CalculateResidue(q), x)
|
||||
{
|
||||
}
|
||||
|
||||
internal FpFieldElement(BigInteger q, BigInteger r, BigInteger x)
|
||||
{
|
||||
if (x == null || x.SignValue < 0 || x.CompareTo(q) >= 0)
|
||||
{
|
||||
throw new ArgumentException("value invalid in Fp field element", "x");
|
||||
}
|
||||
this.q = q;
|
||||
this.r = r;
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public override BigInteger ToBigInteger()
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
public override ECFieldElement Add(ECFieldElement b)
|
||||
{
|
||||
return new FpFieldElement(q, r, ModAdd(x, b.ToBigInteger()));
|
||||
}
|
||||
|
||||
public override ECFieldElement AddOne()
|
||||
{
|
||||
BigInteger bigInteger = x.Add(BigInteger.One);
|
||||
if (bigInteger.CompareTo(q) == 0)
|
||||
{
|
||||
bigInteger = BigInteger.Zero;
|
||||
}
|
||||
return new FpFieldElement(q, r, bigInteger);
|
||||
}
|
||||
|
||||
public override ECFieldElement Subtract(ECFieldElement b)
|
||||
{
|
||||
return new FpFieldElement(q, r, ModSubtract(x, b.ToBigInteger()));
|
||||
}
|
||||
|
||||
public override ECFieldElement Multiply(ECFieldElement b)
|
||||
{
|
||||
return new FpFieldElement(q, r, ModMult(x, b.ToBigInteger()));
|
||||
}
|
||||
|
||||
public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
BigInteger bigInteger = this.x;
|
||||
BigInteger val = b.ToBigInteger();
|
||||
BigInteger bigInteger2 = x.ToBigInteger();
|
||||
BigInteger val2 = y.ToBigInteger();
|
||||
BigInteger bigInteger3 = bigInteger.Multiply(val);
|
||||
BigInteger n = bigInteger2.Multiply(val2);
|
||||
return new FpFieldElement(q, r, ModReduce(bigInteger3.Subtract(n)));
|
||||
}
|
||||
|
||||
public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
BigInteger bigInteger = this.x;
|
||||
BigInteger val = b.ToBigInteger();
|
||||
BigInteger bigInteger2 = x.ToBigInteger();
|
||||
BigInteger val2 = y.ToBigInteger();
|
||||
BigInteger bigInteger3 = bigInteger.Multiply(val);
|
||||
BigInteger value = bigInteger2.Multiply(val2);
|
||||
BigInteger bigInteger4 = bigInteger3.Add(value);
|
||||
if (r != null && r.SignValue < 0 && bigInteger4.BitLength > q.BitLength << 1)
|
||||
{
|
||||
bigInteger4 = bigInteger4.Subtract(q.ShiftLeft(q.BitLength));
|
||||
}
|
||||
return new FpFieldElement(q, r, ModReduce(bigInteger4));
|
||||
}
|
||||
|
||||
public override ECFieldElement Divide(ECFieldElement b)
|
||||
{
|
||||
return new FpFieldElement(q, r, ModMult(x, ModInverse(b.ToBigInteger())));
|
||||
}
|
||||
|
||||
public override ECFieldElement Negate()
|
||||
{
|
||||
if (x.SignValue != 0)
|
||||
{
|
||||
return new FpFieldElement(q, r, q.Subtract(x));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public override ECFieldElement Square()
|
||||
{
|
||||
return new FpFieldElement(q, r, ModMult(x, x));
|
||||
}
|
||||
|
||||
public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
BigInteger bigInteger = this.x;
|
||||
BigInteger bigInteger2 = x.ToBigInteger();
|
||||
BigInteger val = y.ToBigInteger();
|
||||
BigInteger bigInteger3 = bigInteger.Multiply(bigInteger);
|
||||
BigInteger n = bigInteger2.Multiply(val);
|
||||
return new FpFieldElement(q, r, ModReduce(bigInteger3.Subtract(n)));
|
||||
}
|
||||
|
||||
public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
|
||||
{
|
||||
BigInteger bigInteger = this.x;
|
||||
BigInteger bigInteger2 = x.ToBigInteger();
|
||||
BigInteger val = y.ToBigInteger();
|
||||
BigInteger bigInteger3 = bigInteger.Multiply(bigInteger);
|
||||
BigInteger value = bigInteger2.Multiply(val);
|
||||
BigInteger bigInteger4 = bigInteger3.Add(value);
|
||||
if (r != null && r.SignValue < 0 && bigInteger4.BitLength > q.BitLength << 1)
|
||||
{
|
||||
bigInteger4 = bigInteger4.Subtract(q.ShiftLeft(q.BitLength));
|
||||
}
|
||||
return new FpFieldElement(q, r, ModReduce(bigInteger4));
|
||||
}
|
||||
|
||||
public override ECFieldElement Invert()
|
||||
{
|
||||
return new FpFieldElement(q, r, ModInverse(x));
|
||||
}
|
||||
|
||||
public override ECFieldElement Sqrt()
|
||||
{
|
||||
if (IsZero || IsOne)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
if (!q.TestBit(0))
|
||||
{
|
||||
throw Platform.CreateNotImplementedException("even value of q");
|
||||
}
|
||||
if (q.TestBit(1))
|
||||
{
|
||||
BigInteger e = q.ShiftRight(2).Add(BigInteger.One);
|
||||
return CheckSqrt(new FpFieldElement(q, r, this.x.ModPow(e, q)));
|
||||
}
|
||||
if (q.TestBit(2))
|
||||
{
|
||||
BigInteger bigInteger = this.x.ModPow(q.ShiftRight(3), q);
|
||||
BigInteger x = ModMult(bigInteger, this.x);
|
||||
BigInteger bigInteger2 = ModMult(x, bigInteger);
|
||||
if (bigInteger2.Equals(BigInteger.One))
|
||||
{
|
||||
return CheckSqrt(new FpFieldElement(q, r, x));
|
||||
}
|
||||
BigInteger x2 = BigInteger.Two.ModPow(q.ShiftRight(2), q);
|
||||
BigInteger bigInteger3 = ModMult(x, x2);
|
||||
return CheckSqrt(new FpFieldElement(q, r, bigInteger3));
|
||||
}
|
||||
BigInteger bigInteger4 = q.ShiftRight(1);
|
||||
if (!this.x.ModPow(bigInteger4, q).Equals(BigInteger.One))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
BigInteger bigInteger5 = this.x;
|
||||
BigInteger bigInteger6 = ModDouble(ModDouble(bigInteger5));
|
||||
BigInteger k = bigInteger4.Add(BigInteger.One);
|
||||
BigInteger obj = q.Subtract(BigInteger.One);
|
||||
while (true)
|
||||
{
|
||||
BigInteger bigInteger7 = BigInteger.Arbitrary(q.BitLength);
|
||||
if (bigInteger7.CompareTo(q) < 0 && ModReduce(bigInteger7.Multiply(bigInteger7).Subtract(bigInteger6)).ModPow(bigInteger4, q).Equals(obj))
|
||||
{
|
||||
BigInteger[] array = LucasSequence(bigInteger7, bigInteger5, k);
|
||||
BigInteger bigInteger8 = array[0];
|
||||
BigInteger bigInteger9 = array[1];
|
||||
if (ModMult(bigInteger9, bigInteger9).Equals(bigInteger6))
|
||||
{
|
||||
return new FpFieldElement(q, r, ModHalfAbs(bigInteger9));
|
||||
}
|
||||
if (!bigInteger8.Equals(BigInteger.One) && !bigInteger8.Equals(obj))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ECFieldElement CheckSqrt(ECFieldElement z)
|
||||
{
|
||||
if (!z.Square().Equals(this))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
private BigInteger[] LucasSequence(BigInteger P, BigInteger Q, BigInteger k)
|
||||
{
|
||||
int bitLength = k.BitLength;
|
||||
int lowestSetBit = k.GetLowestSetBit();
|
||||
BigInteger bigInteger = BigInteger.One;
|
||||
BigInteger bigInteger2 = BigInteger.Two;
|
||||
BigInteger bigInteger3 = P;
|
||||
BigInteger bigInteger4 = BigInteger.One;
|
||||
BigInteger bigInteger5 = BigInteger.One;
|
||||
for (int num = bitLength - 1; num >= lowestSetBit + 1; num--)
|
||||
{
|
||||
bigInteger4 = ModMult(bigInteger4, bigInteger5);
|
||||
if (k.TestBit(num))
|
||||
{
|
||||
bigInteger5 = ModMult(bigInteger4, Q);
|
||||
bigInteger = ModMult(bigInteger, bigInteger3);
|
||||
bigInteger2 = ModReduce(bigInteger3.Multiply(bigInteger2).Subtract(P.Multiply(bigInteger4)));
|
||||
bigInteger3 = ModReduce(bigInteger3.Multiply(bigInteger3).Subtract(bigInteger5.ShiftLeft(1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
bigInteger5 = bigInteger4;
|
||||
bigInteger = ModReduce(bigInteger.Multiply(bigInteger2).Subtract(bigInteger4));
|
||||
bigInteger3 = ModReduce(bigInteger3.Multiply(bigInteger2).Subtract(P.Multiply(bigInteger4)));
|
||||
bigInteger2 = ModReduce(bigInteger2.Multiply(bigInteger2).Subtract(bigInteger4.ShiftLeft(1)));
|
||||
}
|
||||
}
|
||||
bigInteger4 = ModMult(bigInteger4, bigInteger5);
|
||||
bigInteger5 = ModMult(bigInteger4, Q);
|
||||
bigInteger = ModReduce(bigInteger.Multiply(bigInteger2).Subtract(bigInteger4));
|
||||
bigInteger2 = ModReduce(bigInteger3.Multiply(bigInteger2).Subtract(P.Multiply(bigInteger4)));
|
||||
bigInteger4 = ModMult(bigInteger4, bigInteger5);
|
||||
for (int i = 1; i <= lowestSetBit; i++)
|
||||
{
|
||||
bigInteger = ModMult(bigInteger, bigInteger2);
|
||||
bigInteger2 = ModReduce(bigInteger2.Multiply(bigInteger2).Subtract(bigInteger4.ShiftLeft(1)));
|
||||
bigInteger4 = ModMult(bigInteger4, bigInteger4);
|
||||
}
|
||||
return new BigInteger[2] { bigInteger, bigInteger2 };
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModAdd(BigInteger x1, BigInteger x2)
|
||||
{
|
||||
BigInteger bigInteger = x1.Add(x2);
|
||||
if (bigInteger.CompareTo(q) >= 0)
|
||||
{
|
||||
bigInteger = bigInteger.Subtract(q);
|
||||
}
|
||||
return bigInteger;
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModDouble(BigInteger x)
|
||||
{
|
||||
BigInteger bigInteger = x.ShiftLeft(1);
|
||||
if (bigInteger.CompareTo(q) >= 0)
|
||||
{
|
||||
bigInteger = bigInteger.Subtract(q);
|
||||
}
|
||||
return bigInteger;
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModHalf(BigInteger x)
|
||||
{
|
||||
if (x.TestBit(0))
|
||||
{
|
||||
x = q.Add(x);
|
||||
}
|
||||
return x.ShiftRight(1);
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModHalfAbs(BigInteger x)
|
||||
{
|
||||
if (x.TestBit(0))
|
||||
{
|
||||
x = q.Subtract(x);
|
||||
}
|
||||
return x.ShiftRight(1);
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModInverse(BigInteger x)
|
||||
{
|
||||
int fieldSize = FieldSize;
|
||||
int len = fieldSize + 31 >> 5;
|
||||
uint[] p = Nat.FromBigInteger(fieldSize, q);
|
||||
uint[] array = Nat.FromBigInteger(fieldSize, x);
|
||||
uint[] z = Nat.Create(len);
|
||||
Mod.Invert(p, array, z);
|
||||
return Nat.ToBigInteger(len, z);
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModMult(BigInteger x1, BigInteger x2)
|
||||
{
|
||||
return ModReduce(x1.Multiply(x2));
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModReduce(BigInteger x)
|
||||
{
|
||||
if (r == null)
|
||||
{
|
||||
x = x.Mod(q);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool flag = x.SignValue < 0;
|
||||
if (flag)
|
||||
{
|
||||
x = x.Abs();
|
||||
}
|
||||
int bitLength = q.BitLength;
|
||||
if (r.SignValue > 0)
|
||||
{
|
||||
BigInteger n = BigInteger.One.ShiftLeft(bitLength);
|
||||
bool flag2 = r.Equals(BigInteger.One);
|
||||
while (x.BitLength > bitLength + 1)
|
||||
{
|
||||
BigInteger bigInteger = x.ShiftRight(bitLength);
|
||||
BigInteger value = x.Remainder(n);
|
||||
if (!flag2)
|
||||
{
|
||||
bigInteger = bigInteger.Multiply(r);
|
||||
}
|
||||
x = bigInteger.Add(value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int num = ((bitLength - 1) & 0x1F) + 1;
|
||||
BigInteger bigInteger2 = r.Negate();
|
||||
BigInteger bigInteger3 = bigInteger2.Multiply(x.ShiftRight(bitLength - num));
|
||||
BigInteger bigInteger4 = bigInteger3.ShiftRight(bitLength + num);
|
||||
BigInteger bigInteger5 = bigInteger4.Multiply(q);
|
||||
BigInteger bigInteger6 = BigInteger.One.ShiftLeft(bitLength + num);
|
||||
bigInteger5 = bigInteger5.Remainder(bigInteger6);
|
||||
x = x.Remainder(bigInteger6);
|
||||
x = x.Subtract(bigInteger5);
|
||||
if (x.SignValue < 0)
|
||||
{
|
||||
x = x.Add(bigInteger6);
|
||||
}
|
||||
}
|
||||
while (x.CompareTo(q) >= 0)
|
||||
{
|
||||
x = x.Subtract(q);
|
||||
}
|
||||
if (flag && x.SignValue != 0)
|
||||
{
|
||||
x = q.Subtract(x);
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
protected virtual BigInteger ModSubtract(BigInteger x1, BigInteger x2)
|
||||
{
|
||||
BigInteger bigInteger = x1.Subtract(x2);
|
||||
if (bigInteger.SignValue < 0)
|
||||
{
|
||||
bigInteger = bigInteger.Add(q);
|
||||
}
|
||||
return bigInteger;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!(obj is FpFieldElement other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Equals(other);
|
||||
}
|
||||
|
||||
public virtual bool Equals(FpFieldElement other)
|
||||
{
|
||||
if (q.Equals(other.q))
|
||||
{
|
||||
return base.Equals(other);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return q.GetHashCode() ^ base.GetHashCode();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user