<PackageReference Include="SSH.NET" Version="2020.0.2" />

ECPoint

abstract class ECPoint
using Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier; using System; using System.Collections; using System.Text; namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC { internal abstract class ECPoint { private class ValidityCallback : IPreCompCallback { private readonly ECPoint m_outer; private readonly bool m_decompressed; private readonly bool m_checkOrder; internal ValidityCallback(ECPoint outer, bool decompressed, bool checkOrder) { m_outer = outer; m_decompressed = decompressed; m_checkOrder = checkOrder; } public PreCompInfo Precompute(PreCompInfo existing) { ValidityPreCompInfo validityPreCompInfo = existing as ValidityPreCompInfo; if (validityPreCompInfo == null) validityPreCompInfo = new ValidityPreCompInfo(); if (validityPreCompInfo.HasFailed()) return validityPreCompInfo; if (!validityPreCompInfo.HasCurveEquationPassed()) { if (!m_decompressed && !m_outer.SatisfiesCurveEquation()) { validityPreCompInfo.ReportFailed(); return validityPreCompInfo; } validityPreCompInfo.ReportCurveEquationPassed(); } if (m_checkOrder && !validityPreCompInfo.HasOrderPassed()) { if (!m_outer.SatisfiesOrder()) { validityPreCompInfo.ReportFailed(); return validityPreCompInfo; } validityPreCompInfo.ReportOrderPassed(); } return validityPreCompInfo; } } protected static ECFieldElement[] EMPTY_ZS = new ECFieldElement[0]; protected internal readonly ECCurve m_curve; protected internal readonly ECFieldElement m_x; protected internal readonly ECFieldElement m_y; protected internal readonly ECFieldElement[] m_zs; protected internal readonly bool m_withCompression; protected internal IDictionary m_preCompTable; public virtual ECCurve Curve => m_curve; protected virtual int CurveCoordinateSystem { get { if (m_curve != null) return m_curve.CoordinateSystem; return 0; } } public virtual ECFieldElement AffineXCoord { get { CheckNormalized(); return XCoord; } } public virtual ECFieldElement AffineYCoord { get { CheckNormalized(); return YCoord; } } public virtual ECFieldElement XCoord => m_x; public virtual ECFieldElement YCoord => m_y; protected internal ECFieldElement RawXCoord => m_x; protected internal ECFieldElement RawYCoord => m_y; protected internal ECFieldElement[] RawZCoords => m_zs; public bool IsInfinity { get { if (m_x == null) return m_y == null; return false; } } public bool IsCompressed => m_withCompression; protected internal abstract bool CompressionYTilde { get; } protected static ECFieldElement[] GetInitialZCoords(ECCurve curve) { int num = curve?.CoordinateSystem ?? 0; if (num != 0 && num != 5) { ECFieldElement eCFieldElement = curve.FromBigInteger(BigInteger.One); switch (num) { case 1: case 2: case 6: return new ECFieldElement[1] { eCFieldElement }; case 3: return new ECFieldElement[3] { eCFieldElement, eCFieldElement, eCFieldElement }; case 4: return new ECFieldElement[2] { eCFieldElement, curve.A }; default: throw new ArgumentException("unknown coordinate system"); } } return EMPTY_ZS; } protected ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) : this(curve, x, y, GetInitialZCoords(curve), withCompression) { } internal ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) { m_curve = curve; m_x = x; m_y = y; m_zs = zs; m_withCompression = withCompression; } protected abstract bool SatisfiesCurveEquation(); protected virtual bool SatisfiesOrder() { if (BigInteger.One.Equals(Curve.Cofactor)) return true; BigInteger order = Curve.Order; if (order != null) return ECAlgorithms.ReferenceMultiply(this, order).IsInfinity; return true; } public ECPoint GetDetachedPoint() { return Normalize().Detach(); } protected abstract ECPoint Detach(); public virtual ECFieldElement GetZCoord(int index) { if (index >= 0 && index < m_zs.Length) return m_zs[index]; return null; } public virtual ECFieldElement[] GetZCoords() { int num = m_zs.Length; if (num == 0) return m_zs; ECFieldElement[] array = new ECFieldElement[num]; Array.Copy(m_zs, 0, array, 0, num); return array; } protected virtual void CheckNormalized() { if (!IsNormalized()) throw new InvalidOperationException("point not in normal form"); } public virtual bool IsNormalized() { int curveCoordinateSystem = CurveCoordinateSystem; if (curveCoordinateSystem != 0 && curveCoordinateSystem != 5 && !IsInfinity) return RawZCoords[0].IsOne; return true; } public virtual ECPoint Normalize() { if (IsInfinity) return this; int curveCoordinateSystem = CurveCoordinateSystem; if (curveCoordinateSystem == 0 || curveCoordinateSystem == 5) return this; ECFieldElement eCFieldElement = RawZCoords[0]; if (eCFieldElement.IsOne) return this; return Normalize(eCFieldElement.Invert()); } internal virtual ECPoint Normalize(ECFieldElement zInv) { switch (CurveCoordinateSystem) { case 1: case 6: return CreateScaledPoint(zInv, zInv); case 2: case 3: case 4: { ECFieldElement eCFieldElement = zInv.Square(); ECFieldElement sy = eCFieldElement.Multiply(zInv); return CreateScaledPoint(eCFieldElement, sy); } default: throw new InvalidOperationException("not a projective coordinate system"); } } protected virtual ECPoint CreateScaledPoint(ECFieldElement sx, ECFieldElement sy) { return Curve.CreateRawPoint(RawXCoord.Multiply(sx), RawYCoord.Multiply(sy), IsCompressed); } public bool IsValid() { return ImplIsValid(false, true); } internal bool IsValidPartial() { return ImplIsValid(false, false); } internal bool ImplIsValid(bool decompressed, bool checkOrder) { if (IsInfinity) return true; ValidityCallback callback = new ValidityCallback(this, decompressed, checkOrder); return !((ValidityPreCompInfo)Curve.Precompute(this, ValidityPreCompInfo.PRECOMP_NAME, callback)).HasFailed(); } public virtual ECPoint ScaleX(ECFieldElement scale) { if (!IsInfinity) return Curve.CreateRawPoint(RawXCoord.Multiply(scale), RawYCoord, RawZCoords, IsCompressed); return this; } public virtual ECPoint ScaleY(ECFieldElement scale) { if (!IsInfinity) return Curve.CreateRawPoint(RawXCoord, RawYCoord.Multiply(scale), RawZCoords, IsCompressed); return this; } public override bool Equals(object obj) { return Equals(obj as ECPoint); } public virtual bool Equals(ECPoint other) { if (this == other) return true; if (other == null) return false; ECCurve curve = Curve; ECCurve curve2 = other.Curve; bool flag = curve == null; bool flag2 = curve2 == null; bool isInfinity = IsInfinity; bool isInfinity2 = other.IsInfinity; if (isInfinity | isInfinity2) { if (isInfinity & isInfinity2) { if (!(flag | flag2)) return curve.Equals(curve2); return true; } return false; } ECPoint eCPoint = this; ECPoint eCPoint2 = other; if (!(flag & flag2)) { if (flag) eCPoint2 = eCPoint2.Normalize(); else if (flag2) { eCPoint = eCPoint.Normalize(); } else { if (!curve.Equals(curve2)) return false; ECPoint[] array = new ECPoint[2] { this, curve.ImportPoint(eCPoint2) }; curve.NormalizeAll(array); eCPoint = array[0]; eCPoint2 = array[1]; } } if (eCPoint.XCoord.Equals(eCPoint2.XCoord)) return eCPoint.YCoord.Equals(eCPoint2.YCoord); return false; } public override int GetHashCode() { ECCurve curve = Curve; int num = (curve != null) ? (~curve.GetHashCode()) : 0; if (!IsInfinity) { ECPoint eCPoint = Normalize(); num ^= eCPoint.XCoord.GetHashCode() * 17; num ^= eCPoint.YCoord.GetHashCode() * 257; } return num; } public override string ToString() { if (IsInfinity) return "INF"; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append('('); stringBuilder.Append(RawXCoord); stringBuilder.Append(','); stringBuilder.Append(RawYCoord); for (int i = 0; i < m_zs.Length; i++) { stringBuilder.Append(','); stringBuilder.Append(m_zs[i]); } stringBuilder.Append(')'); return stringBuilder.ToString(); } public virtual byte[] GetEncoded() { return GetEncoded(m_withCompression); } public abstract byte[] GetEncoded(bool compressed); public abstract ECPoint Add(ECPoint b); public abstract ECPoint Subtract(ECPoint b); public abstract ECPoint Negate(); public virtual ECPoint TimesPow2(int e) { if (e < 0) throw new ArgumentException("cannot be negative", "e"); ECPoint eCPoint = this; while (--e >= 0) { eCPoint = eCPoint.Twice(); } return eCPoint; } public abstract ECPoint Twice(); public abstract ECPoint Multiply(BigInteger b); public virtual ECPoint TwicePlus(ECPoint b) { return Twice().Add(b); } public virtual ECPoint ThreeTimes() { return TwicePlus(this); } } }