Пример #1
0
        /// <summary>
        /// Doubling the point in elliptic curve
        /// </summary>
        /// <returns></returns>
        public IEllipticCurvePoint Doubling()
        {
            if (Infinity)
            {
                return(GetInfinity());
            }
            // Coordinates
            uint[] a                 = m_a4.m_Value;
            uint[] b                 = m_a6.m_Value;
            uint[] x                 = m_X.m_Value;
            uint[] y                 = m_Y.m_Value;
            uint[] z                 = m_Z.m_Value;
            uint[] modulo            = m_Modulo.m_Value;
            int    maxModuloBitIndex = BigHelper.MaxNonZeroBitIndex(modulo);
            int    length            = modulo.Length;

            // Get the cache
            uint[] cache = new uint[length * 2];
            uint[] s     = new uint[length];
            uint[] m     = new uint[length];

            uint[] x1 = new uint[length];
            uint[] y1 = new uint[length];
            uint[] z1 = new uint[length];


            // X^2
            ModuloOperations.Multiply(x, x, modulo, x1, cache);
            // Z^2
            ModuloOperations.Multiply(z, z, modulo, y1, cache);
            // Z1 = Z^2*X^2
            ModuloOperations.Multiply(x1, y1, modulo, z1, cache);

            // X^4
            ModuloOperations.Multiply(x1, x1, modulo, x1, cache);
            // Z^4
            ModuloOperations.Multiply(y1, y1, modulo, y1, cache);
            // b*Z^4
            ModuloOperations.Multiply(y1, y1, modulo, y1, cache);
            // X1 = X^4 + b*Z^4
            ModuloOperations.Addition(x1, y1, modulo);

            // a*Z1
            ModuloOperations.Multiply(z1, a, modulo, s, cache);
            // Y^2
            ModuloOperations.Multiply(y, y, modulo, m, cache);
            // a*Z1 + Y^2
            ModuloOperations.Addition(s, m, modulo);
            // a*Z1 + Y^2 + b*Z^4
            ModuloOperations.Addition(s, y1, modulo);
            // X1*(a*Z1 + Y^2 + b*Z^4)
            ModuloOperations.Multiply(s, x1, modulo, s, cache);
            // b*Z^4*Z1
            ModuloOperations.Multiply(y1, z1, modulo, y1, cache);

            // Y1 = b*Z^4*Z1 + X1*(a*Z1 + Y^2 + b*Z^4)
            ModuloOperations.Addition(y1, s, modulo);

            return(new EllipticCurvePointC(x1, y1, z1, this));
        }
Пример #2
0
        /// <summary>
        /// Удвоить точку на кривой
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public IEllipticCurvePoint Doubling()
        {
            if (m_Y.Zero)
            {
                return(GetInfinity());
            }
            // Исходные координаты
            uint[] a                 = m_a4.m_Value;
            uint[] x                 = m_X.m_Value;
            uint[] y                 = m_Y.m_Value;
            uint[] z                 = m_Z.m_Value;
            uint[] modulo            = m_Modulo.m_Value;
            int    maxModuloBitIndex = BigHelper.MaxNonZeroBitIndex(modulo);
            int    length            = modulo.Length;

            // Выделим кэш операций умножения
            uint[] cache = new uint[length * 2];
            uint[] s     = new uint[length];
            uint[] m     = new uint[length];

            uint[] x1 = new uint[length];
            uint[] y1 = new uint[length];
            uint[] z1 = new uint[length];

            // Расчитаем m
            // Первое слагаемое a*Z1^4
            ModuloOperations.Multiply(z, z, modulo, z1, cache);
            ModuloOperations.Multiply(z1, z1, modulo, z1, cache);
            ModuloOperations.Multiply(z1, a, modulo, z1, cache);
            // Второе слагаемое 3*X1^2
            ModuloOperations.Multiply(x, x, modulo, m, cache);
            ModuloOperations.Multiply(m, 3, modulo, m, cache);
            // Результат m = 3*X1^2 + a*Z1^4
            ModuloOperations.Addition(m, z1, modulo);

            // Расчитаем s = 4*X1*Y1^2
            ModuloOperations.Multiply(y, y, modulo, z1, cache);

            ModuloOperations.Multiply(z1, x, modulo, s, cache);
            ModuloOperations.Multiply(s, 4, modulo, s, cache);

            // Расчитаем X3 = m^2 - 2*s
            ModuloOperations.Multiply(m, m, modulo, x1, cache);
            ModuloOperations.Multiply(s, 2, modulo, y1, cache);
            ModuloOperations.Substraction(x1, y1, modulo);

            // Расчитаем Y3 = m*(s - X3) - 8*Y1^4
            ModuloOperations.Multiply(z1, z1, modulo, z1, cache);
            ModuloOperations.Multiply(z1, 8, modulo, z1, cache);

            ModuloOperations.Substraction(s, x1, modulo, y1);
            ModuloOperations.Multiply(y1, m, modulo, y1, cache);
            ModuloOperations.Substraction(y1, z1, modulo);

            // Расчитаем Z3 = 2*Y1*Z1
            ModuloOperations.Multiply(y, z, modulo, z1, cache);
            ModuloOperations.Multiply(z1, 2, modulo, z1, cache);

            return(new EllipticCurvePointB(x1, y1, z1, this));
        }
Пример #3
0
 /// <summary>
 /// Invert this value at elliptic curve
 /// </summary>
 /// <returns></returns>
 public IEllipticCurvePoint Invert()
 {
     if (m_Y.Zero)
     {
         return(GetInfinity());
     }
     uint[] items = new uint[m_Modulo.m_Value.Length];
     ModuloOperations.Addition(m_X.m_Value, m_Y.m_Value, m_Modulo.m_Value, items);
     return(new EllipticCurvePointC(m_X, new IntBig(items), m_Z, this));
 }
Пример #4
0
 /// <summary>
 ///  Increments the value
 /// </summary>
 /// <param name="value">The value to increment</param>
 /// <returns>Incremented value</returns>
 public static MIntBig operator ++(MIntBig value)
 {
     if (value as object == null)
     {
         throw new ArgumentNullException("value");
     }
     uint[] items = new uint[value.m_Modulo.m_Value.Length];
     ModuloOperations.Addition(value.m_Value.m_Value, 1, value.m_Modulo.m_Value, items);
     return(new MIntBig(new IntBig(items), value.m_Modulo));
 }
Пример #5
0
 /// <summary>
 /// Raises value to the power of a specified value
 /// </summary>
 /// <param name="value">The number to raise to the exponent power</param>
 /// <param name="degree">The exponent to raise value by</param>
 /// <returns>The result of raising value to the exponent power</returns>
 public static MIntBig Pow(MIntBig value, int degree)
 {
     if (value as object == null)
     {
         throw new ArgumentNullException("value");
     }
     if (value.Zero)
     {
         return(new MIntBig(value.m_Value, value.m_Modulo));
     }
     return(new MIntBig(new IntBig(ModuloOperations.Pow(value.m_Value.m_Value, value.m_Modulo.m_Value, degree)), value.m_Modulo));
 }
Пример #6
0
 /// <summary>
 /// Invert
 /// </summary>
 /// <remarks>
 /// value^(-1)
 /// </remarks>
 /// <param name="value">The value to invert</param>
 /// <returns>The result of the invert</returns>
 public static MIntBig operator ~(MIntBig value)
 {
     if (value as object == null)
     {
         throw new ArgumentNullException("value");
     }
     if (value.Zero)
     {
         throw new DivideByZeroException("value");
     }
     uint[] items = new uint[value.m_Modulo.m_Value.Length];
     ModuloOperations.Invert(value.m_Value.m_Value, value.m_Modulo.m_Value, items);
     return(new MIntBig(new IntBig(items), value.m_Modulo));
 }
Пример #7
0
 /// <summary>
 /// Multiplies two values
 /// </summary>
 /// <param name="value1">First multiplier</param>
 /// <param name="value2">Second multiplier</param>
 /// <returns>Result value</returns>
 public static MIntBig operator *(MIntBig value1, MIntBig value2)
 {
     if (value1 as object == null)
     {
         throw new ArgumentNullException("value1");
     }
     if (value2 as object == null)
     {
         throw new ArgumentNullException("value2");
     }
     if (value1.m_Modulo != value2.m_Modulo)
     {
         throw new Exception("Modules not equal!");
     }
     uint[] items = new uint[value1.m_Modulo.m_Value.Length];
     ModuloOperations.Multiply(value1.m_Value.m_Value, value2.m_Value.m_Value, value1.m_Modulo.m_Value, items);
     return(new MIntBig(new IntBig(items), value1.m_Modulo));
 }
Пример #8
0
 /// <summary>
 /// Shifts the value a to the right
 /// </summary>
 /// <param name="value">The value whose bits are to be shifted</param>
 /// <param name="shift">The number of bits to shift value to the right</param>
 /// <returns>A value that has been shifted to the right by the specified number of bits</returns>
 public static MIntBig operator >>(MIntBig value, int shift)
 {
     if (value as object == null)
     {
         throw new ArgumentNullException("value");
     }
     shift %= value.m_Value.Length;
     if (shift < 0)
     {
         shift += value.m_Value.Length;
     }
     if (!value.Zero && shift != 0)
     {
         uint[] items = new uint[value.m_Value.m_Value.Length];
         uint[] cache = new uint[value.m_Value.m_Value.Length * 2];
         ModuloOperations.RightShift(value.m_Value.m_Value, items, value.m_Modulo.m_Value, cache, shift);
         return(new MIntBig(new IntBig(items), value.m_Modulo));
     }
     else
     {
         return(new MIntBig(value.m_Value, value.m_Modulo));
     }
 }
Пример #9
0
        /// <summary>
        /// Adds the this value with another value in elliptic curve
        /// </summary>
        /// <param name="value">The value to add with this value</param>
        /// <returns>The sum of values</returns>
        public IEllipticCurvePoint Addition(IEllipticCurvePoint value)
        {
            EllipticCurvePointC value2 = value as EllipticCurvePointC;

            if (value2 as object == null)
            {
                throw new Exception("Incorrect point type!");
            }
            if (m_a4 != value2.m_a4 || m_a6 != value2.m_a6 || m_Modulo != value2.m_Modulo)
            {
                throw new Exception("Incorrect value elliptic curve parameters!");
            }
            if (value2.Infinity)
            {
                return(new EllipticCurvePointC(m_X, m_Y, m_Z, this));
            }
            if (Infinity)
            {
                return(new EllipticCurvePointC(value2.m_X, value2.m_Y, value2.m_Z, value2));
            }
            if (Equals(value2))
            {
                return(Doubling());
            }
            // Coordinates
            uint[] a                 = m_a4.m_Value;
            uint[] x1                = m_X.m_Value;
            uint[] y1                = m_Y.m_Value;
            uint[] z1                = m_Z.m_Value;
            uint[] x2                = value2.m_X.m_Value;
            uint[] y2                = value2.m_Y.m_Value;
            uint[] z2                = value2.m_Z.m_Value;
            uint[] modulo            = m_Modulo.m_Value;
            int    maxModuloBitIndex = BigHelper.MaxNonZeroBitIndex(modulo);
            int    length            = modulo.Length;

            // Get the cache
            uint[] cache = new uint[length * 2];

            uint[] A = new uint[length];
            uint[] D = new uint[length];
            uint[] B = new uint[length];
            uint[] C = new uint[length];

            uint[] xr = new uint[length];
            uint[] yr = new uint[length];
            uint[] zr = new uint[length];
            // Z1^2
            ModuloOperations.Multiply(z1, z1, modulo, A, cache);
            // Z1^2 * a
            ModuloOperations.Multiply(z1, a, modulo, D, cache);
            // X2 * Z1
            ModuloOperations.Multiply(x2, z1, modulo, B, cache);
            // B = X2 * Z1 + X1
            ModuloOperations.Addition(B, x1, modulo);

            // C = Z1*B
            ModuloOperations.Multiply(z1, B, modulo, C, cache);

            // C + Z1^2 * a
            ModuloOperations.Addition(D, C, modulo);
            // B * (C + Z1^2 * a)
            ModuloOperations.Multiply(D, B, modulo, D, cache);
            // D = B^2 * (C + Z1^2 * a)
            ModuloOperations.Multiply(D, B, modulo, D, cache);

            // Y2 * Z1^2
            ModuloOperations.Multiply(A, y2, modulo, A, cache);
            // A =  Y2 * Z1^2 + Y1
            ModuloOperations.Addition(A, y1, modulo);

            if (BigHelper.IfZero(B))
            {
                if (BigHelper.IfZero(A))
                {
                    return(value2.Doubling());
                }
                else
                {
                    return(GetInfinity());
                }
            }

            // Z3 = C^2
            ModuloOperations.Multiply(C, C, modulo, zr, cache);

            // E = A * C
            ModuloOperations.Multiply(C, A, modulo, C, cache);

            // A^2
            ModuloOperations.Multiply(A, A, modulo, xr, cache);
            // A^2 + D
            ModuloOperations.Addition(xr, D, modulo);
            // X3 = A^2 + D + E
            ModuloOperations.Addition(xr, C, modulo);

            // X2 * Z3
            ModuloOperations.Multiply(x2, zr, modulo, A, cache);
            // F = X3 + X2 * Z3
            ModuloOperations.Addition(A, xr, modulo);

            // X2 + Y2
            ModuloOperations.Addition(x2, y2, modulo, B);
            // (X2 + Y2) * Z3
            ModuloOperations.Multiply(B, zr, modulo, B, cache);
            // G = (X2 + Y2) * Z3^2
            ModuloOperations.Multiply(B, zr, modulo, B, cache);

            // E + Z3
            ModuloOperations.Addition(C, zr, modulo, yr);
            // (E + Z3) * F
            ModuloOperations.Multiply(yr, A, modulo, yr, cache);
            // (E + Z3) * F + G
            ModuloOperations.Addition(yr, B, modulo, yr);

            return(new EllipticCurvePointC(xr, yr, zr, this));
        }
Пример #10
0
        /// <summary>
        /// Сложить две точки на кривой
        /// </summary>
        /// <param name="value1"></param>
        /// <param name="value2"></param>
        /// <returns></returns>
        public IEllipticCurvePoint Addition(IEllipticCurvePoint value)
        {
            EllipticCurvePointB value2 = value as EllipticCurvePointB;

            if (value2 as object == null)
            {
                throw new Exception("Incorrect point type!");
            }
            if (m_a4 != value2.m_a4 || m_a6 != value2.m_a6 || m_Modulo != value2.m_Modulo)
            {
                throw new Exception("Incorrect value elliptic curve parameters!");
            }

            if (Equals(value2))
            {
                return(Doubling());
            }
            // Исходные координаты
            uint[] a                 = m_a4.m_Value;
            uint[] x1                = m_X.m_Value;
            uint[] y1                = m_Y.m_Value;
            uint[] z1                = m_Z.m_Value;
            uint[] x2                = value2.m_X.m_Value;
            uint[] y2                = value2.m_Y.m_Value;
            uint[] z2                = value2.m_Z.m_Value;
            uint[] modulo            = m_Modulo.m_Value;
            int    maxModuloBitIndex = BigHelper.MaxNonZeroBitIndex(modulo);
            int    length            = modulo.Length;

            // Выделим кэш операций умножения
            uint[] cache = new uint[length * 2];
            // Временные переменные
            uint[] u1 = new uint[length];
            uint[] u2 = new uint[length];
            uint[] s1 = new uint[length];
            uint[] s2 = new uint[length];

            uint[] xr = new uint[length];
            uint[] yr = new uint[length];
            uint[] zr = new uint[length];
            // Вычислить U1, U2, S1, S2
            ModuloOperations.Multiply(z2, z2, modulo, u1, cache);
            ModuloOperations.Multiply(z1, z1, modulo, u2, cache);

            ModuloOperations.Multiply(u1, z2, modulo, s1, cache);
            ModuloOperations.Multiply(u2, z1, modulo, s2, cache);

            ModuloOperations.Multiply(u1, x1, modulo, u1, cache);
            ModuloOperations.Multiply(u2, x2, modulo, u2, cache);

            ModuloOperations.Multiply(s1, y1, modulo, s1, cache);
            ModuloOperations.Multiply(s2, y2, modulo, s2, cache);
            // Проверим, может расчет
            if (Eguals(u1, u2))
            {
                if (Eguals(s1, s2))
                {
                    return(Doubling());
                }
                else
                {
                    return(GetInfinity());
                }
            }
            ModuloOperations.Substraction(u2, u1, modulo);
            ModuloOperations.Substraction(s2, s1, modulo);
            //H^2
            ModuloOperations.Multiply(u2, u2, modulo, yr, cache);
            //H^3
            ModuloOperations.Multiply(yr, u2, modulo, zr, cache);
            //R^2
            ModuloOperations.Multiply(s2, s2, modulo, xr, cache);
            //R^2 - H^3
            ModuloOperations.Substraction(xr, zr, modulo);
            //U1*H^2
            ModuloOperations.Multiply(u1, yr, modulo, yr, cache);
            //2*U1*H^2
            ModuloOperations.Multiply(yr, 2, modulo, u1, cache);

            //X3 = R^2 - H^3 - 2*U1*H^2
            ModuloOperations.Substraction(xr, u1, modulo);

            //U1*H^2 - X3
            ModuloOperations.Substraction(yr, xr, modulo);
            //R*(U1*H^2 - X3)
            ModuloOperations.Multiply(yr, s2, modulo, yr, cache);
            //S1*H^3
            ModuloOperations.Multiply(s1, zr, modulo, zr, cache);
            //R*(U1*H^2 - X3) - S1*H^3
            ModuloOperations.Substraction(yr, zr, modulo);

            //Z1*Z2
            ModuloOperations.Multiply(z1, z2, modulo, zr, cache);
            //Z3 = H*Z1*Z2
            ModuloOperations.Multiply(zr, u2, modulo, zr, cache);

            return(new EllipticCurvePointB(xr, yr, zr, this));
        }