using System; using System.Numerics; using ln.crypto.ec; // namespace Crypto.EC // { // public class ProjectiveCurvePoint // { // public static readonly ProjectiveCurvePoint INFINITY = new ProjectiveCurvePoint(null,1,0,0); // public BigInteger X { get; set; } // public BigInteger Y { get; set; } // public BigInteger Z { get; set; } // public EllipticCurve Curve { get; private set; } // public ProjectiveCurvePoint(CurvePoint p) // { // this.Curve = p.Curve; // this.X = p.X; // this.Y = p.Y; // this.Z = 1; // } // public ProjectiveCurvePoint(EllipticCurve curve,BigInteger x,BigInteger y,BigInteger z) // { // this.Curve = curve; // this.X = x; // this.Y = y; // this.Z = z; // } // public CurvePoint toCurvePoint(){ // if (Z.IsZero){ // return CurvePoint.INFINITY; // } // BigInteger iz = Euclid.inverse(Z, Curve.Fp.FieldModulo); // BigInteger nx = Curve.Fp.Fit(X * iz); // BigInteger ny = Curve.Fp.Fit(Y * iz); // return new CurvePoint(Curve, nx, ny); // } // public override bool Equals(object obj) // { // ProjectiveCurvePoint p = INFINITY; // return new BooleanConditional() // .requires(obj != null) // .requires(GetType().IsInstanceOfType(obj)) // .does( () => { p = (ProjectiveCurvePoint)obj; } ) // .requires(this.Curve == p.Curve) // .requires(this.X == p.X) // .requires(this.Y == p.Y) // .requires(this.Z == p.Z) // .isSuccess(); // } // public ProjectiveCurvePoint doubled() // { // BigInteger s = Curve.Fp.Fit(Y * Z); // BigInteger B = Curve.Fp.Fit(X * Y * s); // BigInteger w = Curve.Fp.Fit( // (Curve.a * BigInteger.Pow(Z,2)) + // (BigInteger.Pow(X,2) * 3) // ); // BigInteger h = Curve.Fp.Fit(w.Pow(2) - (B * 8)); // BigInteger xd = h * s * 2; // BigInteger yd = ( // (w * ((B * 4) - h)) - // (Y.Pow(2) * s.Pow(2) * 8) // ); // BigInteger zd = s.Pow(3) * 8; // xd = Curve.Fp.Fit(xd); // yd = Curve.Fp.Fit(yd); // zd = Curve.Fp.Fit(zd); // return new ProjectiveCurvePoint(Curve,xd,yd,zd); // } // public ProjectiveCurvePoint add(ProjectiveCurvePoint p){ // BigInteger u = Curve.Fp.Fit( (p.Y * Z) - (Y * p.Z) ); // BigInteger v = Curve.Fp.Fit( (p.X * Z) - (X * p.Z) ); // BigInteger A = Curve.Fp.Fit( // (Z * p.Z * u.Pow(2)) - v.Pow(3) - (v.Pow(2) * X * p.Z * 2) // ); // BigInteger xd = v * A; // BigInteger yd = ( // (u * ((X * p.Z * v.Pow(2)) - A)) - // (v.Pow(3) * Y * p.Z) // ); // BigInteger zd = Z * p.Z * v.Pow(3); // xd = Curve.Fp.Fit(xd); // yd = Curve.Fp.Fit(yd); // zd = Curve.Fp.Fit(zd); // if (zd == 0){ // return INFINITY; // } // return new ProjectiveCurvePoint(Curve, xd, yd, zd); // } // public ProjectiveCurvePoint Negated(){ // return new ProjectiveCurvePoint(Curve, X, Curve.Fp.AdditiveInverse(Y), Z); // } // public override string ToString() // { // return string.Format("[ProjectiveCurvePoint: Curve=... X={1} Y={2} Z={3}]", Curve,X,Y,Z); // } // public static implicit operator ProjectiveCurvePoint(CurvePoint p){ // return new ProjectiveCurvePoint(p); // } // public static ProjectiveCurvePoint operator +(ProjectiveCurvePoint p1, ProjectiveCurvePoint p2) // { // if ((object)p1 == INFINITY){ // return p2; // } else if ((object)p2 == INFINITY){ // return p1; // } else if (p1.Equals(p2)){ // return p1.doubled(); // } else { // return p1.add(p2); // } // } // public static ProjectiveCurvePoint operator -(ProjectiveCurvePoint p1, ProjectiveCurvePoint p2) // { // if ((object)p1 == INFINITY) // { // return p2; // } // else if ((object)p2 == INFINITY) // { // return p1; // } // return p1 + p2.Negated(); // } // public static ProjectiveCurvePoint operator *(ProjectiveCurvePoint p1, Integer n) // { // if ((object)p1 == (object)INFINITY) // { // return INFINITY; // } // if (p1.Y == BigInteger.Zero) // { // return INFINITY; // } // if (n.isZero()) // { // throw new NotImplementedException("CurevPoint * 0"); // } // ProjectiveCurvePoint result = null; // ProjectiveCurvePoint p = p1; // int i; // int bitwidth = n.Log2(); // if (bitwidth < 0) // { // bitwidth = -bitwidth; // } // for (i = 0; i < bitwidth; i++) // { // if (n[i]) // break; // p += p; // } // result = p; // for (i++; i <= bitwidth; i++) // { // p += p; // if (n[i]) // { // result = p + result; // } // } // return result; // } // } // }