init commit

This commit is contained in:
2025-10-09 09:57:24 +09:00
commit 4d551bd74f
6636 changed files with 1218703 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Djb;
internal class Curve25519 : AbstractFpCurve
{
private class Curve25519LookupTable : ECLookupTable
{
private readonly Curve25519 m_outer;
private readonly uint[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal Curve25519LookupTable(Curve25519 outer, uint[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
uint[] array = Nat256.Create();
uint[] array2 = Nat256.Create();
int num = 0;
for (int i = 0; i < m_size; i++)
{
uint num2 = (uint)((i ^ index) - 1 >> 31);
for (int j = 0; j < 8; j++)
{
uint[] array4;
uint[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
uint[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 8 + j] & num2);
}
num += 16;
}
return m_outer.CreateRawPoint(new Curve25519FieldElement(array), new Curve25519FieldElement(array2), withCompression: false);
}
}
private const int Curve25519_DEFAULT_COORDS = 4;
private const int CURVE25519_FE_INTS = 8;
public static readonly BigInteger q = Nat256.ToBigInteger(Curve25519Field.P);
protected readonly Curve25519Point m_infinity;
public virtual BigInteger Q => q;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => q.BitLength;
public Curve25519()
: base(q)
{
m_infinity = new Curve25519Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA984914A144")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("7B425ED097B425ED097B425ED097B425ED097B425ED097B4260B5E9C7710C864")));
m_order = new BigInteger(1, Hex.Decode("1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED"));
m_cofactor = BigInteger.ValueOf(8L);
m_coord = 4;
}
protected override ECCurve CloneCurve()
{
return new Curve25519();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 4)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new Curve25519FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new Curve25519Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new Curve25519Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
uint[] array = new uint[len * 8 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat256.Copy(((Curve25519FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 8;
Nat256.Copy(((Curve25519FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 8;
}
return new Curve25519LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,237 @@
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Djb;
internal class Curve25519Field
{
private const uint P7 = 2147483647u;
private const uint PInv = 19u;
internal static readonly uint[] P = new uint[8] { 4294967277u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 2147483647u };
private static readonly uint[] PExt = new uint[16]
{
361u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4294967277u, 4294967295u,
4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 1073741823u
};
public static void Add(uint[] x, uint[] y, uint[] z)
{
Nat256.Add(x, y, z);
if (Nat256.Gte(z, P))
{
SubPFrom(z);
}
}
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
{
Nat.Add(16, xx, yy, zz);
if (Nat.Gte(16, zz, PExt))
{
SubPExtFrom(zz);
}
}
public static void AddOne(uint[] x, uint[] z)
{
Nat.Inc(8, x, z);
if (Nat256.Gte(z, P))
{
SubPFrom(z);
}
}
public static uint[] FromBigInteger(BigInteger x)
{
uint[] array = Nat256.FromBigInteger(x);
while (Nat256.Gte(array, P))
{
Nat256.SubFrom(P, array);
}
return array;
}
public static void Half(uint[] x, uint[] z)
{
if ((x[0] & 1) == 0)
{
Nat.ShiftDownBit(8, x, 0u, z);
return;
}
Nat256.Add(x, P, z);
Nat.ShiftDownBit(8, z, 0u);
}
public static void Multiply(uint[] x, uint[] y, uint[] z)
{
uint[] array = Nat256.CreateExt();
Nat256.Mul(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
{
Nat256.MulAddTo(x, y, zz);
if (Nat.Gte(16, zz, PExt))
{
SubPExtFrom(zz);
}
}
public static void Negate(uint[] x, uint[] z)
{
if (Nat256.IsZero(x))
{
Nat256.Zero(z);
}
else
{
Nat256.Sub(P, x, z);
}
}
public static void Reduce(uint[] xx, uint[] z)
{
uint num = xx[7];
Nat.ShiftUpBit(8, xx, 8, num, z, 0);
uint num2 = Nat256.MulByWordAddTo(19u, xx, z) << 1;
uint num3 = z[7];
num2 += (num3 >> 31) - (num >> 31);
num3 &= 0x7FFFFFFF;
if ((z[7] = num3 + Nat.AddWordTo(7, num2 * 19, z)) >= int.MaxValue && Nat256.Gte(z, P))
{
SubPFrom(z);
}
}
public static void Reduce27(uint x, uint[] z)
{
uint num = z[7];
uint num2 = (x << 1) | (num >> 31);
num &= 0x7FFFFFFF;
if ((z[7] = num + Nat.AddWordTo(7, num2 * 19, z)) >= int.MaxValue && Nat256.Gte(z, P))
{
SubPFrom(z);
}
}
public static void Square(uint[] x, uint[] z)
{
uint[] array = Nat256.CreateExt();
Nat256.Square(x, array);
Reduce(array, z);
}
public static void SquareN(uint[] x, int n, uint[] z)
{
uint[] array = Nat256.CreateExt();
Nat256.Square(x, array);
Reduce(array, z);
while (--n > 0)
{
Nat256.Square(z, array);
Reduce(array, z);
}
}
public static void Subtract(uint[] x, uint[] y, uint[] z)
{
if (Nat256.Sub(x, y, z) != 0)
{
AddPTo(z);
}
}
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat.Sub(16, xx, yy, zz) != 0)
{
AddPExtTo(zz);
}
}
public static void Twice(uint[] x, uint[] z)
{
Nat.ShiftUpBit(8, x, 0u, z);
if (Nat256.Gte(z, P))
{
SubPFrom(z);
}
}
private static uint AddPTo(uint[] z)
{
long num = (long)z[0] - 19L;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num = Nat.DecAt(7, z, 1);
}
num += (long)z[7] + 2147483648L;
z[7] = (uint)num;
num >>= 32;
return (uint)num;
}
private static uint AddPExtTo(uint[] zz)
{
long num = (long)zz[0] + (long)PExt[0];
zz[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num = Nat.IncAt(8, zz, 1);
}
num += (long)zz[8] - 19L;
zz[8] = (uint)num;
num >>= 32;
if (num != 0)
{
num = Nat.DecAt(15, zz, 9);
}
num += (long)zz[15] + (long)(PExt[15] + 1);
zz[15] = (uint)num;
num >>= 32;
return (uint)num;
}
private static int SubPFrom(uint[] z)
{
long num = (long)z[0] + 19L;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num = Nat.IncAt(7, z, 1);
}
num += (long)z[7] - 2147483648L;
z[7] = (uint)num;
num >>= 32;
return (int)num;
}
private static int SubPExtFrom(uint[] zz)
{
long num = (long)zz[0] - (long)PExt[0];
zz[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num = Nat.DecAt(8, zz, 1);
}
num += (long)zz[8] + 19L;
zz[8] = (uint)num;
num >>= 32;
if (num != 0)
{
num = Nat.IncAt(15, zz, 9);
}
num += (long)zz[15] - (long)(PExt[15] + 1);
zz[15] = (uint)num;
num >>= 32;
return (int)num;
}
}

View File

@@ -0,0 +1,193 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Djb;
internal class Curve25519FieldElement : AbstractFpFieldElement
{
public static readonly BigInteger Q = Curve25519.q;
private static readonly uint[] PRECOMP_POW2 = new uint[8] { 1242472624u, 3303938855u, 2905597048u, 792926214u, 1039914919u, 726466713u, 1338105611u, 730014848u };
protected internal readonly uint[] x;
public override bool IsZero => Nat256.IsZero(x);
public override bool IsOne => Nat256.IsOne(x);
public override string FieldName => "Curve25519Field";
public override int FieldSize => Q.BitLength;
public Curve25519FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
{
throw new ArgumentException("value invalid for Curve25519FieldElement", "x");
}
this.x = Curve25519Field.FromBigInteger(x);
}
public Curve25519FieldElement()
{
x = Nat256.Create();
}
protected internal Curve25519FieldElement(uint[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return Nat256.GetBit(x, 0) == 1;
}
public override BigInteger ToBigInteger()
{
return Nat256.ToBigInteger(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
uint[] z = Nat256.Create();
Curve25519Field.Add(x, ((Curve25519FieldElement)b).x, z);
return new Curve25519FieldElement(z);
}
public override ECFieldElement AddOne()
{
uint[] z = Nat256.Create();
Curve25519Field.AddOne(x, z);
return new Curve25519FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
uint[] z = Nat256.Create();
Curve25519Field.Subtract(x, ((Curve25519FieldElement)b).x, z);
return new Curve25519FieldElement(z);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
uint[] z = Nat256.Create();
Curve25519Field.Multiply(x, ((Curve25519FieldElement)b).x, z);
return new Curve25519FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
uint[] z = Nat256.Create();
Mod.Invert(Curve25519Field.P, ((Curve25519FieldElement)b).x, z);
Curve25519Field.Multiply(z, x, z);
return new Curve25519FieldElement(z);
}
public override ECFieldElement Negate()
{
uint[] z = Nat256.Create();
Curve25519Field.Negate(x, z);
return new Curve25519FieldElement(z);
}
public override ECFieldElement Square()
{
uint[] z = Nat256.Create();
Curve25519Field.Square(x, z);
return new Curve25519FieldElement(z);
}
public override ECFieldElement Invert()
{
uint[] z = Nat256.Create();
Mod.Invert(Curve25519Field.P, x, z);
return new Curve25519FieldElement(z);
}
public override ECFieldElement Sqrt()
{
uint[] y = x;
if (Nat256.IsZero(y) || Nat256.IsOne(y))
{
return this;
}
uint[] array = Nat256.Create();
Curve25519Field.Square(y, array);
Curve25519Field.Multiply(array, y, array);
uint[] array2 = array;
Curve25519Field.Square(array, array2);
Curve25519Field.Multiply(array2, y, array2);
uint[] array3 = Nat256.Create();
Curve25519Field.Square(array2, array3);
Curve25519Field.Multiply(array3, y, array3);
uint[] array4 = Nat256.Create();
Curve25519Field.SquareN(array3, 3, array4);
Curve25519Field.Multiply(array4, array2, array4);
uint[] array5 = array2;
Curve25519Field.SquareN(array4, 4, array5);
Curve25519Field.Multiply(array5, array3, array5);
uint[] array6 = array4;
Curve25519Field.SquareN(array5, 4, array6);
Curve25519Field.Multiply(array6, array3, array6);
uint[] array7 = array3;
Curve25519Field.SquareN(array6, 15, array7);
Curve25519Field.Multiply(array7, array6, array7);
uint[] array8 = array6;
Curve25519Field.SquareN(array7, 30, array8);
Curve25519Field.Multiply(array8, array7, array8);
uint[] array9 = array7;
Curve25519Field.SquareN(array8, 60, array9);
Curve25519Field.Multiply(array9, array8, array9);
uint[] z = array8;
Curve25519Field.SquareN(array9, 11, z);
Curve25519Field.Multiply(z, array5, z);
uint[] array10 = array5;
Curve25519Field.SquareN(z, 120, array10);
Curve25519Field.Multiply(array10, array9, array10);
uint[] z2 = array10;
Curve25519Field.Square(z2, z2);
uint[] array11 = array9;
Curve25519Field.Square(z2, array11);
if (Nat256.Eq(y, array11))
{
return new Curve25519FieldElement(z2);
}
Curve25519Field.Multiply(z2, PRECOMP_POW2, z2);
Curve25519Field.Square(z2, array11);
if (Nat256.Eq(y, array11))
{
return new Curve25519FieldElement(z2);
}
return null;
}
public override bool Equals(object obj)
{
return Equals(obj as Curve25519FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as Curve25519FieldElement);
}
public virtual bool Equals(Curve25519FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat256.Eq(x, other.x);
}
public override int GetHashCode()
{
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 8);
}
}

View File

@@ -0,0 +1,271 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Djb;
internal class Curve25519Point : AbstractFpPoint
{
public Curve25519Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public Curve25519Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal Curve25519Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new Curve25519Point(null, AffineXCoord, AffineYCoord);
}
public override ECFieldElement GetZCoord(int index)
{
if (index == 1)
{
return GetJacobianModifiedW();
}
return base.GetZCoord(index);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
Curve25519FieldElement curve25519FieldElement = (Curve25519FieldElement)base.RawXCoord;
Curve25519FieldElement curve25519FieldElement2 = (Curve25519FieldElement)base.RawYCoord;
Curve25519FieldElement curve25519FieldElement3 = (Curve25519FieldElement)base.RawZCoords[0];
Curve25519FieldElement curve25519FieldElement4 = (Curve25519FieldElement)b.RawXCoord;
Curve25519FieldElement curve25519FieldElement5 = (Curve25519FieldElement)b.RawYCoord;
Curve25519FieldElement curve25519FieldElement6 = (Curve25519FieldElement)b.RawZCoords[0];
uint[] array = Nat256.CreateExt();
uint[] array2 = Nat256.Create();
uint[] array3 = Nat256.Create();
uint[] array4 = Nat256.Create();
bool isOne = curve25519FieldElement3.IsOne;
uint[] array5;
uint[] array6;
if (isOne)
{
array5 = curve25519FieldElement4.x;
array6 = curve25519FieldElement5.x;
}
else
{
array6 = array3;
Curve25519Field.Square(curve25519FieldElement3.x, array6);
array5 = array2;
Curve25519Field.Multiply(array6, curve25519FieldElement4.x, array5);
Curve25519Field.Multiply(array6, curve25519FieldElement3.x, array6);
Curve25519Field.Multiply(array6, curve25519FieldElement5.x, array6);
}
bool isOne2 = curve25519FieldElement6.IsOne;
uint[] array7;
uint[] array8;
if (isOne2)
{
array7 = curve25519FieldElement.x;
array8 = curve25519FieldElement2.x;
}
else
{
array8 = array4;
Curve25519Field.Square(curve25519FieldElement6.x, array8);
array7 = array;
Curve25519Field.Multiply(array8, curve25519FieldElement.x, array7);
Curve25519Field.Multiply(array8, curve25519FieldElement6.x, array8);
Curve25519Field.Multiply(array8, curve25519FieldElement2.x, array8);
}
uint[] array9 = Nat256.Create();
Curve25519Field.Subtract(array7, array5, array9);
uint[] array10 = array2;
Curve25519Field.Subtract(array8, array6, array10);
if (Nat256.IsZero(array9))
{
if (Nat256.IsZero(array10))
{
return Twice();
}
return curve.Infinity;
}
uint[] array11 = Nat256.Create();
Curve25519Field.Square(array9, array11);
uint[] array12 = Nat256.Create();
Curve25519Field.Multiply(array11, array9, array12);
uint[] array13 = array3;
Curve25519Field.Multiply(array11, array7, array13);
Curve25519Field.Negate(array12, array12);
Nat256.Mul(array8, array12, array);
uint x = Nat256.AddBothTo(array13, array13, array12);
Curve25519Field.Reduce27(x, array12);
Curve25519FieldElement curve25519FieldElement7 = new Curve25519FieldElement(array4);
Curve25519Field.Square(array10, curve25519FieldElement7.x);
Curve25519Field.Subtract(curve25519FieldElement7.x, array12, curve25519FieldElement7.x);
Curve25519FieldElement curve25519FieldElement8 = new Curve25519FieldElement(array12);
Curve25519Field.Subtract(array13, curve25519FieldElement7.x, curve25519FieldElement8.x);
Curve25519Field.MultiplyAddToExt(curve25519FieldElement8.x, array10, array);
Curve25519Field.Reduce(array, curve25519FieldElement8.x);
Curve25519FieldElement curve25519FieldElement9 = new Curve25519FieldElement(array9);
if (!isOne)
{
Curve25519Field.Multiply(curve25519FieldElement9.x, curve25519FieldElement3.x, curve25519FieldElement9.x);
}
if (!isOne2)
{
Curve25519Field.Multiply(curve25519FieldElement9.x, curve25519FieldElement6.x, curve25519FieldElement9.x);
}
uint[] zSquared = ((isOne && isOne2) ? array11 : null);
Curve25519FieldElement curve25519FieldElement10 = CalculateJacobianModifiedW(curve25519FieldElement9, zSquared);
ECFieldElement[] zs = new ECFieldElement[2] { curve25519FieldElement9, curve25519FieldElement10 };
return new Curve25519Point(curve, curve25519FieldElement7, curve25519FieldElement8, zs, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return curve.Infinity;
}
return TwiceJacobianModified(calculateW: true);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
return TwiceJacobianModified(calculateW: false).Add(b);
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity || base.RawYCoord.IsZero)
{
return this;
}
return TwiceJacobianModified(calculateW: false).Add(this);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
return new Curve25519Point(Curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
protected virtual Curve25519FieldElement CalculateJacobianModifiedW(Curve25519FieldElement Z, uint[] ZSquared)
{
Curve25519FieldElement curve25519FieldElement = (Curve25519FieldElement)Curve.A;
if (Z.IsOne)
{
return curve25519FieldElement;
}
Curve25519FieldElement curve25519FieldElement2 = new Curve25519FieldElement();
if (ZSquared == null)
{
ZSquared = curve25519FieldElement2.x;
Curve25519Field.Square(Z.x, ZSquared);
}
Curve25519Field.Square(ZSquared, curve25519FieldElement2.x);
Curve25519Field.Multiply(curve25519FieldElement2.x, curve25519FieldElement.x, curve25519FieldElement2.x);
return curve25519FieldElement2;
}
protected virtual Curve25519FieldElement GetJacobianModifiedW()
{
ECFieldElement[] rawZCoords = base.RawZCoords;
Curve25519FieldElement curve25519FieldElement = (Curve25519FieldElement)rawZCoords[1];
if (curve25519FieldElement == null)
{
curve25519FieldElement = (Curve25519FieldElement)(rawZCoords[1] = CalculateJacobianModifiedW((Curve25519FieldElement)rawZCoords[0], null));
}
return curve25519FieldElement;
}
protected virtual Curve25519Point TwiceJacobianModified(bool calculateW)
{
Curve25519FieldElement curve25519FieldElement = (Curve25519FieldElement)base.RawXCoord;
Curve25519FieldElement curve25519FieldElement2 = (Curve25519FieldElement)base.RawYCoord;
Curve25519FieldElement curve25519FieldElement3 = (Curve25519FieldElement)base.RawZCoords[0];
Curve25519FieldElement jacobianModifiedW = GetJacobianModifiedW();
uint[] array = Nat256.Create();
Curve25519Field.Square(curve25519FieldElement.x, array);
uint num = Nat256.AddBothTo(array, array, array);
num += Nat256.AddTo(jacobianModifiedW.x, array);
Curve25519Field.Reduce27(num, array);
uint[] array2 = Nat256.Create();
Curve25519Field.Twice(curve25519FieldElement2.x, array2);
uint[] array3 = Nat256.Create();
Curve25519Field.Multiply(array2, curve25519FieldElement2.x, array3);
uint[] array4 = Nat256.Create();
Curve25519Field.Multiply(array3, curve25519FieldElement.x, array4);
Curve25519Field.Twice(array4, array4);
uint[] array5 = Nat256.Create();
Curve25519Field.Square(array3, array5);
Curve25519Field.Twice(array5, array5);
Curve25519FieldElement curve25519FieldElement4 = new Curve25519FieldElement(array3);
Curve25519Field.Square(array, curve25519FieldElement4.x);
Curve25519Field.Subtract(curve25519FieldElement4.x, array4, curve25519FieldElement4.x);
Curve25519Field.Subtract(curve25519FieldElement4.x, array4, curve25519FieldElement4.x);
Curve25519FieldElement curve25519FieldElement5 = new Curve25519FieldElement(array4);
Curve25519Field.Subtract(array4, curve25519FieldElement4.x, curve25519FieldElement5.x);
Curve25519Field.Multiply(curve25519FieldElement5.x, array, curve25519FieldElement5.x);
Curve25519Field.Subtract(curve25519FieldElement5.x, array5, curve25519FieldElement5.x);
Curve25519FieldElement curve25519FieldElement6 = new Curve25519FieldElement(array2);
if (!Nat256.IsOne(curve25519FieldElement3.x))
{
Curve25519Field.Multiply(curve25519FieldElement6.x, curve25519FieldElement3.x, curve25519FieldElement6.x);
}
Curve25519FieldElement curve25519FieldElement7 = null;
if (calculateW)
{
curve25519FieldElement7 = new Curve25519FieldElement(array5);
Curve25519Field.Multiply(curve25519FieldElement7.x, jacobianModifiedW.x, curve25519FieldElement7.x);
Curve25519Field.Twice(curve25519FieldElement7.x, curve25519FieldElement7.x);
}
return new Curve25519Point(Curve, curve25519FieldElement4, curve25519FieldElement5, new ECFieldElement[2] { curve25519FieldElement6, curve25519FieldElement7 }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,119 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.GM;
internal class SM2P256V1Curve : AbstractFpCurve
{
private class SM2P256V1LookupTable : ECLookupTable
{
private readonly SM2P256V1Curve m_outer;
private readonly uint[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SM2P256V1LookupTable(SM2P256V1Curve outer, uint[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
uint[] array = Nat256.Create();
uint[] array2 = Nat256.Create();
int num = 0;
for (int i = 0; i < m_size; i++)
{
uint num2 = (uint)((i ^ index) - 1 >> 31);
for (int j = 0; j < 8; j++)
{
uint[] array4;
uint[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
uint[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 8 + j] & num2);
}
num += 16;
}
return m_outer.CreateRawPoint(new SM2P256V1FieldElement(array), new SM2P256V1FieldElement(array2), withCompression: false);
}
}
private const int SM2P256V1_DEFAULT_COORDS = 2;
private const int SM2P256V1_FE_INTS = 8;
public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF"));
protected readonly SM2P256V1Point m_infinity;
public virtual BigInteger Q => q;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => q.BitLength;
public SM2P256V1Curve()
: base(q)
{
m_infinity = new SM2P256V1Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93")));
m_order = new BigInteger(1, Hex.Decode("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123"));
m_cofactor = BigInteger.One;
m_coord = 2;
}
protected override ECCurve CloneCurve()
{
return new SM2P256V1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 2)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SM2P256V1FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SM2P256V1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SM2P256V1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
uint[] array = new uint[len * 8 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat256.Copy(((SM2P256V1FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 8;
Nat256.Copy(((SM2P256V1FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 8;
}
return new SM2P256V1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,287 @@
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.GM;
internal class SM2P256V1Field
{
internal const uint P7 = 4294967294u;
internal const uint PExt15 = 4294967294u;
internal static readonly uint[] P = new uint[8] { 4294967295u, 4294967295u, 0u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967294u };
internal static readonly uint[] PExt = new uint[16]
{
1u, 0u, 4294967294u, 1u, 1u, 4294967294u, 0u, 2u, 4294967294u, 4294967293u,
3u, 4294967294u, 4294967295u, 4294967295u, 0u, 4294967294u
};
public static void Add(uint[] x, uint[] y, uint[] z)
{
if (Nat256.Add(x, y, z) != 0 || (z[7] >= 4294967294u && Nat256.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat.Add(16, xx, yy, zz) != 0 || (zz[15] >= 4294967294u && Nat.Gte(16, zz, PExt)))
{
Nat.SubFrom(16, PExt, zz);
}
}
public static void AddOne(uint[] x, uint[] z)
{
if (Nat.Inc(8, x, z) != 0 || (z[7] >= 4294967294u && Nat256.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static uint[] FromBigInteger(BigInteger x)
{
uint[] array = Nat256.FromBigInteger(x);
if (array[7] >= 4294967294u && Nat256.Gte(array, P))
{
Nat256.SubFrom(P, array);
}
return array;
}
public static void Half(uint[] x, uint[] z)
{
if ((x[0] & 1) == 0)
{
Nat.ShiftDownBit(8, x, 0u, z);
return;
}
uint c = Nat256.Add(x, P, z);
Nat.ShiftDownBit(8, z, c);
}
public static void Multiply(uint[] x, uint[] y, uint[] z)
{
uint[] array = Nat256.CreateExt();
Nat256.Mul(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
{
if (Nat256.MulAddTo(x, y, zz) != 0 || (zz[15] >= 4294967294u && Nat.Gte(16, zz, PExt)))
{
Nat.SubFrom(16, PExt, zz);
}
}
public static void Negate(uint[] x, uint[] z)
{
if (Nat256.IsZero(x))
{
Nat256.Zero(z);
}
else
{
Nat256.Sub(P, x, z);
}
}
public static void Reduce(uint[] xx, uint[] z)
{
long num = xx[8];
long num2 = xx[9];
long num3 = xx[10];
long num4 = xx[11];
long num5 = xx[12];
long num6 = xx[13];
long num7 = xx[14];
long num8 = xx[15];
long num9 = num + num2;
long num10 = num3 + num4;
long num11 = num5 + num8;
long num12 = num6 + num7;
long num13 = num12 + (num8 << 1);
long num14 = num9 + num12;
long num15 = num10 + num11 + num14;
long num16 = 0L;
num16 += xx[0] + num15 + num6 + num7 + num8;
z[0] = (uint)num16;
num16 >>= 32;
num16 += xx[1] + num15 - num + num7 + num8;
z[1] = (uint)num16;
num16 >>= 32;
num16 += xx[2] - num14;
z[2] = (uint)num16;
num16 >>= 32;
num16 += xx[3] + num15 - num2 - num3 + num6;
z[3] = (uint)num16;
num16 >>= 32;
num16 += xx[4] + num15 - num10 - num + num7;
z[4] = (uint)num16;
num16 >>= 32;
num16 += xx[5] + num13 + num3;
z[5] = (uint)num16;
num16 >>= 32;
num16 += xx[6] + num4 + num7 + num8;
z[6] = (uint)num16;
num16 >>= 32;
num16 += xx[7] + num15 + num13 + num5;
z[7] = (uint)num16;
num16 >>= 32;
Reduce32((uint)num16, z);
}
public static void Reduce32(uint x, uint[] z)
{
long num = 0L;
if (x != 0)
{
long num2 = x;
num += z[0] + num2;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[1];
z[1] = (uint)num;
num >>= 32;
}
num += z[2] - num2;
z[2] = (uint)num;
num >>= 32;
num += z[3] + num2;
z[3] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[4];
z[4] = (uint)num;
num >>= 32;
num += z[5];
z[5] = (uint)num;
num >>= 32;
num += z[6];
z[6] = (uint)num;
num >>= 32;
}
num += z[7] + num2;
z[7] = (uint)num;
num >>= 32;
}
if (num != 0 || (z[7] >= 4294967294u && Nat256.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static void Square(uint[] x, uint[] z)
{
uint[] array = Nat256.CreateExt();
Nat256.Square(x, array);
Reduce(array, z);
}
public static void SquareN(uint[] x, int n, uint[] z)
{
uint[] array = Nat256.CreateExt();
Nat256.Square(x, array);
Reduce(array, z);
while (--n > 0)
{
Nat256.Square(z, array);
Reduce(array, z);
}
}
public static void Subtract(uint[] x, uint[] y, uint[] z)
{
if (Nat256.Sub(x, y, z) != 0)
{
SubPInvFrom(z);
}
}
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat.Sub(16, xx, yy, zz) != 0)
{
Nat.AddTo(16, PExt, zz);
}
}
public static void Twice(uint[] x, uint[] z)
{
if (Nat.ShiftUpBit(8, x, 0u, z) != 0 || (z[7] >= 4294967294u && Nat256.Gte(z, P)))
{
AddPInvTo(z);
}
}
private static void AddPInvTo(uint[] z)
{
long num = (long)z[0] + 1L;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[1];
z[1] = (uint)num;
num >>= 32;
}
num += (long)z[2] - 1L;
z[2] = (uint)num;
num >>= 32;
num += (long)z[3] + 1L;
z[3] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[4];
z[4] = (uint)num;
num >>= 32;
num += z[5];
z[5] = (uint)num;
num >>= 32;
num += z[6];
z[6] = (uint)num;
num >>= 32;
}
num += (long)z[7] + 1L;
z[7] = (uint)num;
}
private static void SubPInvFrom(uint[] z)
{
long num = (long)z[0] - 1L;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[1];
z[1] = (uint)num;
num >>= 32;
}
num += (long)z[2] + 1L;
z[2] = (uint)num;
num >>= 32;
num += (long)z[3] - 1L;
z[3] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[4];
z[4] = (uint)num;
num >>= 32;
num += z[5];
z[5] = (uint)num;
num >>= 32;
num += z[6];
z[6] = (uint)num;
num >>= 32;
}
num += (long)z[7] - 1L;
z[7] = (uint)num;
}
}

View File

@@ -0,0 +1,184 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.GM;
internal class SM2P256V1FieldElement : AbstractFpFieldElement
{
public static readonly BigInteger Q = SM2P256V1Curve.q;
protected internal readonly uint[] x;
public override bool IsZero => Nat256.IsZero(x);
public override bool IsOne => Nat256.IsOne(x);
public override string FieldName => "SM2P256V1Field";
public override int FieldSize => Q.BitLength;
public SM2P256V1FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
{
throw new ArgumentException("value invalid for SM2P256V1FieldElement", "x");
}
this.x = SM2P256V1Field.FromBigInteger(x);
}
public SM2P256V1FieldElement()
{
x = Nat256.Create();
}
protected internal SM2P256V1FieldElement(uint[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return Nat256.GetBit(x, 0) == 1;
}
public override BigInteger ToBigInteger()
{
return Nat256.ToBigInteger(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
uint[] z = Nat256.Create();
SM2P256V1Field.Add(x, ((SM2P256V1FieldElement)b).x, z);
return new SM2P256V1FieldElement(z);
}
public override ECFieldElement AddOne()
{
uint[] z = Nat256.Create();
SM2P256V1Field.AddOne(x, z);
return new SM2P256V1FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
uint[] z = Nat256.Create();
SM2P256V1Field.Subtract(x, ((SM2P256V1FieldElement)b).x, z);
return new SM2P256V1FieldElement(z);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
uint[] z = Nat256.Create();
SM2P256V1Field.Multiply(x, ((SM2P256V1FieldElement)b).x, z);
return new SM2P256V1FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
uint[] z = Nat256.Create();
Mod.Invert(SM2P256V1Field.P, ((SM2P256V1FieldElement)b).x, z);
SM2P256V1Field.Multiply(z, x, z);
return new SM2P256V1FieldElement(z);
}
public override ECFieldElement Negate()
{
uint[] z = Nat256.Create();
SM2P256V1Field.Negate(x, z);
return new SM2P256V1FieldElement(z);
}
public override ECFieldElement Square()
{
uint[] z = Nat256.Create();
SM2P256V1Field.Square(x, z);
return new SM2P256V1FieldElement(z);
}
public override ECFieldElement Invert()
{
uint[] z = Nat256.Create();
Mod.Invert(SM2P256V1Field.P, x, z);
return new SM2P256V1FieldElement(z);
}
public override ECFieldElement Sqrt()
{
uint[] y = x;
if (Nat256.IsZero(y) || Nat256.IsOne(y))
{
return this;
}
uint[] array = Nat256.Create();
SM2P256V1Field.Square(y, array);
SM2P256V1Field.Multiply(array, y, array);
uint[] array2 = Nat256.Create();
SM2P256V1Field.SquareN(array, 2, array2);
SM2P256V1Field.Multiply(array2, array, array2);
uint[] array3 = Nat256.Create();
SM2P256V1Field.SquareN(array2, 2, array3);
SM2P256V1Field.Multiply(array3, array, array3);
uint[] array4 = array;
SM2P256V1Field.SquareN(array3, 6, array4);
SM2P256V1Field.Multiply(array4, array3, array4);
uint[] array5 = Nat256.Create();
SM2P256V1Field.SquareN(array4, 12, array5);
SM2P256V1Field.Multiply(array5, array4, array5);
uint[] array6 = array4;
SM2P256V1Field.SquareN(array5, 6, array6);
SM2P256V1Field.Multiply(array6, array3, array6);
uint[] array7 = array3;
SM2P256V1Field.Square(array6, array7);
SM2P256V1Field.Multiply(array7, y, array7);
uint[] z = array5;
SM2P256V1Field.SquareN(array7, 31, z);
uint[] array8 = array6;
SM2P256V1Field.Multiply(z, array7, array8);
SM2P256V1Field.SquareN(z, 32, z);
SM2P256V1Field.Multiply(z, array8, z);
SM2P256V1Field.SquareN(z, 62, z);
SM2P256V1Field.Multiply(z, array8, z);
SM2P256V1Field.SquareN(z, 4, z);
SM2P256V1Field.Multiply(z, array2, z);
SM2P256V1Field.SquareN(z, 32, z);
SM2P256V1Field.Multiply(z, y, z);
SM2P256V1Field.SquareN(z, 62, z);
uint[] array9 = array2;
SM2P256V1Field.Square(z, array9);
if (!Nat256.Eq(y, array9))
{
return null;
}
return new SM2P256V1FieldElement(z);
}
public override bool Equals(object obj)
{
return Equals(obj as SM2P256V1FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SM2P256V1FieldElement);
}
public virtual bool Equals(SM2P256V1FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat256.Eq(x, other.x);
}
public override int GetHashCode()
{
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 8);
}
}

View File

@@ -0,0 +1,228 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.GM;
internal class SM2P256V1Point : AbstractFpPoint
{
public SM2P256V1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SM2P256V1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SM2P256V1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SM2P256V1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
SM2P256V1FieldElement sM2P256V1FieldElement = (SM2P256V1FieldElement)base.RawXCoord;
SM2P256V1FieldElement sM2P256V1FieldElement2 = (SM2P256V1FieldElement)base.RawYCoord;
SM2P256V1FieldElement sM2P256V1FieldElement3 = (SM2P256V1FieldElement)b.RawXCoord;
SM2P256V1FieldElement sM2P256V1FieldElement4 = (SM2P256V1FieldElement)b.RawYCoord;
SM2P256V1FieldElement sM2P256V1FieldElement5 = (SM2P256V1FieldElement)base.RawZCoords[0];
SM2P256V1FieldElement sM2P256V1FieldElement6 = (SM2P256V1FieldElement)b.RawZCoords[0];
uint[] array = Nat256.CreateExt();
uint[] array2 = Nat256.Create();
uint[] array3 = Nat256.Create();
uint[] array4 = Nat256.Create();
bool isOne = sM2P256V1FieldElement5.IsOne;
uint[] array5;
uint[] array6;
if (isOne)
{
array5 = sM2P256V1FieldElement3.x;
array6 = sM2P256V1FieldElement4.x;
}
else
{
array6 = array3;
SM2P256V1Field.Square(sM2P256V1FieldElement5.x, array6);
array5 = array2;
SM2P256V1Field.Multiply(array6, sM2P256V1FieldElement3.x, array5);
SM2P256V1Field.Multiply(array6, sM2P256V1FieldElement5.x, array6);
SM2P256V1Field.Multiply(array6, sM2P256V1FieldElement4.x, array6);
}
bool isOne2 = sM2P256V1FieldElement6.IsOne;
uint[] array7;
uint[] array8;
if (isOne2)
{
array7 = sM2P256V1FieldElement.x;
array8 = sM2P256V1FieldElement2.x;
}
else
{
array8 = array4;
SM2P256V1Field.Square(sM2P256V1FieldElement6.x, array8);
array7 = array;
SM2P256V1Field.Multiply(array8, sM2P256V1FieldElement.x, array7);
SM2P256V1Field.Multiply(array8, sM2P256V1FieldElement6.x, array8);
SM2P256V1Field.Multiply(array8, sM2P256V1FieldElement2.x, array8);
}
uint[] array9 = Nat256.Create();
SM2P256V1Field.Subtract(array7, array5, array9);
uint[] array10 = array2;
SM2P256V1Field.Subtract(array8, array6, array10);
if (Nat256.IsZero(array9))
{
if (Nat256.IsZero(array10))
{
return Twice();
}
return curve.Infinity;
}
uint[] array11 = array3;
SM2P256V1Field.Square(array9, array11);
uint[] array12 = Nat256.Create();
SM2P256V1Field.Multiply(array11, array9, array12);
uint[] array13 = array3;
SM2P256V1Field.Multiply(array11, array7, array13);
SM2P256V1Field.Negate(array12, array12);
Nat256.Mul(array8, array12, array);
uint x = Nat256.AddBothTo(array13, array13, array12);
SM2P256V1Field.Reduce32(x, array12);
SM2P256V1FieldElement sM2P256V1FieldElement7 = new SM2P256V1FieldElement(array4);
SM2P256V1Field.Square(array10, sM2P256V1FieldElement7.x);
SM2P256V1Field.Subtract(sM2P256V1FieldElement7.x, array12, sM2P256V1FieldElement7.x);
SM2P256V1FieldElement sM2P256V1FieldElement8 = new SM2P256V1FieldElement(array12);
SM2P256V1Field.Subtract(array13, sM2P256V1FieldElement7.x, sM2P256V1FieldElement8.x);
SM2P256V1Field.MultiplyAddToExt(sM2P256V1FieldElement8.x, array10, array);
SM2P256V1Field.Reduce(array, sM2P256V1FieldElement8.x);
SM2P256V1FieldElement sM2P256V1FieldElement9 = new SM2P256V1FieldElement(array9);
if (!isOne)
{
SM2P256V1Field.Multiply(sM2P256V1FieldElement9.x, sM2P256V1FieldElement5.x, sM2P256V1FieldElement9.x);
}
if (!isOne2)
{
SM2P256V1Field.Multiply(sM2P256V1FieldElement9.x, sM2P256V1FieldElement6.x, sM2P256V1FieldElement9.x);
}
ECFieldElement[] zs = new ECFieldElement[1] { sM2P256V1FieldElement9 };
return new SM2P256V1Point(curve, sM2P256V1FieldElement7, sM2P256V1FieldElement8, zs, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
SM2P256V1FieldElement sM2P256V1FieldElement = (SM2P256V1FieldElement)base.RawYCoord;
if (sM2P256V1FieldElement.IsZero)
{
return curve.Infinity;
}
SM2P256V1FieldElement sM2P256V1FieldElement2 = (SM2P256V1FieldElement)base.RawXCoord;
SM2P256V1FieldElement sM2P256V1FieldElement3 = (SM2P256V1FieldElement)base.RawZCoords[0];
uint[] array = Nat256.Create();
uint[] array2 = Nat256.Create();
uint[] array3 = Nat256.Create();
SM2P256V1Field.Square(sM2P256V1FieldElement.x, array3);
uint[] array4 = Nat256.Create();
SM2P256V1Field.Square(array3, array4);
bool isOne = sM2P256V1FieldElement3.IsOne;
uint[] array5 = sM2P256V1FieldElement3.x;
if (!isOne)
{
array5 = array2;
SM2P256V1Field.Square(sM2P256V1FieldElement3.x, array5);
}
SM2P256V1Field.Subtract(sM2P256V1FieldElement2.x, array5, array);
uint[] array6 = array2;
SM2P256V1Field.Add(sM2P256V1FieldElement2.x, array5, array6);
SM2P256V1Field.Multiply(array6, array, array6);
uint x = Nat256.AddBothTo(array6, array6, array6);
SM2P256V1Field.Reduce32(x, array6);
uint[] array7 = array3;
SM2P256V1Field.Multiply(array3, sM2P256V1FieldElement2.x, array7);
x = Nat.ShiftUpBits(8, array7, 2, 0u);
SM2P256V1Field.Reduce32(x, array7);
x = Nat.ShiftUpBits(8, array4, 3, 0u, array);
SM2P256V1Field.Reduce32(x, array);
SM2P256V1FieldElement sM2P256V1FieldElement4 = new SM2P256V1FieldElement(array4);
SM2P256V1Field.Square(array6, sM2P256V1FieldElement4.x);
SM2P256V1Field.Subtract(sM2P256V1FieldElement4.x, array7, sM2P256V1FieldElement4.x);
SM2P256V1Field.Subtract(sM2P256V1FieldElement4.x, array7, sM2P256V1FieldElement4.x);
SM2P256V1FieldElement sM2P256V1FieldElement5 = new SM2P256V1FieldElement(array7);
SM2P256V1Field.Subtract(array7, sM2P256V1FieldElement4.x, sM2P256V1FieldElement5.x);
SM2P256V1Field.Multiply(sM2P256V1FieldElement5.x, array6, sM2P256V1FieldElement5.x);
SM2P256V1Field.Subtract(sM2P256V1FieldElement5.x, array, sM2P256V1FieldElement5.x);
SM2P256V1FieldElement sM2P256V1FieldElement6 = new SM2P256V1FieldElement(array6);
SM2P256V1Field.Twice(sM2P256V1FieldElement.x, sM2P256V1FieldElement6.x);
if (!isOne)
{
SM2P256V1Field.Multiply(sM2P256V1FieldElement6.x, sM2P256V1FieldElement3.x, sM2P256V1FieldElement6.x);
}
return new SM2P256V1Point(curve, sM2P256V1FieldElement4, sM2P256V1FieldElement5, new ECFieldElement[1] { sM2P256V1FieldElement6 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
return Twice().Add(b);
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity || base.RawYCoord.IsZero)
{
return this;
}
return Twice().Add(this);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
return new SM2P256V1Point(Curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
}

View File

@@ -0,0 +1,119 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP128R1Curve : AbstractFpCurve
{
private class SecP128R1LookupTable : ECLookupTable
{
private readonly SecP128R1Curve m_outer;
private readonly uint[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecP128R1LookupTable(SecP128R1Curve outer, uint[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
uint[] array = Nat128.Create();
uint[] array2 = Nat128.Create();
int num = 0;
for (int i = 0; i < m_size; i++)
{
uint num2 = (uint)((i ^ index) - 1 >> 31);
for (int j = 0; j < 4; j++)
{
uint[] array4;
uint[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
uint[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 4 + j] & num2);
}
num += 8;
}
return m_outer.CreateRawPoint(new SecP128R1FieldElement(array), new SecP128R1FieldElement(array2), withCompression: false);
}
}
private const int SECP128R1_DEFAULT_COORDS = 2;
private const int SECP128R1_FE_INTS = 4;
public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"));
protected readonly SecP128R1Point m_infinity;
public virtual BigInteger Q => q;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => q.BitLength;
public SecP128R1Curve()
: base(q)
{
m_infinity = new SecP128R1Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("E87579C11079F43DD824993C2CEE5ED3")));
m_order = new BigInteger(1, Hex.Decode("FFFFFFFE0000000075A30D1B9038A115"));
m_cofactor = BigInteger.One;
m_coord = 2;
}
protected override ECCurve CloneCurve()
{
return new SecP128R1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 2)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecP128R1FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecP128R1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecP128R1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
uint[] array = new uint[len * 4 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat128.Copy(((SecP128R1FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 4;
Nat128.Copy(((SecP128R1FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 4;
}
return new SecP128R1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,219 @@
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP128R1Field
{
private const uint P3 = 4294967293u;
private const uint PExt7 = 4294967292u;
internal static readonly uint[] P = new uint[4] { 4294967295u, 4294967295u, 4294967295u, 4294967293u };
internal static readonly uint[] PExt = new uint[8] { 1u, 0u, 0u, 4u, 4294967294u, 4294967295u, 3u, 4294967292u };
private static readonly uint[] PExtInv = new uint[8] { 4294967295u, 4294967295u, 4294967295u, 4294967291u, 1u, 0u, 4294967292u, 3u };
public static void Add(uint[] x, uint[] y, uint[] z)
{
if (Nat128.Add(x, y, z) != 0 || (z[3] >= 4294967293u && Nat128.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat256.Add(xx, yy, zz) != 0 || (zz[7] >= 4294967292u && Nat256.Gte(zz, PExt)))
{
Nat.AddTo(PExtInv.Length, PExtInv, zz);
}
}
public static void AddOne(uint[] x, uint[] z)
{
if (Nat.Inc(4, x, z) != 0 || (z[3] >= 4294967293u && Nat128.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static uint[] FromBigInteger(BigInteger x)
{
uint[] array = Nat128.FromBigInteger(x);
if (array[3] >= 4294967293u && Nat128.Gte(array, P))
{
Nat128.SubFrom(P, array);
}
return array;
}
public static void Half(uint[] x, uint[] z)
{
if ((x[0] & 1) == 0)
{
Nat.ShiftDownBit(4, x, 0u, z);
return;
}
uint c = Nat128.Add(x, P, z);
Nat.ShiftDownBit(4, z, c);
}
public static void Multiply(uint[] x, uint[] y, uint[] z)
{
uint[] array = Nat128.CreateExt();
Nat128.Mul(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
{
if (Nat128.MulAddTo(x, y, zz) != 0 || (zz[7] >= 4294967292u && Nat256.Gte(zz, PExt)))
{
Nat.AddTo(PExtInv.Length, PExtInv, zz);
}
}
public static void Negate(uint[] x, uint[] z)
{
if (Nat128.IsZero(x))
{
Nat128.Zero(z);
}
else
{
Nat128.Sub(P, x, z);
}
}
public static void Reduce(uint[] xx, uint[] z)
{
ulong num = xx[0];
ulong num2 = xx[1];
ulong num3 = xx[2];
ulong num4 = xx[3];
ulong num5 = xx[4];
ulong num6 = xx[5];
ulong num7 = xx[6];
ulong num8 = xx[7];
num4 += num8;
num7 += num8 << 1;
num3 += num7;
num6 += num7 << 1;
num2 += num6;
num5 += num6 << 1;
num += num5;
num4 += num5 << 1;
z[0] = (uint)num;
num2 += num >> 32;
z[1] = (uint)num2;
num3 += num2 >> 32;
z[2] = (uint)num3;
num4 += num3 >> 32;
z[3] = (uint)num4;
Reduce32((uint)(num4 >> 32), z);
}
public static void Reduce32(uint x, uint[] z)
{
while (x != 0)
{
ulong num = x;
ulong num2 = z[0] + num;
z[0] = (uint)num2;
num2 >>= 32;
if (num2 != 0)
{
num2 += z[1];
z[1] = (uint)num2;
num2 >>= 32;
num2 += z[2];
z[2] = (uint)num2;
num2 >>= 32;
}
num2 += z[3] + (num << 1);
z[3] = (uint)num2;
num2 >>= 32;
x = (uint)num2;
}
}
public static void Square(uint[] x, uint[] z)
{
uint[] array = Nat128.CreateExt();
Nat128.Square(x, array);
Reduce(array, z);
}
public static void SquareN(uint[] x, int n, uint[] z)
{
uint[] array = Nat128.CreateExt();
Nat128.Square(x, array);
Reduce(array, z);
while (--n > 0)
{
Nat128.Square(z, array);
Reduce(array, z);
}
}
public static void Subtract(uint[] x, uint[] y, uint[] z)
{
if (Nat128.Sub(x, y, z) != 0)
{
SubPInvFrom(z);
}
}
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat.Sub(10, xx, yy, zz) != 0)
{
Nat.SubFrom(PExtInv.Length, PExtInv, zz);
}
}
public static void Twice(uint[] x, uint[] z)
{
if (Nat.ShiftUpBit(4, x, 0u, z) != 0 || (z[3] >= 4294967293u && Nat128.Gte(z, P)))
{
AddPInvTo(z);
}
}
private static void AddPInvTo(uint[] z)
{
long num = (long)z[0] + 1L;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[1];
z[1] = (uint)num;
num >>= 32;
num += z[2];
z[2] = (uint)num;
num >>= 32;
}
num += (long)z[3] + 2L;
z[3] = (uint)num;
}
private static void SubPInvFrom(uint[] z)
{
long num = (long)z[0] - 1L;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[1];
z[1] = (uint)num;
num >>= 32;
num += z[2];
z[2] = (uint)num;
num >>= 32;
}
num += (long)z[3] - 2L;
z[3] = (uint)num;
}
}

View File

@@ -0,0 +1,173 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP128R1FieldElement : AbstractFpFieldElement
{
public static readonly BigInteger Q = SecP128R1Curve.q;
protected internal readonly uint[] x;
public override bool IsZero => Nat128.IsZero(x);
public override bool IsOne => Nat128.IsOne(x);
public override string FieldName => "SecP128R1Field";
public override int FieldSize => Q.BitLength;
public SecP128R1FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
{
throw new ArgumentException("value invalid for SecP128R1FieldElement", "x");
}
this.x = SecP128R1Field.FromBigInteger(x);
}
public SecP128R1FieldElement()
{
x = Nat128.Create();
}
protected internal SecP128R1FieldElement(uint[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return Nat128.GetBit(x, 0) == 1;
}
public override BigInteger ToBigInteger()
{
return Nat128.ToBigInteger(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
uint[] z = Nat128.Create();
SecP128R1Field.Add(x, ((SecP128R1FieldElement)b).x, z);
return new SecP128R1FieldElement(z);
}
public override ECFieldElement AddOne()
{
uint[] z = Nat128.Create();
SecP128R1Field.AddOne(x, z);
return new SecP128R1FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
uint[] z = Nat128.Create();
SecP128R1Field.Subtract(x, ((SecP128R1FieldElement)b).x, z);
return new SecP128R1FieldElement(z);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
uint[] z = Nat128.Create();
SecP128R1Field.Multiply(x, ((SecP128R1FieldElement)b).x, z);
return new SecP128R1FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
uint[] z = Nat128.Create();
Mod.Invert(SecP128R1Field.P, ((SecP128R1FieldElement)b).x, z);
SecP128R1Field.Multiply(z, x, z);
return new SecP128R1FieldElement(z);
}
public override ECFieldElement Negate()
{
uint[] z = Nat128.Create();
SecP128R1Field.Negate(x, z);
return new SecP128R1FieldElement(z);
}
public override ECFieldElement Square()
{
uint[] z = Nat128.Create();
SecP128R1Field.Square(x, z);
return new SecP128R1FieldElement(z);
}
public override ECFieldElement Invert()
{
uint[] z = Nat128.Create();
Mod.Invert(SecP128R1Field.P, x, z);
return new SecP128R1FieldElement(z);
}
public override ECFieldElement Sqrt()
{
uint[] y = x;
if (Nat128.IsZero(y) || Nat128.IsOne(y))
{
return this;
}
uint[] array = Nat128.Create();
SecP128R1Field.Square(y, array);
SecP128R1Field.Multiply(array, y, array);
uint[] array2 = Nat128.Create();
SecP128R1Field.SquareN(array, 2, array2);
SecP128R1Field.Multiply(array2, array, array2);
uint[] array3 = Nat128.Create();
SecP128R1Field.SquareN(array2, 4, array3);
SecP128R1Field.Multiply(array3, array2, array3);
uint[] array4 = array2;
SecP128R1Field.SquareN(array3, 2, array4);
SecP128R1Field.Multiply(array4, array, array4);
uint[] z = array;
SecP128R1Field.SquareN(array4, 10, z);
SecP128R1Field.Multiply(z, array4, z);
uint[] array5 = array3;
SecP128R1Field.SquareN(z, 10, array5);
SecP128R1Field.Multiply(array5, array4, array5);
uint[] array6 = array4;
SecP128R1Field.Square(array5, array6);
SecP128R1Field.Multiply(array6, y, array6);
uint[] z2 = array6;
SecP128R1Field.SquareN(z2, 95, z2);
uint[] array7 = array5;
SecP128R1Field.Square(z2, array7);
if (!Nat128.Eq(y, array7))
{
return null;
}
return new SecP128R1FieldElement(z2);
}
public override bool Equals(object obj)
{
return Equals(obj as SecP128R1FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecP128R1FieldElement);
}
public virtual bool Equals(SecP128R1FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat128.Eq(x, other.x);
}
public override int GetHashCode()
{
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 4);
}
}

View File

@@ -0,0 +1,228 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP128R1Point : AbstractFpPoint
{
public SecP128R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecP128R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecP128R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecP128R1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
SecP128R1FieldElement secP128R1FieldElement = (SecP128R1FieldElement)base.RawXCoord;
SecP128R1FieldElement secP128R1FieldElement2 = (SecP128R1FieldElement)base.RawYCoord;
SecP128R1FieldElement secP128R1FieldElement3 = (SecP128R1FieldElement)b.RawXCoord;
SecP128R1FieldElement secP128R1FieldElement4 = (SecP128R1FieldElement)b.RawYCoord;
SecP128R1FieldElement secP128R1FieldElement5 = (SecP128R1FieldElement)base.RawZCoords[0];
SecP128R1FieldElement secP128R1FieldElement6 = (SecP128R1FieldElement)b.RawZCoords[0];
uint[] array = Nat128.CreateExt();
uint[] array2 = Nat128.Create();
uint[] array3 = Nat128.Create();
uint[] array4 = Nat128.Create();
bool isOne = secP128R1FieldElement5.IsOne;
uint[] array5;
uint[] array6;
if (isOne)
{
array5 = secP128R1FieldElement3.x;
array6 = secP128R1FieldElement4.x;
}
else
{
array6 = array3;
SecP128R1Field.Square(secP128R1FieldElement5.x, array6);
array5 = array2;
SecP128R1Field.Multiply(array6, secP128R1FieldElement3.x, array5);
SecP128R1Field.Multiply(array6, secP128R1FieldElement5.x, array6);
SecP128R1Field.Multiply(array6, secP128R1FieldElement4.x, array6);
}
bool isOne2 = secP128R1FieldElement6.IsOne;
uint[] array7;
uint[] array8;
if (isOne2)
{
array7 = secP128R1FieldElement.x;
array8 = secP128R1FieldElement2.x;
}
else
{
array8 = array4;
SecP128R1Field.Square(secP128R1FieldElement6.x, array8);
array7 = array;
SecP128R1Field.Multiply(array8, secP128R1FieldElement.x, array7);
SecP128R1Field.Multiply(array8, secP128R1FieldElement6.x, array8);
SecP128R1Field.Multiply(array8, secP128R1FieldElement2.x, array8);
}
uint[] array9 = Nat128.Create();
SecP128R1Field.Subtract(array7, array5, array9);
uint[] array10 = array2;
SecP128R1Field.Subtract(array8, array6, array10);
if (Nat128.IsZero(array9))
{
if (Nat128.IsZero(array10))
{
return Twice();
}
return curve.Infinity;
}
uint[] array11 = array3;
SecP128R1Field.Square(array9, array11);
uint[] array12 = Nat128.Create();
SecP128R1Field.Multiply(array11, array9, array12);
uint[] array13 = array3;
SecP128R1Field.Multiply(array11, array7, array13);
SecP128R1Field.Negate(array12, array12);
Nat128.Mul(array8, array12, array);
uint x = Nat128.AddBothTo(array13, array13, array12);
SecP128R1Field.Reduce32(x, array12);
SecP128R1FieldElement secP128R1FieldElement7 = new SecP128R1FieldElement(array4);
SecP128R1Field.Square(array10, secP128R1FieldElement7.x);
SecP128R1Field.Subtract(secP128R1FieldElement7.x, array12, secP128R1FieldElement7.x);
SecP128R1FieldElement secP128R1FieldElement8 = new SecP128R1FieldElement(array12);
SecP128R1Field.Subtract(array13, secP128R1FieldElement7.x, secP128R1FieldElement8.x);
SecP128R1Field.MultiplyAddToExt(secP128R1FieldElement8.x, array10, array);
SecP128R1Field.Reduce(array, secP128R1FieldElement8.x);
SecP128R1FieldElement secP128R1FieldElement9 = new SecP128R1FieldElement(array9);
if (!isOne)
{
SecP128R1Field.Multiply(secP128R1FieldElement9.x, secP128R1FieldElement5.x, secP128R1FieldElement9.x);
}
if (!isOne2)
{
SecP128R1Field.Multiply(secP128R1FieldElement9.x, secP128R1FieldElement6.x, secP128R1FieldElement9.x);
}
ECFieldElement[] zs = new ECFieldElement[1] { secP128R1FieldElement9 };
return new SecP128R1Point(curve, secP128R1FieldElement7, secP128R1FieldElement8, zs, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
SecP128R1FieldElement secP128R1FieldElement = (SecP128R1FieldElement)base.RawYCoord;
if (secP128R1FieldElement.IsZero)
{
return curve.Infinity;
}
SecP128R1FieldElement secP128R1FieldElement2 = (SecP128R1FieldElement)base.RawXCoord;
SecP128R1FieldElement secP128R1FieldElement3 = (SecP128R1FieldElement)base.RawZCoords[0];
uint[] array = Nat128.Create();
uint[] array2 = Nat128.Create();
uint[] array3 = Nat128.Create();
SecP128R1Field.Square(secP128R1FieldElement.x, array3);
uint[] array4 = Nat128.Create();
SecP128R1Field.Square(array3, array4);
bool isOne = secP128R1FieldElement3.IsOne;
uint[] array5 = secP128R1FieldElement3.x;
if (!isOne)
{
array5 = array2;
SecP128R1Field.Square(secP128R1FieldElement3.x, array5);
}
SecP128R1Field.Subtract(secP128R1FieldElement2.x, array5, array);
uint[] array6 = array2;
SecP128R1Field.Add(secP128R1FieldElement2.x, array5, array6);
SecP128R1Field.Multiply(array6, array, array6);
uint x = Nat128.AddBothTo(array6, array6, array6);
SecP128R1Field.Reduce32(x, array6);
uint[] array7 = array3;
SecP128R1Field.Multiply(array3, secP128R1FieldElement2.x, array7);
x = Nat.ShiftUpBits(4, array7, 2, 0u);
SecP128R1Field.Reduce32(x, array7);
x = Nat.ShiftUpBits(4, array4, 3, 0u, array);
SecP128R1Field.Reduce32(x, array);
SecP128R1FieldElement secP128R1FieldElement4 = new SecP128R1FieldElement(array4);
SecP128R1Field.Square(array6, secP128R1FieldElement4.x);
SecP128R1Field.Subtract(secP128R1FieldElement4.x, array7, secP128R1FieldElement4.x);
SecP128R1Field.Subtract(secP128R1FieldElement4.x, array7, secP128R1FieldElement4.x);
SecP128R1FieldElement secP128R1FieldElement5 = new SecP128R1FieldElement(array7);
SecP128R1Field.Subtract(array7, secP128R1FieldElement4.x, secP128R1FieldElement5.x);
SecP128R1Field.Multiply(secP128R1FieldElement5.x, array6, secP128R1FieldElement5.x);
SecP128R1Field.Subtract(secP128R1FieldElement5.x, array, secP128R1FieldElement5.x);
SecP128R1FieldElement secP128R1FieldElement6 = new SecP128R1FieldElement(array6);
SecP128R1Field.Twice(secP128R1FieldElement.x, secP128R1FieldElement6.x);
if (!isOne)
{
SecP128R1Field.Multiply(secP128R1FieldElement6.x, secP128R1FieldElement3.x, secP128R1FieldElement6.x);
}
return new SecP128R1Point(curve, secP128R1FieldElement4, secP128R1FieldElement5, new ECFieldElement[1] { secP128R1FieldElement6 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
return Twice().Add(b);
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity || base.RawYCoord.IsZero)
{
return this;
}
return Twice().Add(this);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
return new SecP128R1Point(Curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
}

View File

@@ -0,0 +1,119 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP160K1Curve : AbstractFpCurve
{
private class SecP160K1LookupTable : ECLookupTable
{
private readonly SecP160K1Curve m_outer;
private readonly uint[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecP160K1LookupTable(SecP160K1Curve outer, uint[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
uint[] array = Nat256.Create();
uint[] array2 = Nat256.Create();
int num = 0;
for (int i = 0; i < m_size; i++)
{
uint num2 = (uint)((i ^ index) - 1 >> 31);
for (int j = 0; j < 5; j++)
{
uint[] array4;
uint[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
uint[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 5 + j] & num2);
}
num += 10;
}
return m_outer.CreateRawPoint(new SecP160R2FieldElement(array), new SecP160R2FieldElement(array2), withCompression: false);
}
}
private const int SECP160K1_DEFAULT_COORDS = 2;
private const int SECP160K1_FE_INTS = 5;
public static readonly BigInteger q = SecP160R2Curve.q;
protected readonly SecP160K1Point m_infinity;
public virtual BigInteger Q => q;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => q.BitLength;
public SecP160K1Curve()
: base(q)
{
m_infinity = new SecP160K1Point(this, null, null);
m_a = FromBigInteger(BigInteger.Zero);
m_b = FromBigInteger(BigInteger.ValueOf(7L));
m_order = new BigInteger(1, Hex.Decode("0100000000000000000001B8FA16DFAB9ACA16B6B3"));
m_cofactor = BigInteger.One;
m_coord = 2;
}
protected override ECCurve CloneCurve()
{
return new SecP160K1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 2)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecP160R2FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecP160K1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecP160K1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
uint[] array = new uint[len * 5 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat160.Copy(((SecP160R2FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 5;
Nat160.Copy(((SecP160R2FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 5;
}
return new SecP160K1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,218 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP160K1Point : AbstractFpPoint
{
public SecP160K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecP160K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecP160K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecP160K1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
SecP160R2FieldElement secP160R2FieldElement = (SecP160R2FieldElement)base.RawXCoord;
SecP160R2FieldElement secP160R2FieldElement2 = (SecP160R2FieldElement)base.RawYCoord;
SecP160R2FieldElement secP160R2FieldElement3 = (SecP160R2FieldElement)b.RawXCoord;
SecP160R2FieldElement secP160R2FieldElement4 = (SecP160R2FieldElement)b.RawYCoord;
SecP160R2FieldElement secP160R2FieldElement5 = (SecP160R2FieldElement)base.RawZCoords[0];
SecP160R2FieldElement secP160R2FieldElement6 = (SecP160R2FieldElement)b.RawZCoords[0];
uint[] array = Nat160.CreateExt();
uint[] array2 = Nat160.Create();
uint[] array3 = Nat160.Create();
uint[] array4 = Nat160.Create();
bool isOne = secP160R2FieldElement5.IsOne;
uint[] array5;
uint[] array6;
if (isOne)
{
array5 = secP160R2FieldElement3.x;
array6 = secP160R2FieldElement4.x;
}
else
{
array6 = array3;
SecP160R2Field.Square(secP160R2FieldElement5.x, array6);
array5 = array2;
SecP160R2Field.Multiply(array6, secP160R2FieldElement3.x, array5);
SecP160R2Field.Multiply(array6, secP160R2FieldElement5.x, array6);
SecP160R2Field.Multiply(array6, secP160R2FieldElement4.x, array6);
}
bool isOne2 = secP160R2FieldElement6.IsOne;
uint[] array7;
uint[] array8;
if (isOne2)
{
array7 = secP160R2FieldElement.x;
array8 = secP160R2FieldElement2.x;
}
else
{
array8 = array4;
SecP160R2Field.Square(secP160R2FieldElement6.x, array8);
array7 = array;
SecP160R2Field.Multiply(array8, secP160R2FieldElement.x, array7);
SecP160R2Field.Multiply(array8, secP160R2FieldElement6.x, array8);
SecP160R2Field.Multiply(array8, secP160R2FieldElement2.x, array8);
}
uint[] array9 = Nat160.Create();
SecP160R2Field.Subtract(array7, array5, array9);
uint[] array10 = array2;
SecP160R2Field.Subtract(array8, array6, array10);
if (Nat160.IsZero(array9))
{
if (Nat160.IsZero(array10))
{
return Twice();
}
return curve.Infinity;
}
uint[] array11 = array3;
SecP160R2Field.Square(array9, array11);
uint[] array12 = Nat160.Create();
SecP160R2Field.Multiply(array11, array9, array12);
uint[] array13 = array3;
SecP160R2Field.Multiply(array11, array7, array13);
SecP160R2Field.Negate(array12, array12);
Nat160.Mul(array8, array12, array);
uint x = Nat160.AddBothTo(array13, array13, array12);
SecP160R2Field.Reduce32(x, array12);
SecP160R2FieldElement secP160R2FieldElement7 = new SecP160R2FieldElement(array4);
SecP160R2Field.Square(array10, secP160R2FieldElement7.x);
SecP160R2Field.Subtract(secP160R2FieldElement7.x, array12, secP160R2FieldElement7.x);
SecP160R2FieldElement secP160R2FieldElement8 = new SecP160R2FieldElement(array12);
SecP160R2Field.Subtract(array13, secP160R2FieldElement7.x, secP160R2FieldElement8.x);
SecP160R2Field.MultiplyAddToExt(secP160R2FieldElement8.x, array10, array);
SecP160R2Field.Reduce(array, secP160R2FieldElement8.x);
SecP160R2FieldElement secP160R2FieldElement9 = new SecP160R2FieldElement(array9);
if (!isOne)
{
SecP160R2Field.Multiply(secP160R2FieldElement9.x, secP160R2FieldElement5.x, secP160R2FieldElement9.x);
}
if (!isOne2)
{
SecP160R2Field.Multiply(secP160R2FieldElement9.x, secP160R2FieldElement6.x, secP160R2FieldElement9.x);
}
ECFieldElement[] zs = new ECFieldElement[1] { secP160R2FieldElement9 };
return new SecP160K1Point(curve, secP160R2FieldElement7, secP160R2FieldElement8, zs, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
SecP160R2FieldElement secP160R2FieldElement = (SecP160R2FieldElement)base.RawYCoord;
if (secP160R2FieldElement.IsZero)
{
return curve.Infinity;
}
SecP160R2FieldElement secP160R2FieldElement2 = (SecP160R2FieldElement)base.RawXCoord;
SecP160R2FieldElement secP160R2FieldElement3 = (SecP160R2FieldElement)base.RawZCoords[0];
uint[] array = Nat160.Create();
SecP160R2Field.Square(secP160R2FieldElement.x, array);
uint[] array2 = Nat160.Create();
SecP160R2Field.Square(array, array2);
uint[] array3 = Nat160.Create();
SecP160R2Field.Square(secP160R2FieldElement2.x, array3);
uint x = Nat160.AddBothTo(array3, array3, array3);
SecP160R2Field.Reduce32(x, array3);
uint[] array4 = array;
SecP160R2Field.Multiply(array, secP160R2FieldElement2.x, array4);
x = Nat.ShiftUpBits(5, array4, 2, 0u);
SecP160R2Field.Reduce32(x, array4);
uint[] array5 = Nat160.Create();
x = Nat.ShiftUpBits(5, array2, 3, 0u, array5);
SecP160R2Field.Reduce32(x, array5);
SecP160R2FieldElement secP160R2FieldElement4 = new SecP160R2FieldElement(array2);
SecP160R2Field.Square(array3, secP160R2FieldElement4.x);
SecP160R2Field.Subtract(secP160R2FieldElement4.x, array4, secP160R2FieldElement4.x);
SecP160R2Field.Subtract(secP160R2FieldElement4.x, array4, secP160R2FieldElement4.x);
SecP160R2FieldElement secP160R2FieldElement5 = new SecP160R2FieldElement(array4);
SecP160R2Field.Subtract(array4, secP160R2FieldElement4.x, secP160R2FieldElement5.x);
SecP160R2Field.Multiply(secP160R2FieldElement5.x, array3, secP160R2FieldElement5.x);
SecP160R2Field.Subtract(secP160R2FieldElement5.x, array5, secP160R2FieldElement5.x);
SecP160R2FieldElement secP160R2FieldElement6 = new SecP160R2FieldElement(array3);
SecP160R2Field.Twice(secP160R2FieldElement.x, secP160R2FieldElement6.x);
if (!secP160R2FieldElement3.IsOne)
{
SecP160R2Field.Multiply(secP160R2FieldElement6.x, secP160R2FieldElement3.x, secP160R2FieldElement6.x);
}
return new SecP160K1Point(curve, secP160R2FieldElement4, secP160R2FieldElement5, new ECFieldElement[1] { secP160R2FieldElement6 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
return Twice().Add(b);
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity || base.RawYCoord.IsZero)
{
return this;
}
return Twice().Add(this);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
return new SecP160K1Point(Curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
}

View File

@@ -0,0 +1,119 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP160R1Curve : AbstractFpCurve
{
private class SecP160R1LookupTable : ECLookupTable
{
private readonly SecP160R1Curve m_outer;
private readonly uint[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecP160R1LookupTable(SecP160R1Curve outer, uint[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
uint[] array = Nat160.Create();
uint[] array2 = Nat160.Create();
int num = 0;
for (int i = 0; i < m_size; i++)
{
uint num2 = (uint)((i ^ index) - 1 >> 31);
for (int j = 0; j < 5; j++)
{
uint[] array4;
uint[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
uint[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 5 + j] & num2);
}
num += 10;
}
return m_outer.CreateRawPoint(new SecP160R1FieldElement(array), new SecP160R1FieldElement(array2), withCompression: false);
}
}
private const int SECP160R1_DEFAULT_COORDS = 2;
private const int SECP160R1_FE_INTS = 5;
public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"));
protected readonly SecP160R1Point m_infinity;
public virtual BigInteger Q => q;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => q.BitLength;
public SecP160R1Curve()
: base(q)
{
m_infinity = new SecP160R1Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")));
m_order = new BigInteger(1, Hex.Decode("0100000000000000000001F4C8F927AED3CA752257"));
m_cofactor = BigInteger.One;
m_coord = 2;
}
protected override ECCurve CloneCurve()
{
return new SecP160R1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 2)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecP160R1FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecP160R1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecP160R1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
uint[] array = new uint[len * 5 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat160.Copy(((SecP160R1FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 5;
Nat160.Copy(((SecP160R1FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 5;
}
return new SecP160R1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,167 @@
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP160R1Field
{
private const uint P4 = uint.MaxValue;
private const uint PExt9 = uint.MaxValue;
private const uint PInv = 2147483649u;
internal static readonly uint[] P = new uint[5] { 2147483647u, 4294967295u, 4294967295u, 4294967295u, 4294967295u };
internal static readonly uint[] PExt = new uint[10] { 1u, 1073741825u, 0u, 0u, 0u, 4294967294u, 4294967294u, 4294967295u, 4294967295u, 4294967295u };
private static readonly uint[] PExtInv = new uint[7] { 4294967295u, 3221225470u, 4294967295u, 4294967295u, 4294967295u, 1u, 1u };
public static void Add(uint[] x, uint[] y, uint[] z)
{
if (Nat160.Add(x, y, z) != 0 || (z[4] == uint.MaxValue && Nat160.Gte(z, P)))
{
Nat.AddWordTo(5, 2147483649u, z);
}
}
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
{
if ((Nat.Add(10, xx, yy, zz) != 0 || (zz[9] == uint.MaxValue && Nat.Gte(10, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(10, zz, PExtInv.Length);
}
}
public static void AddOne(uint[] x, uint[] z)
{
if (Nat.Inc(5, x, z) != 0 || (z[4] == uint.MaxValue && Nat160.Gte(z, P)))
{
Nat.AddWordTo(5, 2147483649u, z);
}
}
public static uint[] FromBigInteger(BigInteger x)
{
uint[] array = Nat160.FromBigInteger(x);
if (array[4] == uint.MaxValue && Nat160.Gte(array, P))
{
Nat160.SubFrom(P, array);
}
return array;
}
public static void Half(uint[] x, uint[] z)
{
if ((x[0] & 1) == 0)
{
Nat.ShiftDownBit(5, x, 0u, z);
return;
}
uint c = Nat160.Add(x, P, z);
Nat.ShiftDownBit(5, z, c);
}
public static void Multiply(uint[] x, uint[] y, uint[] z)
{
uint[] array = Nat160.CreateExt();
Nat160.Mul(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
{
if ((Nat160.MulAddTo(x, y, zz) != 0 || (zz[9] == uint.MaxValue && Nat.Gte(10, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(10, zz, PExtInv.Length);
}
}
public static void Negate(uint[] x, uint[] z)
{
if (Nat160.IsZero(x))
{
Nat160.Zero(z);
}
else
{
Nat160.Sub(P, x, z);
}
}
public static void Reduce(uint[] xx, uint[] z)
{
ulong num = xx[5];
ulong num2 = xx[6];
ulong num3 = xx[7];
ulong num4 = xx[8];
ulong num5 = xx[9];
ulong num6 = 0uL;
num6 += xx[0] + num + (num << 31);
z[0] = (uint)num6;
num6 >>= 32;
num6 += xx[1] + num2 + (num2 << 31);
z[1] = (uint)num6;
num6 >>= 32;
num6 += xx[2] + num3 + (num3 << 31);
z[2] = (uint)num6;
num6 >>= 32;
num6 += xx[3] + num4 + (num4 << 31);
z[3] = (uint)num6;
num6 >>= 32;
num6 += xx[4] + num5 + (num5 << 31);
z[4] = (uint)num6;
num6 >>= 32;
Reduce32((uint)num6, z);
}
public static void Reduce32(uint x, uint[] z)
{
if ((x != 0 && Nat160.MulWordsAdd(2147483649u, x, z, 0) != 0) || (z[4] == uint.MaxValue && Nat160.Gte(z, P)))
{
Nat.AddWordTo(5, 2147483649u, z);
}
}
public static void Square(uint[] x, uint[] z)
{
uint[] array = Nat160.CreateExt();
Nat160.Square(x, array);
Reduce(array, z);
}
public static void SquareN(uint[] x, int n, uint[] z)
{
uint[] array = Nat160.CreateExt();
Nat160.Square(x, array);
Reduce(array, z);
while (--n > 0)
{
Nat160.Square(z, array);
Reduce(array, z);
}
}
public static void Subtract(uint[] x, uint[] y, uint[] z)
{
if (Nat160.Sub(x, y, z) != 0)
{
Nat.SubWordFrom(5, 2147483649u, z);
}
}
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat.Sub(10, xx, yy, zz) != 0 && Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.DecAt(10, zz, PExtInv.Length);
}
}
public static void Twice(uint[] x, uint[] z)
{
if (Nat.ShiftUpBit(5, x, 0u, z) != 0 || (z[4] == uint.MaxValue && Nat160.Gte(z, P)))
{
Nat.AddWordTo(5, 2147483649u, z);
}
}
}

View File

@@ -0,0 +1,176 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP160R1FieldElement : AbstractFpFieldElement
{
public static readonly BigInteger Q = SecP160R1Curve.q;
protected internal readonly uint[] x;
public override bool IsZero => Nat160.IsZero(x);
public override bool IsOne => Nat160.IsOne(x);
public override string FieldName => "SecP160R1Field";
public override int FieldSize => Q.BitLength;
public SecP160R1FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
{
throw new ArgumentException("value invalid for SecP160R1FieldElement", "x");
}
this.x = SecP160R1Field.FromBigInteger(x);
}
public SecP160R1FieldElement()
{
x = Nat160.Create();
}
protected internal SecP160R1FieldElement(uint[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return Nat160.GetBit(x, 0) == 1;
}
public override BigInteger ToBigInteger()
{
return Nat160.ToBigInteger(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
uint[] z = Nat160.Create();
SecP160R1Field.Add(x, ((SecP160R1FieldElement)b).x, z);
return new SecP160R1FieldElement(z);
}
public override ECFieldElement AddOne()
{
uint[] z = Nat160.Create();
SecP160R1Field.AddOne(x, z);
return new SecP160R1FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
uint[] z = Nat160.Create();
SecP160R1Field.Subtract(x, ((SecP160R1FieldElement)b).x, z);
return new SecP160R1FieldElement(z);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
uint[] z = Nat160.Create();
SecP160R1Field.Multiply(x, ((SecP160R1FieldElement)b).x, z);
return new SecP160R1FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
uint[] z = Nat160.Create();
Mod.Invert(SecP160R1Field.P, ((SecP160R1FieldElement)b).x, z);
SecP160R1Field.Multiply(z, x, z);
return new SecP160R1FieldElement(z);
}
public override ECFieldElement Negate()
{
uint[] z = Nat160.Create();
SecP160R1Field.Negate(x, z);
return new SecP160R1FieldElement(z);
}
public override ECFieldElement Square()
{
uint[] z = Nat160.Create();
SecP160R1Field.Square(x, z);
return new SecP160R1FieldElement(z);
}
public override ECFieldElement Invert()
{
uint[] z = Nat160.Create();
Mod.Invert(SecP160R1Field.P, x, z);
return new SecP160R1FieldElement(z);
}
public override ECFieldElement Sqrt()
{
uint[] y = x;
if (Nat160.IsZero(y) || Nat160.IsOne(y))
{
return this;
}
uint[] array = Nat160.Create();
SecP160R1Field.Square(y, array);
SecP160R1Field.Multiply(array, y, array);
uint[] array2 = Nat160.Create();
SecP160R1Field.SquareN(array, 2, array2);
SecP160R1Field.Multiply(array2, array, array2);
uint[] array3 = array;
SecP160R1Field.SquareN(array2, 4, array3);
SecP160R1Field.Multiply(array3, array2, array3);
uint[] array4 = array2;
SecP160R1Field.SquareN(array3, 8, array4);
SecP160R1Field.Multiply(array4, array3, array4);
uint[] array5 = array3;
SecP160R1Field.SquareN(array4, 16, array5);
SecP160R1Field.Multiply(array5, array4, array5);
uint[] array6 = array4;
SecP160R1Field.SquareN(array5, 32, array6);
SecP160R1Field.Multiply(array6, array5, array6);
uint[] array7 = array5;
SecP160R1Field.SquareN(array6, 64, array7);
SecP160R1Field.Multiply(array7, array6, array7);
uint[] array8 = array6;
SecP160R1Field.Square(array7, array8);
SecP160R1Field.Multiply(array8, y, array8);
uint[] z = array8;
SecP160R1Field.SquareN(z, 29, z);
uint[] array9 = array7;
SecP160R1Field.Square(z, array9);
if (!Nat160.Eq(y, array9))
{
return null;
}
return new SecP160R1FieldElement(z);
}
public override bool Equals(object obj)
{
return Equals(obj as SecP160R1FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecP160R1FieldElement);
}
public virtual bool Equals(SecP160R1FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat160.Eq(x, other.x);
}
public override int GetHashCode()
{
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 5);
}
}

View File

@@ -0,0 +1,228 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP160R1Point : AbstractFpPoint
{
public SecP160R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecP160R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecP160R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecP160R1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
SecP160R1FieldElement secP160R1FieldElement = (SecP160R1FieldElement)base.RawXCoord;
SecP160R1FieldElement secP160R1FieldElement2 = (SecP160R1FieldElement)base.RawYCoord;
SecP160R1FieldElement secP160R1FieldElement3 = (SecP160R1FieldElement)b.RawXCoord;
SecP160R1FieldElement secP160R1FieldElement4 = (SecP160R1FieldElement)b.RawYCoord;
SecP160R1FieldElement secP160R1FieldElement5 = (SecP160R1FieldElement)base.RawZCoords[0];
SecP160R1FieldElement secP160R1FieldElement6 = (SecP160R1FieldElement)b.RawZCoords[0];
uint[] array = Nat160.CreateExt();
uint[] array2 = Nat160.Create();
uint[] array3 = Nat160.Create();
uint[] array4 = Nat160.Create();
bool isOne = secP160R1FieldElement5.IsOne;
uint[] array5;
uint[] array6;
if (isOne)
{
array5 = secP160R1FieldElement3.x;
array6 = secP160R1FieldElement4.x;
}
else
{
array6 = array3;
SecP160R1Field.Square(secP160R1FieldElement5.x, array6);
array5 = array2;
SecP160R1Field.Multiply(array6, secP160R1FieldElement3.x, array5);
SecP160R1Field.Multiply(array6, secP160R1FieldElement5.x, array6);
SecP160R1Field.Multiply(array6, secP160R1FieldElement4.x, array6);
}
bool isOne2 = secP160R1FieldElement6.IsOne;
uint[] array7;
uint[] array8;
if (isOne2)
{
array7 = secP160R1FieldElement.x;
array8 = secP160R1FieldElement2.x;
}
else
{
array8 = array4;
SecP160R1Field.Square(secP160R1FieldElement6.x, array8);
array7 = array;
SecP160R1Field.Multiply(array8, secP160R1FieldElement.x, array7);
SecP160R1Field.Multiply(array8, secP160R1FieldElement6.x, array8);
SecP160R1Field.Multiply(array8, secP160R1FieldElement2.x, array8);
}
uint[] array9 = Nat160.Create();
SecP160R1Field.Subtract(array7, array5, array9);
uint[] array10 = array2;
SecP160R1Field.Subtract(array8, array6, array10);
if (Nat160.IsZero(array9))
{
if (Nat160.IsZero(array10))
{
return Twice();
}
return curve.Infinity;
}
uint[] array11 = array3;
SecP160R1Field.Square(array9, array11);
uint[] array12 = Nat160.Create();
SecP160R1Field.Multiply(array11, array9, array12);
uint[] array13 = array3;
SecP160R1Field.Multiply(array11, array7, array13);
SecP160R1Field.Negate(array12, array12);
Nat160.Mul(array8, array12, array);
uint x = Nat160.AddBothTo(array13, array13, array12);
SecP160R1Field.Reduce32(x, array12);
SecP160R1FieldElement secP160R1FieldElement7 = new SecP160R1FieldElement(array4);
SecP160R1Field.Square(array10, secP160R1FieldElement7.x);
SecP160R1Field.Subtract(secP160R1FieldElement7.x, array12, secP160R1FieldElement7.x);
SecP160R1FieldElement secP160R1FieldElement8 = new SecP160R1FieldElement(array12);
SecP160R1Field.Subtract(array13, secP160R1FieldElement7.x, secP160R1FieldElement8.x);
SecP160R1Field.MultiplyAddToExt(secP160R1FieldElement8.x, array10, array);
SecP160R1Field.Reduce(array, secP160R1FieldElement8.x);
SecP160R1FieldElement secP160R1FieldElement9 = new SecP160R1FieldElement(array9);
if (!isOne)
{
SecP160R1Field.Multiply(secP160R1FieldElement9.x, secP160R1FieldElement5.x, secP160R1FieldElement9.x);
}
if (!isOne2)
{
SecP160R1Field.Multiply(secP160R1FieldElement9.x, secP160R1FieldElement6.x, secP160R1FieldElement9.x);
}
ECFieldElement[] zs = new ECFieldElement[1] { secP160R1FieldElement9 };
return new SecP160R1Point(curve, secP160R1FieldElement7, secP160R1FieldElement8, zs, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
SecP160R1FieldElement secP160R1FieldElement = (SecP160R1FieldElement)base.RawYCoord;
if (secP160R1FieldElement.IsZero)
{
return curve.Infinity;
}
SecP160R1FieldElement secP160R1FieldElement2 = (SecP160R1FieldElement)base.RawXCoord;
SecP160R1FieldElement secP160R1FieldElement3 = (SecP160R1FieldElement)base.RawZCoords[0];
uint[] array = Nat160.Create();
uint[] array2 = Nat160.Create();
uint[] array3 = Nat160.Create();
SecP160R1Field.Square(secP160R1FieldElement.x, array3);
uint[] array4 = Nat160.Create();
SecP160R1Field.Square(array3, array4);
bool isOne = secP160R1FieldElement3.IsOne;
uint[] array5 = secP160R1FieldElement3.x;
if (!isOne)
{
array5 = array2;
SecP160R1Field.Square(secP160R1FieldElement3.x, array5);
}
SecP160R1Field.Subtract(secP160R1FieldElement2.x, array5, array);
uint[] array6 = array2;
SecP160R1Field.Add(secP160R1FieldElement2.x, array5, array6);
SecP160R1Field.Multiply(array6, array, array6);
uint x = Nat160.AddBothTo(array6, array6, array6);
SecP160R1Field.Reduce32(x, array6);
uint[] array7 = array3;
SecP160R1Field.Multiply(array3, secP160R1FieldElement2.x, array7);
x = Nat.ShiftUpBits(5, array7, 2, 0u);
SecP160R1Field.Reduce32(x, array7);
x = Nat.ShiftUpBits(5, array4, 3, 0u, array);
SecP160R1Field.Reduce32(x, array);
SecP160R1FieldElement secP160R1FieldElement4 = new SecP160R1FieldElement(array4);
SecP160R1Field.Square(array6, secP160R1FieldElement4.x);
SecP160R1Field.Subtract(secP160R1FieldElement4.x, array7, secP160R1FieldElement4.x);
SecP160R1Field.Subtract(secP160R1FieldElement4.x, array7, secP160R1FieldElement4.x);
SecP160R1FieldElement secP160R1FieldElement5 = new SecP160R1FieldElement(array7);
SecP160R1Field.Subtract(array7, secP160R1FieldElement4.x, secP160R1FieldElement5.x);
SecP160R1Field.Multiply(secP160R1FieldElement5.x, array6, secP160R1FieldElement5.x);
SecP160R1Field.Subtract(secP160R1FieldElement5.x, array, secP160R1FieldElement5.x);
SecP160R1FieldElement secP160R1FieldElement6 = new SecP160R1FieldElement(array6);
SecP160R1Field.Twice(secP160R1FieldElement.x, secP160R1FieldElement6.x);
if (!isOne)
{
SecP160R1Field.Multiply(secP160R1FieldElement6.x, secP160R1FieldElement3.x, secP160R1FieldElement6.x);
}
return new SecP160R1Point(curve, secP160R1FieldElement4, secP160R1FieldElement5, new ECFieldElement[1] { secP160R1FieldElement6 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
return Twice().Add(b);
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity || base.RawYCoord.IsZero)
{
return this;
}
return Twice().Add(this);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
return new SecP160R1Point(Curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
}

View File

@@ -0,0 +1,119 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP160R2Curve : AbstractFpCurve
{
private class SecP160R2LookupTable : ECLookupTable
{
private readonly SecP160R2Curve m_outer;
private readonly uint[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecP160R2LookupTable(SecP160R2Curve outer, uint[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
uint[] array = Nat160.Create();
uint[] array2 = Nat160.Create();
int num = 0;
for (int i = 0; i < m_size; i++)
{
uint num2 = (uint)((i ^ index) - 1 >> 31);
for (int j = 0; j < 5; j++)
{
uint[] array4;
uint[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
uint[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 5 + j] & num2);
}
num += 10;
}
return m_outer.CreateRawPoint(new SecP160R2FieldElement(array), new SecP160R2FieldElement(array2), withCompression: false);
}
}
private const int SECP160R2_DEFAULT_COORDS = 2;
private const int SECP160R2_FE_INTS = 5;
public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"));
protected readonly SecP160R2Point m_infinity;
public virtual BigInteger Q => q;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => q.BitLength;
public SecP160R2Curve()
: base(q)
{
m_infinity = new SecP160R2Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("B4E134D3FB59EB8BAB57274904664D5AF50388BA")));
m_order = new BigInteger(1, Hex.Decode("0100000000000000000000351EE786A818F3A1A16B"));
m_cofactor = BigInteger.One;
m_coord = 2;
}
protected override ECCurve CloneCurve()
{
return new SecP160R2Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 2)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecP160R2FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecP160R2Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecP160R2Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
uint[] array = new uint[len * 5 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat160.Copy(((SecP160R2FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 5;
Nat160.Copy(((SecP160R2FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 5;
}
return new SecP160R2LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,150 @@
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP160R2Field
{
private const uint P4 = uint.MaxValue;
private const uint PExt9 = uint.MaxValue;
private const uint PInv33 = 21389u;
internal static readonly uint[] P = new uint[5] { 4294945907u, 4294967294u, 4294967295u, 4294967295u, 4294967295u };
internal static readonly uint[] PExt = new uint[10] { 457489321u, 42778u, 1u, 0u, 0u, 4294924518u, 4294967293u, 4294967295u, 4294967295u, 4294967295u };
private static readonly uint[] PExtInv = new uint[7] { 3837477975u, 4294924517u, 4294967294u, 4294967295u, 4294967295u, 42777u, 2u };
public static void Add(uint[] x, uint[] y, uint[] z)
{
if (Nat160.Add(x, y, z) != 0 || (z[4] == uint.MaxValue && Nat160.Gte(z, P)))
{
Nat.Add33To(5, 21389u, z);
}
}
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
{
if ((Nat.Add(10, xx, yy, zz) != 0 || (zz[9] == uint.MaxValue && Nat.Gte(10, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(10, zz, PExtInv.Length);
}
}
public static void AddOne(uint[] x, uint[] z)
{
if (Nat.Inc(5, x, z) != 0 || (z[4] == uint.MaxValue && Nat160.Gte(z, P)))
{
Nat.Add33To(5, 21389u, z);
}
}
public static uint[] FromBigInteger(BigInteger x)
{
uint[] array = Nat160.FromBigInteger(x);
if (array[4] == uint.MaxValue && Nat160.Gte(array, P))
{
Nat160.SubFrom(P, array);
}
return array;
}
public static void Half(uint[] x, uint[] z)
{
if ((x[0] & 1) == 0)
{
Nat.ShiftDownBit(5, x, 0u, z);
return;
}
uint c = Nat160.Add(x, P, z);
Nat.ShiftDownBit(5, z, c);
}
public static void Multiply(uint[] x, uint[] y, uint[] z)
{
uint[] array = Nat160.CreateExt();
Nat160.Mul(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
{
if ((Nat160.MulAddTo(x, y, zz) != 0 || (zz[9] == uint.MaxValue && Nat.Gte(10, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(10, zz, PExtInv.Length);
}
}
public static void Negate(uint[] x, uint[] z)
{
if (Nat160.IsZero(x))
{
Nat160.Zero(z);
}
else
{
Nat160.Sub(P, x, z);
}
}
public static void Reduce(uint[] xx, uint[] z)
{
ulong y = Nat160.Mul33Add(21389u, xx, 5, xx, 0, z, 0);
if (Nat160.Mul33DWordAdd(21389u, y, z, 0) != 0 || (z[4] == uint.MaxValue && Nat160.Gte(z, P)))
{
Nat.Add33To(5, 21389u, z);
}
}
public static void Reduce32(uint x, uint[] z)
{
if ((x != 0 && Nat160.Mul33WordAdd(21389u, x, z, 0) != 0) || (z[4] == uint.MaxValue && Nat160.Gte(z, P)))
{
Nat.Add33To(5, 21389u, z);
}
}
public static void Square(uint[] x, uint[] z)
{
uint[] array = Nat160.CreateExt();
Nat160.Square(x, array);
Reduce(array, z);
}
public static void SquareN(uint[] x, int n, uint[] z)
{
uint[] array = Nat160.CreateExt();
Nat160.Square(x, array);
Reduce(array, z);
while (--n > 0)
{
Nat160.Square(z, array);
Reduce(array, z);
}
}
public static void Subtract(uint[] x, uint[] y, uint[] z)
{
if (Nat160.Sub(x, y, z) != 0)
{
Nat.Sub33From(5, 21389u, z);
}
}
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat.Sub(10, xx, yy, zz) != 0 && Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.DecAt(10, zz, PExtInv.Length);
}
}
public static void Twice(uint[] x, uint[] z)
{
if (Nat.ShiftUpBit(5, x, 0u, z) != 0 || (z[4] == uint.MaxValue && Nat160.Gte(z, P)))
{
Nat.Add33To(5, 21389u, z);
}
}
}

View File

@@ -0,0 +1,191 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP160R2FieldElement : AbstractFpFieldElement
{
public static readonly BigInteger Q = SecP160R2Curve.q;
protected internal readonly uint[] x;
public override bool IsZero => Nat160.IsZero(x);
public override bool IsOne => Nat160.IsOne(x);
public override string FieldName => "SecP160R2Field";
public override int FieldSize => Q.BitLength;
public SecP160R2FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
{
throw new ArgumentException("value invalid for SecP160R2FieldElement", "x");
}
this.x = SecP160R2Field.FromBigInteger(x);
}
public SecP160R2FieldElement()
{
x = Nat160.Create();
}
protected internal SecP160R2FieldElement(uint[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return Nat160.GetBit(x, 0) == 1;
}
public override BigInteger ToBigInteger()
{
return Nat160.ToBigInteger(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
uint[] z = Nat160.Create();
SecP160R2Field.Add(x, ((SecP160R2FieldElement)b).x, z);
return new SecP160R2FieldElement(z);
}
public override ECFieldElement AddOne()
{
uint[] z = Nat160.Create();
SecP160R2Field.AddOne(x, z);
return new SecP160R2FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
uint[] z = Nat160.Create();
SecP160R2Field.Subtract(x, ((SecP160R2FieldElement)b).x, z);
return new SecP160R2FieldElement(z);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
uint[] z = Nat160.Create();
SecP160R2Field.Multiply(x, ((SecP160R2FieldElement)b).x, z);
return new SecP160R2FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
uint[] z = Nat160.Create();
Mod.Invert(SecP160R2Field.P, ((SecP160R2FieldElement)b).x, z);
SecP160R2Field.Multiply(z, x, z);
return new SecP160R2FieldElement(z);
}
public override ECFieldElement Negate()
{
uint[] z = Nat160.Create();
SecP160R2Field.Negate(x, z);
return new SecP160R2FieldElement(z);
}
public override ECFieldElement Square()
{
uint[] z = Nat160.Create();
SecP160R2Field.Square(x, z);
return new SecP160R2FieldElement(z);
}
public override ECFieldElement Invert()
{
uint[] z = Nat160.Create();
Mod.Invert(SecP160R2Field.P, x, z);
return new SecP160R2FieldElement(z);
}
public override ECFieldElement Sqrt()
{
uint[] y = x;
if (Nat160.IsZero(y) || Nat160.IsOne(y))
{
return this;
}
uint[] array = Nat160.Create();
SecP160R2Field.Square(y, array);
SecP160R2Field.Multiply(array, y, array);
uint[] array2 = Nat160.Create();
SecP160R2Field.Square(array, array2);
SecP160R2Field.Multiply(array2, y, array2);
uint[] array3 = Nat160.Create();
SecP160R2Field.Square(array2, array3);
SecP160R2Field.Multiply(array3, y, array3);
uint[] array4 = Nat160.Create();
SecP160R2Field.SquareN(array3, 3, array4);
SecP160R2Field.Multiply(array4, array2, array4);
uint[] array5 = array3;
SecP160R2Field.SquareN(array4, 7, array5);
SecP160R2Field.Multiply(array5, array4, array5);
uint[] array6 = array4;
SecP160R2Field.SquareN(array5, 3, array6);
SecP160R2Field.Multiply(array6, array2, array6);
uint[] array7 = Nat160.Create();
SecP160R2Field.SquareN(array6, 14, array7);
SecP160R2Field.Multiply(array7, array5, array7);
uint[] array8 = array5;
SecP160R2Field.SquareN(array7, 31, array8);
SecP160R2Field.Multiply(array8, array7, array8);
uint[] z = array7;
SecP160R2Field.SquareN(array8, 62, z);
SecP160R2Field.Multiply(z, array8, z);
uint[] array9 = array8;
SecP160R2Field.SquareN(z, 3, array9);
SecP160R2Field.Multiply(array9, array2, array9);
uint[] z2 = array9;
SecP160R2Field.SquareN(z2, 18, z2);
SecP160R2Field.Multiply(z2, array6, z2);
SecP160R2Field.SquareN(z2, 2, z2);
SecP160R2Field.Multiply(z2, y, z2);
SecP160R2Field.SquareN(z2, 3, z2);
SecP160R2Field.Multiply(z2, array, z2);
SecP160R2Field.SquareN(z2, 6, z2);
SecP160R2Field.Multiply(z2, array2, z2);
SecP160R2Field.SquareN(z2, 2, z2);
SecP160R2Field.Multiply(z2, y, z2);
uint[] array10 = array;
SecP160R2Field.Square(z2, array10);
if (!Nat160.Eq(y, array10))
{
return null;
}
return new SecP160R2FieldElement(z2);
}
public override bool Equals(object obj)
{
return Equals(obj as SecP160R2FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecP160R2FieldElement);
}
public virtual bool Equals(SecP160R2FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat160.Eq(x, other.x);
}
public override int GetHashCode()
{
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 5);
}
}

View File

@@ -0,0 +1,228 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP160R2Point : AbstractFpPoint
{
public SecP160R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecP160R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecP160R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecP160R2Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
SecP160R2FieldElement secP160R2FieldElement = (SecP160R2FieldElement)base.RawXCoord;
SecP160R2FieldElement secP160R2FieldElement2 = (SecP160R2FieldElement)base.RawYCoord;
SecP160R2FieldElement secP160R2FieldElement3 = (SecP160R2FieldElement)b.RawXCoord;
SecP160R2FieldElement secP160R2FieldElement4 = (SecP160R2FieldElement)b.RawYCoord;
SecP160R2FieldElement secP160R2FieldElement5 = (SecP160R2FieldElement)base.RawZCoords[0];
SecP160R2FieldElement secP160R2FieldElement6 = (SecP160R2FieldElement)b.RawZCoords[0];
uint[] array = Nat160.CreateExt();
uint[] array2 = Nat160.Create();
uint[] array3 = Nat160.Create();
uint[] array4 = Nat160.Create();
bool isOne = secP160R2FieldElement5.IsOne;
uint[] array5;
uint[] array6;
if (isOne)
{
array5 = secP160R2FieldElement3.x;
array6 = secP160R2FieldElement4.x;
}
else
{
array6 = array3;
SecP160R2Field.Square(secP160R2FieldElement5.x, array6);
array5 = array2;
SecP160R2Field.Multiply(array6, secP160R2FieldElement3.x, array5);
SecP160R2Field.Multiply(array6, secP160R2FieldElement5.x, array6);
SecP160R2Field.Multiply(array6, secP160R2FieldElement4.x, array6);
}
bool isOne2 = secP160R2FieldElement6.IsOne;
uint[] array7;
uint[] array8;
if (isOne2)
{
array7 = secP160R2FieldElement.x;
array8 = secP160R2FieldElement2.x;
}
else
{
array8 = array4;
SecP160R2Field.Square(secP160R2FieldElement6.x, array8);
array7 = array;
SecP160R2Field.Multiply(array8, secP160R2FieldElement.x, array7);
SecP160R2Field.Multiply(array8, secP160R2FieldElement6.x, array8);
SecP160R2Field.Multiply(array8, secP160R2FieldElement2.x, array8);
}
uint[] array9 = Nat160.Create();
SecP160R2Field.Subtract(array7, array5, array9);
uint[] array10 = array2;
SecP160R2Field.Subtract(array8, array6, array10);
if (Nat160.IsZero(array9))
{
if (Nat160.IsZero(array10))
{
return Twice();
}
return curve.Infinity;
}
uint[] array11 = array3;
SecP160R2Field.Square(array9, array11);
uint[] array12 = Nat160.Create();
SecP160R2Field.Multiply(array11, array9, array12);
uint[] array13 = array3;
SecP160R2Field.Multiply(array11, array7, array13);
SecP160R2Field.Negate(array12, array12);
Nat160.Mul(array8, array12, array);
uint x = Nat160.AddBothTo(array13, array13, array12);
SecP160R2Field.Reduce32(x, array12);
SecP160R2FieldElement secP160R2FieldElement7 = new SecP160R2FieldElement(array4);
SecP160R2Field.Square(array10, secP160R2FieldElement7.x);
SecP160R2Field.Subtract(secP160R2FieldElement7.x, array12, secP160R2FieldElement7.x);
SecP160R2FieldElement secP160R2FieldElement8 = new SecP160R2FieldElement(array12);
SecP160R2Field.Subtract(array13, secP160R2FieldElement7.x, secP160R2FieldElement8.x);
SecP160R2Field.MultiplyAddToExt(secP160R2FieldElement8.x, array10, array);
SecP160R2Field.Reduce(array, secP160R2FieldElement8.x);
SecP160R2FieldElement secP160R2FieldElement9 = new SecP160R2FieldElement(array9);
if (!isOne)
{
SecP160R2Field.Multiply(secP160R2FieldElement9.x, secP160R2FieldElement5.x, secP160R2FieldElement9.x);
}
if (!isOne2)
{
SecP160R2Field.Multiply(secP160R2FieldElement9.x, secP160R2FieldElement6.x, secP160R2FieldElement9.x);
}
ECFieldElement[] zs = new ECFieldElement[1] { secP160R2FieldElement9 };
return new SecP160R2Point(curve, secP160R2FieldElement7, secP160R2FieldElement8, zs, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
SecP160R2FieldElement secP160R2FieldElement = (SecP160R2FieldElement)base.RawYCoord;
if (secP160R2FieldElement.IsZero)
{
return curve.Infinity;
}
SecP160R2FieldElement secP160R2FieldElement2 = (SecP160R2FieldElement)base.RawXCoord;
SecP160R2FieldElement secP160R2FieldElement3 = (SecP160R2FieldElement)base.RawZCoords[0];
uint[] array = Nat160.Create();
uint[] array2 = Nat160.Create();
uint[] array3 = Nat160.Create();
SecP160R2Field.Square(secP160R2FieldElement.x, array3);
uint[] array4 = Nat160.Create();
SecP160R2Field.Square(array3, array4);
bool isOne = secP160R2FieldElement3.IsOne;
uint[] array5 = secP160R2FieldElement3.x;
if (!isOne)
{
array5 = array2;
SecP160R2Field.Square(secP160R2FieldElement3.x, array5);
}
SecP160R2Field.Subtract(secP160R2FieldElement2.x, array5, array);
uint[] array6 = array2;
SecP160R2Field.Add(secP160R2FieldElement2.x, array5, array6);
SecP160R2Field.Multiply(array6, array, array6);
uint x = Nat160.AddBothTo(array6, array6, array6);
SecP160R2Field.Reduce32(x, array6);
uint[] array7 = array3;
SecP160R2Field.Multiply(array3, secP160R2FieldElement2.x, array7);
x = Nat.ShiftUpBits(5, array7, 2, 0u);
SecP160R2Field.Reduce32(x, array7);
x = Nat.ShiftUpBits(5, array4, 3, 0u, array);
SecP160R2Field.Reduce32(x, array);
SecP160R2FieldElement secP160R2FieldElement4 = new SecP160R2FieldElement(array4);
SecP160R2Field.Square(array6, secP160R2FieldElement4.x);
SecP160R2Field.Subtract(secP160R2FieldElement4.x, array7, secP160R2FieldElement4.x);
SecP160R2Field.Subtract(secP160R2FieldElement4.x, array7, secP160R2FieldElement4.x);
SecP160R2FieldElement secP160R2FieldElement5 = new SecP160R2FieldElement(array7);
SecP160R2Field.Subtract(array7, secP160R2FieldElement4.x, secP160R2FieldElement5.x);
SecP160R2Field.Multiply(secP160R2FieldElement5.x, array6, secP160R2FieldElement5.x);
SecP160R2Field.Subtract(secP160R2FieldElement5.x, array, secP160R2FieldElement5.x);
SecP160R2FieldElement secP160R2FieldElement6 = new SecP160R2FieldElement(array6);
SecP160R2Field.Twice(secP160R2FieldElement.x, secP160R2FieldElement6.x);
if (!isOne)
{
SecP160R2Field.Multiply(secP160R2FieldElement6.x, secP160R2FieldElement3.x, secP160R2FieldElement6.x);
}
return new SecP160R2Point(curve, secP160R2FieldElement4, secP160R2FieldElement5, new ECFieldElement[1] { secP160R2FieldElement6 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
return Twice().Add(b);
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity || base.RawYCoord.IsZero)
{
return this;
}
return Twice().Add(this);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
return new SecP160R2Point(Curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
}

View File

@@ -0,0 +1,119 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP192K1Curve : AbstractFpCurve
{
private class SecP192K1LookupTable : ECLookupTable
{
private readonly SecP192K1Curve m_outer;
private readonly uint[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecP192K1LookupTable(SecP192K1Curve outer, uint[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
uint[] array = Nat192.Create();
uint[] array2 = Nat192.Create();
int num = 0;
for (int i = 0; i < m_size; i++)
{
uint num2 = (uint)((i ^ index) - 1 >> 31);
for (int j = 0; j < 6; j++)
{
uint[] array4;
uint[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
uint[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 6 + j] & num2);
}
num += 12;
}
return m_outer.CreateRawPoint(new SecP192K1FieldElement(array), new SecP192K1FieldElement(array2), withCompression: false);
}
}
private const int SECP192K1_DEFAULT_COORDS = 2;
private const int SECP192K1_FE_INTS = 6;
public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"));
protected readonly SecP192K1Point m_infinity;
public virtual BigInteger Q => q;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => q.BitLength;
public SecP192K1Curve()
: base(q)
{
m_infinity = new SecP192K1Point(this, null, null);
m_a = FromBigInteger(BigInteger.Zero);
m_b = FromBigInteger(BigInteger.ValueOf(3L));
m_order = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"));
m_cofactor = BigInteger.One;
m_coord = 2;
}
protected override ECCurve CloneCurve()
{
return new SecP192K1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 2)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecP192K1FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecP192K1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecP192K1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
uint[] array = new uint[len * 6 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat192.Copy(((SecP192K1FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 6;
Nat192.Copy(((SecP192K1FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 6;
}
return new SecP192K1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,154 @@
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP192K1Field
{
private const uint P5 = uint.MaxValue;
private const uint PExt11 = uint.MaxValue;
private const uint PInv33 = 4553u;
internal static readonly uint[] P = new uint[6] { 4294962743u, 4294967294u, 4294967295u, 4294967295u, 4294967295u, 4294967295u };
internal static readonly uint[] PExt = new uint[12]
{
20729809u, 9106u, 1u, 0u, 0u, 0u, 4294958190u, 4294967293u, 4294967295u, 4294967295u,
4294967295u, 4294967295u
};
private static readonly uint[] PExtInv = new uint[8] { 4274237487u, 4294958189u, 4294967294u, 4294967295u, 4294967295u, 4294967295u, 9105u, 2u };
public static void Add(uint[] x, uint[] y, uint[] z)
{
if (Nat192.Add(x, y, z) != 0 || (z[5] == uint.MaxValue && Nat192.Gte(z, P)))
{
Nat.Add33To(6, 4553u, z);
}
}
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
{
if ((Nat.Add(12, xx, yy, zz) != 0 || (zz[11] == uint.MaxValue && Nat.Gte(12, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(12, zz, PExtInv.Length);
}
}
public static void AddOne(uint[] x, uint[] z)
{
if (Nat.Inc(6, x, z) != 0 || (z[5] == uint.MaxValue && Nat192.Gte(z, P)))
{
Nat.Add33To(6, 4553u, z);
}
}
public static uint[] FromBigInteger(BigInteger x)
{
uint[] array = Nat192.FromBigInteger(x);
if (array[5] == uint.MaxValue && Nat192.Gte(array, P))
{
Nat192.SubFrom(P, array);
}
return array;
}
public static void Half(uint[] x, uint[] z)
{
if ((x[0] & 1) == 0)
{
Nat.ShiftDownBit(6, x, 0u, z);
return;
}
uint c = Nat192.Add(x, P, z);
Nat.ShiftDownBit(6, z, c);
}
public static void Multiply(uint[] x, uint[] y, uint[] z)
{
uint[] array = Nat192.CreateExt();
Nat192.Mul(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
{
if ((Nat192.MulAddTo(x, y, zz) != 0 || (zz[11] == uint.MaxValue && Nat.Gte(12, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(12, zz, PExtInv.Length);
}
}
public static void Negate(uint[] x, uint[] z)
{
if (Nat192.IsZero(x))
{
Nat192.Zero(z);
}
else
{
Nat192.Sub(P, x, z);
}
}
public static void Reduce(uint[] xx, uint[] z)
{
ulong y = Nat192.Mul33Add(4553u, xx, 6, xx, 0, z, 0);
if (Nat192.Mul33DWordAdd(4553u, y, z, 0) != 0 || (z[5] == uint.MaxValue && Nat192.Gte(z, P)))
{
Nat.Add33To(6, 4553u, z);
}
}
public static void Reduce32(uint x, uint[] z)
{
if ((x != 0 && Nat192.Mul33WordAdd(4553u, x, z, 0) != 0) || (z[5] == uint.MaxValue && Nat192.Gte(z, P)))
{
Nat.Add33To(6, 4553u, z);
}
}
public static void Square(uint[] x, uint[] z)
{
uint[] array = Nat192.CreateExt();
Nat192.Square(x, array);
Reduce(array, z);
}
public static void SquareN(uint[] x, int n, uint[] z)
{
uint[] array = Nat192.CreateExt();
Nat192.Square(x, array);
Reduce(array, z);
while (--n > 0)
{
Nat192.Square(z, array);
Reduce(array, z);
}
}
public static void Subtract(uint[] x, uint[] y, uint[] z)
{
if (Nat192.Sub(x, y, z) != 0)
{
Nat.Sub33From(6, 4553u, z);
}
}
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat.Sub(12, xx, yy, zz) != 0 && Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.DecAt(12, zz, PExtInv.Length);
}
}
public static void Twice(uint[] x, uint[] z)
{
if (Nat.ShiftUpBit(6, x, 0u, z) != 0 || (z[5] == uint.MaxValue && Nat192.Gte(z, P)))
{
Nat.Add33To(6, 4553u, z);
}
}
}

View File

@@ -0,0 +1,188 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP192K1FieldElement : AbstractFpFieldElement
{
public static readonly BigInteger Q = SecP192K1Curve.q;
protected internal readonly uint[] x;
public override bool IsZero => Nat192.IsZero(x);
public override bool IsOne => Nat192.IsOne(x);
public override string FieldName => "SecP192K1Field";
public override int FieldSize => Q.BitLength;
public SecP192K1FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
{
throw new ArgumentException("value invalid for SecP192K1FieldElement", "x");
}
this.x = SecP192K1Field.FromBigInteger(x);
}
public SecP192K1FieldElement()
{
x = Nat192.Create();
}
protected internal SecP192K1FieldElement(uint[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return Nat192.GetBit(x, 0) == 1;
}
public override BigInteger ToBigInteger()
{
return Nat192.ToBigInteger(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
uint[] z = Nat192.Create();
SecP192K1Field.Add(x, ((SecP192K1FieldElement)b).x, z);
return new SecP192K1FieldElement(z);
}
public override ECFieldElement AddOne()
{
uint[] z = Nat192.Create();
SecP192K1Field.AddOne(x, z);
return new SecP192K1FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
uint[] z = Nat192.Create();
SecP192K1Field.Subtract(x, ((SecP192K1FieldElement)b).x, z);
return new SecP192K1FieldElement(z);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
uint[] z = Nat192.Create();
SecP192K1Field.Multiply(x, ((SecP192K1FieldElement)b).x, z);
return new SecP192K1FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
uint[] z = Nat192.Create();
Mod.Invert(SecP192K1Field.P, ((SecP192K1FieldElement)b).x, z);
SecP192K1Field.Multiply(z, x, z);
return new SecP192K1FieldElement(z);
}
public override ECFieldElement Negate()
{
uint[] z = Nat192.Create();
SecP192K1Field.Negate(x, z);
return new SecP192K1FieldElement(z);
}
public override ECFieldElement Square()
{
uint[] z = Nat192.Create();
SecP192K1Field.Square(x, z);
return new SecP192K1FieldElement(z);
}
public override ECFieldElement Invert()
{
uint[] z = Nat192.Create();
Mod.Invert(SecP192K1Field.P, x, z);
return new SecP192K1FieldElement(z);
}
public override ECFieldElement Sqrt()
{
uint[] y = x;
if (Nat192.IsZero(y) || Nat192.IsOne(y))
{
return this;
}
uint[] array = Nat192.Create();
SecP192K1Field.Square(y, array);
SecP192K1Field.Multiply(array, y, array);
uint[] array2 = Nat192.Create();
SecP192K1Field.Square(array, array2);
SecP192K1Field.Multiply(array2, y, array2);
uint[] array3 = Nat192.Create();
SecP192K1Field.SquareN(array2, 3, array3);
SecP192K1Field.Multiply(array3, array2, array3);
uint[] array4 = array3;
SecP192K1Field.SquareN(array3, 2, array4);
SecP192K1Field.Multiply(array4, array, array4);
uint[] array5 = array;
SecP192K1Field.SquareN(array4, 8, array5);
SecP192K1Field.Multiply(array5, array4, array5);
uint[] array6 = array4;
SecP192K1Field.SquareN(array5, 3, array6);
SecP192K1Field.Multiply(array6, array2, array6);
uint[] array7 = Nat192.Create();
SecP192K1Field.SquareN(array6, 16, array7);
SecP192K1Field.Multiply(array7, array5, array7);
uint[] array8 = array5;
SecP192K1Field.SquareN(array7, 35, array8);
SecP192K1Field.Multiply(array8, array7, array8);
uint[] z = array7;
SecP192K1Field.SquareN(array8, 70, z);
SecP192K1Field.Multiply(z, array8, z);
uint[] array9 = array8;
SecP192K1Field.SquareN(z, 19, array9);
SecP192K1Field.Multiply(array9, array6, array9);
uint[] z2 = array9;
SecP192K1Field.SquareN(z2, 20, z2);
SecP192K1Field.Multiply(z2, array6, z2);
SecP192K1Field.SquareN(z2, 4, z2);
SecP192K1Field.Multiply(z2, array2, z2);
SecP192K1Field.SquareN(z2, 6, z2);
SecP192K1Field.Multiply(z2, array2, z2);
SecP192K1Field.Square(z2, z2);
uint[] array10 = array2;
SecP192K1Field.Square(z2, array10);
if (!Nat192.Eq(y, array10))
{
return null;
}
return new SecP192K1FieldElement(z2);
}
public override bool Equals(object obj)
{
return Equals(obj as SecP192K1FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecP192K1FieldElement);
}
public virtual bool Equals(SecP192K1FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat192.Eq(x, other.x);
}
public override int GetHashCode()
{
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 6);
}
}

View File

@@ -0,0 +1,218 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP192K1Point : AbstractFpPoint
{
public SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecP192K1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
SecP192K1FieldElement secP192K1FieldElement = (SecP192K1FieldElement)base.RawXCoord;
SecP192K1FieldElement secP192K1FieldElement2 = (SecP192K1FieldElement)base.RawYCoord;
SecP192K1FieldElement secP192K1FieldElement3 = (SecP192K1FieldElement)b.RawXCoord;
SecP192K1FieldElement secP192K1FieldElement4 = (SecP192K1FieldElement)b.RawYCoord;
SecP192K1FieldElement secP192K1FieldElement5 = (SecP192K1FieldElement)base.RawZCoords[0];
SecP192K1FieldElement secP192K1FieldElement6 = (SecP192K1FieldElement)b.RawZCoords[0];
uint[] array = Nat192.CreateExt();
uint[] array2 = Nat192.Create();
uint[] array3 = Nat192.Create();
uint[] array4 = Nat192.Create();
bool isOne = secP192K1FieldElement5.IsOne;
uint[] array5;
uint[] array6;
if (isOne)
{
array5 = secP192K1FieldElement3.x;
array6 = secP192K1FieldElement4.x;
}
else
{
array6 = array3;
SecP192K1Field.Square(secP192K1FieldElement5.x, array6);
array5 = array2;
SecP192K1Field.Multiply(array6, secP192K1FieldElement3.x, array5);
SecP192K1Field.Multiply(array6, secP192K1FieldElement5.x, array6);
SecP192K1Field.Multiply(array6, secP192K1FieldElement4.x, array6);
}
bool isOne2 = secP192K1FieldElement6.IsOne;
uint[] array7;
uint[] array8;
if (isOne2)
{
array7 = secP192K1FieldElement.x;
array8 = secP192K1FieldElement2.x;
}
else
{
array8 = array4;
SecP192K1Field.Square(secP192K1FieldElement6.x, array8);
array7 = array;
SecP192K1Field.Multiply(array8, secP192K1FieldElement.x, array7);
SecP192K1Field.Multiply(array8, secP192K1FieldElement6.x, array8);
SecP192K1Field.Multiply(array8, secP192K1FieldElement2.x, array8);
}
uint[] array9 = Nat192.Create();
SecP192K1Field.Subtract(array7, array5, array9);
uint[] array10 = array2;
SecP192K1Field.Subtract(array8, array6, array10);
if (Nat192.IsZero(array9))
{
if (Nat192.IsZero(array10))
{
return Twice();
}
return curve.Infinity;
}
uint[] array11 = array3;
SecP192K1Field.Square(array9, array11);
uint[] array12 = Nat192.Create();
SecP192K1Field.Multiply(array11, array9, array12);
uint[] array13 = array3;
SecP192K1Field.Multiply(array11, array7, array13);
SecP192K1Field.Negate(array12, array12);
Nat192.Mul(array8, array12, array);
uint x = Nat192.AddBothTo(array13, array13, array12);
SecP192K1Field.Reduce32(x, array12);
SecP192K1FieldElement secP192K1FieldElement7 = new SecP192K1FieldElement(array4);
SecP192K1Field.Square(array10, secP192K1FieldElement7.x);
SecP192K1Field.Subtract(secP192K1FieldElement7.x, array12, secP192K1FieldElement7.x);
SecP192K1FieldElement secP192K1FieldElement8 = new SecP192K1FieldElement(array12);
SecP192K1Field.Subtract(array13, secP192K1FieldElement7.x, secP192K1FieldElement8.x);
SecP192K1Field.MultiplyAddToExt(secP192K1FieldElement8.x, array10, array);
SecP192K1Field.Reduce(array, secP192K1FieldElement8.x);
SecP192K1FieldElement secP192K1FieldElement9 = new SecP192K1FieldElement(array9);
if (!isOne)
{
SecP192K1Field.Multiply(secP192K1FieldElement9.x, secP192K1FieldElement5.x, secP192K1FieldElement9.x);
}
if (!isOne2)
{
SecP192K1Field.Multiply(secP192K1FieldElement9.x, secP192K1FieldElement6.x, secP192K1FieldElement9.x);
}
ECFieldElement[] zs = new ECFieldElement[1] { secP192K1FieldElement9 };
return new SecP192K1Point(curve, secP192K1FieldElement7, secP192K1FieldElement8, zs, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
SecP192K1FieldElement secP192K1FieldElement = (SecP192K1FieldElement)base.RawYCoord;
if (secP192K1FieldElement.IsZero)
{
return curve.Infinity;
}
SecP192K1FieldElement secP192K1FieldElement2 = (SecP192K1FieldElement)base.RawXCoord;
SecP192K1FieldElement secP192K1FieldElement3 = (SecP192K1FieldElement)base.RawZCoords[0];
uint[] array = Nat192.Create();
SecP192K1Field.Square(secP192K1FieldElement.x, array);
uint[] array2 = Nat192.Create();
SecP192K1Field.Square(array, array2);
uint[] array3 = Nat192.Create();
SecP192K1Field.Square(secP192K1FieldElement2.x, array3);
uint x = Nat192.AddBothTo(array3, array3, array3);
SecP192K1Field.Reduce32(x, array3);
uint[] array4 = array;
SecP192K1Field.Multiply(array, secP192K1FieldElement2.x, array4);
x = Nat.ShiftUpBits(6, array4, 2, 0u);
SecP192K1Field.Reduce32(x, array4);
uint[] array5 = Nat192.Create();
x = Nat.ShiftUpBits(6, array2, 3, 0u, array5);
SecP192K1Field.Reduce32(x, array5);
SecP192K1FieldElement secP192K1FieldElement4 = new SecP192K1FieldElement(array2);
SecP192K1Field.Square(array3, secP192K1FieldElement4.x);
SecP192K1Field.Subtract(secP192K1FieldElement4.x, array4, secP192K1FieldElement4.x);
SecP192K1Field.Subtract(secP192K1FieldElement4.x, array4, secP192K1FieldElement4.x);
SecP192K1FieldElement secP192K1FieldElement5 = new SecP192K1FieldElement(array4);
SecP192K1Field.Subtract(array4, secP192K1FieldElement4.x, secP192K1FieldElement5.x);
SecP192K1Field.Multiply(secP192K1FieldElement5.x, array3, secP192K1FieldElement5.x);
SecP192K1Field.Subtract(secP192K1FieldElement5.x, array5, secP192K1FieldElement5.x);
SecP192K1FieldElement secP192K1FieldElement6 = new SecP192K1FieldElement(array3);
SecP192K1Field.Twice(secP192K1FieldElement.x, secP192K1FieldElement6.x);
if (!secP192K1FieldElement3.IsOne)
{
SecP192K1Field.Multiply(secP192K1FieldElement6.x, secP192K1FieldElement3.x, secP192K1FieldElement6.x);
}
return new SecP192K1Point(curve, secP192K1FieldElement4, secP192K1FieldElement5, new ECFieldElement[1] { secP192K1FieldElement6 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
return Twice().Add(b);
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity || base.RawYCoord.IsZero)
{
return this;
}
return Twice().Add(this);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
return new SecP192K1Point(Curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
}

View File

@@ -0,0 +1,119 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP192R1Curve : AbstractFpCurve
{
private class SecP192R1LookupTable : ECLookupTable
{
private readonly SecP192R1Curve m_outer;
private readonly uint[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecP192R1LookupTable(SecP192R1Curve outer, uint[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
uint[] array = Nat192.Create();
uint[] array2 = Nat192.Create();
int num = 0;
for (int i = 0; i < m_size; i++)
{
uint num2 = (uint)((i ^ index) - 1 >> 31);
for (int j = 0; j < 6; j++)
{
uint[] array4;
uint[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
uint[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 6 + j] & num2);
}
num += 12;
}
return m_outer.CreateRawPoint(new SecP192R1FieldElement(array), new SecP192R1FieldElement(array2), withCompression: false);
}
}
private const int SECP192R1_DEFAULT_COORDS = 2;
private const int SECP192R1_FE_INTS = 6;
public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"));
protected readonly SecP192R1Point m_infinity;
public virtual BigInteger Q => q;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => q.BitLength;
public SecP192R1Curve()
: base(q)
{
m_infinity = new SecP192R1Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")));
m_order = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"));
m_cofactor = BigInteger.One;
m_coord = 2;
}
protected override ECCurve CloneCurve()
{
return new SecP192R1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 2)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecP192R1FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecP192R1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecP192R1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
uint[] array = new uint[len * 6 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat192.Copy(((SecP192R1FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 6;
Nat192.Copy(((SecP192R1FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 6;
}
return new SecP192R1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,250 @@
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP192R1Field
{
private const uint P5 = uint.MaxValue;
private const uint PExt11 = uint.MaxValue;
internal static readonly uint[] P = new uint[6] { 4294967295u, 4294967295u, 4294967294u, 4294967295u, 4294967295u, 4294967295u };
internal static readonly uint[] PExt = new uint[12]
{
1u, 0u, 2u, 0u, 1u, 0u, 4294967294u, 4294967295u, 4294967293u, 4294967295u,
4294967295u, 4294967295u
};
private static readonly uint[] PExtInv = new uint[9] { 4294967295u, 4294967295u, 4294967293u, 4294967295u, 4294967294u, 4294967295u, 1u, 0u, 2u };
public static void Add(uint[] x, uint[] y, uint[] z)
{
if (Nat192.Add(x, y, z) != 0 || (z[5] == uint.MaxValue && Nat192.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
{
if ((Nat.Add(12, xx, yy, zz) != 0 || (zz[11] == uint.MaxValue && Nat.Gte(12, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(12, zz, PExtInv.Length);
}
}
public static void AddOne(uint[] x, uint[] z)
{
if (Nat.Inc(6, x, z) != 0 || (z[5] == uint.MaxValue && Nat192.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static uint[] FromBigInteger(BigInteger x)
{
uint[] array = Nat192.FromBigInteger(x);
if (array[5] == uint.MaxValue && Nat192.Gte(array, P))
{
Nat192.SubFrom(P, array);
}
return array;
}
public static void Half(uint[] x, uint[] z)
{
if ((x[0] & 1) == 0)
{
Nat.ShiftDownBit(6, x, 0u, z);
return;
}
uint c = Nat192.Add(x, P, z);
Nat.ShiftDownBit(6, z, c);
}
public static void Multiply(uint[] x, uint[] y, uint[] z)
{
uint[] array = Nat192.CreateExt();
Nat192.Mul(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
{
if ((Nat192.MulAddTo(x, y, zz) != 0 || (zz[11] == uint.MaxValue && Nat.Gte(12, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(12, zz, PExtInv.Length);
}
}
public static void Negate(uint[] x, uint[] z)
{
if (Nat192.IsZero(x))
{
Nat192.Zero(z);
}
else
{
Nat192.Sub(P, x, z);
}
}
public static void Reduce(uint[] xx, uint[] z)
{
ulong num = xx[6];
ulong num2 = xx[7];
ulong num3 = xx[8];
ulong num4 = xx[9];
ulong num5 = xx[10];
ulong num6 = xx[11];
ulong num7 = num + num5;
ulong num8 = num2 + num6;
ulong num9 = 0uL;
num9 += xx[0] + num7;
uint num10 = (uint)num9;
num9 >>= 32;
num9 += xx[1] + num8;
z[1] = (uint)num9;
num9 >>= 32;
num7 += num3;
num8 += num4;
num9 += xx[2] + num7;
ulong num11 = (uint)num9;
num9 >>= 32;
num9 += xx[3] + num8;
z[3] = (uint)num9;
num9 >>= 32;
num7 -= num;
num8 -= num2;
num9 += xx[4] + num7;
z[4] = (uint)num9;
num9 >>= 32;
num9 += xx[5] + num8;
z[5] = (uint)num9;
num9 >>= 32;
num11 += num9;
num9 += num10;
z[0] = (uint)num9;
num9 >>= 32;
if (num9 != 0)
{
num9 += z[1];
z[1] = (uint)num9;
num11 += num9 >> 32;
}
z[2] = (uint)num11;
num9 = num11 >> 32;
if ((num9 != 0 && Nat.IncAt(6, z, 3) != 0) || (z[5] == uint.MaxValue && Nat192.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static void Reduce32(uint x, uint[] z)
{
ulong num = 0uL;
if (x != 0)
{
num += (ulong)((long)z[0] + (long)x);
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[1];
z[1] = (uint)num;
num >>= 32;
}
num += (ulong)((long)z[2] + (long)x);
z[2] = (uint)num;
num >>= 32;
}
if ((num != 0 && Nat.IncAt(6, z, 3) != 0) || (z[5] == uint.MaxValue && Nat192.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static void Square(uint[] x, uint[] z)
{
uint[] array = Nat192.CreateExt();
Nat192.Square(x, array);
Reduce(array, z);
}
public static void SquareN(uint[] x, int n, uint[] z)
{
uint[] array = Nat192.CreateExt();
Nat192.Square(x, array);
Reduce(array, z);
while (--n > 0)
{
Nat192.Square(z, array);
Reduce(array, z);
}
}
public static void Subtract(uint[] x, uint[] y, uint[] z)
{
if (Nat192.Sub(x, y, z) != 0)
{
SubPInvFrom(z);
}
}
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat.Sub(12, xx, yy, zz) != 0 && Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.DecAt(12, zz, PExtInv.Length);
}
}
public static void Twice(uint[] x, uint[] z)
{
if (Nat.ShiftUpBit(6, x, 0u, z) != 0 || (z[5] == uint.MaxValue && Nat192.Gte(z, P)))
{
AddPInvTo(z);
}
}
private static void AddPInvTo(uint[] z)
{
long num = (long)z[0] + 1L;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[1];
z[1] = (uint)num;
num >>= 32;
}
num += (long)z[2] + 1L;
z[2] = (uint)num;
num >>= 32;
if (num != 0)
{
Nat.IncAt(6, z, 3);
}
}
private static void SubPInvFrom(uint[] z)
{
long num = (long)z[0] - 1L;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[1];
z[1] = (uint)num;
num >>= 32;
}
num += (long)z[2] - 1L;
z[2] = (uint)num;
num >>= 32;
if (num != 0)
{
Nat.DecAt(6, z, 3);
}
}
}

View File

@@ -0,0 +1,166 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP192R1FieldElement : AbstractFpFieldElement
{
public static readonly BigInteger Q = SecP192R1Curve.q;
protected internal readonly uint[] x;
public override bool IsZero => Nat192.IsZero(x);
public override bool IsOne => Nat192.IsOne(x);
public override string FieldName => "SecP192R1Field";
public override int FieldSize => Q.BitLength;
public SecP192R1FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
{
throw new ArgumentException("value invalid for SecP192R1FieldElement", "x");
}
this.x = SecP192R1Field.FromBigInteger(x);
}
public SecP192R1FieldElement()
{
x = Nat192.Create();
}
protected internal SecP192R1FieldElement(uint[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return Nat192.GetBit(x, 0) == 1;
}
public override BigInteger ToBigInteger()
{
return Nat192.ToBigInteger(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
uint[] z = Nat192.Create();
SecP192R1Field.Add(x, ((SecP192R1FieldElement)b).x, z);
return new SecP192R1FieldElement(z);
}
public override ECFieldElement AddOne()
{
uint[] z = Nat192.Create();
SecP192R1Field.AddOne(x, z);
return new SecP192R1FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
uint[] z = Nat192.Create();
SecP192R1Field.Subtract(x, ((SecP192R1FieldElement)b).x, z);
return new SecP192R1FieldElement(z);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
uint[] z = Nat192.Create();
SecP192R1Field.Multiply(x, ((SecP192R1FieldElement)b).x, z);
return new SecP192R1FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
uint[] z = Nat192.Create();
Mod.Invert(SecP192R1Field.P, ((SecP192R1FieldElement)b).x, z);
SecP192R1Field.Multiply(z, x, z);
return new SecP192R1FieldElement(z);
}
public override ECFieldElement Negate()
{
uint[] z = Nat192.Create();
SecP192R1Field.Negate(x, z);
return new SecP192R1FieldElement(z);
}
public override ECFieldElement Square()
{
uint[] z = Nat192.Create();
SecP192R1Field.Square(x, z);
return new SecP192R1FieldElement(z);
}
public override ECFieldElement Invert()
{
uint[] z = Nat192.Create();
Mod.Invert(SecP192R1Field.P, x, z);
return new SecP192R1FieldElement(z);
}
public override ECFieldElement Sqrt()
{
uint[] y = x;
if (Nat192.IsZero(y) || Nat192.IsOne(y))
{
return this;
}
uint[] array = Nat192.Create();
uint[] array2 = Nat192.Create();
SecP192R1Field.Square(y, array);
SecP192R1Field.Multiply(array, y, array);
SecP192R1Field.SquareN(array, 2, array2);
SecP192R1Field.Multiply(array2, array, array2);
SecP192R1Field.SquareN(array2, 4, array);
SecP192R1Field.Multiply(array, array2, array);
SecP192R1Field.SquareN(array, 8, array2);
SecP192R1Field.Multiply(array2, array, array2);
SecP192R1Field.SquareN(array2, 16, array);
SecP192R1Field.Multiply(array, array2, array);
SecP192R1Field.SquareN(array, 32, array2);
SecP192R1Field.Multiply(array2, array, array2);
SecP192R1Field.SquareN(array2, 64, array);
SecP192R1Field.Multiply(array, array2, array);
SecP192R1Field.SquareN(array, 62, array);
SecP192R1Field.Square(array, array2);
if (!Nat192.Eq(y, array2))
{
return null;
}
return new SecP192R1FieldElement(array);
}
public override bool Equals(object obj)
{
return Equals(obj as SecP192R1FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecP192R1FieldElement);
}
public virtual bool Equals(SecP192R1FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat192.Eq(x, other.x);
}
public override int GetHashCode()
{
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 6);
}
}

View File

@@ -0,0 +1,228 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP192R1Point : AbstractFpPoint
{
public SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecP192R1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
SecP192R1FieldElement secP192R1FieldElement = (SecP192R1FieldElement)base.RawXCoord;
SecP192R1FieldElement secP192R1FieldElement2 = (SecP192R1FieldElement)base.RawYCoord;
SecP192R1FieldElement secP192R1FieldElement3 = (SecP192R1FieldElement)b.RawXCoord;
SecP192R1FieldElement secP192R1FieldElement4 = (SecP192R1FieldElement)b.RawYCoord;
SecP192R1FieldElement secP192R1FieldElement5 = (SecP192R1FieldElement)base.RawZCoords[0];
SecP192R1FieldElement secP192R1FieldElement6 = (SecP192R1FieldElement)b.RawZCoords[0];
uint[] array = Nat192.CreateExt();
uint[] array2 = Nat192.Create();
uint[] array3 = Nat192.Create();
uint[] array4 = Nat192.Create();
bool isOne = secP192R1FieldElement5.IsOne;
uint[] array5;
uint[] array6;
if (isOne)
{
array5 = secP192R1FieldElement3.x;
array6 = secP192R1FieldElement4.x;
}
else
{
array6 = array3;
SecP192R1Field.Square(secP192R1FieldElement5.x, array6);
array5 = array2;
SecP192R1Field.Multiply(array6, secP192R1FieldElement3.x, array5);
SecP192R1Field.Multiply(array6, secP192R1FieldElement5.x, array6);
SecP192R1Field.Multiply(array6, secP192R1FieldElement4.x, array6);
}
bool isOne2 = secP192R1FieldElement6.IsOne;
uint[] array7;
uint[] array8;
if (isOne2)
{
array7 = secP192R1FieldElement.x;
array8 = secP192R1FieldElement2.x;
}
else
{
array8 = array4;
SecP192R1Field.Square(secP192R1FieldElement6.x, array8);
array7 = array;
SecP192R1Field.Multiply(array8, secP192R1FieldElement.x, array7);
SecP192R1Field.Multiply(array8, secP192R1FieldElement6.x, array8);
SecP192R1Field.Multiply(array8, secP192R1FieldElement2.x, array8);
}
uint[] array9 = Nat192.Create();
SecP192R1Field.Subtract(array7, array5, array9);
uint[] array10 = array2;
SecP192R1Field.Subtract(array8, array6, array10);
if (Nat192.IsZero(array9))
{
if (Nat192.IsZero(array10))
{
return Twice();
}
return curve.Infinity;
}
uint[] array11 = array3;
SecP192R1Field.Square(array9, array11);
uint[] array12 = Nat192.Create();
SecP192R1Field.Multiply(array11, array9, array12);
uint[] array13 = array3;
SecP192R1Field.Multiply(array11, array7, array13);
SecP192R1Field.Negate(array12, array12);
Nat192.Mul(array8, array12, array);
uint x = Nat192.AddBothTo(array13, array13, array12);
SecP192R1Field.Reduce32(x, array12);
SecP192R1FieldElement secP192R1FieldElement7 = new SecP192R1FieldElement(array4);
SecP192R1Field.Square(array10, secP192R1FieldElement7.x);
SecP192R1Field.Subtract(secP192R1FieldElement7.x, array12, secP192R1FieldElement7.x);
SecP192R1FieldElement secP192R1FieldElement8 = new SecP192R1FieldElement(array12);
SecP192R1Field.Subtract(array13, secP192R1FieldElement7.x, secP192R1FieldElement8.x);
SecP192R1Field.MultiplyAddToExt(secP192R1FieldElement8.x, array10, array);
SecP192R1Field.Reduce(array, secP192R1FieldElement8.x);
SecP192R1FieldElement secP192R1FieldElement9 = new SecP192R1FieldElement(array9);
if (!isOne)
{
SecP192R1Field.Multiply(secP192R1FieldElement9.x, secP192R1FieldElement5.x, secP192R1FieldElement9.x);
}
if (!isOne2)
{
SecP192R1Field.Multiply(secP192R1FieldElement9.x, secP192R1FieldElement6.x, secP192R1FieldElement9.x);
}
ECFieldElement[] zs = new ECFieldElement[1] { secP192R1FieldElement9 };
return new SecP192R1Point(curve, secP192R1FieldElement7, secP192R1FieldElement8, zs, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
SecP192R1FieldElement secP192R1FieldElement = (SecP192R1FieldElement)base.RawYCoord;
if (secP192R1FieldElement.IsZero)
{
return curve.Infinity;
}
SecP192R1FieldElement secP192R1FieldElement2 = (SecP192R1FieldElement)base.RawXCoord;
SecP192R1FieldElement secP192R1FieldElement3 = (SecP192R1FieldElement)base.RawZCoords[0];
uint[] array = Nat192.Create();
uint[] array2 = Nat192.Create();
uint[] array3 = Nat192.Create();
SecP192R1Field.Square(secP192R1FieldElement.x, array3);
uint[] array4 = Nat192.Create();
SecP192R1Field.Square(array3, array4);
bool isOne = secP192R1FieldElement3.IsOne;
uint[] array5 = secP192R1FieldElement3.x;
if (!isOne)
{
array5 = array2;
SecP192R1Field.Square(secP192R1FieldElement3.x, array5);
}
SecP192R1Field.Subtract(secP192R1FieldElement2.x, array5, array);
uint[] array6 = array2;
SecP192R1Field.Add(secP192R1FieldElement2.x, array5, array6);
SecP192R1Field.Multiply(array6, array, array6);
uint x = Nat192.AddBothTo(array6, array6, array6);
SecP192R1Field.Reduce32(x, array6);
uint[] array7 = array3;
SecP192R1Field.Multiply(array3, secP192R1FieldElement2.x, array7);
x = Nat.ShiftUpBits(6, array7, 2, 0u);
SecP192R1Field.Reduce32(x, array7);
x = Nat.ShiftUpBits(6, array4, 3, 0u, array);
SecP192R1Field.Reduce32(x, array);
SecP192R1FieldElement secP192R1FieldElement4 = new SecP192R1FieldElement(array4);
SecP192R1Field.Square(array6, secP192R1FieldElement4.x);
SecP192R1Field.Subtract(secP192R1FieldElement4.x, array7, secP192R1FieldElement4.x);
SecP192R1Field.Subtract(secP192R1FieldElement4.x, array7, secP192R1FieldElement4.x);
SecP192R1FieldElement secP192R1FieldElement5 = new SecP192R1FieldElement(array7);
SecP192R1Field.Subtract(array7, secP192R1FieldElement4.x, secP192R1FieldElement5.x);
SecP192R1Field.Multiply(secP192R1FieldElement5.x, array6, secP192R1FieldElement5.x);
SecP192R1Field.Subtract(secP192R1FieldElement5.x, array, secP192R1FieldElement5.x);
SecP192R1FieldElement secP192R1FieldElement6 = new SecP192R1FieldElement(array6);
SecP192R1Field.Twice(secP192R1FieldElement.x, secP192R1FieldElement6.x);
if (!isOne)
{
SecP192R1Field.Multiply(secP192R1FieldElement6.x, secP192R1FieldElement3.x, secP192R1FieldElement6.x);
}
return new SecP192R1Point(curve, secP192R1FieldElement4, secP192R1FieldElement5, new ECFieldElement[1] { secP192R1FieldElement6 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
return Twice().Add(b);
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity || base.RawYCoord.IsZero)
{
return this;
}
return Twice().Add(this);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
return new SecP192R1Point(Curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
}

View File

@@ -0,0 +1,119 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP224K1Curve : AbstractFpCurve
{
private class SecP224K1LookupTable : ECLookupTable
{
private readonly SecP224K1Curve m_outer;
private readonly uint[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecP224K1LookupTable(SecP224K1Curve outer, uint[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
uint[] array = Nat224.Create();
uint[] array2 = Nat224.Create();
int num = 0;
for (int i = 0; i < m_size; i++)
{
uint num2 = (uint)((i ^ index) - 1 >> 31);
for (int j = 0; j < 7; j++)
{
uint[] array4;
uint[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
uint[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 7 + j] & num2);
}
num += 14;
}
return m_outer.CreateRawPoint(new SecP224K1FieldElement(array), new SecP224K1FieldElement(array2), withCompression: false);
}
}
private const int SECP224K1_DEFAULT_COORDS = 2;
private const int SECP224K1_FE_INTS = 7;
public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D"));
protected readonly SecP224K1Point m_infinity;
public virtual BigInteger Q => q;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => q.BitLength;
public SecP224K1Curve()
: base(q)
{
m_infinity = new SecP224K1Point(this, null, null);
m_a = FromBigInteger(BigInteger.Zero);
m_b = FromBigInteger(BigInteger.ValueOf(5L));
m_order = new BigInteger(1, Hex.Decode("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7"));
m_cofactor = BigInteger.One;
m_coord = 2;
}
protected override ECCurve CloneCurve()
{
return new SecP224K1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 2)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecP224K1FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecP224K1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecP224K1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
uint[] array = new uint[len * 7 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat224.Copy(((SecP224K1FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 7;
Nat224.Copy(((SecP224K1FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 7;
}
return new SecP224K1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,154 @@
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP224K1Field
{
private const uint P6 = uint.MaxValue;
private const uint PExt13 = uint.MaxValue;
private const uint PInv33 = 6803u;
internal static readonly uint[] P = new uint[7] { 4294960493u, 4294967294u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u };
internal static readonly uint[] PExt = new uint[14]
{
46280809u, 13606u, 1u, 0u, 0u, 0u, 0u, 4294953690u, 4294967293u, 4294967295u,
4294967295u, 4294967295u, 4294967295u, 4294967295u
};
private static readonly uint[] PExtInv = new uint[9] { 4248686487u, 4294953689u, 4294967294u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 13605u, 2u };
public static void Add(uint[] x, uint[] y, uint[] z)
{
if (Nat224.Add(x, y, z) != 0 || (z[6] == uint.MaxValue && Nat224.Gte(z, P)))
{
Nat.Add33To(7, 6803u, z);
}
}
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
{
if ((Nat.Add(14, xx, yy, zz) != 0 || (zz[13] == uint.MaxValue && Nat.Gte(14, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(14, zz, PExtInv.Length);
}
}
public static void AddOne(uint[] x, uint[] z)
{
if (Nat.Inc(7, x, z) != 0 || (z[6] == uint.MaxValue && Nat224.Gte(z, P)))
{
Nat.Add33To(7, 6803u, z);
}
}
public static uint[] FromBigInteger(BigInteger x)
{
uint[] array = Nat224.FromBigInteger(x);
if (array[6] == uint.MaxValue && Nat224.Gte(array, P))
{
Nat224.SubFrom(P, array);
}
return array;
}
public static void Half(uint[] x, uint[] z)
{
if ((x[0] & 1) == 0)
{
Nat.ShiftDownBit(7, x, 0u, z);
return;
}
uint c = Nat224.Add(x, P, z);
Nat.ShiftDownBit(7, z, c);
}
public static void Multiply(uint[] x, uint[] y, uint[] z)
{
uint[] array = Nat224.CreateExt();
Nat224.Mul(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
{
if ((Nat224.MulAddTo(x, y, zz) != 0 || (zz[13] == uint.MaxValue && Nat.Gte(14, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(14, zz, PExtInv.Length);
}
}
public static void Negate(uint[] x, uint[] z)
{
if (Nat224.IsZero(x))
{
Nat224.Zero(z);
}
else
{
Nat224.Sub(P, x, z);
}
}
public static void Reduce(uint[] xx, uint[] z)
{
ulong y = Nat224.Mul33Add(6803u, xx, 7, xx, 0, z, 0);
if (Nat224.Mul33DWordAdd(6803u, y, z, 0) != 0 || (z[6] == uint.MaxValue && Nat224.Gte(z, P)))
{
Nat.Add33To(7, 6803u, z);
}
}
public static void Reduce32(uint x, uint[] z)
{
if ((x != 0 && Nat224.Mul33WordAdd(6803u, x, z, 0) != 0) || (z[6] == uint.MaxValue && Nat224.Gte(z, P)))
{
Nat.Add33To(7, 6803u, z);
}
}
public static void Square(uint[] x, uint[] z)
{
uint[] array = Nat224.CreateExt();
Nat224.Square(x, array);
Reduce(array, z);
}
public static void SquareN(uint[] x, int n, uint[] z)
{
uint[] array = Nat224.CreateExt();
Nat224.Square(x, array);
Reduce(array, z);
while (--n > 0)
{
Nat224.Square(z, array);
Reduce(array, z);
}
}
public static void Subtract(uint[] x, uint[] y, uint[] z)
{
if (Nat224.Sub(x, y, z) != 0)
{
Nat.Sub33From(7, 6803u, z);
}
}
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat.Sub(14, xx, yy, zz) != 0 && Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.DecAt(14, zz, PExtInv.Length);
}
}
public static void Twice(uint[] x, uint[] z)
{
if (Nat.ShiftUpBit(7, x, 0u, z) != 0 || (z[6] == uint.MaxValue && Nat224.Gte(z, P)))
{
Nat.Add33To(7, 6803u, z);
}
}
}

View File

@@ -0,0 +1,201 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP224K1FieldElement : AbstractFpFieldElement
{
public static readonly BigInteger Q = SecP224K1Curve.q;
private static readonly uint[] PRECOMP_POW2 = new uint[7] { 868209154u, 3707425075u, 579297866u, 3280018344u, 2824165628u, 514782679u, 2396984652u };
protected internal readonly uint[] x;
public override bool IsZero => Nat224.IsZero(x);
public override bool IsOne => Nat224.IsOne(x);
public override string FieldName => "SecP224K1Field";
public override int FieldSize => Q.BitLength;
public SecP224K1FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
{
throw new ArgumentException("value invalid for SecP224K1FieldElement", "x");
}
this.x = SecP224K1Field.FromBigInteger(x);
}
public SecP224K1FieldElement()
{
x = Nat224.Create();
}
protected internal SecP224K1FieldElement(uint[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return Nat224.GetBit(x, 0) == 1;
}
public override BigInteger ToBigInteger()
{
return Nat224.ToBigInteger(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
uint[] z = Nat224.Create();
SecP224K1Field.Add(x, ((SecP224K1FieldElement)b).x, z);
return new SecP224K1FieldElement(z);
}
public override ECFieldElement AddOne()
{
uint[] z = Nat224.Create();
SecP224K1Field.AddOne(x, z);
return new SecP224K1FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
uint[] z = Nat224.Create();
SecP224K1Field.Subtract(x, ((SecP224K1FieldElement)b).x, z);
return new SecP224K1FieldElement(z);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
uint[] z = Nat224.Create();
SecP224K1Field.Multiply(x, ((SecP224K1FieldElement)b).x, z);
return new SecP224K1FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
uint[] z = Nat224.Create();
Mod.Invert(SecP224K1Field.P, ((SecP224K1FieldElement)b).x, z);
SecP224K1Field.Multiply(z, x, z);
return new SecP224K1FieldElement(z);
}
public override ECFieldElement Negate()
{
uint[] z = Nat224.Create();
SecP224K1Field.Negate(x, z);
return new SecP224K1FieldElement(z);
}
public override ECFieldElement Square()
{
uint[] z = Nat224.Create();
SecP224K1Field.Square(x, z);
return new SecP224K1FieldElement(z);
}
public override ECFieldElement Invert()
{
uint[] z = Nat224.Create();
Mod.Invert(SecP224K1Field.P, x, z);
return new SecP224K1FieldElement(z);
}
public override ECFieldElement Sqrt()
{
uint[] y = x;
if (Nat224.IsZero(y) || Nat224.IsOne(y))
{
return this;
}
uint[] array = Nat224.Create();
SecP224K1Field.Square(y, array);
SecP224K1Field.Multiply(array, y, array);
uint[] array2 = array;
SecP224K1Field.Square(array, array2);
SecP224K1Field.Multiply(array2, y, array2);
uint[] array3 = Nat224.Create();
SecP224K1Field.Square(array2, array3);
SecP224K1Field.Multiply(array3, y, array3);
uint[] array4 = Nat224.Create();
SecP224K1Field.SquareN(array3, 4, array4);
SecP224K1Field.Multiply(array4, array3, array4);
uint[] array5 = Nat224.Create();
SecP224K1Field.SquareN(array4, 3, array5);
SecP224K1Field.Multiply(array5, array2, array5);
uint[] array6 = array5;
SecP224K1Field.SquareN(array5, 8, array6);
SecP224K1Field.Multiply(array6, array4, array6);
uint[] array7 = array4;
SecP224K1Field.SquareN(array6, 4, array7);
SecP224K1Field.Multiply(array7, array3, array7);
uint[] array8 = array3;
SecP224K1Field.SquareN(array7, 19, array8);
SecP224K1Field.Multiply(array8, array6, array8);
uint[] array9 = Nat224.Create();
SecP224K1Field.SquareN(array8, 42, array9);
SecP224K1Field.Multiply(array9, array8, array9);
uint[] z = array8;
SecP224K1Field.SquareN(array9, 23, z);
SecP224K1Field.Multiply(z, array7, z);
uint[] array10 = array7;
SecP224K1Field.SquareN(z, 84, array10);
SecP224K1Field.Multiply(array10, array9, array10);
uint[] z2 = array10;
SecP224K1Field.SquareN(z2, 20, z2);
SecP224K1Field.Multiply(z2, array6, z2);
SecP224K1Field.SquareN(z2, 3, z2);
SecP224K1Field.Multiply(z2, y, z2);
SecP224K1Field.SquareN(z2, 2, z2);
SecP224K1Field.Multiply(z2, y, z2);
SecP224K1Field.SquareN(z2, 4, z2);
SecP224K1Field.Multiply(z2, array2, z2);
SecP224K1Field.Square(z2, z2);
uint[] array11 = array9;
SecP224K1Field.Square(z2, array11);
if (Nat224.Eq(y, array11))
{
return new SecP224K1FieldElement(z2);
}
SecP224K1Field.Multiply(z2, PRECOMP_POW2, z2);
SecP224K1Field.Square(z2, array11);
if (Nat224.Eq(y, array11))
{
return new SecP224K1FieldElement(z2);
}
return null;
}
public override bool Equals(object obj)
{
return Equals(obj as SecP224K1FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecP224K1FieldElement);
}
public virtual bool Equals(SecP224K1FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat224.Eq(x, other.x);
}
public override int GetHashCode()
{
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 7);
}
}

View File

@@ -0,0 +1,218 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP224K1Point : AbstractFpPoint
{
public SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecP224K1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
SecP224K1FieldElement secP224K1FieldElement = (SecP224K1FieldElement)base.RawXCoord;
SecP224K1FieldElement secP224K1FieldElement2 = (SecP224K1FieldElement)base.RawYCoord;
SecP224K1FieldElement secP224K1FieldElement3 = (SecP224K1FieldElement)b.RawXCoord;
SecP224K1FieldElement secP224K1FieldElement4 = (SecP224K1FieldElement)b.RawYCoord;
SecP224K1FieldElement secP224K1FieldElement5 = (SecP224K1FieldElement)base.RawZCoords[0];
SecP224K1FieldElement secP224K1FieldElement6 = (SecP224K1FieldElement)b.RawZCoords[0];
uint[] array = Nat224.CreateExt();
uint[] array2 = Nat224.Create();
uint[] array3 = Nat224.Create();
uint[] array4 = Nat224.Create();
bool isOne = secP224K1FieldElement5.IsOne;
uint[] array5;
uint[] array6;
if (isOne)
{
array5 = secP224K1FieldElement3.x;
array6 = secP224K1FieldElement4.x;
}
else
{
array6 = array3;
SecP224K1Field.Square(secP224K1FieldElement5.x, array6);
array5 = array2;
SecP224K1Field.Multiply(array6, secP224K1FieldElement3.x, array5);
SecP224K1Field.Multiply(array6, secP224K1FieldElement5.x, array6);
SecP224K1Field.Multiply(array6, secP224K1FieldElement4.x, array6);
}
bool isOne2 = secP224K1FieldElement6.IsOne;
uint[] array7;
uint[] array8;
if (isOne2)
{
array7 = secP224K1FieldElement.x;
array8 = secP224K1FieldElement2.x;
}
else
{
array8 = array4;
SecP224K1Field.Square(secP224K1FieldElement6.x, array8);
array7 = array;
SecP224K1Field.Multiply(array8, secP224K1FieldElement.x, array7);
SecP224K1Field.Multiply(array8, secP224K1FieldElement6.x, array8);
SecP224K1Field.Multiply(array8, secP224K1FieldElement2.x, array8);
}
uint[] array9 = Nat224.Create();
SecP224K1Field.Subtract(array7, array5, array9);
uint[] array10 = array2;
SecP224K1Field.Subtract(array8, array6, array10);
if (Nat224.IsZero(array9))
{
if (Nat224.IsZero(array10))
{
return Twice();
}
return curve.Infinity;
}
uint[] array11 = array3;
SecP224K1Field.Square(array9, array11);
uint[] array12 = Nat224.Create();
SecP224K1Field.Multiply(array11, array9, array12);
uint[] array13 = array3;
SecP224K1Field.Multiply(array11, array7, array13);
SecP224K1Field.Negate(array12, array12);
Nat224.Mul(array8, array12, array);
uint x = Nat224.AddBothTo(array13, array13, array12);
SecP224K1Field.Reduce32(x, array12);
SecP224K1FieldElement secP224K1FieldElement7 = new SecP224K1FieldElement(array4);
SecP224K1Field.Square(array10, secP224K1FieldElement7.x);
SecP224K1Field.Subtract(secP224K1FieldElement7.x, array12, secP224K1FieldElement7.x);
SecP224K1FieldElement secP224K1FieldElement8 = new SecP224K1FieldElement(array12);
SecP224K1Field.Subtract(array13, secP224K1FieldElement7.x, secP224K1FieldElement8.x);
SecP224K1Field.MultiplyAddToExt(secP224K1FieldElement8.x, array10, array);
SecP224K1Field.Reduce(array, secP224K1FieldElement8.x);
SecP224K1FieldElement secP224K1FieldElement9 = new SecP224K1FieldElement(array9);
if (!isOne)
{
SecP224K1Field.Multiply(secP224K1FieldElement9.x, secP224K1FieldElement5.x, secP224K1FieldElement9.x);
}
if (!isOne2)
{
SecP224K1Field.Multiply(secP224K1FieldElement9.x, secP224K1FieldElement6.x, secP224K1FieldElement9.x);
}
ECFieldElement[] zs = new ECFieldElement[1] { secP224K1FieldElement9 };
return new SecP224K1Point(curve, secP224K1FieldElement7, secP224K1FieldElement8, zs, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
SecP224K1FieldElement secP224K1FieldElement = (SecP224K1FieldElement)base.RawYCoord;
if (secP224K1FieldElement.IsZero)
{
return curve.Infinity;
}
SecP224K1FieldElement secP224K1FieldElement2 = (SecP224K1FieldElement)base.RawXCoord;
SecP224K1FieldElement secP224K1FieldElement3 = (SecP224K1FieldElement)base.RawZCoords[0];
uint[] array = Nat224.Create();
SecP224K1Field.Square(secP224K1FieldElement.x, array);
uint[] array2 = Nat224.Create();
SecP224K1Field.Square(array, array2);
uint[] array3 = Nat224.Create();
SecP224K1Field.Square(secP224K1FieldElement2.x, array3);
uint x = Nat224.AddBothTo(array3, array3, array3);
SecP224K1Field.Reduce32(x, array3);
uint[] array4 = array;
SecP224K1Field.Multiply(array, secP224K1FieldElement2.x, array4);
x = Nat.ShiftUpBits(7, array4, 2, 0u);
SecP224K1Field.Reduce32(x, array4);
uint[] array5 = Nat224.Create();
x = Nat.ShiftUpBits(7, array2, 3, 0u, array5);
SecP224K1Field.Reduce32(x, array5);
SecP224K1FieldElement secP224K1FieldElement4 = new SecP224K1FieldElement(array2);
SecP224K1Field.Square(array3, secP224K1FieldElement4.x);
SecP224K1Field.Subtract(secP224K1FieldElement4.x, array4, secP224K1FieldElement4.x);
SecP224K1Field.Subtract(secP224K1FieldElement4.x, array4, secP224K1FieldElement4.x);
SecP224K1FieldElement secP224K1FieldElement5 = new SecP224K1FieldElement(array4);
SecP224K1Field.Subtract(array4, secP224K1FieldElement4.x, secP224K1FieldElement5.x);
SecP224K1Field.Multiply(secP224K1FieldElement5.x, array3, secP224K1FieldElement5.x);
SecP224K1Field.Subtract(secP224K1FieldElement5.x, array5, secP224K1FieldElement5.x);
SecP224K1FieldElement secP224K1FieldElement6 = new SecP224K1FieldElement(array3);
SecP224K1Field.Twice(secP224K1FieldElement.x, secP224K1FieldElement6.x);
if (!secP224K1FieldElement3.IsOne)
{
SecP224K1Field.Multiply(secP224K1FieldElement6.x, secP224K1FieldElement3.x, secP224K1FieldElement6.x);
}
return new SecP224K1Point(curve, secP224K1FieldElement4, secP224K1FieldElement5, new ECFieldElement[1] { secP224K1FieldElement6 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
return Twice().Add(b);
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity || base.RawYCoord.IsZero)
{
return this;
}
return Twice().Add(this);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
return new SecP224K1Point(Curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
}

View File

@@ -0,0 +1,119 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP224R1Curve : AbstractFpCurve
{
private class SecP224R1LookupTable : ECLookupTable
{
private readonly SecP224R1Curve m_outer;
private readonly uint[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecP224R1LookupTable(SecP224R1Curve outer, uint[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
uint[] array = Nat224.Create();
uint[] array2 = Nat224.Create();
int num = 0;
for (int i = 0; i < m_size; i++)
{
uint num2 = (uint)((i ^ index) - 1 >> 31);
for (int j = 0; j < 7; j++)
{
uint[] array4;
uint[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
uint[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 7 + j] & num2);
}
num += 14;
}
return m_outer.CreateRawPoint(new SecP224R1FieldElement(array), new SecP224R1FieldElement(array2), withCompression: false);
}
}
private const int SECP224R1_DEFAULT_COORDS = 2;
private const int SECP224R1_FE_INTS = 7;
public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"));
protected readonly SecP224R1Point m_infinity;
public virtual BigInteger Q => q;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => q.BitLength;
public SecP224R1Curve()
: base(q)
{
m_infinity = new SecP224R1Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")));
m_order = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"));
m_cofactor = BigInteger.One;
m_coord = 2;
}
protected override ECCurve CloneCurve()
{
return new SecP224R1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 2)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecP224R1FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecP224R1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecP224R1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
uint[] array = new uint[len * 7 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat224.Copy(((SecP224R1FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 7;
Nat224.Copy(((SecP224R1FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 7;
}
return new SecP224R1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,266 @@
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP224R1Field
{
private const uint P6 = uint.MaxValue;
private const uint PExt13 = uint.MaxValue;
internal static readonly uint[] P = new uint[7] { 1u, 0u, 0u, 4294967295u, 4294967295u, 4294967295u, 4294967295u };
internal static readonly uint[] PExt = new uint[14]
{
1u, 0u, 0u, 4294967294u, 4294967295u, 4294967295u, 0u, 2u, 0u, 0u,
4294967294u, 4294967295u, 4294967295u, 4294967295u
};
private static readonly uint[] PExtInv = new uint[11]
{
4294967295u, 4294967295u, 4294967295u, 1u, 0u, 0u, 4294967295u, 4294967293u, 4294967295u, 4294967295u,
1u
};
public static void Add(uint[] x, uint[] y, uint[] z)
{
if (Nat224.Add(x, y, z) != 0 || (z[6] == uint.MaxValue && Nat224.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
{
if ((Nat.Add(14, xx, yy, zz) != 0 || (zz[13] == uint.MaxValue && Nat.Gte(14, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(14, zz, PExtInv.Length);
}
}
public static void AddOne(uint[] x, uint[] z)
{
if (Nat.Inc(7, x, z) != 0 || (z[6] == uint.MaxValue && Nat224.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static uint[] FromBigInteger(BigInteger x)
{
uint[] array = Nat224.FromBigInteger(x);
if (array[6] == uint.MaxValue && Nat224.Gte(array, P))
{
Nat224.SubFrom(P, array);
}
return array;
}
public static void Half(uint[] x, uint[] z)
{
if ((x[0] & 1) == 0)
{
Nat.ShiftDownBit(7, x, 0u, z);
return;
}
uint c = Nat224.Add(x, P, z);
Nat.ShiftDownBit(7, z, c);
}
public static void Multiply(uint[] x, uint[] y, uint[] z)
{
uint[] array = Nat224.CreateExt();
Nat224.Mul(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
{
if ((Nat224.MulAddTo(x, y, zz) != 0 || (zz[13] == uint.MaxValue && Nat.Gte(14, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(14, zz, PExtInv.Length);
}
}
public static void Negate(uint[] x, uint[] z)
{
if (Nat224.IsZero(x))
{
Nat224.Zero(z);
}
else
{
Nat224.Sub(P, x, z);
}
}
public static void Reduce(uint[] xx, uint[] z)
{
long num = xx[10];
long num2 = xx[11];
long num3 = xx[12];
long num4 = xx[13];
long num5 = xx[7] + num2 - 1;
long num6 = xx[8] + num3;
long num7 = xx[9] + num4;
long num8 = 0L;
num8 += xx[0] - num5;
long num9 = (uint)num8;
num8 >>= 32;
num8 += xx[1] - num6;
z[1] = (uint)num8;
num8 >>= 32;
num8 += xx[2] - num7;
z[2] = (uint)num8;
num8 >>= 32;
num8 += xx[3] + num5 - num;
long num10 = (uint)num8;
num8 >>= 32;
num8 += xx[4] + num6 - num2;
z[4] = (uint)num8;
num8 >>= 32;
num8 += xx[5] + num7 - num3;
z[5] = (uint)num8;
num8 >>= 32;
num8 += xx[6] + num - num4;
z[6] = (uint)num8;
num8 >>= 32;
num8++;
num10 += num8;
num9 -= num8;
z[0] = (uint)num9;
num8 = num9 >> 32;
if (num8 != 0)
{
num8 += z[1];
z[1] = (uint)num8;
num8 >>= 32;
num8 += z[2];
z[2] = (uint)num8;
num10 += num8 >> 32;
}
z[3] = (uint)num10;
num8 = num10 >> 32;
if ((num8 != 0 && Nat.IncAt(7, z, 4) != 0) || (z[6] == uint.MaxValue && Nat224.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static void Reduce32(uint x, uint[] z)
{
long num = 0L;
if (x != 0)
{
long num2 = x;
num += z[0] - num2;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[1];
z[1] = (uint)num;
num >>= 32;
num += z[2];
z[2] = (uint)num;
num >>= 32;
}
num += z[3] + num2;
z[3] = (uint)num;
num >>= 32;
}
if ((num != 0 && Nat.IncAt(7, z, 4) != 0) || (z[6] == uint.MaxValue && Nat224.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static void Square(uint[] x, uint[] z)
{
uint[] array = Nat224.CreateExt();
Nat224.Square(x, array);
Reduce(array, z);
}
public static void SquareN(uint[] x, int n, uint[] z)
{
uint[] array = Nat224.CreateExt();
Nat224.Square(x, array);
Reduce(array, z);
while (--n > 0)
{
Nat224.Square(z, array);
Reduce(array, z);
}
}
public static void Subtract(uint[] x, uint[] y, uint[] z)
{
if (Nat224.Sub(x, y, z) != 0)
{
SubPInvFrom(z);
}
}
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat.Sub(14, xx, yy, zz) != 0 && Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.DecAt(14, zz, PExtInv.Length);
}
}
public static void Twice(uint[] x, uint[] z)
{
if (Nat.ShiftUpBit(7, x, 0u, z) != 0 || (z[6] == uint.MaxValue && Nat224.Gte(z, P)))
{
AddPInvTo(z);
}
}
private static void AddPInvTo(uint[] z)
{
long num = (long)z[0] - 1L;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[1];
z[1] = (uint)num;
num >>= 32;
num += z[2];
z[2] = (uint)num;
num >>= 32;
}
num += (long)z[3] + 1L;
z[3] = (uint)num;
num >>= 32;
if (num != 0)
{
Nat.IncAt(7, z, 4);
}
}
private static void SubPInvFrom(uint[] z)
{
long num = (long)z[0] + 1L;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[1];
z[1] = (uint)num;
num >>= 32;
num += z[2];
z[2] = (uint)num;
num >>= 32;
}
num += (long)z[3] - 1L;
z[3] = (uint)num;
num >>= 32;
if (num != 0)
{
Nat.DecAt(7, z, 4);
}
}
}

View File

@@ -0,0 +1,244 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP224R1FieldElement : AbstractFpFieldElement
{
public static readonly BigInteger Q = SecP224R1Curve.q;
protected internal readonly uint[] x;
public override bool IsZero => Nat224.IsZero(x);
public override bool IsOne => Nat224.IsOne(x);
public override string FieldName => "SecP224R1Field";
public override int FieldSize => Q.BitLength;
public SecP224R1FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
{
throw new ArgumentException("value invalid for SecP224R1FieldElement", "x");
}
this.x = SecP224R1Field.FromBigInteger(x);
}
public SecP224R1FieldElement()
{
x = Nat224.Create();
}
protected internal SecP224R1FieldElement(uint[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return Nat224.GetBit(x, 0) == 1;
}
public override BigInteger ToBigInteger()
{
return Nat224.ToBigInteger(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
uint[] z = Nat224.Create();
SecP224R1Field.Add(x, ((SecP224R1FieldElement)b).x, z);
return new SecP224R1FieldElement(z);
}
public override ECFieldElement AddOne()
{
uint[] z = Nat224.Create();
SecP224R1Field.AddOne(x, z);
return new SecP224R1FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
uint[] z = Nat224.Create();
SecP224R1Field.Subtract(x, ((SecP224R1FieldElement)b).x, z);
return new SecP224R1FieldElement(z);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
uint[] z = Nat224.Create();
SecP224R1Field.Multiply(x, ((SecP224R1FieldElement)b).x, z);
return new SecP224R1FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
uint[] z = Nat224.Create();
Mod.Invert(SecP224R1Field.P, ((SecP224R1FieldElement)b).x, z);
SecP224R1Field.Multiply(z, x, z);
return new SecP224R1FieldElement(z);
}
public override ECFieldElement Negate()
{
uint[] z = Nat224.Create();
SecP224R1Field.Negate(x, z);
return new SecP224R1FieldElement(z);
}
public override ECFieldElement Square()
{
uint[] z = Nat224.Create();
SecP224R1Field.Square(x, z);
return new SecP224R1FieldElement(z);
}
public override ECFieldElement Invert()
{
uint[] z = Nat224.Create();
Mod.Invert(SecP224R1Field.P, x, z);
return new SecP224R1FieldElement(z);
}
public override ECFieldElement Sqrt()
{
uint[] array = x;
if (Nat224.IsZero(array) || Nat224.IsOne(array))
{
return this;
}
uint[] array2 = Nat224.Create();
SecP224R1Field.Negate(array, array2);
uint[] array3 = Mod.Random(SecP224R1Field.P);
uint[] t = Nat224.Create();
if (!IsSquare(array))
{
return null;
}
while (!TrySqrt(array2, array3, t))
{
SecP224R1Field.AddOne(array3, array3);
}
SecP224R1Field.Square(t, array3);
if (!Nat224.Eq(array, array3))
{
return null;
}
return new SecP224R1FieldElement(t);
}
public override bool Equals(object obj)
{
return Equals(obj as SecP224R1FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecP224R1FieldElement);
}
public virtual bool Equals(SecP224R1FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat224.Eq(x, other.x);
}
public override int GetHashCode()
{
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 7);
}
private static bool IsSquare(uint[] x)
{
uint[] z = Nat224.Create();
uint[] array = Nat224.Create();
Nat224.Copy(x, z);
for (int i = 0; i < 7; i++)
{
Nat224.Copy(z, array);
SecP224R1Field.SquareN(z, 1 << i, z);
SecP224R1Field.Multiply(z, array, z);
}
SecP224R1Field.SquareN(z, 95, z);
return Nat224.IsOne(z);
}
private static void RM(uint[] nc, uint[] d0, uint[] e0, uint[] d1, uint[] e1, uint[] f1, uint[] t)
{
SecP224R1Field.Multiply(e1, e0, t);
SecP224R1Field.Multiply(t, nc, t);
SecP224R1Field.Multiply(d1, d0, f1);
SecP224R1Field.Add(f1, t, f1);
SecP224R1Field.Multiply(d1, e0, t);
Nat224.Copy(f1, d1);
SecP224R1Field.Multiply(e1, d0, e1);
SecP224R1Field.Add(e1, t, e1);
SecP224R1Field.Square(e1, f1);
SecP224R1Field.Multiply(f1, nc, f1);
}
private static void RP(uint[] nc, uint[] d1, uint[] e1, uint[] f1, uint[] t)
{
Nat224.Copy(nc, f1);
uint[] array = Nat224.Create();
uint[] array2 = Nat224.Create();
for (int i = 0; i < 7; i++)
{
Nat224.Copy(d1, array);
Nat224.Copy(e1, array2);
int num = 1 << i;
while (--num >= 0)
{
RS(d1, e1, f1, t);
}
RM(nc, array, array2, d1, e1, f1, t);
}
}
private static void RS(uint[] d, uint[] e, uint[] f, uint[] t)
{
SecP224R1Field.Multiply(e, d, e);
SecP224R1Field.Twice(e, e);
SecP224R1Field.Square(d, t);
SecP224R1Field.Add(f, t, d);
SecP224R1Field.Multiply(f, t, f);
uint num = Nat.ShiftUpBits(7, f, 2, 0u);
SecP224R1Field.Reduce32(num, f);
}
private static bool TrySqrt(uint[] nc, uint[] r, uint[] t)
{
uint[] array = Nat224.Create();
Nat224.Copy(r, array);
uint[] array2 = Nat224.Create();
array2[0] = 1u;
uint[] array3 = Nat224.Create();
RP(nc, array, array2, array3, t);
uint[] array4 = Nat224.Create();
uint[] z = Nat224.Create();
for (int i = 1; i < 96; i++)
{
Nat224.Copy(array, array4);
Nat224.Copy(array2, z);
RS(array, array2, array3, t);
if (Nat224.IsZero(array))
{
Mod.Invert(SecP224R1Field.P, z, t);
SecP224R1Field.Multiply(t, array4, t);
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,228 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP224R1Point : AbstractFpPoint
{
public SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecP224R1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
SecP224R1FieldElement secP224R1FieldElement = (SecP224R1FieldElement)base.RawXCoord;
SecP224R1FieldElement secP224R1FieldElement2 = (SecP224R1FieldElement)base.RawYCoord;
SecP224R1FieldElement secP224R1FieldElement3 = (SecP224R1FieldElement)b.RawXCoord;
SecP224R1FieldElement secP224R1FieldElement4 = (SecP224R1FieldElement)b.RawYCoord;
SecP224R1FieldElement secP224R1FieldElement5 = (SecP224R1FieldElement)base.RawZCoords[0];
SecP224R1FieldElement secP224R1FieldElement6 = (SecP224R1FieldElement)b.RawZCoords[0];
uint[] array = Nat224.CreateExt();
uint[] array2 = Nat224.Create();
uint[] array3 = Nat224.Create();
uint[] array4 = Nat224.Create();
bool isOne = secP224R1FieldElement5.IsOne;
uint[] array5;
uint[] array6;
if (isOne)
{
array5 = secP224R1FieldElement3.x;
array6 = secP224R1FieldElement4.x;
}
else
{
array6 = array3;
SecP224R1Field.Square(secP224R1FieldElement5.x, array6);
array5 = array2;
SecP224R1Field.Multiply(array6, secP224R1FieldElement3.x, array5);
SecP224R1Field.Multiply(array6, secP224R1FieldElement5.x, array6);
SecP224R1Field.Multiply(array6, secP224R1FieldElement4.x, array6);
}
bool isOne2 = secP224R1FieldElement6.IsOne;
uint[] array7;
uint[] array8;
if (isOne2)
{
array7 = secP224R1FieldElement.x;
array8 = secP224R1FieldElement2.x;
}
else
{
array8 = array4;
SecP224R1Field.Square(secP224R1FieldElement6.x, array8);
array7 = array;
SecP224R1Field.Multiply(array8, secP224R1FieldElement.x, array7);
SecP224R1Field.Multiply(array8, secP224R1FieldElement6.x, array8);
SecP224R1Field.Multiply(array8, secP224R1FieldElement2.x, array8);
}
uint[] array9 = Nat224.Create();
SecP224R1Field.Subtract(array7, array5, array9);
uint[] array10 = array2;
SecP224R1Field.Subtract(array8, array6, array10);
if (Nat224.IsZero(array9))
{
if (Nat224.IsZero(array10))
{
return Twice();
}
return curve.Infinity;
}
uint[] array11 = array3;
SecP224R1Field.Square(array9, array11);
uint[] array12 = Nat224.Create();
SecP224R1Field.Multiply(array11, array9, array12);
uint[] array13 = array3;
SecP224R1Field.Multiply(array11, array7, array13);
SecP224R1Field.Negate(array12, array12);
Nat224.Mul(array8, array12, array);
uint x = Nat224.AddBothTo(array13, array13, array12);
SecP224R1Field.Reduce32(x, array12);
SecP224R1FieldElement secP224R1FieldElement7 = new SecP224R1FieldElement(array4);
SecP224R1Field.Square(array10, secP224R1FieldElement7.x);
SecP224R1Field.Subtract(secP224R1FieldElement7.x, array12, secP224R1FieldElement7.x);
SecP224R1FieldElement secP224R1FieldElement8 = new SecP224R1FieldElement(array12);
SecP224R1Field.Subtract(array13, secP224R1FieldElement7.x, secP224R1FieldElement8.x);
SecP224R1Field.MultiplyAddToExt(secP224R1FieldElement8.x, array10, array);
SecP224R1Field.Reduce(array, secP224R1FieldElement8.x);
SecP224R1FieldElement secP224R1FieldElement9 = new SecP224R1FieldElement(array9);
if (!isOne)
{
SecP224R1Field.Multiply(secP224R1FieldElement9.x, secP224R1FieldElement5.x, secP224R1FieldElement9.x);
}
if (!isOne2)
{
SecP224R1Field.Multiply(secP224R1FieldElement9.x, secP224R1FieldElement6.x, secP224R1FieldElement9.x);
}
ECFieldElement[] zs = new ECFieldElement[1] { secP224R1FieldElement9 };
return new SecP224R1Point(curve, secP224R1FieldElement7, secP224R1FieldElement8, zs, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
SecP224R1FieldElement secP224R1FieldElement = (SecP224R1FieldElement)base.RawYCoord;
if (secP224R1FieldElement.IsZero)
{
return curve.Infinity;
}
SecP224R1FieldElement secP224R1FieldElement2 = (SecP224R1FieldElement)base.RawXCoord;
SecP224R1FieldElement secP224R1FieldElement3 = (SecP224R1FieldElement)base.RawZCoords[0];
uint[] array = Nat224.Create();
uint[] array2 = Nat224.Create();
uint[] array3 = Nat224.Create();
SecP224R1Field.Square(secP224R1FieldElement.x, array3);
uint[] array4 = Nat224.Create();
SecP224R1Field.Square(array3, array4);
bool isOne = secP224R1FieldElement3.IsOne;
uint[] array5 = secP224R1FieldElement3.x;
if (!isOne)
{
array5 = array2;
SecP224R1Field.Square(secP224R1FieldElement3.x, array5);
}
SecP224R1Field.Subtract(secP224R1FieldElement2.x, array5, array);
uint[] array6 = array2;
SecP224R1Field.Add(secP224R1FieldElement2.x, array5, array6);
SecP224R1Field.Multiply(array6, array, array6);
uint x = Nat224.AddBothTo(array6, array6, array6);
SecP224R1Field.Reduce32(x, array6);
uint[] array7 = array3;
SecP224R1Field.Multiply(array3, secP224R1FieldElement2.x, array7);
x = Nat.ShiftUpBits(7, array7, 2, 0u);
SecP224R1Field.Reduce32(x, array7);
x = Nat.ShiftUpBits(7, array4, 3, 0u, array);
SecP224R1Field.Reduce32(x, array);
SecP224R1FieldElement secP224R1FieldElement4 = new SecP224R1FieldElement(array4);
SecP224R1Field.Square(array6, secP224R1FieldElement4.x);
SecP224R1Field.Subtract(secP224R1FieldElement4.x, array7, secP224R1FieldElement4.x);
SecP224R1Field.Subtract(secP224R1FieldElement4.x, array7, secP224R1FieldElement4.x);
SecP224R1FieldElement secP224R1FieldElement5 = new SecP224R1FieldElement(array7);
SecP224R1Field.Subtract(array7, secP224R1FieldElement4.x, secP224R1FieldElement5.x);
SecP224R1Field.Multiply(secP224R1FieldElement5.x, array6, secP224R1FieldElement5.x);
SecP224R1Field.Subtract(secP224R1FieldElement5.x, array, secP224R1FieldElement5.x);
SecP224R1FieldElement secP224R1FieldElement6 = new SecP224R1FieldElement(array6);
SecP224R1Field.Twice(secP224R1FieldElement.x, secP224R1FieldElement6.x);
if (!isOne)
{
SecP224R1Field.Multiply(secP224R1FieldElement6.x, secP224R1FieldElement3.x, secP224R1FieldElement6.x);
}
return new SecP224R1Point(curve, secP224R1FieldElement4, secP224R1FieldElement5, new ECFieldElement[1] { secP224R1FieldElement6 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
return Twice().Add(b);
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity || base.RawYCoord.IsZero)
{
return this;
}
return Twice().Add(this);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
return new SecP224R1Point(Curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
}

View File

@@ -0,0 +1,119 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP256K1Curve : AbstractFpCurve
{
private class SecP256K1LookupTable : ECLookupTable
{
private readonly SecP256K1Curve m_outer;
private readonly uint[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecP256K1LookupTable(SecP256K1Curve outer, uint[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
uint[] array = Nat256.Create();
uint[] array2 = Nat256.Create();
int num = 0;
for (int i = 0; i < m_size; i++)
{
uint num2 = (uint)((i ^ index) - 1 >> 31);
for (int j = 0; j < 8; j++)
{
uint[] array4;
uint[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
uint[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 8 + j] & num2);
}
num += 16;
}
return m_outer.CreateRawPoint(new SecP256K1FieldElement(array), new SecP256K1FieldElement(array2), withCompression: false);
}
}
private const int SECP256K1_DEFAULT_COORDS = 2;
private const int SECP256K1_FE_INTS = 8;
public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"));
protected readonly SecP256K1Point m_infinity;
public virtual BigInteger Q => q;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => q.BitLength;
public SecP256K1Curve()
: base(q)
{
m_infinity = new SecP256K1Point(this, null, null);
m_a = FromBigInteger(BigInteger.Zero);
m_b = FromBigInteger(BigInteger.ValueOf(7L));
m_order = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"));
m_cofactor = BigInteger.One;
m_coord = 2;
}
protected override ECCurve CloneCurve()
{
return new SecP256K1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 2)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecP256K1FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecP256K1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecP256K1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
uint[] array = new uint[len * 8 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat256.Copy(((SecP256K1FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 8;
Nat256.Copy(((SecP256K1FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 8;
}
return new SecP256K1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,154 @@
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP256K1Field
{
private const uint P7 = uint.MaxValue;
private const uint PExt15 = uint.MaxValue;
private const uint PInv33 = 977u;
internal static readonly uint[] P = new uint[8] { 4294966319u, 4294967294u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u };
internal static readonly uint[] PExt = new uint[16]
{
954529u, 1954u, 1u, 0u, 0u, 0u, 0u, 0u, 4294965342u, 4294967293u,
4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u
};
private static readonly uint[] PExtInv = new uint[10] { 4294012767u, 4294965341u, 4294967294u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 1953u, 2u };
public static void Add(uint[] x, uint[] y, uint[] z)
{
if (Nat256.Add(x, y, z) != 0 || (z[7] == uint.MaxValue && Nat256.Gte(z, P)))
{
Nat.Add33To(8, 977u, z);
}
}
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
{
if ((Nat.Add(16, xx, yy, zz) != 0 || (zz[15] == uint.MaxValue && Nat.Gte(16, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(16, zz, PExtInv.Length);
}
}
public static void AddOne(uint[] x, uint[] z)
{
if (Nat.Inc(8, x, z) != 0 || (z[7] == uint.MaxValue && Nat256.Gte(z, P)))
{
Nat.Add33To(8, 977u, z);
}
}
public static uint[] FromBigInteger(BigInteger x)
{
uint[] array = Nat256.FromBigInteger(x);
if (array[7] == uint.MaxValue && Nat256.Gte(array, P))
{
Nat256.SubFrom(P, array);
}
return array;
}
public static void Half(uint[] x, uint[] z)
{
if ((x[0] & 1) == 0)
{
Nat.ShiftDownBit(8, x, 0u, z);
return;
}
uint c = Nat256.Add(x, P, z);
Nat.ShiftDownBit(8, z, c);
}
public static void Multiply(uint[] x, uint[] y, uint[] z)
{
uint[] array = Nat256.CreateExt();
Nat256.Mul(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
{
if ((Nat256.MulAddTo(x, y, zz) != 0 || (zz[15] == uint.MaxValue && Nat.Gte(16, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(16, zz, PExtInv.Length);
}
}
public static void Negate(uint[] x, uint[] z)
{
if (Nat256.IsZero(x))
{
Nat256.Zero(z);
}
else
{
Nat256.Sub(P, x, z);
}
}
public static void Reduce(uint[] xx, uint[] z)
{
ulong y = Nat256.Mul33Add(977u, xx, 8, xx, 0, z, 0);
if (Nat256.Mul33DWordAdd(977u, y, z, 0) != 0 || (z[7] == uint.MaxValue && Nat256.Gte(z, P)))
{
Nat.Add33To(8, 977u, z);
}
}
public static void Reduce32(uint x, uint[] z)
{
if ((x != 0 && Nat256.Mul33WordAdd(977u, x, z, 0) != 0) || (z[7] == uint.MaxValue && Nat256.Gte(z, P)))
{
Nat.Add33To(8, 977u, z);
}
}
public static void Square(uint[] x, uint[] z)
{
uint[] array = Nat256.CreateExt();
Nat256.Square(x, array);
Reduce(array, z);
}
public static void SquareN(uint[] x, int n, uint[] z)
{
uint[] array = Nat256.CreateExt();
Nat256.Square(x, array);
Reduce(array, z);
while (--n > 0)
{
Nat256.Square(z, array);
Reduce(array, z);
}
}
public static void Subtract(uint[] x, uint[] y, uint[] z)
{
if (Nat256.Sub(x, y, z) != 0)
{
Nat.Sub33From(8, 977u, z);
}
}
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat.Sub(16, xx, yy, zz) != 0 && Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.DecAt(16, zz, PExtInv.Length);
}
}
public static void Twice(uint[] x, uint[] z)
{
if (Nat.ShiftUpBit(8, x, 0u, z) != 0 || (z[7] == uint.MaxValue && Nat256.Gte(z, P)))
{
Nat.Add33To(8, 977u, z);
}
}
}

View File

@@ -0,0 +1,189 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP256K1FieldElement : AbstractFpFieldElement
{
public static readonly BigInteger Q = SecP256K1Curve.q;
protected internal readonly uint[] x;
public override bool IsZero => Nat256.IsZero(x);
public override bool IsOne => Nat256.IsOne(x);
public override string FieldName => "SecP256K1Field";
public override int FieldSize => Q.BitLength;
public SecP256K1FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
{
throw new ArgumentException("value invalid for SecP256K1FieldElement", "x");
}
this.x = SecP256K1Field.FromBigInteger(x);
}
public SecP256K1FieldElement()
{
x = Nat256.Create();
}
protected internal SecP256K1FieldElement(uint[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return Nat256.GetBit(x, 0) == 1;
}
public override BigInteger ToBigInteger()
{
return Nat256.ToBigInteger(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
uint[] z = Nat256.Create();
SecP256K1Field.Add(x, ((SecP256K1FieldElement)b).x, z);
return new SecP256K1FieldElement(z);
}
public override ECFieldElement AddOne()
{
uint[] z = Nat256.Create();
SecP256K1Field.AddOne(x, z);
return new SecP256K1FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
uint[] z = Nat256.Create();
SecP256K1Field.Subtract(x, ((SecP256K1FieldElement)b).x, z);
return new SecP256K1FieldElement(z);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
uint[] z = Nat256.Create();
SecP256K1Field.Multiply(x, ((SecP256K1FieldElement)b).x, z);
return new SecP256K1FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
uint[] z = Nat256.Create();
Mod.Invert(SecP256K1Field.P, ((SecP256K1FieldElement)b).x, z);
SecP256K1Field.Multiply(z, x, z);
return new SecP256K1FieldElement(z);
}
public override ECFieldElement Negate()
{
uint[] z = Nat256.Create();
SecP256K1Field.Negate(x, z);
return new SecP256K1FieldElement(z);
}
public override ECFieldElement Square()
{
uint[] z = Nat256.Create();
SecP256K1Field.Square(x, z);
return new SecP256K1FieldElement(z);
}
public override ECFieldElement Invert()
{
uint[] z = Nat256.Create();
Mod.Invert(SecP256K1Field.P, x, z);
return new SecP256K1FieldElement(z);
}
public override ECFieldElement Sqrt()
{
uint[] y = x;
if (Nat256.IsZero(y) || Nat256.IsOne(y))
{
return this;
}
uint[] array = Nat256.Create();
SecP256K1Field.Square(y, array);
SecP256K1Field.Multiply(array, y, array);
uint[] array2 = Nat256.Create();
SecP256K1Field.Square(array, array2);
SecP256K1Field.Multiply(array2, y, array2);
uint[] array3 = Nat256.Create();
SecP256K1Field.SquareN(array2, 3, array3);
SecP256K1Field.Multiply(array3, array2, array3);
uint[] array4 = array3;
SecP256K1Field.SquareN(array3, 3, array4);
SecP256K1Field.Multiply(array4, array2, array4);
uint[] array5 = array4;
SecP256K1Field.SquareN(array4, 2, array5);
SecP256K1Field.Multiply(array5, array, array5);
uint[] array6 = Nat256.Create();
SecP256K1Field.SquareN(array5, 11, array6);
SecP256K1Field.Multiply(array6, array5, array6);
uint[] array7 = array5;
SecP256K1Field.SquareN(array6, 22, array7);
SecP256K1Field.Multiply(array7, array6, array7);
uint[] array8 = Nat256.Create();
SecP256K1Field.SquareN(array7, 44, array8);
SecP256K1Field.Multiply(array8, array7, array8);
uint[] z = Nat256.Create();
SecP256K1Field.SquareN(array8, 88, z);
SecP256K1Field.Multiply(z, array8, z);
uint[] z2 = array8;
SecP256K1Field.SquareN(z, 44, z2);
SecP256K1Field.Multiply(z2, array7, z2);
uint[] array9 = array7;
SecP256K1Field.SquareN(z2, 3, array9);
SecP256K1Field.Multiply(array9, array2, array9);
uint[] z3 = array9;
SecP256K1Field.SquareN(z3, 23, z3);
SecP256K1Field.Multiply(z3, array6, z3);
SecP256K1Field.SquareN(z3, 6, z3);
SecP256K1Field.Multiply(z3, array, z3);
SecP256K1Field.SquareN(z3, 2, z3);
uint[] array10 = array;
SecP256K1Field.Square(z3, array10);
if (!Nat256.Eq(y, array10))
{
return null;
}
return new SecP256K1FieldElement(z3);
}
public override bool Equals(object obj)
{
return Equals(obj as SecP256K1FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecP256K1FieldElement);
}
public virtual bool Equals(SecP256K1FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat256.Eq(x, other.x);
}
public override int GetHashCode()
{
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 8);
}
}

View File

@@ -0,0 +1,218 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP256K1Point : AbstractFpPoint
{
public SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecP256K1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
SecP256K1FieldElement secP256K1FieldElement = (SecP256K1FieldElement)base.RawXCoord;
SecP256K1FieldElement secP256K1FieldElement2 = (SecP256K1FieldElement)base.RawYCoord;
SecP256K1FieldElement secP256K1FieldElement3 = (SecP256K1FieldElement)b.RawXCoord;
SecP256K1FieldElement secP256K1FieldElement4 = (SecP256K1FieldElement)b.RawYCoord;
SecP256K1FieldElement secP256K1FieldElement5 = (SecP256K1FieldElement)base.RawZCoords[0];
SecP256K1FieldElement secP256K1FieldElement6 = (SecP256K1FieldElement)b.RawZCoords[0];
uint[] array = Nat256.CreateExt();
uint[] array2 = Nat256.Create();
uint[] array3 = Nat256.Create();
uint[] array4 = Nat256.Create();
bool isOne = secP256K1FieldElement5.IsOne;
uint[] array5;
uint[] array6;
if (isOne)
{
array5 = secP256K1FieldElement3.x;
array6 = secP256K1FieldElement4.x;
}
else
{
array6 = array3;
SecP256K1Field.Square(secP256K1FieldElement5.x, array6);
array5 = array2;
SecP256K1Field.Multiply(array6, secP256K1FieldElement3.x, array5);
SecP256K1Field.Multiply(array6, secP256K1FieldElement5.x, array6);
SecP256K1Field.Multiply(array6, secP256K1FieldElement4.x, array6);
}
bool isOne2 = secP256K1FieldElement6.IsOne;
uint[] array7;
uint[] array8;
if (isOne2)
{
array7 = secP256K1FieldElement.x;
array8 = secP256K1FieldElement2.x;
}
else
{
array8 = array4;
SecP256K1Field.Square(secP256K1FieldElement6.x, array8);
array7 = array;
SecP256K1Field.Multiply(array8, secP256K1FieldElement.x, array7);
SecP256K1Field.Multiply(array8, secP256K1FieldElement6.x, array8);
SecP256K1Field.Multiply(array8, secP256K1FieldElement2.x, array8);
}
uint[] array9 = Nat256.Create();
SecP256K1Field.Subtract(array7, array5, array9);
uint[] array10 = array2;
SecP256K1Field.Subtract(array8, array6, array10);
if (Nat256.IsZero(array9))
{
if (Nat256.IsZero(array10))
{
return Twice();
}
return curve.Infinity;
}
uint[] array11 = array3;
SecP256K1Field.Square(array9, array11);
uint[] array12 = Nat256.Create();
SecP256K1Field.Multiply(array11, array9, array12);
uint[] array13 = array3;
SecP256K1Field.Multiply(array11, array7, array13);
SecP256K1Field.Negate(array12, array12);
Nat256.Mul(array8, array12, array);
uint x = Nat256.AddBothTo(array13, array13, array12);
SecP256K1Field.Reduce32(x, array12);
SecP256K1FieldElement secP256K1FieldElement7 = new SecP256K1FieldElement(array4);
SecP256K1Field.Square(array10, secP256K1FieldElement7.x);
SecP256K1Field.Subtract(secP256K1FieldElement7.x, array12, secP256K1FieldElement7.x);
SecP256K1FieldElement secP256K1FieldElement8 = new SecP256K1FieldElement(array12);
SecP256K1Field.Subtract(array13, secP256K1FieldElement7.x, secP256K1FieldElement8.x);
SecP256K1Field.MultiplyAddToExt(secP256K1FieldElement8.x, array10, array);
SecP256K1Field.Reduce(array, secP256K1FieldElement8.x);
SecP256K1FieldElement secP256K1FieldElement9 = new SecP256K1FieldElement(array9);
if (!isOne)
{
SecP256K1Field.Multiply(secP256K1FieldElement9.x, secP256K1FieldElement5.x, secP256K1FieldElement9.x);
}
if (!isOne2)
{
SecP256K1Field.Multiply(secP256K1FieldElement9.x, secP256K1FieldElement6.x, secP256K1FieldElement9.x);
}
ECFieldElement[] zs = new ECFieldElement[1] { secP256K1FieldElement9 };
return new SecP256K1Point(curve, secP256K1FieldElement7, secP256K1FieldElement8, zs, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
SecP256K1FieldElement secP256K1FieldElement = (SecP256K1FieldElement)base.RawYCoord;
if (secP256K1FieldElement.IsZero)
{
return curve.Infinity;
}
SecP256K1FieldElement secP256K1FieldElement2 = (SecP256K1FieldElement)base.RawXCoord;
SecP256K1FieldElement secP256K1FieldElement3 = (SecP256K1FieldElement)base.RawZCoords[0];
uint[] array = Nat256.Create();
SecP256K1Field.Square(secP256K1FieldElement.x, array);
uint[] array2 = Nat256.Create();
SecP256K1Field.Square(array, array2);
uint[] array3 = Nat256.Create();
SecP256K1Field.Square(secP256K1FieldElement2.x, array3);
uint x = Nat256.AddBothTo(array3, array3, array3);
SecP256K1Field.Reduce32(x, array3);
uint[] array4 = array;
SecP256K1Field.Multiply(array, secP256K1FieldElement2.x, array4);
x = Nat.ShiftUpBits(8, array4, 2, 0u);
SecP256K1Field.Reduce32(x, array4);
uint[] array5 = Nat256.Create();
x = Nat.ShiftUpBits(8, array2, 3, 0u, array5);
SecP256K1Field.Reduce32(x, array5);
SecP256K1FieldElement secP256K1FieldElement4 = new SecP256K1FieldElement(array2);
SecP256K1Field.Square(array3, secP256K1FieldElement4.x);
SecP256K1Field.Subtract(secP256K1FieldElement4.x, array4, secP256K1FieldElement4.x);
SecP256K1Field.Subtract(secP256K1FieldElement4.x, array4, secP256K1FieldElement4.x);
SecP256K1FieldElement secP256K1FieldElement5 = new SecP256K1FieldElement(array4);
SecP256K1Field.Subtract(array4, secP256K1FieldElement4.x, secP256K1FieldElement5.x);
SecP256K1Field.Multiply(secP256K1FieldElement5.x, array3, secP256K1FieldElement5.x);
SecP256K1Field.Subtract(secP256K1FieldElement5.x, array5, secP256K1FieldElement5.x);
SecP256K1FieldElement secP256K1FieldElement6 = new SecP256K1FieldElement(array3);
SecP256K1Field.Twice(secP256K1FieldElement.x, secP256K1FieldElement6.x);
if (!secP256K1FieldElement3.IsOne)
{
SecP256K1Field.Multiply(secP256K1FieldElement6.x, secP256K1FieldElement3.x, secP256K1FieldElement6.x);
}
return new SecP256K1Point(curve, secP256K1FieldElement4, secP256K1FieldElement5, new ECFieldElement[1] { secP256K1FieldElement6 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
return Twice().Add(b);
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity || base.RawYCoord.IsZero)
{
return this;
}
return Twice().Add(this);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
return new SecP256K1Point(Curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
}

View File

@@ -0,0 +1,119 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP256R1Curve : AbstractFpCurve
{
private class SecP256R1LookupTable : ECLookupTable
{
private readonly SecP256R1Curve m_outer;
private readonly uint[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecP256R1LookupTable(SecP256R1Curve outer, uint[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
uint[] array = Nat256.Create();
uint[] array2 = Nat256.Create();
int num = 0;
for (int i = 0; i < m_size; i++)
{
uint num2 = (uint)((i ^ index) - 1 >> 31);
for (int j = 0; j < 8; j++)
{
uint[] array4;
uint[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
uint[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 8 + j] & num2);
}
num += 16;
}
return m_outer.CreateRawPoint(new SecP256R1FieldElement(array), new SecP256R1FieldElement(array2), withCompression: false);
}
}
private const int SECP256R1_DEFAULT_COORDS = 2;
private const int SECP256R1_FE_INTS = 8;
public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"));
protected readonly SecP256R1Point m_infinity;
public virtual BigInteger Q => q;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => q.BitLength;
public SecP256R1Curve()
: base(q)
{
m_infinity = new SecP256R1Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")));
m_order = new BigInteger(1, Hex.Decode("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"));
m_cofactor = BigInteger.One;
m_coord = 2;
}
protected override ECCurve CloneCurve()
{
return new SecP256R1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 2)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecP256R1FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecP256R1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecP256R1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
uint[] array = new uint[len * 8 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat256.Copy(((SecP256R1FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 8;
Nat256.Copy(((SecP256R1FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 8;
}
return new SecP256R1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,290 @@
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP256R1Field
{
internal const uint P7 = uint.MaxValue;
internal const uint PExt15 = 4294967294u;
internal static readonly uint[] P = new uint[8] { 4294967295u, 4294967295u, 4294967295u, 0u, 0u, 0u, 1u, 4294967295u };
internal static readonly uint[] PExt = new uint[16]
{
1u, 0u, 0u, 4294967294u, 4294967295u, 4294967295u, 4294967294u, 1u, 4294967294u, 1u,
4294967294u, 1u, 1u, 4294967294u, 2u, 4294967294u
};
public static void Add(uint[] x, uint[] y, uint[] z)
{
if (Nat256.Add(x, y, z) != 0 || (z[7] == uint.MaxValue && Nat256.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat.Add(16, xx, yy, zz) != 0 || (zz[15] >= 4294967294u && Nat.Gte(16, zz, PExt)))
{
Nat.SubFrom(16, PExt, zz);
}
}
public static void AddOne(uint[] x, uint[] z)
{
if (Nat.Inc(8, x, z) != 0 || (z[7] == uint.MaxValue && Nat256.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static uint[] FromBigInteger(BigInteger x)
{
uint[] array = Nat256.FromBigInteger(x);
if (array[7] == uint.MaxValue && Nat256.Gte(array, P))
{
Nat256.SubFrom(P, array);
}
return array;
}
public static void Half(uint[] x, uint[] z)
{
if ((x[0] & 1) == 0)
{
Nat.ShiftDownBit(8, x, 0u, z);
return;
}
uint c = Nat256.Add(x, P, z);
Nat.ShiftDownBit(8, z, c);
}
public static void Multiply(uint[] x, uint[] y, uint[] z)
{
uint[] array = Nat256.CreateExt();
Nat256.Mul(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
{
if (Nat256.MulAddTo(x, y, zz) != 0 || (zz[15] >= 4294967294u && Nat.Gte(16, zz, PExt)))
{
Nat.SubFrom(16, PExt, zz);
}
}
public static void Negate(uint[] x, uint[] z)
{
if (Nat256.IsZero(x))
{
Nat256.Zero(z);
}
else
{
Nat256.Sub(P, x, z);
}
}
public static void Reduce(uint[] xx, uint[] z)
{
long num = xx[8];
long num2 = xx[9];
long num3 = xx[10];
long num4 = xx[11];
long num5 = xx[12];
long num6 = xx[13];
long num7 = xx[14];
long num8 = xx[15];
num -= 6;
long num9 = num + num2;
long num10 = num2 + num3;
long num11 = num3 + num4 - num8;
long num12 = num4 + num5;
long num13 = num5 + num6;
long num14 = num6 + num7;
long num15 = num7 + num8;
long num16 = num14 - num9;
long num17 = 0L;
num17 += xx[0] - num12 - num16;
z[0] = (uint)num17;
num17 >>= 32;
num17 += xx[1] + num10 - num13 - num15;
z[1] = (uint)num17;
num17 >>= 32;
num17 += xx[2] + num11 - num14;
z[2] = (uint)num17;
num17 >>= 32;
num17 += xx[3] + (num12 << 1) + num16 - num15;
z[3] = (uint)num17;
num17 >>= 32;
num17 += xx[4] + (num13 << 1) + num7 - num10;
z[4] = (uint)num17;
num17 >>= 32;
num17 += xx[5] + (num14 << 1) - num11;
z[5] = (uint)num17;
num17 >>= 32;
num17 += xx[6] + (num15 << 1) + num16;
z[6] = (uint)num17;
num17 >>= 32;
num17 += xx[7] + (num8 << 1) + num - num11 - num13;
z[7] = (uint)num17;
num17 >>= 32;
num17 += 6;
Reduce32((uint)num17, z);
}
public static void Reduce32(uint x, uint[] z)
{
long num = 0L;
if (x != 0)
{
long num2 = x;
num += z[0] + num2;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[1];
z[1] = (uint)num;
num >>= 32;
num += z[2];
z[2] = (uint)num;
num >>= 32;
}
num += z[3] - num2;
z[3] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[4];
z[4] = (uint)num;
num >>= 32;
num += z[5];
z[5] = (uint)num;
num >>= 32;
}
num += z[6] - num2;
z[6] = (uint)num;
num >>= 32;
num += z[7] + num2;
z[7] = (uint)num;
num >>= 32;
}
if (num != 0 || (z[7] == uint.MaxValue && Nat256.Gte(z, P)))
{
AddPInvTo(z);
}
}
public static void Square(uint[] x, uint[] z)
{
uint[] array = Nat256.CreateExt();
Nat256.Square(x, array);
Reduce(array, z);
}
public static void SquareN(uint[] x, int n, uint[] z)
{
uint[] array = Nat256.CreateExt();
Nat256.Square(x, array);
Reduce(array, z);
while (--n > 0)
{
Nat256.Square(z, array);
Reduce(array, z);
}
}
public static void Subtract(uint[] x, uint[] y, uint[] z)
{
if (Nat256.Sub(x, y, z) != 0)
{
SubPInvFrom(z);
}
}
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat.Sub(16, xx, yy, zz) != 0)
{
Nat.AddTo(16, PExt, zz);
}
}
public static void Twice(uint[] x, uint[] z)
{
if (Nat.ShiftUpBit(8, x, 0u, z) != 0 || (z[7] == uint.MaxValue && Nat256.Gte(z, P)))
{
AddPInvTo(z);
}
}
private static void AddPInvTo(uint[] z)
{
long num = (long)z[0] + 1L;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[1];
z[1] = (uint)num;
num >>= 32;
num += z[2];
z[2] = (uint)num;
num >>= 32;
}
num += (long)z[3] - 1L;
z[3] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[4];
z[4] = (uint)num;
num >>= 32;
num += z[5];
z[5] = (uint)num;
num >>= 32;
}
num += (long)z[6] - 1L;
z[6] = (uint)num;
num >>= 32;
num += (long)z[7] + 1L;
z[7] = (uint)num;
}
private static void SubPInvFrom(uint[] z)
{
long num = (long)z[0] - 1L;
z[0] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[1];
z[1] = (uint)num;
num >>= 32;
num += z[2];
z[2] = (uint)num;
num >>= 32;
}
num += (long)z[3] + 1L;
z[3] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[4];
z[4] = (uint)num;
num >>= 32;
num += z[5];
z[5] = (uint)num;
num >>= 32;
}
num += (long)z[6] + 1L;
z[6] = (uint)num;
num >>= 32;
num += (long)z[7] - 1L;
z[7] = (uint)num;
}
}

View File

@@ -0,0 +1,166 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP256R1FieldElement : AbstractFpFieldElement
{
public static readonly BigInteger Q = SecP256R1Curve.q;
protected internal readonly uint[] x;
public override bool IsZero => Nat256.IsZero(x);
public override bool IsOne => Nat256.IsOne(x);
public override string FieldName => "SecP256R1Field";
public override int FieldSize => Q.BitLength;
public SecP256R1FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
{
throw new ArgumentException("value invalid for SecP256R1FieldElement", "x");
}
this.x = SecP256R1Field.FromBigInteger(x);
}
public SecP256R1FieldElement()
{
x = Nat256.Create();
}
protected internal SecP256R1FieldElement(uint[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return Nat256.GetBit(x, 0) == 1;
}
public override BigInteger ToBigInteger()
{
return Nat256.ToBigInteger(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
uint[] z = Nat256.Create();
SecP256R1Field.Add(x, ((SecP256R1FieldElement)b).x, z);
return new SecP256R1FieldElement(z);
}
public override ECFieldElement AddOne()
{
uint[] z = Nat256.Create();
SecP256R1Field.AddOne(x, z);
return new SecP256R1FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
uint[] z = Nat256.Create();
SecP256R1Field.Subtract(x, ((SecP256R1FieldElement)b).x, z);
return new SecP256R1FieldElement(z);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
uint[] z = Nat256.Create();
SecP256R1Field.Multiply(x, ((SecP256R1FieldElement)b).x, z);
return new SecP256R1FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
uint[] z = Nat256.Create();
Mod.Invert(SecP256R1Field.P, ((SecP256R1FieldElement)b).x, z);
SecP256R1Field.Multiply(z, x, z);
return new SecP256R1FieldElement(z);
}
public override ECFieldElement Negate()
{
uint[] z = Nat256.Create();
SecP256R1Field.Negate(x, z);
return new SecP256R1FieldElement(z);
}
public override ECFieldElement Square()
{
uint[] z = Nat256.Create();
SecP256R1Field.Square(x, z);
return new SecP256R1FieldElement(z);
}
public override ECFieldElement Invert()
{
uint[] z = Nat256.Create();
Mod.Invert(SecP256R1Field.P, x, z);
return new SecP256R1FieldElement(z);
}
public override ECFieldElement Sqrt()
{
uint[] y = x;
if (Nat256.IsZero(y) || Nat256.IsOne(y))
{
return this;
}
uint[] array = Nat256.Create();
uint[] array2 = Nat256.Create();
SecP256R1Field.Square(y, array);
SecP256R1Field.Multiply(array, y, array);
SecP256R1Field.SquareN(array, 2, array2);
SecP256R1Field.Multiply(array2, array, array2);
SecP256R1Field.SquareN(array2, 4, array);
SecP256R1Field.Multiply(array, array2, array);
SecP256R1Field.SquareN(array, 8, array2);
SecP256R1Field.Multiply(array2, array, array2);
SecP256R1Field.SquareN(array2, 16, array);
SecP256R1Field.Multiply(array, array2, array);
SecP256R1Field.SquareN(array, 32, array);
SecP256R1Field.Multiply(array, y, array);
SecP256R1Field.SquareN(array, 96, array);
SecP256R1Field.Multiply(array, y, array);
SecP256R1Field.SquareN(array, 94, array);
SecP256R1Field.Multiply(array, array, array2);
if (!Nat256.Eq(y, array2))
{
return null;
}
return new SecP256R1FieldElement(array);
}
public override bool Equals(object obj)
{
return Equals(obj as SecP256R1FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecP256R1FieldElement);
}
public virtual bool Equals(SecP256R1FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat256.Eq(x, other.x);
}
public override int GetHashCode()
{
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 8);
}
}

View File

@@ -0,0 +1,228 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP256R1Point : AbstractFpPoint
{
public SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecP256R1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
SecP256R1FieldElement secP256R1FieldElement = (SecP256R1FieldElement)base.RawXCoord;
SecP256R1FieldElement secP256R1FieldElement2 = (SecP256R1FieldElement)base.RawYCoord;
SecP256R1FieldElement secP256R1FieldElement3 = (SecP256R1FieldElement)b.RawXCoord;
SecP256R1FieldElement secP256R1FieldElement4 = (SecP256R1FieldElement)b.RawYCoord;
SecP256R1FieldElement secP256R1FieldElement5 = (SecP256R1FieldElement)base.RawZCoords[0];
SecP256R1FieldElement secP256R1FieldElement6 = (SecP256R1FieldElement)b.RawZCoords[0];
uint[] array = Nat256.CreateExt();
uint[] array2 = Nat256.Create();
uint[] array3 = Nat256.Create();
uint[] array4 = Nat256.Create();
bool isOne = secP256R1FieldElement5.IsOne;
uint[] array5;
uint[] array6;
if (isOne)
{
array5 = secP256R1FieldElement3.x;
array6 = secP256R1FieldElement4.x;
}
else
{
array6 = array3;
SecP256R1Field.Square(secP256R1FieldElement5.x, array6);
array5 = array2;
SecP256R1Field.Multiply(array6, secP256R1FieldElement3.x, array5);
SecP256R1Field.Multiply(array6, secP256R1FieldElement5.x, array6);
SecP256R1Field.Multiply(array6, secP256R1FieldElement4.x, array6);
}
bool isOne2 = secP256R1FieldElement6.IsOne;
uint[] array7;
uint[] array8;
if (isOne2)
{
array7 = secP256R1FieldElement.x;
array8 = secP256R1FieldElement2.x;
}
else
{
array8 = array4;
SecP256R1Field.Square(secP256R1FieldElement6.x, array8);
array7 = array;
SecP256R1Field.Multiply(array8, secP256R1FieldElement.x, array7);
SecP256R1Field.Multiply(array8, secP256R1FieldElement6.x, array8);
SecP256R1Field.Multiply(array8, secP256R1FieldElement2.x, array8);
}
uint[] array9 = Nat256.Create();
SecP256R1Field.Subtract(array7, array5, array9);
uint[] array10 = array2;
SecP256R1Field.Subtract(array8, array6, array10);
if (Nat256.IsZero(array9))
{
if (Nat256.IsZero(array10))
{
return Twice();
}
return curve.Infinity;
}
uint[] array11 = array3;
SecP256R1Field.Square(array9, array11);
uint[] array12 = Nat256.Create();
SecP256R1Field.Multiply(array11, array9, array12);
uint[] array13 = array3;
SecP256R1Field.Multiply(array11, array7, array13);
SecP256R1Field.Negate(array12, array12);
Nat256.Mul(array8, array12, array);
uint x = Nat256.AddBothTo(array13, array13, array12);
SecP256R1Field.Reduce32(x, array12);
SecP256R1FieldElement secP256R1FieldElement7 = new SecP256R1FieldElement(array4);
SecP256R1Field.Square(array10, secP256R1FieldElement7.x);
SecP256R1Field.Subtract(secP256R1FieldElement7.x, array12, secP256R1FieldElement7.x);
SecP256R1FieldElement secP256R1FieldElement8 = new SecP256R1FieldElement(array12);
SecP256R1Field.Subtract(array13, secP256R1FieldElement7.x, secP256R1FieldElement8.x);
SecP256R1Field.MultiplyAddToExt(secP256R1FieldElement8.x, array10, array);
SecP256R1Field.Reduce(array, secP256R1FieldElement8.x);
SecP256R1FieldElement secP256R1FieldElement9 = new SecP256R1FieldElement(array9);
if (!isOne)
{
SecP256R1Field.Multiply(secP256R1FieldElement9.x, secP256R1FieldElement5.x, secP256R1FieldElement9.x);
}
if (!isOne2)
{
SecP256R1Field.Multiply(secP256R1FieldElement9.x, secP256R1FieldElement6.x, secP256R1FieldElement9.x);
}
ECFieldElement[] zs = new ECFieldElement[1] { secP256R1FieldElement9 };
return new SecP256R1Point(curve, secP256R1FieldElement7, secP256R1FieldElement8, zs, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
SecP256R1FieldElement secP256R1FieldElement = (SecP256R1FieldElement)base.RawYCoord;
if (secP256R1FieldElement.IsZero)
{
return curve.Infinity;
}
SecP256R1FieldElement secP256R1FieldElement2 = (SecP256R1FieldElement)base.RawXCoord;
SecP256R1FieldElement secP256R1FieldElement3 = (SecP256R1FieldElement)base.RawZCoords[0];
uint[] array = Nat256.Create();
uint[] array2 = Nat256.Create();
uint[] array3 = Nat256.Create();
SecP256R1Field.Square(secP256R1FieldElement.x, array3);
uint[] array4 = Nat256.Create();
SecP256R1Field.Square(array3, array4);
bool isOne = secP256R1FieldElement3.IsOne;
uint[] array5 = secP256R1FieldElement3.x;
if (!isOne)
{
array5 = array2;
SecP256R1Field.Square(secP256R1FieldElement3.x, array5);
}
SecP256R1Field.Subtract(secP256R1FieldElement2.x, array5, array);
uint[] array6 = array2;
SecP256R1Field.Add(secP256R1FieldElement2.x, array5, array6);
SecP256R1Field.Multiply(array6, array, array6);
uint x = Nat256.AddBothTo(array6, array6, array6);
SecP256R1Field.Reduce32(x, array6);
uint[] array7 = array3;
SecP256R1Field.Multiply(array3, secP256R1FieldElement2.x, array7);
x = Nat.ShiftUpBits(8, array7, 2, 0u);
SecP256R1Field.Reduce32(x, array7);
x = Nat.ShiftUpBits(8, array4, 3, 0u, array);
SecP256R1Field.Reduce32(x, array);
SecP256R1FieldElement secP256R1FieldElement4 = new SecP256R1FieldElement(array4);
SecP256R1Field.Square(array6, secP256R1FieldElement4.x);
SecP256R1Field.Subtract(secP256R1FieldElement4.x, array7, secP256R1FieldElement4.x);
SecP256R1Field.Subtract(secP256R1FieldElement4.x, array7, secP256R1FieldElement4.x);
SecP256R1FieldElement secP256R1FieldElement5 = new SecP256R1FieldElement(array7);
SecP256R1Field.Subtract(array7, secP256R1FieldElement4.x, secP256R1FieldElement5.x);
SecP256R1Field.Multiply(secP256R1FieldElement5.x, array6, secP256R1FieldElement5.x);
SecP256R1Field.Subtract(secP256R1FieldElement5.x, array, secP256R1FieldElement5.x);
SecP256R1FieldElement secP256R1FieldElement6 = new SecP256R1FieldElement(array6);
SecP256R1Field.Twice(secP256R1FieldElement.x, secP256R1FieldElement6.x);
if (!isOne)
{
SecP256R1Field.Multiply(secP256R1FieldElement6.x, secP256R1FieldElement3.x, secP256R1FieldElement6.x);
}
return new SecP256R1Point(curve, secP256R1FieldElement4, secP256R1FieldElement5, new ECFieldElement[1] { secP256R1FieldElement6 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
return Twice().Add(b);
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity || base.RawYCoord.IsZero)
{
return this;
}
return Twice().Add(this);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
return new SecP256R1Point(Curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
}

View File

@@ -0,0 +1,119 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP384R1Curve : AbstractFpCurve
{
private class SecP384R1LookupTable : ECLookupTable
{
private readonly SecP384R1Curve m_outer;
private readonly uint[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecP384R1LookupTable(SecP384R1Curve outer, uint[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
uint[] array = Nat.Create(12);
uint[] array2 = Nat.Create(12);
int num = 0;
for (int i = 0; i < m_size; i++)
{
uint num2 = (uint)((i ^ index) - 1 >> 31);
for (int j = 0; j < 12; j++)
{
uint[] array4;
uint[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
uint[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 12 + j] & num2);
}
num += 24;
}
return m_outer.CreateRawPoint(new SecP384R1FieldElement(array), new SecP384R1FieldElement(array2), withCompression: false);
}
}
private const int SECP384R1_DEFAULT_COORDS = 2;
private const int SECP384R1_FE_INTS = 12;
public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"));
protected readonly SecP384R1Point m_infinity;
public virtual BigInteger Q => q;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => q.BitLength;
public SecP384R1Curve()
: base(q)
{
m_infinity = new SecP384R1Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")));
m_order = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"));
m_cofactor = BigInteger.One;
m_coord = 2;
}
protected override ECCurve CloneCurve()
{
return new SecP384R1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 2)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecP384R1FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecP384R1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecP384R1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
uint[] array = new uint[len * 12 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat.Copy(12, ((SecP384R1FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 12;
Nat.Copy(12, ((SecP384R1FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 12;
}
return new SecP384R1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,278 @@
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP384R1Field
{
private const uint P11 = uint.MaxValue;
private const uint PExt23 = uint.MaxValue;
internal static readonly uint[] P = new uint[12]
{
4294967295u, 0u, 0u, 4294967295u, 4294967294u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u,
4294967295u, 4294967295u
};
internal static readonly uint[] PExt = new uint[24]
{
1u, 4294967294u, 0u, 2u, 0u, 4294967294u, 0u, 2u, 1u, 0u,
0u, 0u, 4294967294u, 1u, 0u, 4294967294u, 4294967293u, 4294967295u, 4294967295u, 4294967295u,
4294967295u, 4294967295u, 4294967295u, 4294967295u
};
private static readonly uint[] PExtInv = new uint[17]
{
4294967295u, 1u, 4294967295u, 4294967293u, 4294967295u, 1u, 4294967295u, 4294967293u, 4294967294u, 4294967295u,
4294967295u, 4294967295u, 1u, 4294967294u, 4294967295u, 1u, 2u
};
public static void Add(uint[] x, uint[] y, uint[] z)
{
if (Nat.Add(12, x, y, z) != 0 || (z[11] == uint.MaxValue && Nat.Gte(12, z, P)))
{
AddPInvTo(z);
}
}
public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
{
if ((Nat.Add(24, xx, yy, zz) != 0 || (zz[23] == uint.MaxValue && Nat.Gte(24, zz, PExt))) && Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.IncAt(24, zz, PExtInv.Length);
}
}
public static void AddOne(uint[] x, uint[] z)
{
if (Nat.Inc(12, x, z) != 0 || (z[11] == uint.MaxValue && Nat.Gte(12, z, P)))
{
AddPInvTo(z);
}
}
public static uint[] FromBigInteger(BigInteger x)
{
uint[] array = Nat.FromBigInteger(384, x);
if (array[11] == uint.MaxValue && Nat.Gte(12, array, P))
{
Nat.SubFrom(12, P, array);
}
return array;
}
public static void Half(uint[] x, uint[] z)
{
if ((x[0] & 1) == 0)
{
Nat.ShiftDownBit(12, x, 0u, z);
return;
}
uint c = Nat.Add(12, x, P, z);
Nat.ShiftDownBit(12, z, c);
}
public static void Multiply(uint[] x, uint[] y, uint[] z)
{
uint[] array = Nat.Create(24);
Nat384.Mul(x, y, array);
Reduce(array, z);
}
public static void Negate(uint[] x, uint[] z)
{
if (Nat.IsZero(12, x))
{
Nat.Zero(12, z);
}
else
{
Nat.Sub(12, P, x, z);
}
}
public static void Reduce(uint[] xx, uint[] z)
{
long num = xx[16];
long num2 = xx[17];
long num3 = xx[18];
long num4 = xx[19];
long num5 = xx[20];
long num6 = xx[21];
long num7 = xx[22];
long num8 = xx[23];
long num9 = xx[12] + num5 - 1;
long num10 = xx[13] + num7;
long num11 = xx[14] + num7 + num8;
long num12 = xx[15] + num8;
long num13 = num2 + num6;
long num14 = num6 - num8;
long num15 = num7 - num8;
long num16 = num9 + num14;
long num17 = 0L;
num17 += xx[0] + num16;
z[0] = (uint)num17;
num17 >>= 32;
num17 += xx[1] + num8 - num9 + num10;
z[1] = (uint)num17;
num17 >>= 32;
num17 += xx[2] - num6 - num10 + num11;
z[2] = (uint)num17;
num17 >>= 32;
num17 += xx[3] - num11 + num12 + num16;
z[3] = (uint)num17;
num17 >>= 32;
num17 += xx[4] + num + num6 + num10 - num12 + num16;
z[4] = (uint)num17;
num17 >>= 32;
num17 += xx[5] - num + num10 + num11 + num13;
z[5] = (uint)num17;
num17 >>= 32;
num17 += xx[6] + num3 - num2 + num11 + num12;
z[6] = (uint)num17;
num17 >>= 32;
num17 += xx[7] + num + num4 - num3 + num12;
z[7] = (uint)num17;
num17 >>= 32;
num17 += xx[8] + num + num2 + num5 - num4;
z[8] = (uint)num17;
num17 >>= 32;
num17 += xx[9] + num3 - num5 + num13;
z[9] = (uint)num17;
num17 >>= 32;
num17 += xx[10] + num3 + num4 - num14 + num15;
z[10] = (uint)num17;
num17 >>= 32;
num17 += xx[11] + num4 + num5 - num15;
z[11] = (uint)num17;
num17 >>= 32;
num17++;
Reduce32((uint)num17, z);
}
public static void Reduce32(uint x, uint[] z)
{
long num = 0L;
if (x != 0)
{
long num2 = x;
num += z[0] + num2;
z[0] = (uint)num;
num >>= 32;
num += z[1] - num2;
z[1] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[2];
z[2] = (uint)num;
num >>= 32;
}
num += z[3] + num2;
z[3] = (uint)num;
num >>= 32;
num += z[4] + num2;
z[4] = (uint)num;
num >>= 32;
}
if ((num != 0 && Nat.IncAt(12, z, 5) != 0) || (z[11] == uint.MaxValue && Nat.Gte(12, z, P)))
{
AddPInvTo(z);
}
}
public static void Square(uint[] x, uint[] z)
{
uint[] array = Nat.Create(24);
Nat384.Square(x, array);
Reduce(array, z);
}
public static void SquareN(uint[] x, int n, uint[] z)
{
uint[] array = Nat.Create(24);
Nat384.Square(x, array);
Reduce(array, z);
while (--n > 0)
{
Nat384.Square(z, array);
Reduce(array, z);
}
}
public static void Subtract(uint[] x, uint[] y, uint[] z)
{
if (Nat.Sub(12, x, y, z) != 0)
{
SubPInvFrom(z);
}
}
public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
{
if (Nat.Sub(24, xx, yy, zz) != 0 && Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0)
{
Nat.DecAt(24, zz, PExtInv.Length);
}
}
public static void Twice(uint[] x, uint[] z)
{
if (Nat.ShiftUpBit(12, x, 0u, z) != 0 || (z[11] == uint.MaxValue && Nat.Gte(12, z, P)))
{
AddPInvTo(z);
}
}
private static void AddPInvTo(uint[] z)
{
long num = (long)z[0] + 1L;
z[0] = (uint)num;
num >>= 32;
num += (long)z[1] - 1L;
z[1] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[2];
z[2] = (uint)num;
num >>= 32;
}
num += (long)z[3] + 1L;
z[3] = (uint)num;
num >>= 32;
num += (long)z[4] + 1L;
z[4] = (uint)num;
num >>= 32;
if (num != 0)
{
Nat.IncAt(12, z, 5);
}
}
private static void SubPInvFrom(uint[] z)
{
long num = (long)z[0] - 1L;
z[0] = (uint)num;
num >>= 32;
num += (long)z[1] + 1L;
z[1] = (uint)num;
num >>= 32;
if (num != 0)
{
num += z[2];
z[2] = (uint)num;
num >>= 32;
}
num += (long)z[3] - 1L;
z[3] = (uint)num;
num >>= 32;
num += (long)z[4] - 1L;
z[4] = (uint)num;
num >>= 32;
if (num != 0)
{
Nat.DecAt(12, z, 5);
}
}
}

View File

@@ -0,0 +1,181 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP384R1FieldElement : AbstractFpFieldElement
{
public static readonly BigInteger Q = SecP384R1Curve.q;
protected internal readonly uint[] x;
public override bool IsZero => Nat.IsZero(12, x);
public override bool IsOne => Nat.IsOne(12, x);
public override string FieldName => "SecP384R1Field";
public override int FieldSize => Q.BitLength;
public SecP384R1FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
{
throw new ArgumentException("value invalid for SecP384R1FieldElement", "x");
}
this.x = SecP384R1Field.FromBigInteger(x);
}
public SecP384R1FieldElement()
{
x = Nat.Create(12);
}
protected internal SecP384R1FieldElement(uint[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return Nat.GetBit(x, 0) == 1;
}
public override BigInteger ToBigInteger()
{
return Nat.ToBigInteger(12, x);
}
public override ECFieldElement Add(ECFieldElement b)
{
uint[] z = Nat.Create(12);
SecP384R1Field.Add(x, ((SecP384R1FieldElement)b).x, z);
return new SecP384R1FieldElement(z);
}
public override ECFieldElement AddOne()
{
uint[] z = Nat.Create(12);
SecP384R1Field.AddOne(x, z);
return new SecP384R1FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
uint[] z = Nat.Create(12);
SecP384R1Field.Subtract(x, ((SecP384R1FieldElement)b).x, z);
return new SecP384R1FieldElement(z);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
uint[] z = Nat.Create(12);
SecP384R1Field.Multiply(x, ((SecP384R1FieldElement)b).x, z);
return new SecP384R1FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
uint[] z = Nat.Create(12);
Mod.Invert(SecP384R1Field.P, ((SecP384R1FieldElement)b).x, z);
SecP384R1Field.Multiply(z, x, z);
return new SecP384R1FieldElement(z);
}
public override ECFieldElement Negate()
{
uint[] z = Nat.Create(12);
SecP384R1Field.Negate(x, z);
return new SecP384R1FieldElement(z);
}
public override ECFieldElement Square()
{
uint[] z = Nat.Create(12);
SecP384R1Field.Square(x, z);
return new SecP384R1FieldElement(z);
}
public override ECFieldElement Invert()
{
uint[] z = Nat.Create(12);
Mod.Invert(SecP384R1Field.P, x, z);
return new SecP384R1FieldElement(z);
}
public override ECFieldElement Sqrt()
{
uint[] y = x;
if (Nat.IsZero(12, y) || Nat.IsOne(12, y))
{
return this;
}
uint[] array = Nat.Create(12);
uint[] array2 = Nat.Create(12);
uint[] array3 = Nat.Create(12);
uint[] array4 = Nat.Create(12);
SecP384R1Field.Square(y, array);
SecP384R1Field.Multiply(array, y, array);
SecP384R1Field.SquareN(array, 2, array2);
SecP384R1Field.Multiply(array2, array, array2);
SecP384R1Field.Square(array2, array2);
SecP384R1Field.Multiply(array2, y, array2);
SecP384R1Field.SquareN(array2, 5, array3);
SecP384R1Field.Multiply(array3, array2, array3);
SecP384R1Field.SquareN(array3, 5, array4);
SecP384R1Field.Multiply(array4, array2, array4);
SecP384R1Field.SquareN(array4, 15, array2);
SecP384R1Field.Multiply(array2, array4, array2);
SecP384R1Field.SquareN(array2, 2, array3);
SecP384R1Field.Multiply(array, array3, array);
SecP384R1Field.SquareN(array3, 28, array3);
SecP384R1Field.Multiply(array2, array3, array2);
SecP384R1Field.SquareN(array2, 60, array3);
SecP384R1Field.Multiply(array3, array2, array3);
uint[] z = array2;
SecP384R1Field.SquareN(array3, 120, z);
SecP384R1Field.Multiply(z, array3, z);
SecP384R1Field.SquareN(z, 15, z);
SecP384R1Field.Multiply(z, array4, z);
SecP384R1Field.SquareN(z, 33, z);
SecP384R1Field.Multiply(z, array, z);
SecP384R1Field.SquareN(z, 64, z);
SecP384R1Field.Multiply(z, y, z);
SecP384R1Field.SquareN(z, 30, array);
SecP384R1Field.Square(array, array2);
if (!Nat.Eq(12, y, array2))
{
return null;
}
return new SecP384R1FieldElement(array);
}
public override bool Equals(object obj)
{
return Equals(obj as SecP384R1FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecP384R1FieldElement);
}
public virtual bool Equals(SecP384R1FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat.Eq(12, x, other.x);
}
public override int GetHashCode()
{
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 12);
}
}

View File

@@ -0,0 +1,229 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP384R1Point : AbstractFpPoint
{
public SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecP384R1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
SecP384R1FieldElement secP384R1FieldElement = (SecP384R1FieldElement)base.RawXCoord;
SecP384R1FieldElement secP384R1FieldElement2 = (SecP384R1FieldElement)base.RawYCoord;
SecP384R1FieldElement secP384R1FieldElement3 = (SecP384R1FieldElement)b.RawXCoord;
SecP384R1FieldElement secP384R1FieldElement4 = (SecP384R1FieldElement)b.RawYCoord;
SecP384R1FieldElement secP384R1FieldElement5 = (SecP384R1FieldElement)base.RawZCoords[0];
SecP384R1FieldElement secP384R1FieldElement6 = (SecP384R1FieldElement)b.RawZCoords[0];
uint[] array = Nat.Create(24);
uint[] array2 = Nat.Create(24);
uint[] array3 = Nat.Create(12);
uint[] array4 = Nat.Create(12);
bool isOne = secP384R1FieldElement5.IsOne;
uint[] array5;
uint[] array6;
if (isOne)
{
array5 = secP384R1FieldElement3.x;
array6 = secP384R1FieldElement4.x;
}
else
{
array6 = array3;
SecP384R1Field.Square(secP384R1FieldElement5.x, array6);
array5 = array2;
SecP384R1Field.Multiply(array6, secP384R1FieldElement3.x, array5);
SecP384R1Field.Multiply(array6, secP384R1FieldElement5.x, array6);
SecP384R1Field.Multiply(array6, secP384R1FieldElement4.x, array6);
}
bool isOne2 = secP384R1FieldElement6.IsOne;
uint[] array7;
uint[] array8;
if (isOne2)
{
array7 = secP384R1FieldElement.x;
array8 = secP384R1FieldElement2.x;
}
else
{
array8 = array4;
SecP384R1Field.Square(secP384R1FieldElement6.x, array8);
array7 = array;
SecP384R1Field.Multiply(array8, secP384R1FieldElement.x, array7);
SecP384R1Field.Multiply(array8, secP384R1FieldElement6.x, array8);
SecP384R1Field.Multiply(array8, secP384R1FieldElement2.x, array8);
}
uint[] array9 = Nat.Create(12);
SecP384R1Field.Subtract(array7, array5, array9);
uint[] array10 = Nat.Create(12);
SecP384R1Field.Subtract(array8, array6, array10);
if (Nat.IsZero(12, array9))
{
if (Nat.IsZero(12, array10))
{
return Twice();
}
return curve.Infinity;
}
uint[] array11 = array3;
SecP384R1Field.Square(array9, array11);
uint[] array12 = Nat.Create(12);
SecP384R1Field.Multiply(array11, array9, array12);
uint[] array13 = array3;
SecP384R1Field.Multiply(array11, array7, array13);
SecP384R1Field.Negate(array12, array12);
Nat384.Mul(array8, array12, array);
uint x = Nat.AddBothTo(12, array13, array13, array12);
SecP384R1Field.Reduce32(x, array12);
SecP384R1FieldElement secP384R1FieldElement7 = new SecP384R1FieldElement(array4);
SecP384R1Field.Square(array10, secP384R1FieldElement7.x);
SecP384R1Field.Subtract(secP384R1FieldElement7.x, array12, secP384R1FieldElement7.x);
SecP384R1FieldElement secP384R1FieldElement8 = new SecP384R1FieldElement(array12);
SecP384R1Field.Subtract(array13, secP384R1FieldElement7.x, secP384R1FieldElement8.x);
Nat384.Mul(secP384R1FieldElement8.x, array10, array2);
SecP384R1Field.AddExt(array, array2, array);
SecP384R1Field.Reduce(array, secP384R1FieldElement8.x);
SecP384R1FieldElement secP384R1FieldElement9 = new SecP384R1FieldElement(array9);
if (!isOne)
{
SecP384R1Field.Multiply(secP384R1FieldElement9.x, secP384R1FieldElement5.x, secP384R1FieldElement9.x);
}
if (!isOne2)
{
SecP384R1Field.Multiply(secP384R1FieldElement9.x, secP384R1FieldElement6.x, secP384R1FieldElement9.x);
}
ECFieldElement[] zs = new ECFieldElement[1] { secP384R1FieldElement9 };
return new SecP384R1Point(curve, secP384R1FieldElement7, secP384R1FieldElement8, zs, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
SecP384R1FieldElement secP384R1FieldElement = (SecP384R1FieldElement)base.RawYCoord;
if (secP384R1FieldElement.IsZero)
{
return curve.Infinity;
}
SecP384R1FieldElement secP384R1FieldElement2 = (SecP384R1FieldElement)base.RawXCoord;
SecP384R1FieldElement secP384R1FieldElement3 = (SecP384R1FieldElement)base.RawZCoords[0];
uint[] array = Nat.Create(12);
uint[] array2 = Nat.Create(12);
uint[] array3 = Nat.Create(12);
SecP384R1Field.Square(secP384R1FieldElement.x, array3);
uint[] array4 = Nat.Create(12);
SecP384R1Field.Square(array3, array4);
bool isOne = secP384R1FieldElement3.IsOne;
uint[] array5 = secP384R1FieldElement3.x;
if (!isOne)
{
array5 = array2;
SecP384R1Field.Square(secP384R1FieldElement3.x, array5);
}
SecP384R1Field.Subtract(secP384R1FieldElement2.x, array5, array);
uint[] array6 = array2;
SecP384R1Field.Add(secP384R1FieldElement2.x, array5, array6);
SecP384R1Field.Multiply(array6, array, array6);
uint x = Nat.AddBothTo(12, array6, array6, array6);
SecP384R1Field.Reduce32(x, array6);
uint[] array7 = array3;
SecP384R1Field.Multiply(array3, secP384R1FieldElement2.x, array7);
x = Nat.ShiftUpBits(12, array7, 2, 0u);
SecP384R1Field.Reduce32(x, array7);
x = Nat.ShiftUpBits(12, array4, 3, 0u, array);
SecP384R1Field.Reduce32(x, array);
SecP384R1FieldElement secP384R1FieldElement4 = new SecP384R1FieldElement(array4);
SecP384R1Field.Square(array6, secP384R1FieldElement4.x);
SecP384R1Field.Subtract(secP384R1FieldElement4.x, array7, secP384R1FieldElement4.x);
SecP384R1Field.Subtract(secP384R1FieldElement4.x, array7, secP384R1FieldElement4.x);
SecP384R1FieldElement secP384R1FieldElement5 = new SecP384R1FieldElement(array7);
SecP384R1Field.Subtract(array7, secP384R1FieldElement4.x, secP384R1FieldElement5.x);
SecP384R1Field.Multiply(secP384R1FieldElement5.x, array6, secP384R1FieldElement5.x);
SecP384R1Field.Subtract(secP384R1FieldElement5.x, array, secP384R1FieldElement5.x);
SecP384R1FieldElement secP384R1FieldElement6 = new SecP384R1FieldElement(array6);
SecP384R1Field.Twice(secP384R1FieldElement.x, secP384R1FieldElement6.x);
if (!isOne)
{
SecP384R1Field.Multiply(secP384R1FieldElement6.x, secP384R1FieldElement3.x, secP384R1FieldElement6.x);
}
return new SecP384R1Point(curve, secP384R1FieldElement4, secP384R1FieldElement5, new ECFieldElement[1] { secP384R1FieldElement6 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
return Twice().Add(b);
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity || base.RawYCoord.IsZero)
{
return this;
}
return Twice().Add(this);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
return new SecP384R1Point(Curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
}

View File

@@ -0,0 +1,119 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP521R1Curve : AbstractFpCurve
{
private class SecP521R1LookupTable : ECLookupTable
{
private readonly SecP521R1Curve m_outer;
private readonly uint[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecP521R1LookupTable(SecP521R1Curve outer, uint[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
uint[] array = Nat.Create(17);
uint[] array2 = Nat.Create(17);
int num = 0;
for (int i = 0; i < m_size; i++)
{
uint num2 = (uint)((i ^ index) - 1 >> 31);
for (int j = 0; j < 17; j++)
{
uint[] array4;
uint[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
uint[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 17 + j] & num2);
}
num += 34;
}
return m_outer.CreateRawPoint(new SecP521R1FieldElement(array), new SecP521R1FieldElement(array2), withCompression: false);
}
}
private const int SECP521R1_DEFAULT_COORDS = 2;
private const int SECP521R1_FE_INTS = 17;
public static readonly BigInteger q = new BigInteger(1, Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
protected readonly SecP521R1Point m_infinity;
public virtual BigInteger Q => q;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => q.BitLength;
public SecP521R1Curve()
: base(q)
{
m_infinity = new SecP521R1Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00")));
m_order = new BigInteger(1, Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"));
m_cofactor = BigInteger.One;
m_coord = 2;
}
protected override ECCurve CloneCurve()
{
return new SecP521R1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 2)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecP521R1FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecP521R1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecP521R1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
uint[] array = new uint[len * 17 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat.Copy(17, ((SecP521R1FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 17;
Nat.Copy(17, ((SecP521R1FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 17;
}
return new SecP521R1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,150 @@
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP521R1Field
{
private const int P16 = 511;
internal static readonly uint[] P = new uint[17]
{
4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u,
4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 4294967295u, 511u
};
public static void Add(uint[] x, uint[] y, uint[] z)
{
uint num = Nat.Add(16, x, y, z) + x[16] + y[16];
if (num > 511 || (num == 511 && Nat.Eq(16, z, P)))
{
num += Nat.Inc(16, z);
num &= 0x1FF;
}
z[16] = num;
}
public static void AddOne(uint[] x, uint[] z)
{
uint num = Nat.Inc(16, x, z) + x[16];
if (num > 511 || (num == 511 && Nat.Eq(16, z, P)))
{
num += Nat.Inc(16, z);
num &= 0x1FF;
}
z[16] = num;
}
public static uint[] FromBigInteger(BigInteger x)
{
uint[] array = Nat.FromBigInteger(521, x);
if (Nat.Eq(17, array, P))
{
Nat.Zero(17, array);
}
return array;
}
public static void Half(uint[] x, uint[] z)
{
uint num = x[16];
uint num2 = Nat.ShiftDownBit(16, x, num, z);
z[16] = (num >> 1) | (num2 >> 23);
}
public static void Multiply(uint[] x, uint[] y, uint[] z)
{
uint[] array = Nat.Create(33);
ImplMultiply(x, y, array);
Reduce(array, z);
}
public static void Negate(uint[] x, uint[] z)
{
if (Nat.IsZero(17, x))
{
Nat.Zero(17, z);
}
else
{
Nat.Sub(17, P, x, z);
}
}
public static void Reduce(uint[] xx, uint[] z)
{
uint num = xx[32];
uint num2 = Nat.ShiftDownBits(16, xx, 16, 9, num, z, 0) >> 23;
num2 += num >> 9;
num2 += Nat.AddTo(16, xx, z);
if (num2 > 511 || (num2 == 511 && Nat.Eq(16, z, P)))
{
num2 += Nat.Inc(16, z);
num2 &= 0x1FF;
}
z[16] = num2;
}
public static void Reduce23(uint[] z)
{
uint num = z[16];
uint num2 = Nat.AddWordTo(16, num >> 9, z) + (num & 0x1FF);
if (num2 > 511 || (num2 == 511 && Nat.Eq(16, z, P)))
{
num2 += Nat.Inc(16, z);
num2 &= 0x1FF;
}
z[16] = num2;
}
public static void Square(uint[] x, uint[] z)
{
uint[] array = Nat.Create(33);
ImplSquare(x, array);
Reduce(array, z);
}
public static void SquareN(uint[] x, int n, uint[] z)
{
uint[] array = Nat.Create(33);
ImplSquare(x, array);
Reduce(array, z);
while (--n > 0)
{
ImplSquare(z, array);
Reduce(array, z);
}
}
public static void Subtract(uint[] x, uint[] y, uint[] z)
{
int num = Nat.Sub(16, x, y, z) + (int)(x[16] - y[16]);
if (num < 0)
{
num += Nat.Dec(16, z);
num &= 0x1FF;
}
z[16] = (uint)num;
}
public static void Twice(uint[] x, uint[] z)
{
uint num = x[16];
uint num2 = Nat.ShiftUpBit(16, x, num << 23, z) | (num << 1);
z[16] = num2 & 0x1FF;
}
protected static void ImplMultiply(uint[] x, uint[] y, uint[] zz)
{
Nat512.Mul(x, y, zz);
uint num = x[16];
uint num2 = y[16];
zz[32] = Nat.Mul31BothAdd(16, num, y, num2, x, zz, 16) + num * num2;
}
protected static void ImplSquare(uint[] x, uint[] zz)
{
Nat512.Square(x, zz);
uint num = x[16];
zz[32] = Nat.MulWordAddTo(16, num << 1, x, 0, zz, 16) + num * num;
}
}

View File

@@ -0,0 +1,152 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP521R1FieldElement : AbstractFpFieldElement
{
public static readonly BigInteger Q = SecP521R1Curve.q;
protected internal readonly uint[] x;
public override bool IsZero => Nat.IsZero(17, x);
public override bool IsOne => Nat.IsOne(17, x);
public override string FieldName => "SecP521R1Field";
public override int FieldSize => Q.BitLength;
public SecP521R1FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
{
throw new ArgumentException("value invalid for SecP521R1FieldElement", "x");
}
this.x = SecP521R1Field.FromBigInteger(x);
}
public SecP521R1FieldElement()
{
x = Nat.Create(17);
}
protected internal SecP521R1FieldElement(uint[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return Nat.GetBit(x, 0) == 1;
}
public override BigInteger ToBigInteger()
{
return Nat.ToBigInteger(17, x);
}
public override ECFieldElement Add(ECFieldElement b)
{
uint[] z = Nat.Create(17);
SecP521R1Field.Add(x, ((SecP521R1FieldElement)b).x, z);
return new SecP521R1FieldElement(z);
}
public override ECFieldElement AddOne()
{
uint[] z = Nat.Create(17);
SecP521R1Field.AddOne(x, z);
return new SecP521R1FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
uint[] z = Nat.Create(17);
SecP521R1Field.Subtract(x, ((SecP521R1FieldElement)b).x, z);
return new SecP521R1FieldElement(z);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
uint[] z = Nat.Create(17);
SecP521R1Field.Multiply(x, ((SecP521R1FieldElement)b).x, z);
return new SecP521R1FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
uint[] z = Nat.Create(17);
Mod.Invert(SecP521R1Field.P, ((SecP521R1FieldElement)b).x, z);
SecP521R1Field.Multiply(z, x, z);
return new SecP521R1FieldElement(z);
}
public override ECFieldElement Negate()
{
uint[] z = Nat.Create(17);
SecP521R1Field.Negate(x, z);
return new SecP521R1FieldElement(z);
}
public override ECFieldElement Square()
{
uint[] z = Nat.Create(17);
SecP521R1Field.Square(x, z);
return new SecP521R1FieldElement(z);
}
public override ECFieldElement Invert()
{
uint[] z = Nat.Create(17);
Mod.Invert(SecP521R1Field.P, x, z);
return new SecP521R1FieldElement(z);
}
public override ECFieldElement Sqrt()
{
uint[] array = x;
if (Nat.IsZero(17, array) || Nat.IsOne(17, array))
{
return this;
}
uint[] z = Nat.Create(17);
uint[] array2 = Nat.Create(17);
SecP521R1Field.SquareN(array, 519, z);
SecP521R1Field.Square(z, array2);
if (!Nat.Eq(17, array, array2))
{
return null;
}
return new SecP521R1FieldElement(z);
}
public override bool Equals(object obj)
{
return Equals(obj as SecP521R1FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecP521R1FieldElement);
}
public virtual bool Equals(SecP521R1FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat.Eq(17, x, other.x);
}
public override int GetHashCode()
{
return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 17);
}
}

View File

@@ -0,0 +1,227 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecP521R1Point : AbstractFpPoint
{
public SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecP521R1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
SecP521R1FieldElement secP521R1FieldElement = (SecP521R1FieldElement)base.RawXCoord;
SecP521R1FieldElement secP521R1FieldElement2 = (SecP521R1FieldElement)base.RawYCoord;
SecP521R1FieldElement secP521R1FieldElement3 = (SecP521R1FieldElement)b.RawXCoord;
SecP521R1FieldElement secP521R1FieldElement4 = (SecP521R1FieldElement)b.RawYCoord;
SecP521R1FieldElement secP521R1FieldElement5 = (SecP521R1FieldElement)base.RawZCoords[0];
SecP521R1FieldElement secP521R1FieldElement6 = (SecP521R1FieldElement)b.RawZCoords[0];
uint[] array = Nat.Create(17);
uint[] array2 = Nat.Create(17);
uint[] array3 = Nat.Create(17);
uint[] array4 = Nat.Create(17);
bool isOne = secP521R1FieldElement5.IsOne;
uint[] array5;
uint[] array6;
if (isOne)
{
array5 = secP521R1FieldElement3.x;
array6 = secP521R1FieldElement4.x;
}
else
{
array6 = array3;
SecP521R1Field.Square(secP521R1FieldElement5.x, array6);
array5 = array2;
SecP521R1Field.Multiply(array6, secP521R1FieldElement3.x, array5);
SecP521R1Field.Multiply(array6, secP521R1FieldElement5.x, array6);
SecP521R1Field.Multiply(array6, secP521R1FieldElement4.x, array6);
}
bool isOne2 = secP521R1FieldElement6.IsOne;
uint[] array7;
uint[] array8;
if (isOne2)
{
array7 = secP521R1FieldElement.x;
array8 = secP521R1FieldElement2.x;
}
else
{
array8 = array4;
SecP521R1Field.Square(secP521R1FieldElement6.x, array8);
array7 = array;
SecP521R1Field.Multiply(array8, secP521R1FieldElement.x, array7);
SecP521R1Field.Multiply(array8, secP521R1FieldElement6.x, array8);
SecP521R1Field.Multiply(array8, secP521R1FieldElement2.x, array8);
}
uint[] array9 = Nat.Create(17);
SecP521R1Field.Subtract(array7, array5, array9);
uint[] array10 = array2;
SecP521R1Field.Subtract(array8, array6, array10);
if (Nat.IsZero(17, array9))
{
if (Nat.IsZero(17, array10))
{
return Twice();
}
return curve.Infinity;
}
uint[] array11 = array3;
SecP521R1Field.Square(array9, array11);
uint[] array12 = Nat.Create(17);
SecP521R1Field.Multiply(array11, array9, array12);
uint[] array13 = array3;
SecP521R1Field.Multiply(array11, array7, array13);
SecP521R1Field.Multiply(array8, array12, array);
SecP521R1FieldElement secP521R1FieldElement7 = new SecP521R1FieldElement(array4);
SecP521R1Field.Square(array10, secP521R1FieldElement7.x);
SecP521R1Field.Add(secP521R1FieldElement7.x, array12, secP521R1FieldElement7.x);
SecP521R1Field.Subtract(secP521R1FieldElement7.x, array13, secP521R1FieldElement7.x);
SecP521R1Field.Subtract(secP521R1FieldElement7.x, array13, secP521R1FieldElement7.x);
SecP521R1FieldElement secP521R1FieldElement8 = new SecP521R1FieldElement(array12);
SecP521R1Field.Subtract(array13, secP521R1FieldElement7.x, secP521R1FieldElement8.x);
SecP521R1Field.Multiply(secP521R1FieldElement8.x, array10, array2);
SecP521R1Field.Subtract(array2, array, secP521R1FieldElement8.x);
SecP521R1FieldElement secP521R1FieldElement9 = new SecP521R1FieldElement(array9);
if (!isOne)
{
SecP521R1Field.Multiply(secP521R1FieldElement9.x, secP521R1FieldElement5.x, secP521R1FieldElement9.x);
}
if (!isOne2)
{
SecP521R1Field.Multiply(secP521R1FieldElement9.x, secP521R1FieldElement6.x, secP521R1FieldElement9.x);
}
ECFieldElement[] zs = new ECFieldElement[1] { secP521R1FieldElement9 };
return new SecP521R1Point(curve, secP521R1FieldElement7, secP521R1FieldElement8, zs, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
SecP521R1FieldElement secP521R1FieldElement = (SecP521R1FieldElement)base.RawYCoord;
if (secP521R1FieldElement.IsZero)
{
return curve.Infinity;
}
SecP521R1FieldElement secP521R1FieldElement2 = (SecP521R1FieldElement)base.RawXCoord;
SecP521R1FieldElement secP521R1FieldElement3 = (SecP521R1FieldElement)base.RawZCoords[0];
uint[] array = Nat.Create(17);
uint[] array2 = Nat.Create(17);
uint[] array3 = Nat.Create(17);
SecP521R1Field.Square(secP521R1FieldElement.x, array3);
uint[] array4 = Nat.Create(17);
SecP521R1Field.Square(array3, array4);
bool isOne = secP521R1FieldElement3.IsOne;
uint[] array5 = secP521R1FieldElement3.x;
if (!isOne)
{
array5 = array2;
SecP521R1Field.Square(secP521R1FieldElement3.x, array5);
}
SecP521R1Field.Subtract(secP521R1FieldElement2.x, array5, array);
uint[] array6 = array2;
SecP521R1Field.Add(secP521R1FieldElement2.x, array5, array6);
SecP521R1Field.Multiply(array6, array, array6);
Nat.AddBothTo(17, array6, array6, array6);
SecP521R1Field.Reduce23(array6);
uint[] array7 = array3;
SecP521R1Field.Multiply(array3, secP521R1FieldElement2.x, array7);
Nat.ShiftUpBits(17, array7, 2, 0u);
SecP521R1Field.Reduce23(array7);
Nat.ShiftUpBits(17, array4, 3, 0u, array);
SecP521R1Field.Reduce23(array);
SecP521R1FieldElement secP521R1FieldElement4 = new SecP521R1FieldElement(array4);
SecP521R1Field.Square(array6, secP521R1FieldElement4.x);
SecP521R1Field.Subtract(secP521R1FieldElement4.x, array7, secP521R1FieldElement4.x);
SecP521R1Field.Subtract(secP521R1FieldElement4.x, array7, secP521R1FieldElement4.x);
SecP521R1FieldElement secP521R1FieldElement5 = new SecP521R1FieldElement(array7);
SecP521R1Field.Subtract(array7, secP521R1FieldElement4.x, secP521R1FieldElement5.x);
SecP521R1Field.Multiply(secP521R1FieldElement5.x, array6, secP521R1FieldElement5.x);
SecP521R1Field.Subtract(secP521R1FieldElement5.x, array, secP521R1FieldElement5.x);
SecP521R1FieldElement secP521R1FieldElement6 = new SecP521R1FieldElement(array6);
SecP521R1Field.Twice(secP521R1FieldElement.x, secP521R1FieldElement6.x);
if (!isOne)
{
SecP521R1Field.Multiply(secP521R1FieldElement6.x, secP521R1FieldElement3.x, secP521R1FieldElement6.x);
}
return new SecP521R1Point(curve, secP521R1FieldElement4, secP521R1FieldElement5, new ECFieldElement[1] { secP521R1FieldElement6 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
return Twice().Add(b);
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity || base.RawYCoord.IsZero)
{
return this;
}
return Twice().Add(this);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
return new SecP521R1Point(Curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
}

View File

@@ -0,0 +1,204 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT113Field
{
private const ulong M49 = 562949953421311uL;
private const ulong M57 = 144115188075855871uL;
public static void Add(ulong[] x, ulong[] y, ulong[] z)
{
z[0] = x[0] ^ y[0];
z[1] = x[1] ^ y[1];
}
public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz)
{
zz[0] = xx[0] ^ yy[0];
zz[1] = xx[1] ^ yy[1];
zz[2] = xx[2] ^ yy[2];
zz[3] = xx[3] ^ yy[3];
}
public static void AddOne(ulong[] x, ulong[] z)
{
z[0] = x[0] ^ 1;
z[1] = x[1];
}
public static ulong[] FromBigInteger(BigInteger x)
{
ulong[] array = Nat128.FromBigInteger64(x);
Reduce15(array, 0);
return array;
}
public static void Invert(ulong[] x, ulong[] z)
{
if (Nat128.IsZero64(x))
{
throw new InvalidOperationException();
}
ulong[] array = Nat128.Create64();
ulong[] array2 = Nat128.Create64();
Square(x, array);
Multiply(array, x, array);
Square(array, array);
Multiply(array, x, array);
SquareN(array, 3, array2);
Multiply(array2, array, array2);
Square(array2, array2);
Multiply(array2, x, array2);
SquareN(array2, 7, array);
Multiply(array, array2, array);
SquareN(array, 14, array2);
Multiply(array2, array, array2);
SquareN(array2, 28, array);
Multiply(array, array2, array);
SquareN(array, 56, array2);
Multiply(array2, array, array2);
Square(array2, z);
}
public static void Multiply(ulong[] x, ulong[] y, ulong[] z)
{
ulong[] array = Nat128.CreateExt64();
ImplMultiply(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz)
{
ulong[] array = Nat128.CreateExt64();
ImplMultiply(x, y, array);
AddExt(zz, array, zz);
}
public static void Reduce(ulong[] xx, ulong[] z)
{
ulong num = xx[0];
ulong num2 = xx[1];
ulong num3 = xx[2];
ulong num4 = xx[3];
num2 ^= (num4 << 15) ^ (num4 << 24);
num3 ^= (num4 >> 49) ^ (num4 >> 40);
num ^= (num3 << 15) ^ (num3 << 24);
num2 ^= (num3 >> 49) ^ (num3 >> 40);
ulong num5 = num2 >> 49;
z[0] = num ^ num5 ^ (num5 << 9);
z[1] = num2 & 0x1FFFFFFFFFFFFL;
}
public static void Reduce15(ulong[] z, int zOff)
{
ulong num = z[zOff + 1];
ulong num2 = num >> 49;
ulong[] array2;
ulong[] array = (array2 = z);
nint num3 = zOff;
array[zOff] = array2[num3] ^ (num2 ^ (num2 << 9));
z[zOff + 1] = num & 0x1FFFFFFFFFFFFL;
}
public static void Sqrt(ulong[] x, ulong[] z)
{
ulong num = Interleave.Unshuffle(x[0]);
ulong num2 = Interleave.Unshuffle(x[1]);
ulong num3 = (num & 0xFFFFFFFFu) | (num2 << 32);
ulong num4 = (num >> 32) | (num2 & 0xFFFFFFFF00000000uL);
z[0] = num3 ^ (num4 << 57) ^ (num4 << 5);
z[1] = (num4 >> 7) ^ (num4 >> 59);
}
public static void Square(ulong[] x, ulong[] z)
{
ulong[] array = Nat128.CreateExt64();
ImplSquare(x, array);
Reduce(array, z);
}
public static void SquareAddToExt(ulong[] x, ulong[] zz)
{
ulong[] array = Nat128.CreateExt64();
ImplSquare(x, array);
AddExt(zz, array, zz);
}
public static void SquareN(ulong[] x, int n, ulong[] z)
{
ulong[] array = Nat128.CreateExt64();
ImplSquare(x, array);
Reduce(array, z);
while (--n > 0)
{
ImplSquare(z, array);
Reduce(array, z);
}
}
public static uint Trace(ulong[] x)
{
return (uint)((int)x[0] & 1);
}
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
ulong num = x[0];
ulong num2 = x[1];
num2 = ((num >> 57) ^ (num2 << 7)) & 0x1FFFFFFFFFFFFFFL;
num &= 0x1FFFFFFFFFFFFFFL;
ulong num3 = y[0];
ulong num4 = y[1];
num4 = ((num3 >> 57) ^ (num4 << 7)) & 0x1FFFFFFFFFFFFFFL;
num3 &= 0x1FFFFFFFFFFFFFFL;
ulong[] array = new ulong[6];
ImplMulw(num, num3, array, 0);
ImplMulw(num2, num4, array, 2);
ImplMulw(num ^ num2, num3 ^ num4, array, 4);
ulong num5 = array[1] ^ array[2];
ulong num6 = array[0];
ulong num7 = array[3];
ulong num8 = array[4] ^ num6 ^ num5;
ulong num9 = array[5] ^ num7 ^ num5;
zz[0] = num6 ^ (num8 << 57);
zz[1] = (num8 >> 7) ^ (num9 << 50);
zz[2] = (num9 >> 14) ^ (num7 << 43);
zz[3] = num7 >> 21;
}
protected static void ImplMulw(ulong x, ulong y, ulong[] z, int zOff)
{
ulong[] array = new ulong[8];
array[1] = y;
array[2] = array[1] << 1;
array[3] = array[2] ^ y;
array[4] = array[2] << 1;
array[5] = array[4] ^ y;
array[6] = array[3] << 1;
array[7] = array[6] ^ y;
uint num = (uint)x;
ulong num2 = 0uL;
ulong num3 = array[num & 7];
int num4 = 48;
do
{
num = (uint)(x >> num4);
ulong num5 = array[num & 7] ^ (array[(num >> 3) & 7] << 3) ^ (array[(num >> 6) & 7] << 6);
num3 ^= num5 << num4;
num2 ^= num5 >> -num4;
}
while ((num4 -= 9) > 0);
num2 ^= (x & 0x100804020100800L & (ulong)((long)(y << 7) >> 63)) >> 8;
z[zOff] = num3 & 0x1FFFFFFFFFFFFFFL;
z[zOff + 1] = (num3 >> 57) ^ (num2 << 7);
}
protected static void ImplSquare(ulong[] x, ulong[] zz)
{
Interleave.Expand64To128(x[0], zz, 0);
Interleave.Expand64To128(x[1], zz, 2);
}
}

View File

@@ -0,0 +1,195 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT113FieldElement : AbstractF2mFieldElement
{
protected internal readonly ulong[] x;
public override bool IsOne => Nat128.IsOne64(x);
public override bool IsZero => Nat128.IsZero64(x);
public override string FieldName => "SecT113Field";
public override int FieldSize => 113;
public virtual int Representation => 2;
public virtual int M => 113;
public virtual int K1 => 9;
public virtual int K2 => 0;
public virtual int K3 => 0;
public SecT113FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.BitLength > 113)
{
throw new ArgumentException("value invalid for SecT113FieldElement", "x");
}
this.x = SecT113Field.FromBigInteger(x);
}
public SecT113FieldElement()
{
x = Nat128.Create64();
}
protected internal SecT113FieldElement(ulong[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return (x[0] & 1) != 0;
}
public override BigInteger ToBigInteger()
{
return Nat128.ToBigInteger64(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
ulong[] z = Nat128.Create64();
SecT113Field.Add(x, ((SecT113FieldElement)b).x, z);
return new SecT113FieldElement(z);
}
public override ECFieldElement AddOne()
{
ulong[] z = Nat128.Create64();
SecT113Field.AddOne(x, z);
return new SecT113FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
return Add(b);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
ulong[] z = Nat128.Create64();
SecT113Field.Multiply(x, ((SecT113FieldElement)b).x, z);
return new SecT113FieldElement(z);
}
public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
return MultiplyPlusProduct(b, x, y);
}
public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] y2 = ((SecT113FieldElement)b).x;
ulong[] array2 = ((SecT113FieldElement)x).x;
ulong[] y3 = ((SecT113FieldElement)y).x;
ulong[] array3 = Nat128.CreateExt64();
SecT113Field.MultiplyAddToExt(array, y2, array3);
SecT113Field.MultiplyAddToExt(array2, y3, array3);
ulong[] z = Nat128.Create64();
SecT113Field.Reduce(array3, z);
return new SecT113FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
return Multiply(b.Invert());
}
public override ECFieldElement Negate()
{
return this;
}
public override ECFieldElement Square()
{
ulong[] z = Nat128.Create64();
SecT113Field.Square(x, z);
return new SecT113FieldElement(z);
}
public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
{
return SquarePlusProduct(x, y);
}
public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] array2 = ((SecT113FieldElement)x).x;
ulong[] y2 = ((SecT113FieldElement)y).x;
ulong[] array3 = Nat128.CreateExt64();
SecT113Field.SquareAddToExt(array, array3);
SecT113Field.MultiplyAddToExt(array2, y2, array3);
ulong[] z = Nat128.Create64();
SecT113Field.Reduce(array3, z);
return new SecT113FieldElement(z);
}
public override ECFieldElement SquarePow(int pow)
{
if (pow < 1)
{
return this;
}
ulong[] z = Nat128.Create64();
SecT113Field.SquareN(x, pow, z);
return new SecT113FieldElement(z);
}
public override int Trace()
{
return (int)SecT113Field.Trace(x);
}
public override ECFieldElement Invert()
{
ulong[] z = Nat128.Create64();
SecT113Field.Invert(x, z);
return new SecT113FieldElement(z);
}
public override ECFieldElement Sqrt()
{
ulong[] z = Nat128.Create64();
SecT113Field.Sqrt(x, z);
return new SecT113FieldElement(z);
}
public override bool Equals(object obj)
{
return Equals(obj as SecT113FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecT113FieldElement);
}
public virtual bool Equals(SecT113FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat128.Eq64(x, other.x);
}
public override int GetHashCode()
{
return 0x1B971 ^ Arrays.GetHashCode(x, 0, 2);
}
}

View File

@@ -0,0 +1,127 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT113R1Curve : AbstractF2mCurve
{
private class SecT113R1LookupTable : ECLookupTable
{
private readonly SecT113R1Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT113R1LookupTable(SecT113R1Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat128.Create64();
ulong[] array2 = Nat128.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 2; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 2 + j] & num2);
}
num += 4;
}
return m_outer.CreateRawPoint(new SecT113FieldElement(array), new SecT113FieldElement(array2), withCompression: false);
}
}
private const int SECT113R1_DEFAULT_COORDS = 6;
private const int SECT113R1_FE_LONGS = 2;
protected readonly SecT113R1Point m_infinity;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => 113;
public override bool IsKoblitz => false;
public virtual int M => 113;
public virtual bool IsTrinomial => true;
public virtual int K1 => 9;
public virtual int K2 => 0;
public virtual int K3 => 0;
public SecT113R1Curve()
: base(113, 9, 0, 0)
{
m_infinity = new SecT113R1Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("003088250CA6E7C7FE649CE85820F7")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("00E8BEE4D3E2260744188BE0E9C723")));
m_order = new BigInteger(1, Hex.Decode("0100000000000000D9CCEC8A39E56F"));
m_cofactor = BigInteger.Two;
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT113R1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT113FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT113R1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT113R1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 2 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat128.Copy64(((SecT113FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 2;
Nat128.Copy64(((SecT113FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 2;
}
return new SecT113R1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,260 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT113R1Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT113R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT113R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT113R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT113R1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord)
.Add(curve.A);
if (eCFieldElement10.IsZero)
{
return new SecT113R1Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT113R1Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT113R1Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = (isOne ? rawYCoord : rawYCoord.Multiply(eCFieldElement));
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement a = curve.A;
ECFieldElement b2 = (isOne ? a : a.Multiply(b));
ECFieldElement eCFieldElement3 = rawYCoord.Square().Add(eCFieldElement2).Add(b2);
if (eCFieldElement3.IsZero)
{
return new SecT113R1Point(curve, eCFieldElement3, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement4 = eCFieldElement3.Square();
ECFieldElement eCFieldElement5 = (isOne ? eCFieldElement3 : eCFieldElement3.Multiply(b));
ECFieldElement eCFieldElement6 = (isOne ? rawXCoord : rawXCoord.Multiply(eCFieldElement));
ECFieldElement y = eCFieldElement6.SquarePlusProduct(eCFieldElement3, eCFieldElement2).Add(eCFieldElement4).Add(eCFieldElement5);
return new SecT113R1Point(curve, eCFieldElement4, y, new ECFieldElement[1] { eCFieldElement5 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement b2 = rawYCoord.Square();
ECFieldElement eCFieldElement3 = eCFieldElement2.Square();
ECFieldElement b3 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b4 = curve.A.Multiply(eCFieldElement3).Add(b2).Add(b3);
ECFieldElement eCFieldElement4 = rawYCoord2.AddOne();
ECFieldElement eCFieldElement5 = curve.A.Add(eCFieldElement4).Multiply(eCFieldElement3).Add(b2)
.MultiplyPlusProduct(b4, x, eCFieldElement3);
ECFieldElement eCFieldElement6 = rawXCoord2.Multiply(eCFieldElement3);
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(b4).Square();
if (eCFieldElement7.IsZero)
{
if (eCFieldElement5.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement5.IsZero)
{
return new SecT113R1Point(curve, eCFieldElement5, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement5.Square().Multiply(eCFieldElement6);
ECFieldElement eCFieldElement8 = eCFieldElement5.Multiply(eCFieldElement7).Multiply(eCFieldElement3);
ECFieldElement y = eCFieldElement5.Add(eCFieldElement7).Square().MultiplyPlusProduct(b4, eCFieldElement4, eCFieldElement8);
return new SecT113R1Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement8 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT113R1Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,127 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT113R2Curve : AbstractF2mCurve
{
private class SecT113R2LookupTable : ECLookupTable
{
private readonly SecT113R2Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT113R2LookupTable(SecT113R2Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat128.Create64();
ulong[] array2 = Nat128.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 2; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 2 + j] & num2);
}
num += 4;
}
return m_outer.CreateRawPoint(new SecT113FieldElement(array), new SecT113FieldElement(array2), withCompression: false);
}
}
private const int SECT113R2_DEFAULT_COORDS = 6;
private const int SECT113R2_FE_LONGS = 2;
protected readonly SecT113R2Point m_infinity;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => 113;
public override bool IsKoblitz => false;
public virtual int M => 113;
public virtual bool IsTrinomial => true;
public virtual int K1 => 9;
public virtual int K2 => 0;
public virtual int K3 => 0;
public SecT113R2Curve()
: base(113, 9, 0, 0)
{
m_infinity = new SecT113R2Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("00689918DBEC7E5A0DD6DFC0AA55C7")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("0095E9A9EC9B297BD4BF36E059184F")));
m_order = new BigInteger(1, Hex.Decode("010000000000000108789B2496AF93"));
m_cofactor = BigInteger.Two;
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT113R2Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT113FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT113R2Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT113R2Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 2 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat128.Copy64(((SecT113FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 2;
Nat128.Copy64(((SecT113FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 2;
}
return new SecT113R2LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,260 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT113R2Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT113R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT113R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT113R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT113R2Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord)
.Add(curve.A);
if (eCFieldElement10.IsZero)
{
return new SecT113R2Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT113R2Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT113R2Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = (isOne ? rawYCoord : rawYCoord.Multiply(eCFieldElement));
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement a = curve.A;
ECFieldElement b2 = (isOne ? a : a.Multiply(b));
ECFieldElement eCFieldElement3 = rawYCoord.Square().Add(eCFieldElement2).Add(b2);
if (eCFieldElement3.IsZero)
{
return new SecT113R2Point(curve, eCFieldElement3, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement4 = eCFieldElement3.Square();
ECFieldElement eCFieldElement5 = (isOne ? eCFieldElement3 : eCFieldElement3.Multiply(b));
ECFieldElement eCFieldElement6 = (isOne ? rawXCoord : rawXCoord.Multiply(eCFieldElement));
ECFieldElement y = eCFieldElement6.SquarePlusProduct(eCFieldElement3, eCFieldElement2).Add(eCFieldElement4).Add(eCFieldElement5);
return new SecT113R2Point(curve, eCFieldElement4, y, new ECFieldElement[1] { eCFieldElement5 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement b2 = rawYCoord.Square();
ECFieldElement eCFieldElement3 = eCFieldElement2.Square();
ECFieldElement b3 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b4 = curve.A.Multiply(eCFieldElement3).Add(b2).Add(b3);
ECFieldElement eCFieldElement4 = rawYCoord2.AddOne();
ECFieldElement eCFieldElement5 = curve.A.Add(eCFieldElement4).Multiply(eCFieldElement3).Add(b2)
.MultiplyPlusProduct(b4, x, eCFieldElement3);
ECFieldElement eCFieldElement6 = rawXCoord2.Multiply(eCFieldElement3);
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(b4).Square();
if (eCFieldElement7.IsZero)
{
if (eCFieldElement5.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement5.IsZero)
{
return new SecT113R2Point(curve, eCFieldElement5, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement5.Square().Multiply(eCFieldElement6);
ECFieldElement eCFieldElement8 = eCFieldElement5.Multiply(eCFieldElement7).Multiply(eCFieldElement3);
ECFieldElement y = eCFieldElement5.Add(eCFieldElement7).Square().MultiplyPlusProduct(b4, eCFieldElement4, eCFieldElement8);
return new SecT113R2Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement8 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT113R2Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,287 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT131Field
{
private const ulong M03 = 7uL;
private const ulong M44 = 17592186044415uL;
private static readonly ulong[] ROOT_Z = new ulong[3] { 2791191049453778211uL, 2791191049453778402uL, 6uL };
public static void Add(ulong[] x, ulong[] y, ulong[] z)
{
z[0] = x[0] ^ y[0];
z[1] = x[1] ^ y[1];
z[2] = x[2] ^ y[2];
}
public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz)
{
zz[0] = xx[0] ^ yy[0];
zz[1] = xx[1] ^ yy[1];
zz[2] = xx[2] ^ yy[2];
zz[3] = xx[3] ^ yy[3];
zz[4] = xx[4] ^ yy[4];
}
public static void AddOne(ulong[] x, ulong[] z)
{
z[0] = x[0] ^ 1;
z[1] = x[1];
z[2] = x[2];
}
public static ulong[] FromBigInteger(BigInteger x)
{
ulong[] array = Nat192.FromBigInteger64(x);
Reduce61(array, 0);
return array;
}
public static void Invert(ulong[] x, ulong[] z)
{
if (Nat192.IsZero64(x))
{
throw new InvalidOperationException();
}
ulong[] array = Nat192.Create64();
ulong[] array2 = Nat192.Create64();
Square(x, array);
Multiply(array, x, array);
SquareN(array, 2, array2);
Multiply(array2, array, array2);
SquareN(array2, 4, array);
Multiply(array, array2, array);
SquareN(array, 8, array2);
Multiply(array2, array, array2);
SquareN(array2, 16, array);
Multiply(array, array2, array);
SquareN(array, 32, array2);
Multiply(array2, array, array2);
Square(array2, array2);
Multiply(array2, x, array2);
SquareN(array2, 65, array);
Multiply(array, array2, array);
Square(array, z);
}
public static void Multiply(ulong[] x, ulong[] y, ulong[] z)
{
ulong[] array = Nat192.CreateExt64();
ImplMultiply(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz)
{
ulong[] array = Nat192.CreateExt64();
ImplMultiply(x, y, array);
AddExt(zz, array, zz);
}
public static void Reduce(ulong[] xx, ulong[] z)
{
ulong num = xx[0];
ulong num2 = xx[1];
ulong num3 = xx[2];
ulong num4 = xx[3];
ulong num5 = xx[4];
num2 ^= (num5 << 61) ^ (num5 << 63);
num3 ^= (num5 >> 3) ^ (num5 >> 1) ^ num5 ^ (num5 << 5);
num4 ^= num5 >> 59;
num ^= (num4 << 61) ^ (num4 << 63);
num2 ^= (num4 >> 3) ^ (num4 >> 1) ^ num4 ^ (num4 << 5);
num3 ^= num4 >> 59;
ulong num6 = num3 >> 3;
z[0] = num ^ num6 ^ (num6 << 2) ^ (num6 << 3) ^ (num6 << 8);
z[1] = num2 ^ (num6 >> 56);
z[2] = num3 & 7;
}
public static void Reduce61(ulong[] z, int zOff)
{
ulong num = z[zOff + 2];
ulong num2 = num >> 3;
ulong[] array2;
ulong[] array = (array2 = z);
nint num3 = zOff;
array[zOff] = array2[num3] ^ (num2 ^ (num2 << 2) ^ (num2 << 3) ^ (num2 << 8));
ulong[] array3 = (array2 = z);
int num4 = zOff + 1;
num3 = num4;
array3[num4] = array2[num3] ^ (num2 >> 56);
z[zOff + 2] = num & 7;
}
public static void Sqrt(ulong[] x, ulong[] z)
{
ulong[] array = Nat192.Create64();
ulong num = Interleave.Unshuffle(x[0]);
ulong num2 = Interleave.Unshuffle(x[1]);
ulong num3 = (num & 0xFFFFFFFFu) | (num2 << 32);
array[0] = (num >> 32) | (num2 & 0xFFFFFFFF00000000uL);
num = Interleave.Unshuffle(x[2]);
ulong num4 = num & 0xFFFFFFFFu;
array[1] = num >> 32;
Multiply(array, ROOT_Z, z);
ulong[] array2;
(array2 = z)[0] = array2[0] ^ num3;
(array2 = z)[1] = array2[1] ^ num4;
}
public static void Square(ulong[] x, ulong[] z)
{
ulong[] array = Nat.Create64(5);
ImplSquare(x, array);
Reduce(array, z);
}
public static void SquareAddToExt(ulong[] x, ulong[] zz)
{
ulong[] array = Nat.Create64(5);
ImplSquare(x, array);
AddExt(zz, array, zz);
}
public static void SquareN(ulong[] x, int n, ulong[] z)
{
ulong[] array = Nat.Create64(5);
ImplSquare(x, array);
Reduce(array, z);
while (--n > 0)
{
ImplSquare(z, array);
Reduce(array, z);
}
}
public static uint Trace(ulong[] x)
{
return (uint)((int)(x[0] ^ (x[1] >> 59) ^ (x[2] >> 1)) & 1);
}
protected static void ImplCompactExt(ulong[] zz)
{
ulong num = zz[0];
ulong num2 = zz[1];
ulong num3 = zz[2];
ulong num4 = zz[3];
ulong num5 = zz[4];
ulong num6 = zz[5];
zz[0] = num ^ (num2 << 44);
zz[1] = (num2 >> 20) ^ (num3 << 24);
zz[2] = (num3 >> 40) ^ (num4 << 4) ^ (num5 << 48);
zz[3] = (num4 >> 60) ^ (num6 << 28) ^ (num5 >> 16);
zz[4] = num6 >> 36;
zz[5] = 0uL;
}
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
ulong num = x[0];
ulong num2 = x[1];
ulong num3 = x[2];
num3 = ((num2 >> 24) ^ (num3 << 40)) & 0xFFFFFFFFFFFL;
num2 = ((num >> 44) ^ (num2 << 20)) & 0xFFFFFFFFFFFL;
num &= 0xFFFFFFFFFFFL;
ulong num4 = y[0];
ulong num5 = y[1];
ulong num6 = y[2];
num6 = ((num5 >> 24) ^ (num6 << 40)) & 0xFFFFFFFFFFFL;
num5 = ((num4 >> 44) ^ (num5 << 20)) & 0xFFFFFFFFFFFL;
num4 &= 0xFFFFFFFFFFFL;
ulong[] array = new ulong[10];
ImplMulw(num, num4, array, 0);
ImplMulw(num3, num6, array, 2);
ulong num7 = num ^ num2 ^ num3;
ulong num8 = num4 ^ num5 ^ num6;
ImplMulw(num7, num8, array, 4);
ulong num9 = (num2 << 1) ^ (num3 << 2);
ulong num10 = (num5 << 1) ^ (num6 << 2);
ImplMulw(num ^ num9, num4 ^ num10, array, 6);
ImplMulw(num7 ^ num9, num8 ^ num10, array, 8);
ulong num11 = array[6] ^ array[8];
ulong num12 = array[7] ^ array[9];
ulong num13 = (num11 << 1) ^ array[6];
ulong num14 = num11 ^ (num12 << 1) ^ array[7];
ulong num15 = num12;
ulong num16 = array[0];
ulong num17 = array[1] ^ array[0] ^ array[4];
ulong num18 = array[1] ^ array[5];
ulong num19 = num16 ^ num13 ^ (array[2] << 4) ^ (array[2] << 1);
ulong num20 = num17 ^ num14 ^ (array[3] << 4) ^ (array[3] << 1);
ulong num21 = num18 ^ num15;
num20 ^= num19 >> 44;
num19 &= 0xFFFFFFFFFFFL;
num21 ^= num20 >> 44;
num20 &= 0xFFFFFFFFFFFL;
num19 = (num19 >> 1) ^ ((num20 & 1) << 43);
num20 = (num20 >> 1) ^ ((num21 & 1) << 43);
num21 >>= 1;
num19 ^= num19 << 1;
num19 ^= num19 << 2;
num19 ^= num19 << 4;
num19 ^= num19 << 8;
num19 ^= num19 << 16;
num19 ^= num19 << 32;
num19 &= 0xFFFFFFFFFFFL;
num20 ^= num19 >> 43;
num20 ^= num20 << 1;
num20 ^= num20 << 2;
num20 ^= num20 << 4;
num20 ^= num20 << 8;
num20 ^= num20 << 16;
num20 ^= num20 << 32;
num20 &= 0xFFFFFFFFFFFL;
num21 ^= num20 >> 43;
num21 ^= num21 << 1;
num21 ^= num21 << 2;
num21 ^= num21 << 4;
num21 ^= num21 << 8;
num21 ^= num21 << 16;
num21 ^= num21 << 32;
zz[0] = num16;
zz[1] = num17 ^ num19 ^ array[2];
zz[2] = num18 ^ num20 ^ num19 ^ array[3];
zz[3] = num21 ^ num20;
zz[4] = num21 ^ array[2];
zz[5] = array[3];
ImplCompactExt(zz);
}
protected static void ImplMulw(ulong x, ulong y, ulong[] z, int zOff)
{
ulong[] array = new ulong[8];
array[1] = y;
array[2] = array[1] << 1;
array[3] = array[2] ^ y;
array[4] = array[2] << 1;
array[5] = array[4] ^ y;
array[6] = array[3] << 1;
array[7] = array[6] ^ y;
uint num = (uint)x;
ulong num2 = 0uL;
ulong num3 = array[num & 7] ^ (array[(num >> 3) & 7] << 3) ^ (array[(num >> 6) & 7] << 6);
int num4 = 33;
do
{
num = (uint)(x >> num4);
ulong num5 = array[num & 7] ^ (array[(num >> 3) & 7] << 3) ^ (array[(num >> 6) & 7] << 6) ^ (array[(num >> 9) & 7] << 9);
num3 ^= num5 << num4;
num2 ^= num5 >> -num4;
}
while ((num4 -= 12) > 0);
z[zOff] = num3 & 0xFFFFFFFFFFFL;
z[zOff + 1] = (num3 >> 44) ^ (num2 << 20);
}
protected static void ImplSquare(ulong[] x, ulong[] zz)
{
Interleave.Expand64To128(x[0], zz, 0);
Interleave.Expand64To128(x[1], zz, 2);
zz[4] = Interleave.Expand8to16((uint)x[2]);
}
}

View File

@@ -0,0 +1,195 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT131FieldElement : AbstractF2mFieldElement
{
protected internal readonly ulong[] x;
public override bool IsOne => Nat192.IsOne64(x);
public override bool IsZero => Nat192.IsZero64(x);
public override string FieldName => "SecT131Field";
public override int FieldSize => 131;
public virtual int Representation => 3;
public virtual int M => 131;
public virtual int K1 => 2;
public virtual int K2 => 3;
public virtual int K3 => 8;
public SecT131FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.BitLength > 131)
{
throw new ArgumentException("value invalid for SecT131FieldElement", "x");
}
this.x = SecT131Field.FromBigInteger(x);
}
public SecT131FieldElement()
{
x = Nat192.Create64();
}
protected internal SecT131FieldElement(ulong[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return (x[0] & 1) != 0;
}
public override BigInteger ToBigInteger()
{
return Nat192.ToBigInteger64(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
ulong[] z = Nat192.Create64();
SecT131Field.Add(x, ((SecT131FieldElement)b).x, z);
return new SecT131FieldElement(z);
}
public override ECFieldElement AddOne()
{
ulong[] z = Nat192.Create64();
SecT131Field.AddOne(x, z);
return new SecT131FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
return Add(b);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
ulong[] z = Nat192.Create64();
SecT131Field.Multiply(x, ((SecT131FieldElement)b).x, z);
return new SecT131FieldElement(z);
}
public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
return MultiplyPlusProduct(b, x, y);
}
public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] y2 = ((SecT131FieldElement)b).x;
ulong[] array2 = ((SecT131FieldElement)x).x;
ulong[] y3 = ((SecT131FieldElement)y).x;
ulong[] array3 = Nat.Create64(5);
SecT131Field.MultiplyAddToExt(array, y2, array3);
SecT131Field.MultiplyAddToExt(array2, y3, array3);
ulong[] z = Nat192.Create64();
SecT131Field.Reduce(array3, z);
return new SecT131FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
return Multiply(b.Invert());
}
public override ECFieldElement Negate()
{
return this;
}
public override ECFieldElement Square()
{
ulong[] z = Nat192.Create64();
SecT131Field.Square(x, z);
return new SecT131FieldElement(z);
}
public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
{
return SquarePlusProduct(x, y);
}
public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] array2 = ((SecT131FieldElement)x).x;
ulong[] y2 = ((SecT131FieldElement)y).x;
ulong[] array3 = Nat.Create64(5);
SecT131Field.SquareAddToExt(array, array3);
SecT131Field.MultiplyAddToExt(array2, y2, array3);
ulong[] z = Nat192.Create64();
SecT131Field.Reduce(array3, z);
return new SecT131FieldElement(z);
}
public override ECFieldElement SquarePow(int pow)
{
if (pow < 1)
{
return this;
}
ulong[] z = Nat192.Create64();
SecT131Field.SquareN(x, pow, z);
return new SecT131FieldElement(z);
}
public override int Trace()
{
return (int)SecT131Field.Trace(x);
}
public override ECFieldElement Invert()
{
ulong[] z = Nat192.Create64();
SecT131Field.Invert(x, z);
return new SecT131FieldElement(z);
}
public override ECFieldElement Sqrt()
{
ulong[] z = Nat192.Create64();
SecT131Field.Sqrt(x, z);
return new SecT131FieldElement(z);
}
public override bool Equals(object obj)
{
return Equals(obj as SecT131FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecT131FieldElement);
}
public virtual bool Equals(SecT131FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat192.Eq64(x, other.x);
}
public override int GetHashCode()
{
return 0x202F8 ^ Arrays.GetHashCode(x, 0, 3);
}
}

View File

@@ -0,0 +1,127 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT131R1Curve : AbstractF2mCurve
{
private class SecT131R1LookupTable : ECLookupTable
{
private readonly SecT131R1Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT131R1LookupTable(SecT131R1Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat192.Create64();
ulong[] array2 = Nat192.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 3; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 3 + j] & num2);
}
num += 6;
}
return m_outer.CreateRawPoint(new SecT131FieldElement(array), new SecT131FieldElement(array2), withCompression: false);
}
}
private const int SECT131R1_DEFAULT_COORDS = 6;
private const int SECT131R1_FE_LONGS = 3;
protected readonly SecT131R1Point m_infinity;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => 131;
public override bool IsKoblitz => false;
public virtual int M => 131;
public virtual bool IsTrinomial => false;
public virtual int K1 => 2;
public virtual int K2 => 3;
public virtual int K3 => 8;
public SecT131R1Curve()
: base(131, 2, 3, 8)
{
m_infinity = new SecT131R1Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("07A11B09A76B562144418FF3FF8C2570B8")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("0217C05610884B63B9C6C7291678F9D341")));
m_order = new BigInteger(1, Hex.Decode("0400000000000000023123953A9464B54D"));
m_cofactor = BigInteger.Two;
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT131R1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT131FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT131R1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT131R1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 3 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat192.Copy64(((SecT131FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 3;
Nat192.Copy64(((SecT131FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 3;
}
return new SecT131R1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,260 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT131R1Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT131R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT131R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT131R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT131R1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord)
.Add(curve.A);
if (eCFieldElement10.IsZero)
{
return new SecT131R1Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT131R1Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT131R1Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = (isOne ? rawYCoord : rawYCoord.Multiply(eCFieldElement));
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement a = curve.A;
ECFieldElement b2 = (isOne ? a : a.Multiply(b));
ECFieldElement eCFieldElement3 = rawYCoord.Square().Add(eCFieldElement2).Add(b2);
if (eCFieldElement3.IsZero)
{
return new SecT131R1Point(curve, eCFieldElement3, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement4 = eCFieldElement3.Square();
ECFieldElement eCFieldElement5 = (isOne ? eCFieldElement3 : eCFieldElement3.Multiply(b));
ECFieldElement eCFieldElement6 = (isOne ? rawXCoord : rawXCoord.Multiply(eCFieldElement));
ECFieldElement y = eCFieldElement6.SquarePlusProduct(eCFieldElement3, eCFieldElement2).Add(eCFieldElement4).Add(eCFieldElement5);
return new SecT131R1Point(curve, eCFieldElement4, y, new ECFieldElement[1] { eCFieldElement5 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement b2 = rawYCoord.Square();
ECFieldElement eCFieldElement3 = eCFieldElement2.Square();
ECFieldElement b3 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b4 = curve.A.Multiply(eCFieldElement3).Add(b2).Add(b3);
ECFieldElement eCFieldElement4 = rawYCoord2.AddOne();
ECFieldElement eCFieldElement5 = curve.A.Add(eCFieldElement4).Multiply(eCFieldElement3).Add(b2)
.MultiplyPlusProduct(b4, x, eCFieldElement3);
ECFieldElement eCFieldElement6 = rawXCoord2.Multiply(eCFieldElement3);
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(b4).Square();
if (eCFieldElement7.IsZero)
{
if (eCFieldElement5.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement5.IsZero)
{
return new SecT131R1Point(curve, eCFieldElement5, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement5.Square().Multiply(eCFieldElement6);
ECFieldElement eCFieldElement8 = eCFieldElement5.Multiply(eCFieldElement7).Multiply(eCFieldElement3);
ECFieldElement y = eCFieldElement5.Add(eCFieldElement7).Square().MultiplyPlusProduct(b4, eCFieldElement4, eCFieldElement8);
return new SecT131R1Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement8 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT131R1Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,127 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT131R2Curve : AbstractF2mCurve
{
private class SecT131R2LookupTable : ECLookupTable
{
private readonly SecT131R2Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT131R2LookupTable(SecT131R2Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat192.Create64();
ulong[] array2 = Nat192.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 3; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 3 + j] & num2);
}
num += 6;
}
return m_outer.CreateRawPoint(new SecT131FieldElement(array), new SecT131FieldElement(array2), withCompression: false);
}
}
private const int SECT131R2_DEFAULT_COORDS = 6;
private const int SECT131R2_FE_LONGS = 3;
protected readonly SecT131R2Point m_infinity;
public override int FieldSize => 131;
public override ECPoint Infinity => m_infinity;
public override bool IsKoblitz => false;
public virtual int M => 131;
public virtual bool IsTrinomial => false;
public virtual int K1 => 2;
public virtual int K2 => 3;
public virtual int K3 => 8;
public SecT131R2Curve()
: base(131, 2, 3, 8)
{
m_infinity = new SecT131R2Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("03E5A88919D7CAFCBF415F07C2176573B2")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("04B8266A46C55657AC734CE38F018F2192")));
m_order = new BigInteger(1, Hex.Decode("0400000000000000016954A233049BA98F"));
m_cofactor = BigInteger.Two;
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT131R2Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT131FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT131R2Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT131R2Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 3 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat192.Copy64(((SecT131FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 3;
Nat192.Copy64(((SecT131FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 3;
}
return new SecT131R2LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,260 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT131R2Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT131R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT131R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT131R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT131R2Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord)
.Add(curve.A);
if (eCFieldElement10.IsZero)
{
return new SecT131R2Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT131R2Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT131R2Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = (isOne ? rawYCoord : rawYCoord.Multiply(eCFieldElement));
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement a = curve.A;
ECFieldElement b2 = (isOne ? a : a.Multiply(b));
ECFieldElement eCFieldElement3 = rawYCoord.Square().Add(eCFieldElement2).Add(b2);
if (eCFieldElement3.IsZero)
{
return new SecT131R2Point(curve, eCFieldElement3, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement4 = eCFieldElement3.Square();
ECFieldElement eCFieldElement5 = (isOne ? eCFieldElement3 : eCFieldElement3.Multiply(b));
ECFieldElement eCFieldElement6 = (isOne ? rawXCoord : rawXCoord.Multiply(eCFieldElement));
ECFieldElement y = eCFieldElement6.SquarePlusProduct(eCFieldElement3, eCFieldElement2).Add(eCFieldElement4).Add(eCFieldElement5);
return new SecT131R2Point(curve, eCFieldElement4, y, new ECFieldElement[1] { eCFieldElement5 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement b2 = rawYCoord.Square();
ECFieldElement eCFieldElement3 = eCFieldElement2.Square();
ECFieldElement b3 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b4 = curve.A.Multiply(eCFieldElement3).Add(b2).Add(b3);
ECFieldElement eCFieldElement4 = rawYCoord2.AddOne();
ECFieldElement eCFieldElement5 = curve.A.Add(eCFieldElement4).Multiply(eCFieldElement3).Add(b2)
.MultiplyPlusProduct(b4, x, eCFieldElement3);
ECFieldElement eCFieldElement6 = rawXCoord2.Multiply(eCFieldElement3);
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(b4).Square();
if (eCFieldElement7.IsZero)
{
if (eCFieldElement5.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement5.IsZero)
{
return new SecT131R2Point(curve, eCFieldElement5, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement5.Square().Multiply(eCFieldElement6);
ECFieldElement eCFieldElement8 = eCFieldElement5.Multiply(eCFieldElement7).Multiply(eCFieldElement3);
ECFieldElement y = eCFieldElement5.Add(eCFieldElement7).Square().MultiplyPlusProduct(b4, eCFieldElement4, eCFieldElement8);
return new SecT131R2Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement8 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT131R2Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,289 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT163Field
{
private const ulong M35 = 34359738367uL;
private const ulong M55 = 36028797018963967uL;
private static readonly ulong[] ROOT_Z = new ulong[3] { 13176245766935393968uL, 5270498306774195053uL, 19634136210uL };
public static void Add(ulong[] x, ulong[] y, ulong[] z)
{
z[0] = x[0] ^ y[0];
z[1] = x[1] ^ y[1];
z[2] = x[2] ^ y[2];
}
public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz)
{
zz[0] = xx[0] ^ yy[0];
zz[1] = xx[1] ^ yy[1];
zz[2] = xx[2] ^ yy[2];
zz[3] = xx[3] ^ yy[3];
zz[4] = xx[4] ^ yy[4];
zz[5] = xx[5] ^ yy[5];
}
public static void AddOne(ulong[] x, ulong[] z)
{
z[0] = x[0] ^ 1;
z[1] = x[1];
z[2] = x[2];
}
public static ulong[] FromBigInteger(BigInteger x)
{
ulong[] array = Nat192.FromBigInteger64(x);
Reduce29(array, 0);
return array;
}
public static void Invert(ulong[] x, ulong[] z)
{
if (Nat192.IsZero64(x))
{
throw new InvalidOperationException();
}
ulong[] array = Nat192.Create64();
ulong[] array2 = Nat192.Create64();
Square(x, array);
SquareN(array, 1, array2);
Multiply(array, array2, array);
SquareN(array2, 1, array2);
Multiply(array, array2, array);
SquareN(array, 3, array2);
Multiply(array, array2, array);
SquareN(array2, 3, array2);
Multiply(array, array2, array);
SquareN(array, 9, array2);
Multiply(array, array2, array);
SquareN(array2, 9, array2);
Multiply(array, array2, array);
SquareN(array, 27, array2);
Multiply(array, array2, array);
SquareN(array2, 27, array2);
Multiply(array, array2, array);
SquareN(array, 81, array2);
Multiply(array, array2, z);
}
public static void Multiply(ulong[] x, ulong[] y, ulong[] z)
{
ulong[] array = Nat192.CreateExt64();
ImplMultiply(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz)
{
ulong[] array = Nat192.CreateExt64();
ImplMultiply(x, y, array);
AddExt(zz, array, zz);
}
public static void Reduce(ulong[] xx, ulong[] z)
{
ulong num = xx[0];
ulong num2 = xx[1];
ulong num3 = xx[2];
ulong num4 = xx[3];
ulong num5 = xx[4];
ulong num6 = xx[5];
num3 ^= (num6 << 29) ^ (num6 << 32) ^ (num6 << 35) ^ (num6 << 36);
num4 ^= (num6 >> 35) ^ (num6 >> 32) ^ (num6 >> 29) ^ (num6 >> 28);
num2 ^= (num5 << 29) ^ (num5 << 32) ^ (num5 << 35) ^ (num5 << 36);
num3 ^= (num5 >> 35) ^ (num5 >> 32) ^ (num5 >> 29) ^ (num5 >> 28);
num ^= (num4 << 29) ^ (num4 << 32) ^ (num4 << 35) ^ (num4 << 36);
num2 ^= (num4 >> 35) ^ (num4 >> 32) ^ (num4 >> 29) ^ (num4 >> 28);
ulong num7 = num3 >> 35;
z[0] = num ^ num7 ^ (num7 << 3) ^ (num7 << 6) ^ (num7 << 7);
z[1] = num2;
z[2] = num3 & 0x7FFFFFFFFL;
}
public static void Reduce29(ulong[] z, int zOff)
{
ulong num = z[zOff + 2];
ulong num2 = num >> 35;
ulong[] array2;
ulong[] array = (array2 = z);
nint num3 = zOff;
array[zOff] = array2[num3] ^ (num2 ^ (num2 << 3) ^ (num2 << 6) ^ (num2 << 7));
z[zOff + 2] = num & 0x7FFFFFFFFL;
}
public static void Sqrt(ulong[] x, ulong[] z)
{
ulong[] array = Nat192.Create64();
ulong num = Interleave.Unshuffle(x[0]);
ulong num2 = Interleave.Unshuffle(x[1]);
ulong num3 = (num & 0xFFFFFFFFu) | (num2 << 32);
array[0] = (num >> 32) | (num2 & 0xFFFFFFFF00000000uL);
num = Interleave.Unshuffle(x[2]);
ulong num4 = num & 0xFFFFFFFFu;
array[1] = num >> 32;
Multiply(array, ROOT_Z, z);
ulong[] array2;
(array2 = z)[0] = array2[0] ^ num3;
(array2 = z)[1] = array2[1] ^ num4;
}
public static void Square(ulong[] x, ulong[] z)
{
ulong[] array = Nat192.CreateExt64();
ImplSquare(x, array);
Reduce(array, z);
}
public static void SquareAddToExt(ulong[] x, ulong[] zz)
{
ulong[] array = Nat192.CreateExt64();
ImplSquare(x, array);
AddExt(zz, array, zz);
}
public static void SquareN(ulong[] x, int n, ulong[] z)
{
ulong[] array = Nat192.CreateExt64();
ImplSquare(x, array);
Reduce(array, z);
while (--n > 0)
{
ImplSquare(z, array);
Reduce(array, z);
}
}
public static uint Trace(ulong[] x)
{
return (uint)((int)(x[0] ^ (x[2] >> 29)) & 1);
}
protected static void ImplCompactExt(ulong[] zz)
{
ulong num = zz[0];
ulong num2 = zz[1];
ulong num3 = zz[2];
ulong num4 = zz[3];
ulong num5 = zz[4];
ulong num6 = zz[5];
zz[0] = num ^ (num2 << 55);
zz[1] = (num2 >> 9) ^ (num3 << 46);
zz[2] = (num3 >> 18) ^ (num4 << 37);
zz[3] = (num4 >> 27) ^ (num5 << 28);
zz[4] = (num5 >> 36) ^ (num6 << 19);
zz[5] = num6 >> 45;
}
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
ulong num = x[0];
ulong num2 = x[1];
ulong num3 = x[2];
num3 = (num2 >> 46) ^ (num3 << 18);
num2 = ((num >> 55) ^ (num2 << 9)) & 0x7FFFFFFFFFFFFFL;
num &= 0x7FFFFFFFFFFFFFL;
ulong num4 = y[0];
ulong num5 = y[1];
ulong num6 = y[2];
num6 = (num5 >> 46) ^ (num6 << 18);
num5 = ((num4 >> 55) ^ (num5 << 9)) & 0x7FFFFFFFFFFFFFL;
num4 &= 0x7FFFFFFFFFFFFFL;
ulong[] array = new ulong[10];
ImplMulw(num, num4, array, 0);
ImplMulw(num3, num6, array, 2);
ulong num7 = num ^ num2 ^ num3;
ulong num8 = num4 ^ num5 ^ num6;
ImplMulw(num7, num8, array, 4);
ulong num9 = (num2 << 1) ^ (num3 << 2);
ulong num10 = (num5 << 1) ^ (num6 << 2);
ImplMulw(num ^ num9, num4 ^ num10, array, 6);
ImplMulw(num7 ^ num9, num8 ^ num10, array, 8);
ulong num11 = array[6] ^ array[8];
ulong num12 = array[7] ^ array[9];
ulong num13 = (num11 << 1) ^ array[6];
ulong num14 = num11 ^ (num12 << 1) ^ array[7];
ulong num15 = num12;
ulong num16 = array[0];
ulong num17 = array[1] ^ array[0] ^ array[4];
ulong num18 = array[1] ^ array[5];
ulong num19 = num16 ^ num13 ^ (array[2] << 4) ^ (array[2] << 1);
ulong num20 = num17 ^ num14 ^ (array[3] << 4) ^ (array[3] << 1);
ulong num21 = num18 ^ num15;
num20 ^= num19 >> 55;
num19 &= 0x7FFFFFFFFFFFFFL;
num21 ^= num20 >> 55;
num20 &= 0x7FFFFFFFFFFFFFL;
num19 = (num19 >> 1) ^ ((num20 & 1) << 54);
num20 = (num20 >> 1) ^ ((num21 & 1) << 54);
num21 >>= 1;
num19 ^= num19 << 1;
num19 ^= num19 << 2;
num19 ^= num19 << 4;
num19 ^= num19 << 8;
num19 ^= num19 << 16;
num19 ^= num19 << 32;
num19 &= 0x7FFFFFFFFFFFFFL;
num20 ^= num19 >> 54;
num20 ^= num20 << 1;
num20 ^= num20 << 2;
num20 ^= num20 << 4;
num20 ^= num20 << 8;
num20 ^= num20 << 16;
num20 ^= num20 << 32;
num20 &= 0x7FFFFFFFFFFFFFL;
num21 ^= num20 >> 54;
num21 ^= num21 << 1;
num21 ^= num21 << 2;
num21 ^= num21 << 4;
num21 ^= num21 << 8;
num21 ^= num21 << 16;
num21 ^= num21 << 32;
zz[0] = num16;
zz[1] = num17 ^ num19 ^ array[2];
zz[2] = num18 ^ num20 ^ num19 ^ array[3];
zz[3] = num21 ^ num20;
zz[4] = num21 ^ array[2];
zz[5] = array[3];
ImplCompactExt(zz);
}
protected static void ImplMulw(ulong x, ulong y, ulong[] z, int zOff)
{
ulong[] array = new ulong[8];
array[1] = y;
array[2] = array[1] << 1;
array[3] = array[2] ^ y;
array[4] = array[2] << 1;
array[5] = array[4] ^ y;
array[6] = array[3] << 1;
array[7] = array[6] ^ y;
uint num = (uint)x;
ulong num2 = 0uL;
ulong num3 = array[num & 3];
int num4 = 47;
do
{
num = (uint)(x >> num4);
ulong num5 = array[num & 7] ^ (array[(num >> 3) & 7] << 3) ^ (array[(num >> 6) & 7] << 6);
num3 ^= num5 << num4;
num2 ^= num5 >> -num4;
}
while ((num4 -= 9) > 0);
z[zOff] = num3 & 0x7FFFFFFFFFFFFFL;
z[zOff + 1] = (num3 >> 55) ^ (num2 << 9);
}
protected static void ImplSquare(ulong[] x, ulong[] zz)
{
Interleave.Expand64To128(x[0], zz, 0);
Interleave.Expand64To128(x[1], zz, 2);
ulong num = x[2];
zz[4] = Interleave.Expand32to64((uint)num);
zz[5] = Interleave.Expand8to16((uint)(num >> 32));
}
}

View File

@@ -0,0 +1,195 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT163FieldElement : AbstractF2mFieldElement
{
protected internal readonly ulong[] x;
public override bool IsOne => Nat192.IsOne64(x);
public override bool IsZero => Nat192.IsZero64(x);
public override string FieldName => "SecT163Field";
public override int FieldSize => 163;
public virtual int Representation => 3;
public virtual int M => 163;
public virtual int K1 => 3;
public virtual int K2 => 6;
public virtual int K3 => 7;
public SecT163FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.BitLength > 163)
{
throw new ArgumentException("value invalid for SecT163FieldElement", "x");
}
this.x = SecT163Field.FromBigInteger(x);
}
public SecT163FieldElement()
{
x = Nat192.Create64();
}
protected internal SecT163FieldElement(ulong[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return (x[0] & 1) != 0;
}
public override BigInteger ToBigInteger()
{
return Nat192.ToBigInteger64(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
ulong[] z = Nat192.Create64();
SecT163Field.Add(x, ((SecT163FieldElement)b).x, z);
return new SecT163FieldElement(z);
}
public override ECFieldElement AddOne()
{
ulong[] z = Nat192.Create64();
SecT163Field.AddOne(x, z);
return new SecT163FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
return Add(b);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
ulong[] z = Nat192.Create64();
SecT163Field.Multiply(x, ((SecT163FieldElement)b).x, z);
return new SecT163FieldElement(z);
}
public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
return MultiplyPlusProduct(b, x, y);
}
public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] y2 = ((SecT163FieldElement)b).x;
ulong[] array2 = ((SecT163FieldElement)x).x;
ulong[] y3 = ((SecT163FieldElement)y).x;
ulong[] array3 = Nat192.CreateExt64();
SecT163Field.MultiplyAddToExt(array, y2, array3);
SecT163Field.MultiplyAddToExt(array2, y3, array3);
ulong[] z = Nat192.Create64();
SecT163Field.Reduce(array3, z);
return new SecT163FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
return Multiply(b.Invert());
}
public override ECFieldElement Negate()
{
return this;
}
public override ECFieldElement Square()
{
ulong[] z = Nat192.Create64();
SecT163Field.Square(x, z);
return new SecT163FieldElement(z);
}
public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
{
return SquarePlusProduct(x, y);
}
public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] array2 = ((SecT163FieldElement)x).x;
ulong[] y2 = ((SecT163FieldElement)y).x;
ulong[] array3 = Nat192.CreateExt64();
SecT163Field.SquareAddToExt(array, array3);
SecT163Field.MultiplyAddToExt(array2, y2, array3);
ulong[] z = Nat192.Create64();
SecT163Field.Reduce(array3, z);
return new SecT163FieldElement(z);
}
public override ECFieldElement SquarePow(int pow)
{
if (pow < 1)
{
return this;
}
ulong[] z = Nat192.Create64();
SecT163Field.SquareN(x, pow, z);
return new SecT163FieldElement(z);
}
public override int Trace()
{
return (int)SecT163Field.Trace(x);
}
public override ECFieldElement Invert()
{
ulong[] z = Nat192.Create64();
SecT163Field.Invert(x, z);
return new SecT163FieldElement(z);
}
public override ECFieldElement Sqrt()
{
ulong[] z = Nat192.Create64();
SecT163Field.Sqrt(x, z);
return new SecT163FieldElement(z);
}
public override bool Equals(object obj)
{
return Equals(obj as SecT163FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecT163FieldElement);
}
public virtual bool Equals(SecT163FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat192.Eq64(x, other.x);
}
public override int GetHashCode()
{
return 0x27FB3 ^ Arrays.GetHashCode(x, 0, 3);
}
}

View File

@@ -0,0 +1,133 @@
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT163K1Curve : AbstractF2mCurve
{
private class SecT163K1LookupTable : ECLookupTable
{
private readonly SecT163K1Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT163K1LookupTable(SecT163K1Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat192.Create64();
ulong[] array2 = Nat192.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 3; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 3 + j] & num2);
}
num += 6;
}
return m_outer.CreateRawPoint(new SecT163FieldElement(array), new SecT163FieldElement(array2), withCompression: false);
}
}
private const int SECT163K1_DEFAULT_COORDS = 6;
private const int SECT163K1_FE_LONGS = 3;
protected readonly SecT163K1Point m_infinity;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => 163;
public override bool IsKoblitz => true;
public virtual int M => 163;
public virtual bool IsTrinomial => false;
public virtual int K1 => 3;
public virtual int K2 => 6;
public virtual int K3 => 7;
public SecT163K1Curve()
: base(163, 3, 6, 7)
{
m_infinity = new SecT163K1Point(this, null, null);
m_a = FromBigInteger(BigInteger.One);
m_b = m_a;
m_order = new BigInteger(1, Hex.Decode("04000000000000000000020108A2E0CC0D99F8A5EF"));
m_cofactor = BigInteger.Two;
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT163K1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
protected override ECMultiplier CreateDefaultMultiplier()
{
return new WTauNafMultiplier();
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT163FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT163K1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT163K1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 3 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat192.Copy64(((SecT163FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 3;
Nat192.Copy64(((SecT163FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 3;
}
return new SecT163K1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,257 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT163K1Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT163K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT163K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT163K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT163K1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord)
.AddOne();
if (eCFieldElement10.IsZero)
{
return new SecT163K1Point(curve, eCFieldElement10, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT163K1Point(curve, eCFieldElement10, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT163K1Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement b = (isOne ? rawYCoord : rawYCoord.Multiply(eCFieldElement));
ECFieldElement b2 = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement eCFieldElement2 = rawYCoord.Square().Add(b).Add(b2);
if (eCFieldElement2.IsZero)
{
return new SecT163K1Point(curve, eCFieldElement2, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement3 = eCFieldElement2.Square();
ECFieldElement eCFieldElement4 = (isOne ? eCFieldElement2 : eCFieldElement2.Multiply(b2));
ECFieldElement eCFieldElement5 = rawYCoord.Add(rawXCoord).Square();
ECFieldElement y = eCFieldElement5.Add(eCFieldElement2).Add(b2).Multiply(eCFieldElement5)
.Add(eCFieldElement3);
return new SecT163K1Point(curve, eCFieldElement3, y, new ECFieldElement[1] { eCFieldElement4 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement b2 = rawYCoord.Square();
ECFieldElement eCFieldElement3 = eCFieldElement2.Square();
ECFieldElement b3 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b4 = eCFieldElement3.Add(b2).Add(b3);
ECFieldElement eCFieldElement4 = rawYCoord2.Multiply(eCFieldElement3).Add(b2).MultiplyPlusProduct(b4, x, eCFieldElement3);
ECFieldElement eCFieldElement5 = rawXCoord2.Multiply(eCFieldElement3);
ECFieldElement eCFieldElement6 = eCFieldElement5.Add(b4).Square();
if (eCFieldElement6.IsZero)
{
if (eCFieldElement4.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement4.IsZero)
{
return new SecT163K1Point(curve, eCFieldElement4, curve.B, base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement4.Square().Multiply(eCFieldElement5);
ECFieldElement eCFieldElement7 = eCFieldElement4.Multiply(eCFieldElement6).Multiply(eCFieldElement3);
ECFieldElement y = eCFieldElement4.Add(eCFieldElement6).Square().MultiplyPlusProduct(b4, rawYCoord2.AddOne(), eCFieldElement7);
return new SecT163K1Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement7 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT163K1Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,127 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT163R1Curve : AbstractF2mCurve
{
private class SecT163R1LookupTable : ECLookupTable
{
private readonly SecT163R1Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT163R1LookupTable(SecT163R1Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat192.Create64();
ulong[] array2 = Nat192.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 3; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 3 + j] & num2);
}
num += 6;
}
return m_outer.CreateRawPoint(new SecT163FieldElement(array), new SecT163FieldElement(array2), withCompression: false);
}
}
private const int SECT163R1_DEFAULT_COORDS = 6;
private const int SECT163R1_FE_LONGS = 3;
protected readonly SecT163R1Point m_infinity;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => 163;
public override bool IsKoblitz => false;
public virtual int M => 163;
public virtual bool IsTrinomial => false;
public virtual int K1 => 3;
public virtual int K2 => 6;
public virtual int K3 => 7;
public SecT163R1Curve()
: base(163, 3, 6, 7)
{
m_infinity = new SecT163R1Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("07B6882CAAEFA84F9554FF8428BD88E246D2782AE2")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9")));
m_order = new BigInteger(1, Hex.Decode("03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B"));
m_cofactor = BigInteger.Two;
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT163R1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT163FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT163R1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT163R1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 3 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat192.Copy64(((SecT163FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 3;
Nat192.Copy64(((SecT163FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 3;
}
return new SecT163R1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,260 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT163R1Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT163R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT163R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT163R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT163R1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord)
.Add(curve.A);
if (eCFieldElement10.IsZero)
{
return new SecT163R1Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT163R1Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT163R1Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = (isOne ? rawYCoord : rawYCoord.Multiply(eCFieldElement));
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement a = curve.A;
ECFieldElement b2 = (isOne ? a : a.Multiply(b));
ECFieldElement eCFieldElement3 = rawYCoord.Square().Add(eCFieldElement2).Add(b2);
if (eCFieldElement3.IsZero)
{
return new SecT163R1Point(curve, eCFieldElement3, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement4 = eCFieldElement3.Square();
ECFieldElement eCFieldElement5 = (isOne ? eCFieldElement3 : eCFieldElement3.Multiply(b));
ECFieldElement eCFieldElement6 = (isOne ? rawXCoord : rawXCoord.Multiply(eCFieldElement));
ECFieldElement y = eCFieldElement6.SquarePlusProduct(eCFieldElement3, eCFieldElement2).Add(eCFieldElement4).Add(eCFieldElement5);
return new SecT163R1Point(curve, eCFieldElement4, y, new ECFieldElement[1] { eCFieldElement5 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement b2 = rawYCoord.Square();
ECFieldElement eCFieldElement3 = eCFieldElement2.Square();
ECFieldElement b3 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b4 = curve.A.Multiply(eCFieldElement3).Add(b2).Add(b3);
ECFieldElement eCFieldElement4 = rawYCoord2.AddOne();
ECFieldElement eCFieldElement5 = curve.A.Add(eCFieldElement4).Multiply(eCFieldElement3).Add(b2)
.MultiplyPlusProduct(b4, x, eCFieldElement3);
ECFieldElement eCFieldElement6 = rawXCoord2.Multiply(eCFieldElement3);
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(b4).Square();
if (eCFieldElement7.IsZero)
{
if (eCFieldElement5.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement5.IsZero)
{
return new SecT163R1Point(curve, eCFieldElement5, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement5.Square().Multiply(eCFieldElement6);
ECFieldElement eCFieldElement8 = eCFieldElement5.Multiply(eCFieldElement7).Multiply(eCFieldElement3);
ECFieldElement y = eCFieldElement5.Add(eCFieldElement7).Square().MultiplyPlusProduct(b4, eCFieldElement4, eCFieldElement8);
return new SecT163R1Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement8 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT163R1Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,127 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT163R2Curve : AbstractF2mCurve
{
private class SecT163R2LookupTable : ECLookupTable
{
private readonly SecT163R2Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT163R2LookupTable(SecT163R2Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat192.Create64();
ulong[] array2 = Nat192.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 3; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 3 + j] & num2);
}
num += 6;
}
return m_outer.CreateRawPoint(new SecT163FieldElement(array), new SecT163FieldElement(array2), withCompression: false);
}
}
private const int SECT163R2_DEFAULT_COORDS = 6;
private const int SECT163R2_FE_LONGS = 3;
protected readonly SecT163R2Point m_infinity;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => 163;
public override bool IsKoblitz => false;
public virtual int M => 163;
public virtual bool IsTrinomial => false;
public virtual int K1 => 3;
public virtual int K2 => 6;
public virtual int K3 => 7;
public SecT163R2Curve()
: base(163, 3, 6, 7)
{
m_infinity = new SecT163R2Point(this, null, null);
m_a = FromBigInteger(BigInteger.One);
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("020A601907B8C953CA1481EB10512F78744A3205FD")));
m_order = new BigInteger(1, Hex.Decode("040000000000000000000292FE77E70C12A4234C33"));
m_cofactor = BigInteger.Two;
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT163R2Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT163FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT163R2Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT163R2Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 3 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat192.Copy64(((SecT163FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 3;
Nat192.Copy64(((SecT163FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 3;
}
return new SecT163R2LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,256 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT163R2Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT163R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT163R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT163R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT163R2Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord)
.AddOne();
if (eCFieldElement10.IsZero)
{
return new SecT163R2Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT163R2Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT163R2Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = (isOne ? rawYCoord : rawYCoord.Multiply(eCFieldElement));
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement eCFieldElement3 = rawYCoord.Square().Add(eCFieldElement2).Add(b);
if (eCFieldElement3.IsZero)
{
return new SecT163R2Point(curve, eCFieldElement3, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement4 = eCFieldElement3.Square();
ECFieldElement eCFieldElement5 = (isOne ? eCFieldElement3 : eCFieldElement3.Multiply(b));
ECFieldElement eCFieldElement6 = (isOne ? rawXCoord : rawXCoord.Multiply(eCFieldElement));
ECFieldElement y = eCFieldElement6.SquarePlusProduct(eCFieldElement3, eCFieldElement2).Add(eCFieldElement4).Add(eCFieldElement5);
return new SecT163R2Point(curve, eCFieldElement4, y, new ECFieldElement[1] { eCFieldElement5 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement b2 = rawYCoord.Square();
ECFieldElement eCFieldElement3 = eCFieldElement2.Square();
ECFieldElement b3 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b4 = eCFieldElement3.Add(b2).Add(b3);
ECFieldElement eCFieldElement4 = rawYCoord2.Multiply(eCFieldElement3).Add(b2).MultiplyPlusProduct(b4, x, eCFieldElement3);
ECFieldElement eCFieldElement5 = rawXCoord2.Multiply(eCFieldElement3);
ECFieldElement eCFieldElement6 = eCFieldElement5.Add(b4).Square();
if (eCFieldElement6.IsZero)
{
if (eCFieldElement4.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement4.IsZero)
{
return new SecT163R2Point(curve, eCFieldElement4, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement4.Square().Multiply(eCFieldElement5);
ECFieldElement eCFieldElement7 = eCFieldElement4.Multiply(eCFieldElement6).Multiply(eCFieldElement3);
ECFieldElement y = eCFieldElement4.Add(eCFieldElement6).Square().MultiplyPlusProduct(b4, rawYCoord2.AddOne(), eCFieldElement7);
return new SecT163R2Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement7 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT163R2Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,289 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT193Field
{
private const ulong M01 = 1uL;
private const ulong M49 = 562949953421311uL;
public static void Add(ulong[] x, ulong[] y, ulong[] z)
{
z[0] = x[0] ^ y[0];
z[1] = x[1] ^ y[1];
z[2] = x[2] ^ y[2];
z[3] = x[3] ^ y[3];
}
public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz)
{
zz[0] = xx[0] ^ yy[0];
zz[1] = xx[1] ^ yy[1];
zz[2] = xx[2] ^ yy[2];
zz[3] = xx[3] ^ yy[3];
zz[4] = xx[4] ^ yy[4];
zz[5] = xx[5] ^ yy[5];
zz[6] = xx[6] ^ yy[6];
}
public static void AddOne(ulong[] x, ulong[] z)
{
z[0] = x[0] ^ 1;
z[1] = x[1];
z[2] = x[2];
z[3] = x[3];
}
public static ulong[] FromBigInteger(BigInteger x)
{
ulong[] array = Nat256.FromBigInteger64(x);
Reduce63(array, 0);
return array;
}
public static void Invert(ulong[] x, ulong[] z)
{
if (Nat256.IsZero64(x))
{
throw new InvalidOperationException();
}
ulong[] array = Nat256.Create64();
ulong[] array2 = Nat256.Create64();
Square(x, array);
SquareN(array, 1, array2);
Multiply(array, array2, array);
SquareN(array2, 1, array2);
Multiply(array, array2, array);
SquareN(array, 3, array2);
Multiply(array, array2, array);
SquareN(array, 6, array2);
Multiply(array, array2, array);
SquareN(array, 12, array2);
Multiply(array, array2, array);
SquareN(array, 24, array2);
Multiply(array, array2, array);
SquareN(array, 48, array2);
Multiply(array, array2, array);
SquareN(array, 96, array2);
Multiply(array, array2, z);
}
public static void Multiply(ulong[] x, ulong[] y, ulong[] z)
{
ulong[] array = Nat256.CreateExt64();
ImplMultiply(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz)
{
ulong[] array = Nat256.CreateExt64();
ImplMultiply(x, y, array);
AddExt(zz, array, zz);
}
public static void Reduce(ulong[] xx, ulong[] z)
{
ulong num = xx[0];
ulong num2 = xx[1];
ulong num3 = xx[2];
ulong num4 = xx[3];
ulong num5 = xx[4];
ulong num6 = xx[5];
ulong num7 = xx[6];
num3 ^= num7 << 63;
num4 ^= (num7 >> 1) ^ (num7 << 14);
num5 ^= num7 >> 50;
num2 ^= num6 << 63;
num3 ^= (num6 >> 1) ^ (num6 << 14);
num4 ^= num6 >> 50;
num ^= num5 << 63;
num2 ^= (num5 >> 1) ^ (num5 << 14);
num3 ^= num5 >> 50;
ulong num8 = num4 >> 1;
z[0] = num ^ num8 ^ (num8 << 15);
z[1] = num2 ^ (num8 >> 49);
z[2] = num3;
z[3] = num4 & 1;
}
public static void Reduce63(ulong[] z, int zOff)
{
ulong num = z[zOff + 3];
ulong num2 = num >> 1;
ulong[] array2;
ulong[] array = (array2 = z);
nint num3 = zOff;
array[zOff] = array2[num3] ^ (num2 ^ (num2 << 15));
ulong[] array3 = (array2 = z);
int num4 = zOff + 1;
num3 = num4;
array3[num4] = array2[num3] ^ (num2 >> 49);
z[zOff + 3] = num & 1;
}
public static void Sqrt(ulong[] x, ulong[] z)
{
ulong num = Interleave.Unshuffle(x[0]);
ulong num2 = Interleave.Unshuffle(x[1]);
ulong num3 = (num & 0xFFFFFFFFu) | (num2 << 32);
ulong num4 = (num >> 32) | (num2 & 0xFFFFFFFF00000000uL);
num = Interleave.Unshuffle(x[2]);
ulong num5 = (num & 0xFFFFFFFFu) ^ (x[3] << 32);
ulong num6 = num >> 32;
z[0] = num3 ^ (num4 << 8);
z[1] = num5 ^ (num6 << 8) ^ (num4 >> 56) ^ (num4 << 33);
z[2] = (num6 >> 56) ^ (num6 << 33) ^ (num4 >> 31);
z[3] = num6 >> 31;
}
public static void Square(ulong[] x, ulong[] z)
{
ulong[] array = Nat256.CreateExt64();
ImplSquare(x, array);
Reduce(array, z);
}
public static void SquareAddToExt(ulong[] x, ulong[] zz)
{
ulong[] array = Nat256.CreateExt64();
ImplSquare(x, array);
AddExt(zz, array, zz);
}
public static void SquareN(ulong[] x, int n, ulong[] z)
{
ulong[] array = Nat256.CreateExt64();
ImplSquare(x, array);
Reduce(array, z);
while (--n > 0)
{
ImplSquare(z, array);
Reduce(array, z);
}
}
public static uint Trace(ulong[] x)
{
return (uint)((int)x[0] & 1);
}
protected static void ImplCompactExt(ulong[] zz)
{
ulong num = zz[0];
ulong num2 = zz[1];
ulong num3 = zz[2];
ulong num4 = zz[3];
ulong num5 = zz[4];
ulong num6 = zz[5];
ulong num7 = zz[6];
ulong num8 = zz[7];
zz[0] = num ^ (num2 << 49);
zz[1] = (num2 >> 15) ^ (num3 << 34);
zz[2] = (num3 >> 30) ^ (num4 << 19);
zz[3] = (num4 >> 45) ^ (num5 << 4) ^ (num6 << 53);
zz[4] = (num5 >> 60) ^ (num7 << 38) ^ (num6 >> 11);
zz[5] = (num7 >> 26) ^ (num8 << 23);
zz[6] = num8 >> 41;
zz[7] = 0uL;
}
protected static void ImplExpand(ulong[] x, ulong[] z)
{
ulong num = x[0];
ulong num2 = x[1];
ulong num3 = x[2];
ulong num4 = x[3];
z[0] = num & 0x1FFFFFFFFFFFFL;
z[1] = ((num >> 49) ^ (num2 << 15)) & 0x1FFFFFFFFFFFFL;
z[2] = ((num2 >> 34) ^ (num3 << 30)) & 0x1FFFFFFFFFFFFL;
z[3] = (num3 >> 19) ^ (num4 << 45);
}
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
ulong[] array = new ulong[4];
ulong[] array2 = new ulong[4];
ImplExpand(x, array);
ImplExpand(y, array2);
ImplMulwAcc(array[0], array2[0], zz, 0);
ImplMulwAcc(array[1], array2[1], zz, 1);
ImplMulwAcc(array[2], array2[2], zz, 2);
ImplMulwAcc(array[3], array2[3], zz, 3);
ulong[] array4;
for (int num = 5; num > 0; num--)
{
ulong[] array3 = (array4 = zz);
int num2 = num;
nint num3 = num2;
array3[num2] = array4[num3] ^ zz[num - 1];
}
ImplMulwAcc(array[0] ^ array[1], array2[0] ^ array2[1], zz, 1);
ImplMulwAcc(array[2] ^ array[3], array2[2] ^ array2[3], zz, 3);
for (int num4 = 7; num4 > 1; num4--)
{
ulong[] array5 = (array4 = zz);
int num5 = num4;
nint num3 = num5;
array5[num5] = array4[num3] ^ zz[num4 - 2];
}
ulong num6 = array[0] ^ array[2];
ulong num7 = array[1] ^ array[3];
ulong num8 = array2[0] ^ array2[2];
ulong num9 = array2[1] ^ array2[3];
ImplMulwAcc(num6 ^ num7, num8 ^ num9, zz, 3);
ulong[] array6 = new ulong[3];
ImplMulwAcc(num6, num8, array6, 0);
ImplMulwAcc(num7, num9, array6, 1);
ulong num10 = array6[0];
ulong num11 = array6[1];
ulong num12 = array6[2];
(array4 = zz)[2] = array4[2] ^ num10;
(array4 = zz)[3] = array4[3] ^ (num10 ^ num11);
(array4 = zz)[4] = array4[4] ^ (num12 ^ num11);
(array4 = zz)[5] = array4[5] ^ num12;
ImplCompactExt(zz);
}
protected static void ImplMulwAcc(ulong x, ulong y, ulong[] z, int zOff)
{
ulong[] array = new ulong[8];
array[1] = y;
array[2] = array[1] << 1;
array[3] = array[2] ^ y;
array[4] = array[2] << 1;
array[5] = array[4] ^ y;
array[6] = array[3] << 1;
array[7] = array[6] ^ y;
uint num = (uint)x;
ulong num2 = 0uL;
ulong num3 = array[num & 7] ^ (array[(num >> 3) & 7] << 3);
int num4 = 36;
do
{
num = (uint)(x >> num4);
ulong num5 = array[num & 7] ^ (array[(num >> 3) & 7] << 3) ^ (array[(num >> 6) & 7] << 6) ^ (array[(num >> 9) & 7] << 9) ^ (array[(num >> 12) & 7] << 12);
num3 ^= num5 << num4;
num2 ^= num5 >> -num4;
}
while ((num4 -= 15) > 0);
ulong[] array3;
ulong[] array2 = (array3 = z);
nint num6 = zOff;
array2[zOff] = array3[num6] ^ (num3 & 0x1FFFFFFFFFFFFL);
ulong[] array4 = (array3 = z);
int num7 = zOff + 1;
num6 = num7;
array4[num7] = array3[num6] ^ ((num3 >> 49) ^ (num2 << 15));
}
protected static void ImplSquare(ulong[] x, ulong[] zz)
{
Interleave.Expand64To128(x[0], zz, 0);
Interleave.Expand64To128(x[1], zz, 2);
Interleave.Expand64To128(x[2], zz, 4);
zz[6] = x[3] & 1;
}
}

View File

@@ -0,0 +1,195 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT193FieldElement : AbstractF2mFieldElement
{
protected internal readonly ulong[] x;
public override bool IsOne => Nat256.IsOne64(x);
public override bool IsZero => Nat256.IsZero64(x);
public override string FieldName => "SecT193Field";
public override int FieldSize => 193;
public virtual int Representation => 2;
public virtual int M => 193;
public virtual int K1 => 15;
public virtual int K2 => 0;
public virtual int K3 => 0;
public SecT193FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.BitLength > 193)
{
throw new ArgumentException("value invalid for SecT193FieldElement", "x");
}
this.x = SecT193Field.FromBigInteger(x);
}
public SecT193FieldElement()
{
x = Nat256.Create64();
}
protected internal SecT193FieldElement(ulong[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return (x[0] & 1) != 0;
}
public override BigInteger ToBigInteger()
{
return Nat256.ToBigInteger64(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
ulong[] z = Nat256.Create64();
SecT193Field.Add(x, ((SecT193FieldElement)b).x, z);
return new SecT193FieldElement(z);
}
public override ECFieldElement AddOne()
{
ulong[] z = Nat256.Create64();
SecT193Field.AddOne(x, z);
return new SecT193FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
return Add(b);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
ulong[] z = Nat256.Create64();
SecT193Field.Multiply(x, ((SecT193FieldElement)b).x, z);
return new SecT193FieldElement(z);
}
public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
return MultiplyPlusProduct(b, x, y);
}
public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] y2 = ((SecT193FieldElement)b).x;
ulong[] array2 = ((SecT193FieldElement)x).x;
ulong[] y3 = ((SecT193FieldElement)y).x;
ulong[] array3 = Nat256.CreateExt64();
SecT193Field.MultiplyAddToExt(array, y2, array3);
SecT193Field.MultiplyAddToExt(array2, y3, array3);
ulong[] z = Nat256.Create64();
SecT193Field.Reduce(array3, z);
return new SecT193FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
return Multiply(b.Invert());
}
public override ECFieldElement Negate()
{
return this;
}
public override ECFieldElement Square()
{
ulong[] z = Nat256.Create64();
SecT193Field.Square(x, z);
return new SecT193FieldElement(z);
}
public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
{
return SquarePlusProduct(x, y);
}
public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] array2 = ((SecT193FieldElement)x).x;
ulong[] y2 = ((SecT193FieldElement)y).x;
ulong[] array3 = Nat256.CreateExt64();
SecT193Field.SquareAddToExt(array, array3);
SecT193Field.MultiplyAddToExt(array2, y2, array3);
ulong[] z = Nat256.Create64();
SecT193Field.Reduce(array3, z);
return new SecT193FieldElement(z);
}
public override ECFieldElement SquarePow(int pow)
{
if (pow < 1)
{
return this;
}
ulong[] z = Nat256.Create64();
SecT193Field.SquareN(x, pow, z);
return new SecT193FieldElement(z);
}
public override int Trace()
{
return (int)SecT193Field.Trace(x);
}
public override ECFieldElement Invert()
{
ulong[] z = Nat256.Create64();
SecT193Field.Invert(x, z);
return new SecT193FieldElement(z);
}
public override ECFieldElement Sqrt()
{
ulong[] z = Nat256.Create64();
SecT193Field.Sqrt(x, z);
return new SecT193FieldElement(z);
}
public override bool Equals(object obj)
{
return Equals(obj as SecT193FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecT193FieldElement);
}
public virtual bool Equals(SecT193FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat256.Eq64(x, other.x);
}
public override int GetHashCode()
{
return 0x1D731F ^ Arrays.GetHashCode(x, 0, 4);
}
}

View File

@@ -0,0 +1,127 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT193R1Curve : AbstractF2mCurve
{
private class SecT193R1LookupTable : ECLookupTable
{
private readonly SecT193R1Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT193R1LookupTable(SecT193R1Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat256.Create64();
ulong[] array2 = Nat256.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 4; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 4 + j] & num2);
}
num += 8;
}
return m_outer.CreateRawPoint(new SecT193FieldElement(array), new SecT193FieldElement(array2), withCompression: false);
}
}
private const int SECT193R1_DEFAULT_COORDS = 6;
private const int SECT193R1_FE_LONGS = 4;
protected readonly SecT193R1Point m_infinity;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => 193;
public override bool IsKoblitz => false;
public virtual int M => 193;
public virtual bool IsTrinomial => true;
public virtual int K1 => 15;
public virtual int K2 => 0;
public virtual int K3 => 0;
public SecT193R1Curve()
: base(193, 15, 0, 0)
{
m_infinity = new SecT193R1Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814")));
m_order = new BigInteger(1, Hex.Decode("01000000000000000000000000C7F34A778F443ACC920EBA49"));
m_cofactor = BigInteger.Two;
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT193R1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT193FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT193R1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT193R1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 4 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat256.Copy64(((SecT193FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 4;
Nat256.Copy64(((SecT193FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 4;
}
return new SecT193R1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,260 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT193R1Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT193R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT193R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT193R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT193R1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord)
.Add(curve.A);
if (eCFieldElement10.IsZero)
{
return new SecT193R1Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT193R1Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT193R1Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = (isOne ? rawYCoord : rawYCoord.Multiply(eCFieldElement));
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement a = curve.A;
ECFieldElement b2 = (isOne ? a : a.Multiply(b));
ECFieldElement eCFieldElement3 = rawYCoord.Square().Add(eCFieldElement2).Add(b2);
if (eCFieldElement3.IsZero)
{
return new SecT193R1Point(curve, eCFieldElement3, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement4 = eCFieldElement3.Square();
ECFieldElement eCFieldElement5 = (isOne ? eCFieldElement3 : eCFieldElement3.Multiply(b));
ECFieldElement eCFieldElement6 = (isOne ? rawXCoord : rawXCoord.Multiply(eCFieldElement));
ECFieldElement y = eCFieldElement6.SquarePlusProduct(eCFieldElement3, eCFieldElement2).Add(eCFieldElement4).Add(eCFieldElement5);
return new SecT193R1Point(curve, eCFieldElement4, y, new ECFieldElement[1] { eCFieldElement5 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement b2 = rawYCoord.Square();
ECFieldElement eCFieldElement3 = eCFieldElement2.Square();
ECFieldElement b3 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b4 = curve.A.Multiply(eCFieldElement3).Add(b2).Add(b3);
ECFieldElement eCFieldElement4 = rawYCoord2.AddOne();
ECFieldElement eCFieldElement5 = curve.A.Add(eCFieldElement4).Multiply(eCFieldElement3).Add(b2)
.MultiplyPlusProduct(b4, x, eCFieldElement3);
ECFieldElement eCFieldElement6 = rawXCoord2.Multiply(eCFieldElement3);
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(b4).Square();
if (eCFieldElement7.IsZero)
{
if (eCFieldElement5.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement5.IsZero)
{
return new SecT193R1Point(curve, eCFieldElement5, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement5.Square().Multiply(eCFieldElement6);
ECFieldElement eCFieldElement8 = eCFieldElement5.Multiply(eCFieldElement7).Multiply(eCFieldElement3);
ECFieldElement y = eCFieldElement5.Add(eCFieldElement7).Square().MultiplyPlusProduct(b4, eCFieldElement4, eCFieldElement8);
return new SecT193R1Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement8 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT193R1Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,127 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT193R2Curve : AbstractF2mCurve
{
private class SecT193R2LookupTable : ECLookupTable
{
private readonly SecT193R2Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT193R2LookupTable(SecT193R2Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat256.Create64();
ulong[] array2 = Nat256.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 4; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 4 + j] & num2);
}
num += 8;
}
return m_outer.CreateRawPoint(new SecT193FieldElement(array), new SecT193FieldElement(array2), withCompression: false);
}
}
private const int SECT193R2_DEFAULT_COORDS = 6;
private const int SECT193R2_FE_LONGS = 4;
protected readonly SecT193R2Point m_infinity;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => 193;
public override bool IsKoblitz => false;
public virtual int M => 193;
public virtual bool IsTrinomial => true;
public virtual int K1 => 15;
public virtual int K2 => 0;
public virtual int K3 => 0;
public SecT193R2Curve()
: base(193, 15, 0, 0)
{
m_infinity = new SecT193R2Point(this, null, null);
m_a = FromBigInteger(new BigInteger(1, Hex.Decode("0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B")));
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE")));
m_order = new BigInteger(1, Hex.Decode("010000000000000000000000015AAB561B005413CCD4EE99D5"));
m_cofactor = BigInteger.Two;
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT193R2Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT193FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT193R2Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT193R2Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 4 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat256.Copy64(((SecT193FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 4;
Nat256.Copy64(((SecT193FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 4;
}
return new SecT193R2LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,260 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT193R2Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT193R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT193R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT193R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT193R2Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord)
.Add(curve.A);
if (eCFieldElement10.IsZero)
{
return new SecT193R2Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT193R2Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT193R2Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = (isOne ? rawYCoord : rawYCoord.Multiply(eCFieldElement));
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement a = curve.A;
ECFieldElement b2 = (isOne ? a : a.Multiply(b));
ECFieldElement eCFieldElement3 = rawYCoord.Square().Add(eCFieldElement2).Add(b2);
if (eCFieldElement3.IsZero)
{
return new SecT193R2Point(curve, eCFieldElement3, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement4 = eCFieldElement3.Square();
ECFieldElement eCFieldElement5 = (isOne ? eCFieldElement3 : eCFieldElement3.Multiply(b));
ECFieldElement eCFieldElement6 = (isOne ? rawXCoord : rawXCoord.Multiply(eCFieldElement));
ECFieldElement y = eCFieldElement6.SquarePlusProduct(eCFieldElement3, eCFieldElement2).Add(eCFieldElement4).Add(eCFieldElement5);
return new SecT193R2Point(curve, eCFieldElement4, y, new ECFieldElement[1] { eCFieldElement5 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement b2 = rawYCoord.Square();
ECFieldElement eCFieldElement3 = eCFieldElement2.Square();
ECFieldElement b3 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b4 = curve.A.Multiply(eCFieldElement3).Add(b2).Add(b3);
ECFieldElement eCFieldElement4 = rawYCoord2.AddOne();
ECFieldElement eCFieldElement5 = curve.A.Add(eCFieldElement4).Multiply(eCFieldElement3).Add(b2)
.MultiplyPlusProduct(b4, x, eCFieldElement3);
ECFieldElement eCFieldElement6 = rawXCoord2.Multiply(eCFieldElement3);
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(b4).Square();
if (eCFieldElement7.IsZero)
{
if (eCFieldElement5.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement5.IsZero)
{
return new SecT193R2Point(curve, eCFieldElement5, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement5.Square().Multiply(eCFieldElement6);
ECFieldElement eCFieldElement8 = eCFieldElement5.Multiply(eCFieldElement7).Multiply(eCFieldElement3);
ECFieldElement y = eCFieldElement5.Add(eCFieldElement7).Square().MultiplyPlusProduct(b4, eCFieldElement4, eCFieldElement8);
return new SecT193R2Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement8 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT193R2Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,326 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT233Field
{
private const ulong M41 = 2199023255551uL;
private const ulong M59 = 576460752303423487uL;
public static void Add(ulong[] x, ulong[] y, ulong[] z)
{
z[0] = x[0] ^ y[0];
z[1] = x[1] ^ y[1];
z[2] = x[2] ^ y[2];
z[3] = x[3] ^ y[3];
}
public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz)
{
zz[0] = xx[0] ^ yy[0];
zz[1] = xx[1] ^ yy[1];
zz[2] = xx[2] ^ yy[2];
zz[3] = xx[3] ^ yy[3];
zz[4] = xx[4] ^ yy[4];
zz[5] = xx[5] ^ yy[5];
zz[6] = xx[6] ^ yy[6];
zz[7] = xx[7] ^ yy[7];
}
public static void AddOne(ulong[] x, ulong[] z)
{
z[0] = x[0] ^ 1;
z[1] = x[1];
z[2] = x[2];
z[3] = x[3];
}
public static ulong[] FromBigInteger(BigInteger x)
{
ulong[] array = Nat256.FromBigInteger64(x);
Reduce23(array, 0);
return array;
}
public static void Invert(ulong[] x, ulong[] z)
{
if (Nat256.IsZero64(x))
{
throw new InvalidOperationException();
}
ulong[] array = Nat256.Create64();
ulong[] array2 = Nat256.Create64();
Square(x, array);
Multiply(array, x, array);
Square(array, array);
Multiply(array, x, array);
SquareN(array, 3, array2);
Multiply(array2, array, array2);
Square(array2, array2);
Multiply(array2, x, array2);
SquareN(array2, 7, array);
Multiply(array, array2, array);
SquareN(array, 14, array2);
Multiply(array2, array, array2);
Square(array2, array2);
Multiply(array2, x, array2);
SquareN(array2, 29, array);
Multiply(array, array2, array);
SquareN(array, 58, array2);
Multiply(array2, array, array2);
SquareN(array2, 116, array);
Multiply(array, array2, array);
Square(array, z);
}
public static void Multiply(ulong[] x, ulong[] y, ulong[] z)
{
ulong[] array = Nat256.CreateExt64();
ImplMultiply(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz)
{
ulong[] array = Nat256.CreateExt64();
ImplMultiply(x, y, array);
AddExt(zz, array, zz);
}
public static void Reduce(ulong[] xx, ulong[] z)
{
ulong num = xx[0];
ulong num2 = xx[1];
ulong num3 = xx[2];
ulong num4 = xx[3];
ulong num5 = xx[4];
ulong num6 = xx[5];
ulong num7 = xx[6];
ulong num8 = xx[7];
num4 ^= num8 << 23;
num5 ^= (num8 >> 41) ^ (num8 << 33);
num6 ^= num8 >> 31;
num3 ^= num7 << 23;
num4 ^= (num7 >> 41) ^ (num7 << 33);
num5 ^= num7 >> 31;
num2 ^= num6 << 23;
num3 ^= (num6 >> 41) ^ (num6 << 33);
num4 ^= num6 >> 31;
num ^= num5 << 23;
num2 ^= (num5 >> 41) ^ (num5 << 33);
num3 ^= num5 >> 31;
ulong num9 = num4 >> 41;
z[0] = num ^ num9;
z[1] = num2 ^ (num9 << 10);
z[2] = num3;
z[3] = num4 & 0x1FFFFFFFFFFL;
}
public static void Reduce23(ulong[] z, int zOff)
{
ulong num = z[zOff + 3];
ulong num2 = num >> 41;
ulong[] array2;
ulong[] array = (array2 = z);
nint num3 = zOff;
array[zOff] = array2[num3] ^ num2;
ulong[] array3 = (array2 = z);
int num4 = zOff + 1;
num3 = num4;
array3[num4] = array2[num3] ^ (num2 << 10);
z[zOff + 3] = num & 0x1FFFFFFFFFFL;
}
public static void Sqrt(ulong[] x, ulong[] z)
{
ulong num = Interleave.Unshuffle(x[0]);
ulong num2 = Interleave.Unshuffle(x[1]);
ulong num3 = (num & 0xFFFFFFFFu) | (num2 << 32);
ulong num4 = (num >> 32) | (num2 & 0xFFFFFFFF00000000uL);
num = Interleave.Unshuffle(x[2]);
num2 = Interleave.Unshuffle(x[3]);
ulong num5 = (num & 0xFFFFFFFFu) | (num2 << 32);
ulong num6 = (num >> 32) | (num2 & 0xFFFFFFFF00000000uL);
ulong num7 = num6 >> 27;
num6 ^= (num4 >> 27) | (num6 << 37);
num4 ^= num4 << 37;
ulong[] array = Nat256.CreateExt64();
int[] array2 = new int[3] { 32, 117, 191 };
ulong[] array4;
for (int i = 0; i < array2.Length; i++)
{
int num8 = array2[i] >> 6;
int num9 = array2[i] & 0x3F;
ulong[] array3 = (array4 = array);
nint num10 = num8;
array3[num8] = array4[num10] ^ (num4 << num9);
ulong[] array5 = (array4 = array);
int num11 = num8 + 1;
num10 = num11;
array5[num11] = array4[num10] ^ ((num6 << num9) | (num4 >> -num9));
ulong[] array6 = (array4 = array);
int num12 = num8 + 2;
num10 = num12;
array6[num12] = array4[num10] ^ ((num7 << num9) | (num6 >> -num9));
ulong[] array7 = (array4 = array);
int num13 = num8 + 3;
num10 = num13;
array7[num13] = array4[num10] ^ (num7 >> -num9);
}
Reduce(array, z);
(array4 = z)[0] = array4[0] ^ num3;
(array4 = z)[1] = array4[1] ^ num5;
}
public static void Square(ulong[] x, ulong[] z)
{
ulong[] array = Nat256.CreateExt64();
ImplSquare(x, array);
Reduce(array, z);
}
public static void SquareAddToExt(ulong[] x, ulong[] zz)
{
ulong[] array = Nat256.CreateExt64();
ImplSquare(x, array);
AddExt(zz, array, zz);
}
public static void SquareN(ulong[] x, int n, ulong[] z)
{
ulong[] array = Nat256.CreateExt64();
ImplSquare(x, array);
Reduce(array, z);
while (--n > 0)
{
ImplSquare(z, array);
Reduce(array, z);
}
}
public static uint Trace(ulong[] x)
{
return (uint)((int)(x[0] ^ (x[2] >> 31)) & 1);
}
protected static void ImplCompactExt(ulong[] zz)
{
ulong num = zz[0];
ulong num2 = zz[1];
ulong num3 = zz[2];
ulong num4 = zz[3];
ulong num5 = zz[4];
ulong num6 = zz[5];
ulong num7 = zz[6];
ulong num8 = zz[7];
zz[0] = num ^ (num2 << 59);
zz[1] = (num2 >> 5) ^ (num3 << 54);
zz[2] = (num3 >> 10) ^ (num4 << 49);
zz[3] = (num4 >> 15) ^ (num5 << 44);
zz[4] = (num5 >> 20) ^ (num6 << 39);
zz[5] = (num6 >> 25) ^ (num7 << 34);
zz[6] = (num7 >> 30) ^ (num8 << 29);
zz[7] = num8 >> 35;
}
protected static void ImplExpand(ulong[] x, ulong[] z)
{
ulong num = x[0];
ulong num2 = x[1];
ulong num3 = x[2];
ulong num4 = x[3];
z[0] = num & 0x7FFFFFFFFFFFFFFL;
z[1] = ((num >> 59) ^ (num2 << 5)) & 0x7FFFFFFFFFFFFFFL;
z[2] = ((num2 >> 54) ^ (num3 << 10)) & 0x7FFFFFFFFFFFFFFL;
z[3] = (num3 >> 49) ^ (num4 << 15);
}
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
ulong[] array = new ulong[4];
ulong[] array2 = new ulong[4];
ImplExpand(x, array);
ImplExpand(y, array2);
ImplMulwAcc(array[0], array2[0], zz, 0);
ImplMulwAcc(array[1], array2[1], zz, 1);
ImplMulwAcc(array[2], array2[2], zz, 2);
ImplMulwAcc(array[3], array2[3], zz, 3);
ulong[] array4;
for (int num = 5; num > 0; num--)
{
ulong[] array3 = (array4 = zz);
int num2 = num;
nint num3 = num2;
array3[num2] = array4[num3] ^ zz[num - 1];
}
ImplMulwAcc(array[0] ^ array[1], array2[0] ^ array2[1], zz, 1);
ImplMulwAcc(array[2] ^ array[3], array2[2] ^ array2[3], zz, 3);
for (int num4 = 7; num4 > 1; num4--)
{
ulong[] array5 = (array4 = zz);
int num5 = num4;
nint num3 = num5;
array5[num5] = array4[num3] ^ zz[num4 - 2];
}
ulong num6 = array[0] ^ array[2];
ulong num7 = array[1] ^ array[3];
ulong num8 = array2[0] ^ array2[2];
ulong num9 = array2[1] ^ array2[3];
ImplMulwAcc(num6 ^ num7, num8 ^ num9, zz, 3);
ulong[] array6 = new ulong[3];
ImplMulwAcc(num6, num8, array6, 0);
ImplMulwAcc(num7, num9, array6, 1);
ulong num10 = array6[0];
ulong num11 = array6[1];
ulong num12 = array6[2];
(array4 = zz)[2] = array4[2] ^ num10;
(array4 = zz)[3] = array4[3] ^ (num10 ^ num11);
(array4 = zz)[4] = array4[4] ^ (num12 ^ num11);
(array4 = zz)[5] = array4[5] ^ num12;
ImplCompactExt(zz);
}
protected static void ImplMulwAcc(ulong x, ulong y, ulong[] z, int zOff)
{
ulong[] array = new ulong[8];
array[1] = y;
array[2] = array[1] << 1;
array[3] = array[2] ^ y;
array[4] = array[2] << 1;
array[5] = array[4] ^ y;
array[6] = array[3] << 1;
array[7] = array[6] ^ y;
uint num = (uint)x;
ulong num2 = 0uL;
ulong num3 = array[num & 7] ^ (array[(num >> 3) & 7] << 3);
int num4 = 54;
do
{
num = (uint)(x >> num4);
ulong num5 = array[num & 7] ^ (array[(num >> 3) & 7] << 3);
num3 ^= num5 << num4;
num2 ^= num5 >> -num4;
}
while ((num4 -= 6) > 0);
ulong[] array3;
ulong[] array2 = (array3 = z);
nint num6 = zOff;
array2[zOff] = array3[num6] ^ (num3 & 0x7FFFFFFFFFFFFFFL);
ulong[] array4 = (array3 = z);
int num7 = zOff + 1;
num6 = num7;
array4[num7] = array3[num6] ^ ((num3 >> 59) ^ (num2 << 5));
}
protected static void ImplSquare(ulong[] x, ulong[] zz)
{
Interleave.Expand64To128(x[0], zz, 0);
Interleave.Expand64To128(x[1], zz, 2);
Interleave.Expand64To128(x[2], zz, 4);
ulong num = x[3];
zz[6] = Interleave.Expand32to64((uint)num);
zz[7] = Interleave.Expand16to32((uint)(num >> 32));
}
}

View File

@@ -0,0 +1,195 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT233FieldElement : AbstractF2mFieldElement
{
protected internal readonly ulong[] x;
public override bool IsOne => Nat256.IsOne64(x);
public override bool IsZero => Nat256.IsZero64(x);
public override string FieldName => "SecT233Field";
public override int FieldSize => 233;
public virtual int Representation => 2;
public virtual int M => 233;
public virtual int K1 => 74;
public virtual int K2 => 0;
public virtual int K3 => 0;
public SecT233FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.BitLength > 233)
{
throw new ArgumentException("value invalid for SecT233FieldElement", "x");
}
this.x = SecT233Field.FromBigInteger(x);
}
public SecT233FieldElement()
{
x = Nat256.Create64();
}
protected internal SecT233FieldElement(ulong[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return (x[0] & 1) != 0;
}
public override BigInteger ToBigInteger()
{
return Nat256.ToBigInteger64(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
ulong[] z = Nat256.Create64();
SecT233Field.Add(x, ((SecT233FieldElement)b).x, z);
return new SecT233FieldElement(z);
}
public override ECFieldElement AddOne()
{
ulong[] z = Nat256.Create64();
SecT233Field.AddOne(x, z);
return new SecT233FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
return Add(b);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
ulong[] z = Nat256.Create64();
SecT233Field.Multiply(x, ((SecT233FieldElement)b).x, z);
return new SecT233FieldElement(z);
}
public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
return MultiplyPlusProduct(b, x, y);
}
public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] y2 = ((SecT233FieldElement)b).x;
ulong[] array2 = ((SecT233FieldElement)x).x;
ulong[] y3 = ((SecT233FieldElement)y).x;
ulong[] array3 = Nat256.CreateExt64();
SecT233Field.MultiplyAddToExt(array, y2, array3);
SecT233Field.MultiplyAddToExt(array2, y3, array3);
ulong[] z = Nat256.Create64();
SecT233Field.Reduce(array3, z);
return new SecT233FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
return Multiply(b.Invert());
}
public override ECFieldElement Negate()
{
return this;
}
public override ECFieldElement Square()
{
ulong[] z = Nat256.Create64();
SecT233Field.Square(x, z);
return new SecT233FieldElement(z);
}
public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
{
return SquarePlusProduct(x, y);
}
public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] array2 = ((SecT233FieldElement)x).x;
ulong[] y2 = ((SecT233FieldElement)y).x;
ulong[] array3 = Nat256.CreateExt64();
SecT233Field.SquareAddToExt(array, array3);
SecT233Field.MultiplyAddToExt(array2, y2, array3);
ulong[] z = Nat256.Create64();
SecT233Field.Reduce(array3, z);
return new SecT233FieldElement(z);
}
public override ECFieldElement SquarePow(int pow)
{
if (pow < 1)
{
return this;
}
ulong[] z = Nat256.Create64();
SecT233Field.SquareN(x, pow, z);
return new SecT233FieldElement(z);
}
public override int Trace()
{
return (int)SecT233Field.Trace(x);
}
public override ECFieldElement Invert()
{
ulong[] z = Nat256.Create64();
SecT233Field.Invert(x, z);
return new SecT233FieldElement(z);
}
public override ECFieldElement Sqrt()
{
ulong[] z = Nat256.Create64();
SecT233Field.Sqrt(x, z);
return new SecT233FieldElement(z);
}
public override bool Equals(object obj)
{
return Equals(obj as SecT233FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecT233FieldElement);
}
public virtual bool Equals(SecT233FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat256.Eq64(x, other.x);
}
public override int GetHashCode()
{
return 0x238DDA ^ Arrays.GetHashCode(x, 0, 4);
}
}

View File

@@ -0,0 +1,133 @@
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT233K1Curve : AbstractF2mCurve
{
private class SecT233K1LookupTable : ECLookupTable
{
private readonly SecT233K1Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT233K1LookupTable(SecT233K1Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat256.Create64();
ulong[] array2 = Nat256.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 4; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 4 + j] & num2);
}
num += 8;
}
return m_outer.CreateRawPoint(new SecT233FieldElement(array), new SecT233FieldElement(array2), withCompression: false);
}
}
private const int SECT233K1_DEFAULT_COORDS = 6;
private const int SECT233K1_FE_LONGS = 4;
protected readonly SecT233K1Point m_infinity;
public override int FieldSize => 233;
public override ECPoint Infinity => m_infinity;
public override bool IsKoblitz => true;
public virtual int M => 233;
public virtual bool IsTrinomial => true;
public virtual int K1 => 74;
public virtual int K2 => 0;
public virtual int K3 => 0;
public SecT233K1Curve()
: base(233, 74, 0, 0)
{
m_infinity = new SecT233K1Point(this, null, null);
m_a = FromBigInteger(BigInteger.Zero);
m_b = FromBigInteger(BigInteger.One);
m_order = new BigInteger(1, Hex.Decode("8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF"));
m_cofactor = BigInteger.ValueOf(4L);
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT233K1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
protected override ECMultiplier CreateDefaultMultiplier()
{
return new WTauNafMultiplier();
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT233FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT233K1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT233K1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 4 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat256.Copy64(((SecT233FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 4;
Nat256.Copy64(((SecT233FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 4;
}
return new SecT233K1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,259 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT233K1Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT233K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT233K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT233K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT233K1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord);
if (eCFieldElement10.IsZero)
{
return new SecT233K1Point(curve, eCFieldElement10, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT233K1Point(curve, eCFieldElement10, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT233K1Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement eCFieldElement3 = ((!isOne) ? rawYCoord.Add(eCFieldElement).Multiply(rawYCoord) : rawYCoord.Square().Add(rawYCoord));
if (eCFieldElement3.IsZero)
{
return new SecT233K1Point(curve, eCFieldElement3, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement4 = eCFieldElement3.Square();
ECFieldElement eCFieldElement5 = (isOne ? eCFieldElement3 : eCFieldElement3.Multiply(eCFieldElement2));
ECFieldElement eCFieldElement6 = rawYCoord.Add(rawXCoord).Square();
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement2.Square());
ECFieldElement y = eCFieldElement6.Add(eCFieldElement3).Add(eCFieldElement2).Multiply(eCFieldElement6)
.Add(b)
.Add(eCFieldElement4)
.Add(eCFieldElement5);
return new SecT233K1Point(curve, eCFieldElement4, y, new ECFieldElement[1] { eCFieldElement5 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement eCFieldElement3 = rawYCoord.Square();
ECFieldElement eCFieldElement4 = eCFieldElement2.Square();
ECFieldElement b2 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b3 = eCFieldElement3.Add(b2);
ECFieldElement eCFieldElement5 = rawYCoord2.AddOne();
ECFieldElement eCFieldElement6 = eCFieldElement5.Multiply(eCFieldElement4).Add(eCFieldElement3).MultiplyPlusProduct(b3, x, eCFieldElement4);
ECFieldElement eCFieldElement7 = rawXCoord2.Multiply(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement7.Add(b3).Square();
if (eCFieldElement8.IsZero)
{
if (eCFieldElement6.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement6.IsZero)
{
return new SecT233K1Point(curve, eCFieldElement6, curve.B, base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement6.Square().Multiply(eCFieldElement7);
ECFieldElement eCFieldElement9 = eCFieldElement6.Multiply(eCFieldElement8).Multiply(eCFieldElement4);
ECFieldElement y = eCFieldElement6.Add(eCFieldElement8).Square().MultiplyPlusProduct(b3, eCFieldElement5, eCFieldElement9);
return new SecT233K1Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement9 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT233K1Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,127 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT233R1Curve : AbstractF2mCurve
{
private class SecT233R1LookupTable : ECLookupTable
{
private readonly SecT233R1Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT233R1LookupTable(SecT233R1Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat256.Create64();
ulong[] array2 = Nat256.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 4; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 4 + j] & num2);
}
num += 8;
}
return m_outer.CreateRawPoint(new SecT233FieldElement(array), new SecT233FieldElement(array2), withCompression: false);
}
}
private const int SECT233R1_DEFAULT_COORDS = 6;
private const int SECT233R1_FE_LONGS = 4;
protected readonly SecT233R1Point m_infinity;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => 233;
public override bool IsKoblitz => false;
public virtual int M => 233;
public virtual bool IsTrinomial => true;
public virtual int K1 => 74;
public virtual int K2 => 0;
public virtual int K3 => 0;
public SecT233R1Curve()
: base(233, 74, 0, 0)
{
m_infinity = new SecT233R1Point(this, null, null);
m_a = FromBigInteger(BigInteger.One);
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD")));
m_order = new BigInteger(1, Hex.Decode("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7"));
m_cofactor = BigInteger.Two;
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT233R1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT233FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT233R1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT233R1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 4 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat256.Copy64(((SecT233FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 4;
Nat256.Copy64(((SecT233FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 4;
}
return new SecT233R1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,256 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT233R1Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT233R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT233R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT233R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT233R1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord)
.AddOne();
if (eCFieldElement10.IsZero)
{
return new SecT233R1Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT233R1Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT233R1Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = (isOne ? rawYCoord : rawYCoord.Multiply(eCFieldElement));
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement eCFieldElement3 = rawYCoord.Square().Add(eCFieldElement2).Add(b);
if (eCFieldElement3.IsZero)
{
return new SecT233R1Point(curve, eCFieldElement3, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement4 = eCFieldElement3.Square();
ECFieldElement eCFieldElement5 = (isOne ? eCFieldElement3 : eCFieldElement3.Multiply(b));
ECFieldElement eCFieldElement6 = (isOne ? rawXCoord : rawXCoord.Multiply(eCFieldElement));
ECFieldElement y = eCFieldElement6.SquarePlusProduct(eCFieldElement3, eCFieldElement2).Add(eCFieldElement4).Add(eCFieldElement5);
return new SecT233R1Point(curve, eCFieldElement4, y, new ECFieldElement[1] { eCFieldElement5 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement b2 = rawYCoord.Square();
ECFieldElement eCFieldElement3 = eCFieldElement2.Square();
ECFieldElement b3 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b4 = eCFieldElement3.Add(b2).Add(b3);
ECFieldElement eCFieldElement4 = rawYCoord2.Multiply(eCFieldElement3).Add(b2).MultiplyPlusProduct(b4, x, eCFieldElement3);
ECFieldElement eCFieldElement5 = rawXCoord2.Multiply(eCFieldElement3);
ECFieldElement eCFieldElement6 = eCFieldElement5.Add(b4).Square();
if (eCFieldElement6.IsZero)
{
if (eCFieldElement4.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement4.IsZero)
{
return new SecT233R1Point(curve, eCFieldElement4, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement4.Square().Multiply(eCFieldElement5);
ECFieldElement eCFieldElement7 = eCFieldElement4.Multiply(eCFieldElement6).Multiply(eCFieldElement3);
ECFieldElement y = eCFieldElement4.Add(eCFieldElement6).Square().MultiplyPlusProduct(b4, rawYCoord2.AddOne(), eCFieldElement7);
return new SecT233R1Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement7 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT233R1Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,339 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT239Field
{
private const ulong M47 = 140737488355327uL;
private const ulong M60 = 1152921504606846975uL;
public static void Add(ulong[] x, ulong[] y, ulong[] z)
{
z[0] = x[0] ^ y[0];
z[1] = x[1] ^ y[1];
z[2] = x[2] ^ y[2];
z[3] = x[3] ^ y[3];
}
public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz)
{
zz[0] = xx[0] ^ yy[0];
zz[1] = xx[1] ^ yy[1];
zz[2] = xx[2] ^ yy[2];
zz[3] = xx[3] ^ yy[3];
zz[4] = xx[4] ^ yy[4];
zz[5] = xx[5] ^ yy[5];
zz[6] = xx[6] ^ yy[6];
zz[7] = xx[7] ^ yy[7];
}
public static void AddOne(ulong[] x, ulong[] z)
{
z[0] = x[0] ^ 1;
z[1] = x[1];
z[2] = x[2];
z[3] = x[3];
}
public static ulong[] FromBigInteger(BigInteger x)
{
ulong[] array = Nat256.FromBigInteger64(x);
Reduce17(array, 0);
return array;
}
public static void Invert(ulong[] x, ulong[] z)
{
if (Nat256.IsZero64(x))
{
throw new InvalidOperationException();
}
ulong[] array = Nat256.Create64();
ulong[] array2 = Nat256.Create64();
Square(x, array);
Multiply(array, x, array);
Square(array, array);
Multiply(array, x, array);
SquareN(array, 3, array2);
Multiply(array2, array, array2);
Square(array2, array2);
Multiply(array2, x, array2);
SquareN(array2, 7, array);
Multiply(array, array2, array);
SquareN(array, 14, array2);
Multiply(array2, array, array2);
Square(array2, array2);
Multiply(array2, x, array2);
SquareN(array2, 29, array);
Multiply(array, array2, array);
Square(array, array);
Multiply(array, x, array);
SquareN(array, 59, array2);
Multiply(array2, array, array2);
Square(array2, array2);
Multiply(array2, x, array2);
SquareN(array2, 119, array);
Multiply(array, array2, array);
Square(array, z);
}
public static void Multiply(ulong[] x, ulong[] y, ulong[] z)
{
ulong[] array = Nat256.CreateExt64();
ImplMultiply(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz)
{
ulong[] array = Nat256.CreateExt64();
ImplMultiply(x, y, array);
AddExt(zz, array, zz);
}
public static void Reduce(ulong[] xx, ulong[] z)
{
ulong num = xx[0];
ulong num2 = xx[1];
ulong num3 = xx[2];
ulong num4 = xx[3];
ulong num5 = xx[4];
ulong num6 = xx[5];
ulong num7 = xx[6];
ulong num8 = xx[7];
num4 ^= num8 << 17;
num5 ^= num8 >> 47;
num6 ^= num8 << 47;
num7 ^= num8 >> 17;
num3 ^= num7 << 17;
num4 ^= num7 >> 47;
num5 ^= num7 << 47;
num6 ^= num7 >> 17;
num2 ^= num6 << 17;
num3 ^= num6 >> 47;
num4 ^= num6 << 47;
num5 ^= num6 >> 17;
num ^= num5 << 17;
num2 ^= num5 >> 47;
num3 ^= num5 << 47;
num4 ^= num5 >> 17;
ulong num9 = num4 >> 47;
z[0] = num ^ num9;
z[1] = num2;
z[2] = num3 ^ (num9 << 30);
z[3] = num4 & 0x7FFFFFFFFFFFL;
}
public static void Reduce17(ulong[] z, int zOff)
{
ulong num = z[zOff + 3];
ulong num2 = num >> 47;
ulong[] array2;
ulong[] array = (array2 = z);
nint num3 = zOff;
array[zOff] = array2[num3] ^ num2;
ulong[] array3 = (array2 = z);
int num4 = zOff + 2;
num3 = num4;
array3[num4] = array2[num3] ^ (num2 << 30);
z[zOff + 3] = num & 0x7FFFFFFFFFFFL;
}
public static void Sqrt(ulong[] x, ulong[] z)
{
ulong num = Interleave.Unshuffle(x[0]);
ulong num2 = Interleave.Unshuffle(x[1]);
ulong num3 = (num & 0xFFFFFFFFu) | (num2 << 32);
ulong num4 = (num >> 32) | (num2 & 0xFFFFFFFF00000000uL);
num = Interleave.Unshuffle(x[2]);
num2 = Interleave.Unshuffle(x[3]);
ulong num5 = (num & 0xFFFFFFFFu) | (num2 << 32);
ulong num6 = (num >> 32) | (num2 & 0xFFFFFFFF00000000uL);
ulong num7 = num6 >> 49;
ulong num8 = (num4 >> 49) | (num6 << 15);
num6 ^= num4 << 15;
ulong[] array = Nat256.CreateExt64();
int[] array2 = new int[2] { 39, 120 };
ulong[] array4;
for (int i = 0; i < array2.Length; i++)
{
int num9 = array2[i] >> 6;
int num10 = array2[i] & 0x3F;
ulong[] array3 = (array4 = array);
nint num11 = num9;
array3[num9] = array4[num11] ^ (num4 << num10);
ulong[] array5 = (array4 = array);
int num12 = num9 + 1;
num11 = num12;
array5[num12] = array4[num11] ^ ((num6 << num10) | (num4 >> -num10));
ulong[] array6 = (array4 = array);
int num13 = num9 + 2;
num11 = num13;
array6[num13] = array4[num11] ^ ((num8 << num10) | (num6 >> -num10));
ulong[] array7 = (array4 = array);
int num14 = num9 + 3;
num11 = num14;
array7[num14] = array4[num11] ^ ((num7 << num10) | (num8 >> -num10));
ulong[] array8 = (array4 = array);
int num15 = num9 + 4;
num11 = num15;
array8[num15] = array4[num11] ^ (num7 >> -num10);
}
Reduce(array, z);
(array4 = z)[0] = array4[0] ^ num3;
(array4 = z)[1] = array4[1] ^ num5;
}
public static void Square(ulong[] x, ulong[] z)
{
ulong[] array = Nat256.CreateExt64();
ImplSquare(x, array);
Reduce(array, z);
}
public static void SquareAddToExt(ulong[] x, ulong[] zz)
{
ulong[] array = Nat256.CreateExt64();
ImplSquare(x, array);
AddExt(zz, array, zz);
}
public static void SquareN(ulong[] x, int n, ulong[] z)
{
ulong[] array = Nat256.CreateExt64();
ImplSquare(x, array);
Reduce(array, z);
while (--n > 0)
{
ImplSquare(z, array);
Reduce(array, z);
}
}
public static uint Trace(ulong[] x)
{
return (uint)((int)(x[0] ^ (x[1] >> 17) ^ (x[2] >> 34)) & 1);
}
protected static void ImplCompactExt(ulong[] zz)
{
ulong num = zz[0];
ulong num2 = zz[1];
ulong num3 = zz[2];
ulong num4 = zz[3];
ulong num5 = zz[4];
ulong num6 = zz[5];
ulong num7 = zz[6];
ulong num8 = zz[7];
zz[0] = num ^ (num2 << 60);
zz[1] = (num2 >> 4) ^ (num3 << 56);
zz[2] = (num3 >> 8) ^ (num4 << 52);
zz[3] = (num4 >> 12) ^ (num5 << 48);
zz[4] = (num5 >> 16) ^ (num6 << 44);
zz[5] = (num6 >> 20) ^ (num7 << 40);
zz[6] = (num7 >> 24) ^ (num8 << 36);
zz[7] = num8 >> 28;
}
protected static void ImplExpand(ulong[] x, ulong[] z)
{
ulong num = x[0];
ulong num2 = x[1];
ulong num3 = x[2];
ulong num4 = x[3];
z[0] = num & 0xFFFFFFFFFFFFFFFL;
z[1] = ((num >> 60) ^ (num2 << 4)) & 0xFFFFFFFFFFFFFFFL;
z[2] = ((num2 >> 56) ^ (num3 << 8)) & 0xFFFFFFFFFFFFFFFL;
z[3] = (num3 >> 52) ^ (num4 << 12);
}
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
ulong[] array = new ulong[4];
ulong[] array2 = new ulong[4];
ImplExpand(x, array);
ImplExpand(y, array2);
ImplMulwAcc(array[0], array2[0], zz, 0);
ImplMulwAcc(array[1], array2[1], zz, 1);
ImplMulwAcc(array[2], array2[2], zz, 2);
ImplMulwAcc(array[3], array2[3], zz, 3);
ulong[] array4;
for (int num = 5; num > 0; num--)
{
ulong[] array3 = (array4 = zz);
int num2 = num;
nint num3 = num2;
array3[num2] = array4[num3] ^ zz[num - 1];
}
ImplMulwAcc(array[0] ^ array[1], array2[0] ^ array2[1], zz, 1);
ImplMulwAcc(array[2] ^ array[3], array2[2] ^ array2[3], zz, 3);
for (int num4 = 7; num4 > 1; num4--)
{
ulong[] array5 = (array4 = zz);
int num5 = num4;
nint num3 = num5;
array5[num5] = array4[num3] ^ zz[num4 - 2];
}
ulong num6 = array[0] ^ array[2];
ulong num7 = array[1] ^ array[3];
ulong num8 = array2[0] ^ array2[2];
ulong num9 = array2[1] ^ array2[3];
ImplMulwAcc(num6 ^ num7, num8 ^ num9, zz, 3);
ulong[] array6 = new ulong[3];
ImplMulwAcc(num6, num8, array6, 0);
ImplMulwAcc(num7, num9, array6, 1);
ulong num10 = array6[0];
ulong num11 = array6[1];
ulong num12 = array6[2];
(array4 = zz)[2] = array4[2] ^ num10;
(array4 = zz)[3] = array4[3] ^ (num10 ^ num11);
(array4 = zz)[4] = array4[4] ^ (num12 ^ num11);
(array4 = zz)[5] = array4[5] ^ num12;
ImplCompactExt(zz);
}
protected static void ImplMulwAcc(ulong x, ulong y, ulong[] z, int zOff)
{
ulong[] array = new ulong[8];
array[1] = y;
array[2] = array[1] << 1;
array[3] = array[2] ^ y;
array[4] = array[2] << 1;
array[5] = array[4] ^ y;
array[6] = array[3] << 1;
array[7] = array[6] ^ y;
uint num = (uint)x;
ulong num2 = 0uL;
ulong num3 = array[num & 7] ^ (array[(num >> 3) & 7] << 3);
int num4 = 54;
do
{
num = (uint)(x >> num4);
ulong num5 = array[num & 7] ^ (array[(num >> 3) & 7] << 3);
num3 ^= num5 << num4;
num2 ^= num5 >> -num4;
}
while ((num4 -= 6) > 0);
num2 ^= (x & 0x820820820820820L & (ulong)((long)(y << 4) >> 63)) >> 5;
ulong[] array3;
ulong[] array2 = (array3 = z);
nint num6 = zOff;
array2[zOff] = array3[num6] ^ (num3 & 0xFFFFFFFFFFFFFFFL);
ulong[] array4 = (array3 = z);
int num7 = zOff + 1;
num6 = num7;
array4[num7] = array3[num6] ^ ((num3 >> 60) ^ (num2 << 4));
}
protected static void ImplSquare(ulong[] x, ulong[] zz)
{
Interleave.Expand64To128(x[0], zz, 0);
Interleave.Expand64To128(x[1], zz, 2);
Interleave.Expand64To128(x[2], zz, 4);
ulong num = x[3];
zz[6] = Interleave.Expand32to64((uint)num);
zz[7] = Interleave.Expand16to32((uint)(num >> 32));
}
}

View File

@@ -0,0 +1,195 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT239FieldElement : AbstractF2mFieldElement
{
protected internal readonly ulong[] x;
public override bool IsOne => Nat256.IsOne64(x);
public override bool IsZero => Nat256.IsZero64(x);
public override string FieldName => "SecT239Field";
public override int FieldSize => 239;
public virtual int Representation => 2;
public virtual int M => 239;
public virtual int K1 => 158;
public virtual int K2 => 0;
public virtual int K3 => 0;
public SecT239FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.BitLength > 239)
{
throw new ArgumentException("value invalid for SecT239FieldElement", "x");
}
this.x = SecT239Field.FromBigInteger(x);
}
public SecT239FieldElement()
{
x = Nat256.Create64();
}
protected internal SecT239FieldElement(ulong[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return (x[0] & 1) != 0;
}
public override BigInteger ToBigInteger()
{
return Nat256.ToBigInteger64(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
ulong[] z = Nat256.Create64();
SecT239Field.Add(x, ((SecT239FieldElement)b).x, z);
return new SecT239FieldElement(z);
}
public override ECFieldElement AddOne()
{
ulong[] z = Nat256.Create64();
SecT239Field.AddOne(x, z);
return new SecT239FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
return Add(b);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
ulong[] z = Nat256.Create64();
SecT239Field.Multiply(x, ((SecT239FieldElement)b).x, z);
return new SecT239FieldElement(z);
}
public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
return MultiplyPlusProduct(b, x, y);
}
public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] y2 = ((SecT239FieldElement)b).x;
ulong[] array2 = ((SecT239FieldElement)x).x;
ulong[] y3 = ((SecT239FieldElement)y).x;
ulong[] array3 = Nat256.CreateExt64();
SecT239Field.MultiplyAddToExt(array, y2, array3);
SecT239Field.MultiplyAddToExt(array2, y3, array3);
ulong[] z = Nat256.Create64();
SecT239Field.Reduce(array3, z);
return new SecT239FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
return Multiply(b.Invert());
}
public override ECFieldElement Negate()
{
return this;
}
public override ECFieldElement Square()
{
ulong[] z = Nat256.Create64();
SecT239Field.Square(x, z);
return new SecT239FieldElement(z);
}
public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
{
return SquarePlusProduct(x, y);
}
public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] array2 = ((SecT239FieldElement)x).x;
ulong[] y2 = ((SecT239FieldElement)y).x;
ulong[] array3 = Nat256.CreateExt64();
SecT239Field.SquareAddToExt(array, array3);
SecT239Field.MultiplyAddToExt(array2, y2, array3);
ulong[] z = Nat256.Create64();
SecT239Field.Reduce(array3, z);
return new SecT239FieldElement(z);
}
public override ECFieldElement SquarePow(int pow)
{
if (pow < 1)
{
return this;
}
ulong[] z = Nat256.Create64();
SecT239Field.SquareN(x, pow, z);
return new SecT239FieldElement(z);
}
public override int Trace()
{
return (int)SecT239Field.Trace(x);
}
public override ECFieldElement Invert()
{
ulong[] z = Nat256.Create64();
SecT239Field.Invert(x, z);
return new SecT239FieldElement(z);
}
public override ECFieldElement Sqrt()
{
ulong[] z = Nat256.Create64();
SecT239Field.Sqrt(x, z);
return new SecT239FieldElement(z);
}
public override bool Equals(object obj)
{
return Equals(obj as SecT239FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecT239FieldElement);
}
public virtual bool Equals(SecT239FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat256.Eq64(x, other.x);
}
public override int GetHashCode()
{
return 0x16CAFFE ^ Arrays.GetHashCode(x, 0, 4);
}
}

View File

@@ -0,0 +1,133 @@
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT239K1Curve : AbstractF2mCurve
{
private class SecT239K1LookupTable : ECLookupTable
{
private readonly SecT239K1Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT239K1LookupTable(SecT239K1Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat256.Create64();
ulong[] array2 = Nat256.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 4; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 4 + j] & num2);
}
num += 8;
}
return m_outer.CreateRawPoint(new SecT239FieldElement(array), new SecT239FieldElement(array2), withCompression: false);
}
}
private const int SECT239K1_DEFAULT_COORDS = 6;
private const int SECT239K1_FE_LONGS = 4;
protected readonly SecT239K1Point m_infinity;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => 239;
public override bool IsKoblitz => true;
public virtual int M => 239;
public virtual bool IsTrinomial => true;
public virtual int K1 => 158;
public virtual int K2 => 0;
public virtual int K3 => 0;
public SecT239K1Curve()
: base(239, 158, 0, 0)
{
m_infinity = new SecT239K1Point(this, null, null);
m_a = FromBigInteger(BigInteger.Zero);
m_b = FromBigInteger(BigInteger.One);
m_order = new BigInteger(1, Hex.Decode("2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5"));
m_cofactor = BigInteger.ValueOf(4L);
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT239K1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
protected override ECMultiplier CreateDefaultMultiplier()
{
return new WTauNafMultiplier();
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT239FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT239K1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT239K1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 4 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat256.Copy64(((SecT239FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 4;
Nat256.Copy64(((SecT239FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 4;
}
return new SecT239K1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,259 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT239K1Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT239K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT239K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT239K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT239K1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord);
if (eCFieldElement10.IsZero)
{
return new SecT239K1Point(curve, eCFieldElement10, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT239K1Point(curve, eCFieldElement10, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT239K1Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement eCFieldElement3 = ((!isOne) ? rawYCoord.Add(eCFieldElement).Multiply(rawYCoord) : rawYCoord.Square().Add(rawYCoord));
if (eCFieldElement3.IsZero)
{
return new SecT239K1Point(curve, eCFieldElement3, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement4 = eCFieldElement3.Square();
ECFieldElement eCFieldElement5 = (isOne ? eCFieldElement3 : eCFieldElement3.Multiply(eCFieldElement2));
ECFieldElement eCFieldElement6 = rawYCoord.Add(rawXCoord).Square();
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement2.Square());
ECFieldElement y = eCFieldElement6.Add(eCFieldElement3).Add(eCFieldElement2).Multiply(eCFieldElement6)
.Add(b)
.Add(eCFieldElement4)
.Add(eCFieldElement5);
return new SecT239K1Point(curve, eCFieldElement4, y, new ECFieldElement[1] { eCFieldElement5 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement eCFieldElement3 = rawYCoord.Square();
ECFieldElement eCFieldElement4 = eCFieldElement2.Square();
ECFieldElement b2 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b3 = eCFieldElement3.Add(b2);
ECFieldElement eCFieldElement5 = rawYCoord2.AddOne();
ECFieldElement eCFieldElement6 = eCFieldElement5.Multiply(eCFieldElement4).Add(eCFieldElement3).MultiplyPlusProduct(b3, x, eCFieldElement4);
ECFieldElement eCFieldElement7 = rawXCoord2.Multiply(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement7.Add(b3).Square();
if (eCFieldElement8.IsZero)
{
if (eCFieldElement6.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement6.IsZero)
{
return new SecT239K1Point(curve, eCFieldElement6, curve.B, base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement6.Square().Multiply(eCFieldElement7);
ECFieldElement eCFieldElement9 = eCFieldElement6.Multiply(eCFieldElement8).Multiply(eCFieldElement4);
ECFieldElement y = eCFieldElement6.Add(eCFieldElement8).Square().MultiplyPlusProduct(b3, eCFieldElement5, eCFieldElement9);
return new SecT239K1Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement9 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT239K1Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,341 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT283Field
{
private const ulong M27 = 134217727uL;
private const ulong M57 = 144115188075855871uL;
private static readonly ulong[] ROOT_Z = new ulong[5] { 878416384462358536uL, 3513665537849438403uL, 9369774767598502668uL, 585610922974906400uL, 34087042uL };
public static void Add(ulong[] x, ulong[] y, ulong[] z)
{
z[0] = x[0] ^ y[0];
z[1] = x[1] ^ y[1];
z[2] = x[2] ^ y[2];
z[3] = x[3] ^ y[3];
z[4] = x[4] ^ y[4];
}
public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz)
{
zz[0] = xx[0] ^ yy[0];
zz[1] = xx[1] ^ yy[1];
zz[2] = xx[2] ^ yy[2];
zz[3] = xx[3] ^ yy[3];
zz[4] = xx[4] ^ yy[4];
zz[5] = xx[5] ^ yy[5];
zz[6] = xx[6] ^ yy[6];
zz[7] = xx[7] ^ yy[7];
zz[8] = xx[8] ^ yy[8];
}
public static void AddOne(ulong[] x, ulong[] z)
{
z[0] = x[0] ^ 1;
z[1] = x[1];
z[2] = x[2];
z[3] = x[3];
z[4] = x[4];
}
public static ulong[] FromBigInteger(BigInteger x)
{
ulong[] array = Nat320.FromBigInteger64(x);
Reduce37(array, 0);
return array;
}
public static void Invert(ulong[] x, ulong[] z)
{
if (Nat320.IsZero64(x))
{
throw new InvalidOperationException();
}
ulong[] array = Nat320.Create64();
ulong[] array2 = Nat320.Create64();
Square(x, array);
Multiply(array, x, array);
SquareN(array, 2, array2);
Multiply(array2, array, array2);
SquareN(array2, 4, array);
Multiply(array, array2, array);
SquareN(array, 8, array2);
Multiply(array2, array, array2);
Square(array2, array2);
Multiply(array2, x, array2);
SquareN(array2, 17, array);
Multiply(array, array2, array);
Square(array, array);
Multiply(array, x, array);
SquareN(array, 35, array2);
Multiply(array2, array, array2);
SquareN(array2, 70, array);
Multiply(array, array2, array);
Square(array, array);
Multiply(array, x, array);
SquareN(array, 141, array2);
Multiply(array2, array, array2);
Square(array2, z);
}
public static void Multiply(ulong[] x, ulong[] y, ulong[] z)
{
ulong[] array = Nat320.CreateExt64();
ImplMultiply(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz)
{
ulong[] array = Nat320.CreateExt64();
ImplMultiply(x, y, array);
AddExt(zz, array, zz);
}
public static void Reduce(ulong[] xx, ulong[] z)
{
ulong num = xx[0];
ulong num2 = xx[1];
ulong num3 = xx[2];
ulong num4 = xx[3];
ulong num5 = xx[4];
ulong num6 = xx[5];
ulong num7 = xx[6];
ulong num8 = xx[7];
ulong num9 = xx[8];
num4 ^= (num9 << 37) ^ (num9 << 42) ^ (num9 << 44) ^ (num9 << 49);
num5 ^= (num9 >> 27) ^ (num9 >> 22) ^ (num9 >> 20) ^ (num9 >> 15);
num3 ^= (num8 << 37) ^ (num8 << 42) ^ (num8 << 44) ^ (num8 << 49);
num4 ^= (num8 >> 27) ^ (num8 >> 22) ^ (num8 >> 20) ^ (num8 >> 15);
num2 ^= (num7 << 37) ^ (num7 << 42) ^ (num7 << 44) ^ (num7 << 49);
num3 ^= (num7 >> 27) ^ (num7 >> 22) ^ (num7 >> 20) ^ (num7 >> 15);
num ^= (num6 << 37) ^ (num6 << 42) ^ (num6 << 44) ^ (num6 << 49);
num2 ^= (num6 >> 27) ^ (num6 >> 22) ^ (num6 >> 20) ^ (num6 >> 15);
ulong num10 = num5 >> 27;
z[0] = num ^ num10 ^ (num10 << 5) ^ (num10 << 7) ^ (num10 << 12);
z[1] = num2;
z[2] = num3;
z[3] = num4;
z[4] = num5 & 0x7FFFFFF;
}
public static void Reduce37(ulong[] z, int zOff)
{
ulong num = z[zOff + 4];
ulong num2 = num >> 27;
ulong[] array2;
ulong[] array = (array2 = z);
nint num3 = zOff;
array[zOff] = array2[num3] ^ (num2 ^ (num2 << 5) ^ (num2 << 7) ^ (num2 << 12));
z[zOff + 4] = num & 0x7FFFFFF;
}
public static void Sqrt(ulong[] x, ulong[] z)
{
ulong[] array = Nat320.Create64();
ulong num = Interleave.Unshuffle(x[0]);
ulong num2 = Interleave.Unshuffle(x[1]);
ulong num3 = (num & 0xFFFFFFFFu) | (num2 << 32);
array[0] = (num >> 32) | (num2 & 0xFFFFFFFF00000000uL);
num = Interleave.Unshuffle(x[2]);
num2 = Interleave.Unshuffle(x[3]);
ulong num4 = (num & 0xFFFFFFFFu) | (num2 << 32);
array[1] = (num >> 32) | (num2 & 0xFFFFFFFF00000000uL);
num = Interleave.Unshuffle(x[4]);
ulong num5 = num & 0xFFFFFFFFu;
array[2] = num >> 32;
Multiply(array, ROOT_Z, z);
ulong[] array2;
(array2 = z)[0] = array2[0] ^ num3;
(array2 = z)[1] = array2[1] ^ num4;
(array2 = z)[2] = array2[2] ^ num5;
}
public static void Square(ulong[] x, ulong[] z)
{
ulong[] array = Nat.Create64(9);
ImplSquare(x, array);
Reduce(array, z);
}
public static void SquareAddToExt(ulong[] x, ulong[] zz)
{
ulong[] array = Nat.Create64(9);
ImplSquare(x, array);
AddExt(zz, array, zz);
}
public static void SquareN(ulong[] x, int n, ulong[] z)
{
ulong[] array = Nat.Create64(9);
ImplSquare(x, array);
Reduce(array, z);
while (--n > 0)
{
ImplSquare(z, array);
Reduce(array, z);
}
}
public static uint Trace(ulong[] x)
{
return (uint)((int)(x[0] ^ (x[4] >> 15)) & 1);
}
protected static void ImplCompactExt(ulong[] zz)
{
ulong num = zz[0];
ulong num2 = zz[1];
ulong num3 = zz[2];
ulong num4 = zz[3];
ulong num5 = zz[4];
ulong num6 = zz[5];
ulong num7 = zz[6];
ulong num8 = zz[7];
ulong num9 = zz[8];
ulong num10 = zz[9];
zz[0] = num ^ (num2 << 57);
zz[1] = (num2 >> 7) ^ (num3 << 50);
zz[2] = (num3 >> 14) ^ (num4 << 43);
zz[3] = (num4 >> 21) ^ (num5 << 36);
zz[4] = (num5 >> 28) ^ (num6 << 29);
zz[5] = (num6 >> 35) ^ (num7 << 22);
zz[6] = (num7 >> 42) ^ (num8 << 15);
zz[7] = (num8 >> 49) ^ (num9 << 8);
zz[8] = (num9 >> 56) ^ (num10 << 1);
zz[9] = num10 >> 63;
}
protected static void ImplExpand(ulong[] x, ulong[] z)
{
ulong num = x[0];
ulong num2 = x[1];
ulong num3 = x[2];
ulong num4 = x[3];
ulong num5 = x[4];
z[0] = num & 0x1FFFFFFFFFFFFFFL;
z[1] = ((num >> 57) ^ (num2 << 7)) & 0x1FFFFFFFFFFFFFFL;
z[2] = ((num2 >> 50) ^ (num3 << 14)) & 0x1FFFFFFFFFFFFFFL;
z[3] = ((num3 >> 43) ^ (num4 << 21)) & 0x1FFFFFFFFFFFFFFL;
z[4] = (num4 >> 36) ^ (num5 << 28);
}
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
ulong[] array = new ulong[5];
ulong[] array2 = new ulong[5];
ImplExpand(x, array);
ImplExpand(y, array2);
ulong[] array3 = new ulong[26];
ImplMulw(array[0], array2[0], array3, 0);
ImplMulw(array[1], array2[1], array3, 2);
ImplMulw(array[2], array2[2], array3, 4);
ImplMulw(array[3], array2[3], array3, 6);
ImplMulw(array[4], array2[4], array3, 8);
ulong num = array[0] ^ array[1];
ulong num2 = array2[0] ^ array2[1];
ulong num3 = array[0] ^ array[2];
ulong num4 = array2[0] ^ array2[2];
ulong num5 = array[2] ^ array[4];
ulong num6 = array2[2] ^ array2[4];
ulong num7 = array[3] ^ array[4];
ulong num8 = array2[3] ^ array2[4];
ImplMulw(num3 ^ array[3], num4 ^ array2[3], array3, 18);
ImplMulw(num5 ^ array[1], num6 ^ array2[1], array3, 20);
ulong num9 = num ^ num7;
ulong num10 = num2 ^ num8;
ulong x2 = num9 ^ array[2];
ulong y2 = num10 ^ array2[2];
ImplMulw(num9, num10, array3, 22);
ImplMulw(x2, y2, array3, 24);
ImplMulw(num, num2, array3, 10);
ImplMulw(num3, num4, array3, 12);
ImplMulw(num5, num6, array3, 14);
ImplMulw(num7, num8, array3, 16);
zz[0] = array3[0];
zz[9] = array3[9];
ulong num11 = array3[0] ^ array3[1];
ulong num12 = num11 ^ array3[2];
ulong num13 = (zz[1] = num12 ^ array3[10]);
ulong num14 = array3[3] ^ array3[4];
ulong num15 = array3[11] ^ array3[12];
ulong num16 = num14 ^ num15;
ulong num17 = (zz[2] = num12 ^ num16);
ulong num18 = num11 ^ num14;
ulong num19 = array3[5] ^ array3[6];
ulong num20 = num18 ^ num19;
ulong num21 = num20 ^ array3[8];
ulong num22 = array3[13] ^ array3[14];
ulong num23 = num21 ^ num22;
ulong num24 = array3[18] ^ array3[22];
ulong num25 = num24 ^ array3[24];
ulong num26 = num23 ^ num25;
zz[3] = num26;
ulong num27 = array3[7] ^ array3[8];
ulong num28 = num27 ^ array3[9];
ulong num29 = (zz[8] = num28 ^ array3[17]);
ulong num30 = num28 ^ num19;
ulong num31 = array3[15] ^ array3[16];
ulong num32 = (zz[7] = num30 ^ num31) ^ num13;
ulong num33 = array3[19] ^ array3[20];
ulong num34 = array3[25] ^ array3[24];
ulong num35 = array3[18] ^ array3[23];
ulong num36 = num33 ^ num34;
ulong num37 = num36 ^ num35;
ulong num38 = num37 ^ num32;
zz[4] = num38;
ulong num39 = num17 ^ num29;
ulong num40 = num36 ^ num39;
ulong num41 = array3[21] ^ array3[22];
ulong num42 = num40 ^ num41;
zz[5] = num42;
ulong num43 = num21 ^ array3[0];
ulong num44 = num43 ^ array3[9];
ulong num45 = num44 ^ num22;
ulong num46 = num45 ^ array3[21];
ulong num47 = num46 ^ array3[23];
ulong num48 = num47 ^ array3[25];
zz[6] = num48;
ImplCompactExt(zz);
}
protected static void ImplMulw(ulong x, ulong y, ulong[] z, int zOff)
{
ulong[] array = new ulong[8];
array[1] = y;
array[2] = array[1] << 1;
array[3] = array[2] ^ y;
array[4] = array[2] << 1;
array[5] = array[4] ^ y;
array[6] = array[3] << 1;
array[7] = array[6] ^ y;
uint num = (uint)x;
ulong num2 = 0uL;
ulong num3 = array[num & 7];
int num4 = 48;
do
{
num = (uint)(x >> num4);
ulong num5 = array[num & 7] ^ (array[(num >> 3) & 7] << 3) ^ (array[(num >> 6) & 7] << 6);
num3 ^= num5 << num4;
num2 ^= num5 >> -num4;
}
while ((num4 -= 9) > 0);
num2 ^= (x & 0x100804020100800L & (ulong)((long)(y << 7) >> 63)) >> 8;
z[zOff] = num3 & 0x1FFFFFFFFFFFFFFL;
z[zOff + 1] = (num3 >> 57) ^ (num2 << 7);
}
protected static void ImplSquare(ulong[] x, ulong[] zz)
{
for (int i = 0; i < 4; i++)
{
Interleave.Expand64To128(x[i], zz, i << 1);
}
zz[8] = Interleave.Expand32to64((uint)x[4]);
}
}

View File

@@ -0,0 +1,195 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT283FieldElement : AbstractF2mFieldElement
{
protected internal readonly ulong[] x;
public override bool IsOne => Nat320.IsOne64(x);
public override bool IsZero => Nat320.IsZero64(x);
public override string FieldName => "SecT283Field";
public override int FieldSize => 283;
public virtual int Representation => 3;
public virtual int M => 283;
public virtual int K1 => 5;
public virtual int K2 => 7;
public virtual int K3 => 12;
public SecT283FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.BitLength > 283)
{
throw new ArgumentException("value invalid for SecT283FieldElement", "x");
}
this.x = SecT283Field.FromBigInteger(x);
}
public SecT283FieldElement()
{
x = Nat320.Create64();
}
protected internal SecT283FieldElement(ulong[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return (x[0] & 1) != 0;
}
public override BigInteger ToBigInteger()
{
return Nat320.ToBigInteger64(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
ulong[] z = Nat320.Create64();
SecT283Field.Add(x, ((SecT283FieldElement)b).x, z);
return new SecT283FieldElement(z);
}
public override ECFieldElement AddOne()
{
ulong[] z = Nat320.Create64();
SecT283Field.AddOne(x, z);
return new SecT283FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
return Add(b);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
ulong[] z = Nat320.Create64();
SecT283Field.Multiply(x, ((SecT283FieldElement)b).x, z);
return new SecT283FieldElement(z);
}
public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
return MultiplyPlusProduct(b, x, y);
}
public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] y2 = ((SecT283FieldElement)b).x;
ulong[] array2 = ((SecT283FieldElement)x).x;
ulong[] y3 = ((SecT283FieldElement)y).x;
ulong[] array3 = Nat.Create64(9);
SecT283Field.MultiplyAddToExt(array, y2, array3);
SecT283Field.MultiplyAddToExt(array2, y3, array3);
ulong[] z = Nat320.Create64();
SecT283Field.Reduce(array3, z);
return new SecT283FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
return Multiply(b.Invert());
}
public override ECFieldElement Negate()
{
return this;
}
public override ECFieldElement Square()
{
ulong[] z = Nat320.Create64();
SecT283Field.Square(x, z);
return new SecT283FieldElement(z);
}
public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
{
return SquarePlusProduct(x, y);
}
public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] array2 = ((SecT283FieldElement)x).x;
ulong[] y2 = ((SecT283FieldElement)y).x;
ulong[] array3 = Nat.Create64(9);
SecT283Field.SquareAddToExt(array, array3);
SecT283Field.MultiplyAddToExt(array2, y2, array3);
ulong[] z = Nat320.Create64();
SecT283Field.Reduce(array3, z);
return new SecT283FieldElement(z);
}
public override ECFieldElement SquarePow(int pow)
{
if (pow < 1)
{
return this;
}
ulong[] z = Nat320.Create64();
SecT283Field.SquareN(x, pow, z);
return new SecT283FieldElement(z);
}
public override int Trace()
{
return (int)SecT283Field.Trace(x);
}
public override ECFieldElement Invert()
{
ulong[] z = Nat320.Create64();
SecT283Field.Invert(x, z);
return new SecT283FieldElement(z);
}
public override ECFieldElement Sqrt()
{
ulong[] z = Nat320.Create64();
SecT283Field.Sqrt(x, z);
return new SecT283FieldElement(z);
}
public override bool Equals(object obj)
{
return Equals(obj as SecT283FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecT283FieldElement);
}
public virtual bool Equals(SecT283FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat320.Eq64(x, other.x);
}
public override int GetHashCode()
{
return 0x2B33AB ^ Arrays.GetHashCode(x, 0, 5);
}
}

View File

@@ -0,0 +1,133 @@
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT283K1Curve : AbstractF2mCurve
{
private class SecT283K1LookupTable : ECLookupTable
{
private readonly SecT283K1Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT283K1LookupTable(SecT283K1Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat320.Create64();
ulong[] array2 = Nat320.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 5; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 5 + j] & num2);
}
num += 10;
}
return m_outer.CreateRawPoint(new SecT283FieldElement(array), new SecT283FieldElement(array2), withCompression: false);
}
}
private const int SECT283K1_DEFAULT_COORDS = 6;
private const int SECT283K1_FE_LONGS = 5;
protected readonly SecT283K1Point m_infinity;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => 283;
public override bool IsKoblitz => true;
public virtual int M => 283;
public virtual bool IsTrinomial => false;
public virtual int K1 => 5;
public virtual int K2 => 7;
public virtual int K3 => 12;
public SecT283K1Curve()
: base(283, 5, 7, 12)
{
m_infinity = new SecT283K1Point(this, null, null);
m_a = FromBigInteger(BigInteger.Zero);
m_b = FromBigInteger(BigInteger.One);
m_order = new BigInteger(1, Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61"));
m_cofactor = BigInteger.ValueOf(4L);
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT283K1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
protected override ECMultiplier CreateDefaultMultiplier()
{
return new WTauNafMultiplier();
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT283FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT283K1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT283K1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 5 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat320.Copy64(((SecT283FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 5;
Nat320.Copy64(((SecT283FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 5;
}
return new SecT283K1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,259 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT283K1Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT283K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT283K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT283K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT283K1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord);
if (eCFieldElement10.IsZero)
{
return new SecT283K1Point(curve, eCFieldElement10, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT283K1Point(curve, eCFieldElement10, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT283K1Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement eCFieldElement3 = ((!isOne) ? rawYCoord.Add(eCFieldElement).Multiply(rawYCoord) : rawYCoord.Square().Add(rawYCoord));
if (eCFieldElement3.IsZero)
{
return new SecT283K1Point(curve, eCFieldElement3, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement4 = eCFieldElement3.Square();
ECFieldElement eCFieldElement5 = (isOne ? eCFieldElement3 : eCFieldElement3.Multiply(eCFieldElement2));
ECFieldElement eCFieldElement6 = rawYCoord.Add(rawXCoord).Square();
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement2.Square());
ECFieldElement y = eCFieldElement6.Add(eCFieldElement3).Add(eCFieldElement2).Multiply(eCFieldElement6)
.Add(b)
.Add(eCFieldElement4)
.Add(eCFieldElement5);
return new SecT283K1Point(curve, eCFieldElement4, y, new ECFieldElement[1] { eCFieldElement5 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement eCFieldElement3 = rawYCoord.Square();
ECFieldElement eCFieldElement4 = eCFieldElement2.Square();
ECFieldElement b2 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b3 = eCFieldElement3.Add(b2);
ECFieldElement eCFieldElement5 = rawYCoord2.AddOne();
ECFieldElement eCFieldElement6 = eCFieldElement5.Multiply(eCFieldElement4).Add(eCFieldElement3).MultiplyPlusProduct(b3, x, eCFieldElement4);
ECFieldElement eCFieldElement7 = rawXCoord2.Multiply(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement7.Add(b3).Square();
if (eCFieldElement8.IsZero)
{
if (eCFieldElement6.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement6.IsZero)
{
return new SecT283K1Point(curve, eCFieldElement6, curve.B, base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement6.Square().Multiply(eCFieldElement7);
ECFieldElement eCFieldElement9 = eCFieldElement6.Multiply(eCFieldElement8).Multiply(eCFieldElement4);
ECFieldElement y = eCFieldElement6.Add(eCFieldElement8).Square().MultiplyPlusProduct(b3, eCFieldElement5, eCFieldElement9);
return new SecT283K1Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement9 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT283K1Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,127 @@
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT283R1Curve : AbstractF2mCurve
{
private class SecT283R1LookupTable : ECLookupTable
{
private readonly SecT283R1Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT283R1LookupTable(SecT283R1Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat320.Create64();
ulong[] array2 = Nat320.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 5; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 5 + j] & num2);
}
num += 10;
}
return m_outer.CreateRawPoint(new SecT283FieldElement(array), new SecT283FieldElement(array2), withCompression: false);
}
}
private const int SECT283R1_DEFAULT_COORDS = 6;
private const int SECT283R1_FE_LONGS = 5;
protected readonly SecT283R1Point m_infinity;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => 283;
public override bool IsKoblitz => false;
public virtual int M => 283;
public virtual bool IsTrinomial => false;
public virtual int K1 => 5;
public virtual int K2 => 7;
public virtual int K3 => 12;
public SecT283R1Curve()
: base(283, 5, 7, 12)
{
m_infinity = new SecT283R1Point(this, null, null);
m_a = FromBigInteger(BigInteger.One);
m_b = FromBigInteger(new BigInteger(1, Hex.Decode("027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5")));
m_order = new BigInteger(1, Hex.Decode("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307"));
m_cofactor = BigInteger.Two;
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT283R1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT283FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT283R1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT283R1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 5 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat320.Copy64(((SecT283FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 5;
Nat320.Copy64(((SecT283FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 5;
}
return new SecT283R1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,256 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT283R1Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT283R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT283R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT283R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT283R1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord)
.AddOne();
if (eCFieldElement10.IsZero)
{
return new SecT283R1Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT283R1Point(curve, eCFieldElement10, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT283R1Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = (isOne ? rawYCoord : rawYCoord.Multiply(eCFieldElement));
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement eCFieldElement3 = rawYCoord.Square().Add(eCFieldElement2).Add(b);
if (eCFieldElement3.IsZero)
{
return new SecT283R1Point(curve, eCFieldElement3, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement eCFieldElement4 = eCFieldElement3.Square();
ECFieldElement eCFieldElement5 = (isOne ? eCFieldElement3 : eCFieldElement3.Multiply(b));
ECFieldElement eCFieldElement6 = (isOne ? rawXCoord : rawXCoord.Multiply(eCFieldElement));
ECFieldElement y = eCFieldElement6.SquarePlusProduct(eCFieldElement3, eCFieldElement2).Add(eCFieldElement4).Add(eCFieldElement5);
return new SecT283R1Point(curve, eCFieldElement4, y, new ECFieldElement[1] { eCFieldElement5 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement b2 = rawYCoord.Square();
ECFieldElement eCFieldElement3 = eCFieldElement2.Square();
ECFieldElement b3 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b4 = eCFieldElement3.Add(b2).Add(b3);
ECFieldElement eCFieldElement4 = rawYCoord2.Multiply(eCFieldElement3).Add(b2).MultiplyPlusProduct(b4, x, eCFieldElement3);
ECFieldElement eCFieldElement5 = rawXCoord2.Multiply(eCFieldElement3);
ECFieldElement eCFieldElement6 = eCFieldElement5.Add(b4).Square();
if (eCFieldElement6.IsZero)
{
if (eCFieldElement4.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement4.IsZero)
{
return new SecT283R1Point(curve, eCFieldElement4, curve.B.Sqrt(), base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement4.Square().Multiply(eCFieldElement5);
ECFieldElement eCFieldElement7 = eCFieldElement4.Multiply(eCFieldElement6).Multiply(eCFieldElement3);
ECFieldElement y = eCFieldElement4.Add(eCFieldElement6).Square().MultiplyPlusProduct(b4, rawYCoord2.AddOne(), eCFieldElement7);
return new SecT283R1Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement7 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT283R1Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

View File

@@ -0,0 +1,319 @@
using System;
using Org.BouncyCastle.Math.Raw;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT409Field
{
private const ulong M25 = 33554431uL;
private const ulong M59 = 576460752303423487uL;
public static void Add(ulong[] x, ulong[] y, ulong[] z)
{
z[0] = x[0] ^ y[0];
z[1] = x[1] ^ y[1];
z[2] = x[2] ^ y[2];
z[3] = x[3] ^ y[3];
z[4] = x[4] ^ y[4];
z[5] = x[5] ^ y[5];
z[6] = x[6] ^ y[6];
}
public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz)
{
for (int i = 0; i < 13; i++)
{
zz[i] = xx[i] ^ yy[i];
}
}
public static void AddOne(ulong[] x, ulong[] z)
{
z[0] = x[0] ^ 1;
z[1] = x[1];
z[2] = x[2];
z[3] = x[3];
z[4] = x[4];
z[5] = x[5];
z[6] = x[6];
}
public static ulong[] FromBigInteger(BigInteger x)
{
ulong[] array = Nat448.FromBigInteger64(x);
Reduce39(array, 0);
return array;
}
public static void Invert(ulong[] x, ulong[] z)
{
if (Nat448.IsZero64(x))
{
throw new InvalidOperationException();
}
ulong[] array = Nat448.Create64();
ulong[] array2 = Nat448.Create64();
ulong[] array3 = Nat448.Create64();
Square(x, array);
SquareN(array, 1, array2);
Multiply(array, array2, array);
SquareN(array2, 1, array2);
Multiply(array, array2, array);
SquareN(array, 3, array2);
Multiply(array, array2, array);
SquareN(array, 6, array2);
Multiply(array, array2, array);
SquareN(array, 12, array2);
Multiply(array, array2, array3);
SquareN(array3, 24, array);
SquareN(array, 24, array2);
Multiply(array, array2, array);
SquareN(array, 48, array2);
Multiply(array, array2, array);
SquareN(array, 96, array2);
Multiply(array, array2, array);
SquareN(array, 192, array2);
Multiply(array, array2, array);
Multiply(array, array3, z);
}
public static void Multiply(ulong[] x, ulong[] y, ulong[] z)
{
ulong[] array = Nat448.CreateExt64();
ImplMultiply(x, y, array);
Reduce(array, z);
}
public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz)
{
ulong[] array = Nat448.CreateExt64();
ImplMultiply(x, y, array);
AddExt(zz, array, zz);
}
public static void Reduce(ulong[] xx, ulong[] z)
{
ulong num = xx[0];
ulong num2 = xx[1];
ulong num3 = xx[2];
ulong num4 = xx[3];
ulong num5 = xx[4];
ulong num6 = xx[5];
ulong num7 = xx[6];
ulong num8 = xx[7];
ulong num9 = xx[12];
num6 ^= num9 << 39;
num7 ^= (num9 >> 25) ^ (num9 << 62);
num8 ^= num9 >> 2;
num9 = xx[11];
num5 ^= num9 << 39;
num6 ^= (num9 >> 25) ^ (num9 << 62);
num7 ^= num9 >> 2;
num9 = xx[10];
num4 ^= num9 << 39;
num5 ^= (num9 >> 25) ^ (num9 << 62);
num6 ^= num9 >> 2;
num9 = xx[9];
num3 ^= num9 << 39;
num4 ^= (num9 >> 25) ^ (num9 << 62);
num5 ^= num9 >> 2;
num9 = xx[8];
num2 ^= num9 << 39;
num3 ^= (num9 >> 25) ^ (num9 << 62);
num4 ^= num9 >> 2;
num9 = num8;
num ^= num9 << 39;
num2 ^= (num9 >> 25) ^ (num9 << 62);
num3 ^= num9 >> 2;
ulong num10 = num7 >> 25;
z[0] = num ^ num10;
z[1] = num2 ^ (num10 << 23);
z[2] = num3;
z[3] = num4;
z[4] = num5;
z[5] = num6;
z[6] = num7 & 0x1FFFFFF;
}
public static void Reduce39(ulong[] z, int zOff)
{
ulong num = z[zOff + 6];
ulong num2 = num >> 25;
ulong[] array2;
ulong[] array = (array2 = z);
nint num3 = zOff;
array[zOff] = array2[num3] ^ num2;
ulong[] array3 = (array2 = z);
int num4 = zOff + 1;
num3 = num4;
array3[num4] = array2[num3] ^ (num2 << 23);
z[zOff + 6] = num & 0x1FFFFFF;
}
public static void Sqrt(ulong[] x, ulong[] z)
{
ulong num = Interleave.Unshuffle(x[0]);
ulong num2 = Interleave.Unshuffle(x[1]);
ulong num3 = (num & 0xFFFFFFFFu) | (num2 << 32);
ulong num4 = (num >> 32) | (num2 & 0xFFFFFFFF00000000uL);
num = Interleave.Unshuffle(x[2]);
num2 = Interleave.Unshuffle(x[3]);
ulong num5 = (num & 0xFFFFFFFFu) | (num2 << 32);
ulong num6 = (num >> 32) | (num2 & 0xFFFFFFFF00000000uL);
num = Interleave.Unshuffle(x[4]);
num2 = Interleave.Unshuffle(x[5]);
ulong num7 = (num & 0xFFFFFFFFu) | (num2 << 32);
ulong num8 = (num >> 32) | (num2 & 0xFFFFFFFF00000000uL);
num = Interleave.Unshuffle(x[6]);
ulong num9 = num & 0xFFFFFFFFu;
ulong num10 = num >> 32;
z[0] = num3 ^ (num4 << 44);
z[1] = num5 ^ (num6 << 44) ^ (num4 >> 20);
z[2] = num7 ^ (num8 << 44) ^ (num6 >> 20);
z[3] = num9 ^ (num10 << 44) ^ (num8 >> 20) ^ (num4 << 13);
z[4] = (num10 >> 20) ^ (num6 << 13) ^ (num4 >> 51);
z[5] = (num8 << 13) ^ (num6 >> 51);
z[6] = (num10 << 13) ^ (num8 >> 51);
}
public static void Square(ulong[] x, ulong[] z)
{
ulong[] array = Nat.Create64(13);
ImplSquare(x, array);
Reduce(array, z);
}
public static void SquareAddToExt(ulong[] x, ulong[] zz)
{
ulong[] array = Nat.Create64(13);
ImplSquare(x, array);
AddExt(zz, array, zz);
}
public static void SquareN(ulong[] x, int n, ulong[] z)
{
ulong[] array = Nat.Create64(13);
ImplSquare(x, array);
Reduce(array, z);
while (--n > 0)
{
ImplSquare(z, array);
Reduce(array, z);
}
}
public static uint Trace(ulong[] x)
{
return (uint)((int)x[0] & 1);
}
protected static void ImplCompactExt(ulong[] zz)
{
ulong num = zz[0];
ulong num2 = zz[1];
ulong num3 = zz[2];
ulong num4 = zz[3];
ulong num5 = zz[4];
ulong num6 = zz[5];
ulong num7 = zz[6];
ulong num8 = zz[7];
ulong num9 = zz[8];
ulong num10 = zz[9];
ulong num11 = zz[10];
ulong num12 = zz[11];
ulong num13 = zz[12];
ulong num14 = zz[13];
zz[0] = num ^ (num2 << 59);
zz[1] = (num2 >> 5) ^ (num3 << 54);
zz[2] = (num3 >> 10) ^ (num4 << 49);
zz[3] = (num4 >> 15) ^ (num5 << 44);
zz[4] = (num5 >> 20) ^ (num6 << 39);
zz[5] = (num6 >> 25) ^ (num7 << 34);
zz[6] = (num7 >> 30) ^ (num8 << 29);
zz[7] = (num8 >> 35) ^ (num9 << 24);
zz[8] = (num9 >> 40) ^ (num10 << 19);
zz[9] = (num10 >> 45) ^ (num11 << 14);
zz[10] = (num11 >> 50) ^ (num12 << 9);
zz[11] = (num12 >> 55) ^ (num13 << 4) ^ (num14 << 63);
zz[12] = (num13 >> 60) ^ (num14 >> 1);
zz[13] = 0uL;
}
protected static void ImplExpand(ulong[] x, ulong[] z)
{
ulong num = x[0];
ulong num2 = x[1];
ulong num3 = x[2];
ulong num4 = x[3];
ulong num5 = x[4];
ulong num6 = x[5];
ulong num7 = x[6];
z[0] = num & 0x7FFFFFFFFFFFFFFL;
z[1] = ((num >> 59) ^ (num2 << 5)) & 0x7FFFFFFFFFFFFFFL;
z[2] = ((num2 >> 54) ^ (num3 << 10)) & 0x7FFFFFFFFFFFFFFL;
z[3] = ((num3 >> 49) ^ (num4 << 15)) & 0x7FFFFFFFFFFFFFFL;
z[4] = ((num4 >> 44) ^ (num5 << 20)) & 0x7FFFFFFFFFFFFFFL;
z[5] = ((num5 >> 39) ^ (num6 << 25)) & 0x7FFFFFFFFFFFFFFL;
z[6] = (num6 >> 34) ^ (num7 << 30);
}
protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz)
{
ulong[] array = new ulong[7];
ulong[] array2 = new ulong[7];
ImplExpand(x, array);
ImplExpand(y, array2);
for (int i = 0; i < 7; i++)
{
ImplMulwAcc(array, array2[i], zz, i);
}
ImplCompactExt(zz);
}
protected static void ImplMulwAcc(ulong[] xs, ulong y, ulong[] z, int zOff)
{
ulong[] array = new ulong[8];
array[1] = y;
array[2] = array[1] << 1;
array[3] = array[2] ^ y;
array[4] = array[2] << 1;
array[5] = array[4] ^ y;
array[6] = array[3] << 1;
array[7] = array[6] ^ y;
for (int i = 0; i < 7; i++)
{
ulong num = xs[i];
uint num2 = (uint)num;
ulong num3 = 0uL;
ulong num4 = array[num2 & 7] ^ (array[(num2 >> 3) & 7] << 3);
int num5 = 54;
do
{
num2 = (uint)(num >> num5);
ulong num6 = array[num2 & 7] ^ (array[(num2 >> 3) & 7] << 3);
num4 ^= num6 << num5;
num3 ^= num6 >> -num5;
}
while ((num5 -= 6) > 0);
ulong[] array3;
ulong[] array2 = (array3 = z);
int num7 = zOff + i;
nint num8 = num7;
array2[num7] = array3[num8] ^ (num4 & 0x7FFFFFFFFFFFFFFL);
ulong[] array4 = (array3 = z);
int num9 = zOff + i + 1;
num8 = num9;
array4[num9] = array3[num8] ^ ((num4 >> 59) ^ (num3 << 5));
}
}
protected static void ImplSquare(ulong[] x, ulong[] zz)
{
for (int i = 0; i < 6; i++)
{
Interleave.Expand64To128(x[i], zz, i << 1);
}
zz[12] = Interleave.Expand32to64((uint)x[6]);
}
}

View File

@@ -0,0 +1,195 @@
using System;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT409FieldElement : AbstractF2mFieldElement
{
protected internal readonly ulong[] x;
public override bool IsOne => Nat448.IsOne64(x);
public override bool IsZero => Nat448.IsZero64(x);
public override string FieldName => "SecT409Field";
public override int FieldSize => 409;
public virtual int Representation => 2;
public virtual int M => 409;
public virtual int K1 => 87;
public virtual int K2 => 0;
public virtual int K3 => 0;
public SecT409FieldElement(BigInteger x)
{
if (x == null || x.SignValue < 0 || x.BitLength > 409)
{
throw new ArgumentException("value invalid for SecT409FieldElement", "x");
}
this.x = SecT409Field.FromBigInteger(x);
}
public SecT409FieldElement()
{
x = Nat448.Create64();
}
protected internal SecT409FieldElement(ulong[] x)
{
this.x = x;
}
public override bool TestBitZero()
{
return (x[0] & 1) != 0;
}
public override BigInteger ToBigInteger()
{
return Nat448.ToBigInteger64(x);
}
public override ECFieldElement Add(ECFieldElement b)
{
ulong[] z = Nat448.Create64();
SecT409Field.Add(x, ((SecT409FieldElement)b).x, z);
return new SecT409FieldElement(z);
}
public override ECFieldElement AddOne()
{
ulong[] z = Nat448.Create64();
SecT409Field.AddOne(x, z);
return new SecT409FieldElement(z);
}
public override ECFieldElement Subtract(ECFieldElement b)
{
return Add(b);
}
public override ECFieldElement Multiply(ECFieldElement b)
{
ulong[] z = Nat448.Create64();
SecT409Field.Multiply(x, ((SecT409FieldElement)b).x, z);
return new SecT409FieldElement(z);
}
public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
return MultiplyPlusProduct(b, x, y);
}
public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] y2 = ((SecT409FieldElement)b).x;
ulong[] array2 = ((SecT409FieldElement)x).x;
ulong[] y3 = ((SecT409FieldElement)y).x;
ulong[] array3 = Nat.Create64(13);
SecT409Field.MultiplyAddToExt(array, y2, array3);
SecT409Field.MultiplyAddToExt(array2, y3, array3);
ulong[] z = Nat448.Create64();
SecT409Field.Reduce(array3, z);
return new SecT409FieldElement(z);
}
public override ECFieldElement Divide(ECFieldElement b)
{
return Multiply(b.Invert());
}
public override ECFieldElement Negate()
{
return this;
}
public override ECFieldElement Square()
{
ulong[] z = Nat448.Create64();
SecT409Field.Square(x, z);
return new SecT409FieldElement(z);
}
public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
{
return SquarePlusProduct(x, y);
}
public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
{
ulong[] array = this.x;
ulong[] array2 = ((SecT409FieldElement)x).x;
ulong[] y2 = ((SecT409FieldElement)y).x;
ulong[] array3 = Nat.Create64(13);
SecT409Field.SquareAddToExt(array, array3);
SecT409Field.MultiplyAddToExt(array2, y2, array3);
ulong[] z = Nat448.Create64();
SecT409Field.Reduce(array3, z);
return new SecT409FieldElement(z);
}
public override ECFieldElement SquarePow(int pow)
{
if (pow < 1)
{
return this;
}
ulong[] z = Nat448.Create64();
SecT409Field.SquareN(x, pow, z);
return new SecT409FieldElement(z);
}
public override int Trace()
{
return (int)SecT409Field.Trace(x);
}
public override ECFieldElement Invert()
{
ulong[] z = Nat448.Create64();
SecT409Field.Invert(x, z);
return new SecT409FieldElement(z);
}
public override ECFieldElement Sqrt()
{
ulong[] z = Nat448.Create64();
SecT409Field.Sqrt(x, z);
return new SecT409FieldElement(z);
}
public override bool Equals(object obj)
{
return Equals(obj as SecT409FieldElement);
}
public override bool Equals(ECFieldElement other)
{
return Equals(other as SecT409FieldElement);
}
public virtual bool Equals(SecT409FieldElement other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
return Nat448.Eq64(x, other.x);
}
public override int GetHashCode()
{
return 0x3E68E7 ^ Arrays.GetHashCode(x, 0, 7);
}
}

View File

@@ -0,0 +1,133 @@
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT409K1Curve : AbstractF2mCurve
{
private class SecT409K1LookupTable : ECLookupTable
{
private readonly SecT409K1Curve m_outer;
private readonly ulong[] m_table;
private readonly int m_size;
public virtual int Size => m_size;
internal SecT409K1LookupTable(SecT409K1Curve outer, ulong[] table, int size)
{
m_outer = outer;
m_table = table;
m_size = size;
}
public virtual ECPoint Lookup(int index)
{
ulong[] array = Nat448.Create64();
ulong[] array2 = Nat448.Create64();
int num = 0;
for (int i = 0; i < m_size; i++)
{
ulong num2 = (ulong)((i ^ index) - 1 >> 31);
for (int j = 0; j < 7; j++)
{
ulong[] array4;
ulong[] array3 = (array4 = array);
int num3 = j;
nint num4 = num3;
array3[num3] = array4[num4] ^ (m_table[num + j] & num2);
ulong[] array5 = (array4 = array2);
int num5 = j;
num4 = num5;
array5[num5] = array4[num4] ^ (m_table[num + 7 + j] & num2);
}
num += 14;
}
return m_outer.CreateRawPoint(new SecT409FieldElement(array), new SecT409FieldElement(array2), withCompression: false);
}
}
private const int SECT409K1_DEFAULT_COORDS = 6;
private const int SECT409K1_FE_LONGS = 7;
protected readonly SecT409K1Point m_infinity;
public override ECPoint Infinity => m_infinity;
public override int FieldSize => 409;
public override bool IsKoblitz => true;
public virtual int M => 409;
public virtual bool IsTrinomial => true;
public virtual int K1 => 87;
public virtual int K2 => 0;
public virtual int K3 => 0;
public SecT409K1Curve()
: base(409, 87, 0, 0)
{
m_infinity = new SecT409K1Point(this, null, null);
m_a = FromBigInteger(BigInteger.Zero);
m_b = FromBigInteger(BigInteger.One);
m_order = new BigInteger(1, Hex.Decode("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF"));
m_cofactor = BigInteger.ValueOf(4L);
m_coord = 6;
}
protected override ECCurve CloneCurve()
{
return new SecT409K1Curve();
}
public override bool SupportsCoordinateSystem(int coord)
{
if (coord == 6)
{
return true;
}
return false;
}
protected override ECMultiplier CreateDefaultMultiplier()
{
return new WTauNafMultiplier();
}
public override ECFieldElement FromBigInteger(BigInteger x)
{
return new SecT409FieldElement(x);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression)
{
return new SecT409K1Point(this, x, y, withCompression);
}
protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
{
return new SecT409K1Point(this, x, y, zs, withCompression);
}
public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len)
{
ulong[] array = new ulong[len * 7 * 2];
int num = 0;
for (int i = 0; i < len; i++)
{
ECPoint eCPoint = points[off + i];
Nat448.Copy64(((SecT409FieldElement)eCPoint.RawXCoord).x, 0, array, num);
num += 7;
Nat448.Copy64(((SecT409FieldElement)eCPoint.RawYCoord).x, 0, array, num);
num += 7;
}
return new SecT409K1LookupTable(this, array, len);
}
}

View File

@@ -0,0 +1,259 @@
using System;
namespace Org.BouncyCastle.Math.EC.Custom.Sec;
internal class SecT409K1Point : AbstractF2mPoint
{
public override ECFieldElement YCoord
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
if (base.IsInfinity || rawXCoord.IsZero)
{
return rawYCoord;
}
ECFieldElement eCFieldElement = rawYCoord.Add(rawXCoord).Multiply(rawXCoord);
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
if (!eCFieldElement2.IsOne)
{
eCFieldElement = eCFieldElement.Divide(eCFieldElement2);
}
return eCFieldElement;
}
}
protected internal override bool CompressionYTilde
{
get
{
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return false;
}
ECFieldElement rawYCoord = base.RawYCoord;
return rawYCoord.TestBitZero() != rawXCoord.TestBitZero();
}
}
public SecT409K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
public SecT409K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal SecT409K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new SecT409K1Point(null, AffineXCoord, AffineYCoord);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
if (rawXCoord.IsZero)
{
if (rawXCoord2.IsZero)
{
return curve.Infinity;
}
return b.Add(this);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement3 = rawXCoord2;
ECFieldElement eCFieldElement4 = rawYCoord2;
if (!isOne)
{
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement5 = rawXCoord;
ECFieldElement eCFieldElement6 = rawYCoord;
if (!isOne2)
{
eCFieldElement5 = eCFieldElement5.Multiply(eCFieldElement2);
eCFieldElement6 = eCFieldElement6.Multiply(eCFieldElement2);
}
ECFieldElement eCFieldElement7 = eCFieldElement6.Add(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement3);
if (eCFieldElement8.IsZero)
{
if (eCFieldElement7.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement10;
ECFieldElement y;
ECFieldElement eCFieldElement12;
if (rawXCoord2.IsZero)
{
ECPoint eCPoint = Normalize();
rawXCoord = eCPoint.XCoord;
ECFieldElement yCoord = eCPoint.YCoord;
ECFieldElement b2 = rawYCoord2;
ECFieldElement eCFieldElement9 = yCoord.Add(b2).Divide(rawXCoord);
eCFieldElement10 = eCFieldElement9.Square().Add(eCFieldElement9).Add(rawXCoord);
if (eCFieldElement10.IsZero)
{
return new SecT409K1Point(curve, eCFieldElement10, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement11 = eCFieldElement9.Multiply(rawXCoord.Add(eCFieldElement10)).Add(eCFieldElement10).Add(yCoord);
y = eCFieldElement11.Divide(eCFieldElement10).Add(eCFieldElement10);
eCFieldElement12 = curve.FromBigInteger(BigInteger.One);
}
else
{
eCFieldElement8 = eCFieldElement8.Square();
ECFieldElement eCFieldElement13 = eCFieldElement7.Multiply(eCFieldElement5);
ECFieldElement eCFieldElement14 = eCFieldElement7.Multiply(eCFieldElement3);
eCFieldElement10 = eCFieldElement13.Multiply(eCFieldElement14);
if (eCFieldElement10.IsZero)
{
return new SecT409K1Point(curve, eCFieldElement10, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement15 = eCFieldElement7.Multiply(eCFieldElement8);
if (!isOne2)
{
eCFieldElement15 = eCFieldElement15.Multiply(eCFieldElement2);
}
y = eCFieldElement14.Add(eCFieldElement8).SquarePlusProduct(eCFieldElement15, rawYCoord.Add(eCFieldElement));
eCFieldElement12 = eCFieldElement15;
if (!isOne)
{
eCFieldElement12 = eCFieldElement12.Multiply(eCFieldElement);
}
}
return new SecT409K1Point(curve, eCFieldElement10, y, new ECFieldElement[1] { eCFieldElement12 }, base.IsCompressed);
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return curve.Infinity;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement eCFieldElement3 = ((!isOne) ? rawYCoord.Add(eCFieldElement).Multiply(rawYCoord) : rawYCoord.Square().Add(rawYCoord));
if (eCFieldElement3.IsZero)
{
return new SecT409K1Point(curve, eCFieldElement3, curve.B, base.IsCompressed);
}
ECFieldElement eCFieldElement4 = eCFieldElement3.Square();
ECFieldElement eCFieldElement5 = (isOne ? eCFieldElement3 : eCFieldElement3.Multiply(eCFieldElement2));
ECFieldElement eCFieldElement6 = rawYCoord.Add(rawXCoord).Square();
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement2.Square());
ECFieldElement y = eCFieldElement6.Add(eCFieldElement3).Add(eCFieldElement2).Multiply(eCFieldElement6)
.Add(b)
.Add(eCFieldElement4)
.Add(eCFieldElement5);
return new SecT409K1Point(curve, eCFieldElement4, y, new ECFieldElement[1] { eCFieldElement5 }, base.IsCompressed);
}
public override ECPoint TwicePlus(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return b;
}
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement eCFieldElement = b.RawZCoords[0];
if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
{
return Twice().Add(b);
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement2 = base.RawZCoords[0];
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement x = rawXCoord.Square();
ECFieldElement eCFieldElement3 = rawYCoord.Square();
ECFieldElement eCFieldElement4 = eCFieldElement2.Square();
ECFieldElement b2 = rawYCoord.Multiply(eCFieldElement2);
ECFieldElement b3 = eCFieldElement3.Add(b2);
ECFieldElement eCFieldElement5 = rawYCoord2.AddOne();
ECFieldElement eCFieldElement6 = eCFieldElement5.Multiply(eCFieldElement4).Add(eCFieldElement3).MultiplyPlusProduct(b3, x, eCFieldElement4);
ECFieldElement eCFieldElement7 = rawXCoord2.Multiply(eCFieldElement4);
ECFieldElement eCFieldElement8 = eCFieldElement7.Add(b3).Square();
if (eCFieldElement8.IsZero)
{
if (eCFieldElement6.IsZero)
{
return b.Twice();
}
return curve.Infinity;
}
if (eCFieldElement6.IsZero)
{
return new SecT409K1Point(curve, eCFieldElement6, curve.B, base.IsCompressed);
}
ECFieldElement x2 = eCFieldElement6.Square().Multiply(eCFieldElement7);
ECFieldElement eCFieldElement9 = eCFieldElement6.Multiply(eCFieldElement8).Multiply(eCFieldElement4);
ECFieldElement y = eCFieldElement6.Add(eCFieldElement8).Square().MultiplyPlusProduct(b3, eCFieldElement5, eCFieldElement9);
return new SecT409K1Point(curve, x2, y, new ECFieldElement[1] { eCFieldElement9 }, base.IsCompressed);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawXCoord = base.RawXCoord;
if (rawXCoord.IsZero)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
return new SecT409K1Point(Curve, rawXCoord, rawYCoord.Add(eCFieldElement), new ECFieldElement[1] { eCFieldElement }, base.IsCompressed);
}
}

Some files were not shown because too many files have changed in this diff Show More