Как вычислить сложение точек с помощью Якобианской системы координат над эллиптическими кривыми
я пишу небольшой проект криптографии эллиптических кривых, и программа хорошо работает,когда я использую аффинную систему координат, что означает, что каждая точка представлена 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
, есть некоторые специальные случаи для обработки.
- P1 и P2 оба бесконечны:
P3=infinite
. - P1 бесконечно:
P3=P2
. - P2 бесконечно:
P3=P1
. - P1 и P2 имеют одинаковую координату x, но разные y координаты или обе координаты y равны 0:
P3=infinite
. - P1 и P2 имеют разные координаты x:
Addition formula
. - 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
не равно нулю, вы должны уметь делить на 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)