/// <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)); }
/// <summary> /// Decrements value /// </summary> /// <param name="value1">The value to decrement</param> /// <returns>Decremented 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.Substraction(value.m_Value.m_Value, 1, value.m_Modulo.m_Value, items); return(new MIntBig(new IntBig(items), value.m_Modulo)); }
/// <summary> /// Subtracts a value from another value /// </summary> /// <param name="value1">The value to subtract from</param> /// <param name="value2">The value to subtract</param> /// <returns>The result of subtracting</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.Substraction(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)); }
/// <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)); }