Как вычислить сложение точек с помощью Якобианской системы координат над эллиптическими кривыми

я пишу небольшой проект криптографии эллиптических кривых, и программа хорошо работает,когда я использую аффинную систему координат, что означает, что каждая точка представлена 2 координатами (x', y').

теперь я пытаюсь заменить аффинную систему координат якобианской системой координат,в которой каждая точка представлена 3 координатами (x,y, z), x' = x/z2 и y' = y/z3.

я хотел бы знать, как преобразование аффинных координат якобиан координат**. В некоторых учебники, люди используют формулу: (x,y) = (x, y, 1) что означает координата Z всегда равна единице. Но я не уверен, что это правильно.

затем для добавления точек по эллиптической кривой вычислить P(x1,y1,z1) + Q(x2,y2,z2) = R (x3,y3,z3). Я использовал следующие формулы в своей программе:

u1 = x1.z2²
u2 = x2.z1²
s1 = y1.z2³
s2 = y2.z1³
h = u2 - u1
r = s2 - s1
x3 = r² - h³ - 2.u1.h²
Y3 = r. (U1.h² - x3) - s1.h³
z3 = z1.z2.h

но когда я тестирую свою программу,я получаю некоторые отрицательные координаты, например (-2854978200, -5344897546224,578). И когда я пытаюсь преобразовать результат обратно в аффинную координату система с формулой (x '=x/z2,y'=y / z3), я получаю (-8545, -27679), на самом деле координата x равна -8545.689.... Координата якобиана x не делится на z2.

что делать, если координаты не являются целыми числами? А если они отрицательные? Я попытался изменить размер поля моей кривой, но результат тоже не правильный.

так в том и дело, используя якобиан координат (x,y,1) правильно, но не уникально. Все точки, удовлетворяющие (a^2.x,a^3.y,a) эквивалентны. И в моей программа кривая определяется в простом поле, поэтому, когда я вычисляю u1, u2, s1, s2 ... Я должен применить MOD p к каждой переменной?

и для преобразования конечного результата обратно в аффинные координаты, например координату x, на самом деле это не деление, это модульный обратный? например, моя кривая определена в конечном простом поле p=11 и у меня есть точки с помощью координат якобиан (15,3,2), чтобы преобразовать координату якобиана x в аффинную координату x, я должен вычислить 2^2 = 4 => x = 4^-1 mod p => x = 3 и 15.3 mod p = 1, значит, аффинная координата x равна 1, верно?

цель якобиан координат, чтобы избежать раскола в дополнение. Но как Томас Pornin сказал, Когда мы вычисляем P1 + P2 = P3, есть некоторые специальные случаи для обработки.

  1. P1 и P2 оба бесконечны: P3=infinite.
  2. P1 бесконечно:P3=P2.
  3. P2 бесконечно:P3=P1.
  4. P1 и P2 имеют одинаковую координату x, но разные y координаты или обе координаты y равны 0:P3=infinite.
  5. P1 и P2 имеют разные координаты x:Addition formula.
  6. P1 и P2 имеют одинаковые координаты: Doubling formula.

и вот прототипы моих функций C:

jac_addition(jacobian *, point *, jacobian *);
jac_doubling(jacobian *, jacobian *);

point - это структура, представляющая точку, определенную в аффинной системе координат, и jacobian для якобиана системы.

проблема в том, когда я обрабатываю эти особые случаи, особенно 4-й, я все еще есть преобразование обеих точек обратно в аффинные координаты, или я не могу сравнить их координаты, что означает, что мне все еще нужно вычислить деление.

3 ответов


Якобиева форма проективные координаты (как и любая другая форма) не является уникальным - для каждого значения Z (кроме 0) вы получаете другие X и Y без фактического изменения точки.

таким образом, если у вас есть точка в аффинных координатах (X', Y') пара (X', Y', 1) является проективным представителем этой точки, а также (4·X', 8·Y', 2), (9·X', 27·Y', 3), etc. Один с 1 легче всего создать,поэтому обычно вы будете использовать этот.

пока можно определите (и изучите) эллиптические кривые над любым полем, и многие математики изучают кривые, определенные над комплексными числами, для криптографических целей координаты являются элементами некоторого конечного поля. В простейшем случае у нас есть простое поле (т. е. целые числа по модулю простого числа), и вам придется делать сложение, вычитание, умножение и деление (и, возможно, возведение в степень) в этом поле.

пока Z не равно нулю, вы должны уметь делить на - это эквивалентно умножению на обратный Z2, и такой элемент существует и может быть эффективно вычислен с использованием расширенного евклидова алгоритма.

это проще всего, если ваш язык программирования поставляется с некоторой библиотекой больших чисел, которая имеет необходимые предопределенные операции, такие как Java BigInteger класса (с mod, modPow и modInverse методов).

рассматриваемое поле (т. е. модуль) является частью определения эллиптической кривой, и операции в одном поле дают совершенно иные результаты, чем операции в другом. Поэтому убедитесь, что вы используете правильное поле.


при работе с эллиптическими кривыми координаты находятся в поле. Для криптографии это конечное поле; в вашем случае " целые числа по модулю простого p". все операции подразумеваются в этом поле, т. е. вы должны делать каждое сложение, умножение или инверсию по модулю p.

при добавлении точек, есть несколько особых случаев, которые вы должны обрабатывать особенно:

  • существует специальная "точка на Бесконечности", которая не имеет координат x и y. Это "ноль" сложения кривой. В общей процедуре добавления точек вы должны иметь способ кодировать "точку на Бесконечности" и специально проверять ее.

  • при добавлении (x,y) to (x',y'), может случиться, что x = x'. В таком случае, либо y =y', и тогда это точка удвоения который имеет свою конкретную формулу (Если вы применяете общую формулу, вы в конечном итоге делите на ноль, что не будет работать); или, y = - y' в этом случае сумма является "точкой на бесконечности".

таким образом, общая формула должна применяться только после обработки специального случая. Во всей общности, в Кривой y2 = x3+a * x+b, сумма (x1, y1) и (x2, y2) is (x3, y3) такое, что x3 = f2 - x1 - x2 и y3 = f·(x1 - x3) - y1, где f = (y2 - y1)/(x2 - x1). Это предполагает вычисление одного деления и двух умножений и несколько вычитаний (все операции выполняются по целым числам по модулю p, как объяснено выше).

деление и инверсия по модулю p относительно дороги (модульное деление обычно имеет ту же стоимость, что и около 80 умножений), поэтому в некоторых ситуациях мы используем проективный или Якобианский системы координат. Якобиан координат о точку, как три значения (X,Y,Z) (все они в конечном поле, т. е. целые числа по модулю p) такие, что x = X / Z2 и y = Y / Z3.

каждая точка (x,y) имеет много возможных представлений как (X,Y,Z). Преобразование to Якобиан координат легко установив X = x, Y = y и Z = 1: (x,y,1) вполне допустимо Якобиана представление (x,y) точка. Преобразование С Якобиан координат в вычислительном отношении сложнее: вы должны сделать модульную инверсии, и несколько умножений (вычисления U = 1 / Z, потом x = X * U2 и y = Y * U3).

с Якобиан координат, сложение двух точек производится в десяти местах умножения и деления на всех. Вы получите только Якобиан представление результата, поэтому вам все равно придется сделать модульную инверсии или разделение в некоторой точке; (и вот зачем ты тащил через Якобиан координат), что деление может быть mutualized. Если вам нужно сделать сто или около того последовательных точечных дополнений (как это типично в криптографическом контексте, когда "умножаем" точку на целое число), то вы можете использовать Якобиан представительств по всей, и сделать одно преобразование обратно в декартовых координатах (x,y) в конце. Таким образом, вместо 200 умножений и 100 делений вы делаете 1000 умножений и 1 инверсию; поскольку инверсия стоит столько же, сколько 80 умножений, выигрыш заметен.

попробуйте воспользоваться книги; любая хорошая библиотека колледжа должна иметь один. Это все очень ясно объясняет.


вот пример в python:

def to_jacobian((Xp, Yp)):
    """
    Convert point to Jacobian coordinates

    :param (Xp,Yp,Zp): First Point you want to add
    :return: Point in Jacobian coordinates
    """
    return (Xp, Yp, 1)

def from_jacobian((Xp, Yp, Zp), P):
    """
    Convert point back from Jacobian coordinates

    :param (Xp,Yp,Zp): First Point you want to add
    :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p)
    :return: Point in default coordinates
    """
    z = inv(Zp, P)
    return ((Xp * z**2) % P, (Yp * z**3) % P)

def jacobian_add((Xp, Yp, Zp), (Xq, Yq, Zq), A, P):
    """
    Add two points in elliptic curves

    :param (Xp,Yp,Zp): First Point you want to add
    :param (Xq,Yq,Zq): Second Point you want to add
    :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p)
    :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p)
    :return: Point that represents the sum of First and Second Point
    """
    if not Yp:
        return (Xq, Yq, Zq)
    if not Yq:
        return (Xp, Yp, Zp)
    U1 = (Xp * Zq ** 2) % P
    U2 = (Xq * Zp ** 2) % P
    S1 = (Yp * Zq ** 3) % P
    S2 = (Yq * Zp ** 3) % P
    if U1 == U2:
        if S1 != S2:
            return (0, 0, 1)
        return jacobian_double((Xp, Yp, Zp), A, P)
    H = U2 - U1
    R = S2 - S1
    H2 = (H * H) % P
    H3 = (H * H2) % P
    U1H2 = (U1 * H2) % P
    nx = (R ** 2 - H3 - 2 * U1H2) % P
    ny = (R * (U1H2 - nx) - S1 * H3) % P
    nz = (H * Zp * Zq) % P
    return (nx, ny, nz)

таким образом, вы можете суммировать с:

def fast_add(a, b, A, P):
    return from_jacobian(jacobian_add(to_jacobian(a), to_jacobian(b), A, P), P)