//Сумма 2-х точек //a4=A //a6=B //a1,a2,a3=0 ec_point ec_point::operator +(ec_point op2){ ec_curve * ec_singleton = ec_curve::Instance(); ZZ x3,y3,lambda,nu; //Обработка случаев, если среди операндов нуль группы if (is_infinity() && op2.is_infinity()) return ec_point(true); if (is_infinity()) return ec_point(op2.x,op2.y); if (op2.is_infinity()) return ec_point(x,y); //Нулей нет, дальше всё по Вейерштрассу if ((x==op2.x) && (y==NegateMod(op2.y,ec_singleton->p))) { //Если две противоположные точки, результатом будет нуль группы return ec_point(true); } else { if (x!=op2.x) { //Если сладываем две разные точки lambda = (((op2.y-y)%ec_singleton->p) * InvMod((op2.x-x)%ec_singleton->p,ec_singleton->p))%ec_singleton->p; } else { //Если удваиваем точку lambda = ((3*x*x+ec_singleton->A)%ec_singleton->p * InvMod((2*y)%ec_singleton->p,ec_singleton->p))%ec_singleton->p; } x3 = (lambda*lambda - x - op2.x)%ec_singleton->p; y3 = (lambda*(x-x3)-y)%ec_singleton->p; return ec_point(x3,y3); } }
//Функция для использования в бинарном поиске //Считает одинаковыми точку и обратную ей ( x-координаты совпадают) //Порядок задаётся сравнением x-координаты точек //Нуль группы считается меньше любой точки int ec_compare_bs(ec_point ec1, ec_point ec2) { if (!ec1.is_infinity() && !ec2.is_infinity()) { if (ec1.x>ec2.x) return 1; else if (ec1.x<ec2.x) return -1; else if (ec1.x==ec2.x) { return 0; } } else if (ec1.is_infinity() && ec2.is_infinity()) return 0; else if (ec1.is_infinity() && !ec2.is_infinity()) return -1; else if (!ec1.is_infinity() && ec2.is_infinity()) return 1; }