예제 #1
0
        public FastECPoint Multiply(FastInteger b)
        {
            if (b.Sign == -1)
            {
                throw new FormatException("The multiplicator cannot be negative");
            }

            //b = b % Secp256k1.N;
            FastInteger exp      = (b * 3) ^ b;
            FastECPoint result   = FastECPoint.Infinity;
            FastECPoint affine   = this.Normalize();
            FastECPoint negative = affine.Negate();

            int         high = exp.BitsCount;
            FastInteger bit  = FastInteger.One << high;

            for (int i = high; --i >= 0; bit >>= 1)
            {
                result = result.Twice();
                if (!(exp & bit).IsZero)
                {
                    result = result.Add(!(b & bit).IsZero ? negative : affine);
                }
            }

            result = result.Normalize();
            return(result);
        }
예제 #2
0
        public FastECPoint Negate()
        {
            FastECPoint r = (FastECPoint)Clone();

            r._y = Secp256k1.FP - r._y;
            return(r);
        }
예제 #3
0
        public FastECPoint Normalize()
        {
            if (this.Z == FastInteger.One || this.IsInfinity)
            {
                return(this);
            }
            var inverse       = this.Z.ModInverse(Secp256k1.FP);
            var squareInverse = modP(inverse.Square());
            var power3Inverse = modP(inverse * squareInverse);
            var x             = modP(this.X * squareInverse);
            var y             = modP(this.Y * power3Inverse);

            remodP(ref x);
            remodP(ref y);
            var result = new FastECPoint(x, y, this.IsInfinity);

            return(result);
        }
예제 #4
0
        //if (Y == 0)
        //  return POINT_AT_INFINITY
        //S = 4*X*Y^2
        //M = 3*X^2 + a*Z^4
        //X' = M^2 - 2*S
        //Y' = M*(S - X') - 8*Y^4
        //Z' = 2*Y*Z
        //return (X', Y', Z')
        public FastECPoint Twice()
        {   // (3M + 4S)
            if (this.Y.IsZero || this.IsInfinity)
            {
                return(FastECPoint.Infinity);
            }
            var y2 = modP(this.Y.Square());
            var S  = modP(this.X * y2 << 2);
            var M  = this.X.Square();

            M = modP(M + (M << 1));
            var x      = modP(M.Square() - (S << 1));
            var y      = modP(M * (S - x) - (y2.Square() << 3));
            var z      = modP(this.Z * (this.Y << 1));
            var result = new FastECPoint(x, y, z, false);

            return(result);
        }
예제 #5
0
        //U1 = X1*Z2^2
        //U2 = X2*Z1^2
        //S1 = Y1*Z2^3
        //S2 = Y2*Z1^3
        //if (U1 == U2)
        //  if (S1 != S2)
        //    return POINT_AT_INFINITY
        //  else
        //    return POINT_DOUBLE(X1, Y1, Z1)
        //H = U2 - U1
        //R = S2 - S1
        //X3 = R^2 - H^3 - 2*U1*H^2
        //Y3 = R*(U1*H^2 - X3) - S1*H^3
        //Z3 = H*Z1*Z2
        //return (X3, Y3, Z3)
        public FastECPoint Add(FastECPoint q)
        {   // (8M + 3S)
            if (this.IsInfinity)
            {
                return(q);
            }
            if (q.IsInfinity)
            {
                return(this);
            }

            var z2 = modP(this.Z.Square());
            var z3 = modP(z2 * this.Z);
            var U2 = modP(q.X * z2);
            var S2 = modP(q.Y * z3);
            var H  = U2 - this.X;
            var R  = S2 - this.Y;

            if (H.IsZero)
            {
                if (!R.IsZero)
                {
                    return(FastECPoint.Infinity);
                }
                return(this.Twice());
            }

            var H2 = modP(H.Square());
            var H3 = modP(H2 * H);
            var U1 = modP(this.X * H2);

            var X3     = modP(R.Square() - (H3 + (U1 << 1)));
            var Y3     = modP(R * (U1 - X3) - this.Y * H3);
            var Z3     = modP(H * this.Z);
            var result = new FastECPoint(X3, Y3, Z3, false);

            return(result);
        }
예제 #6
0
 public FastECPoint Subtract(FastECPoint b)
 {
     return(Add(b.Negate()));
 }
예제 #7
0
        public override ECPoint ECMultiplication(BigInteger factor)
        {
            FastECPoint result = Secp256k1.FG.Multiply(new FastInteger(factor.ToByteArray()));

            return(new ECPoint(new BigInteger(result.X.ToByteArray()), new BigInteger(result.Y.ToByteArray())));
        }