Python: порядок точек не является регулярным в реализации кривой мешанины

#python #elliptic-curve

#python #эллиптическая кривая

Вопрос:

Я реализовал кривую мешанины с помощью Python

 def checkPoint(P,p,c,d):
  
    #X^3   Y^3   cZ^3 = dXYZ over GF(p)
  
    if ( P[0]**3   P[1]**3   c * P[2]**3) % p == ( d * P[0] * P[1] * P[2] ) % p :
        return True
    
    return False
    
def bits(n):

    while n:
        yield n amp; 1
        n >>= 1
        
def point_add( P, Q , p) : 

    if P is None or Q is None: # check for the zero point
        return P or Q
     
    #12M   3add, consistent with the "12 multiplications" stated in 1986 Chudnovsky/Chudnovsky: 
    X3 = Q[0] * Q[2] * P[1]**2 - P[0] * P[2] * Q[1]**2
    Y3 = Q[1] * Q[2] * P[0]**2 - P[1] * P[2] * Q[0]**2
    Z3 = Q[0] * Q[1] * P[2]**2 - P[0] * P[1] * Q[2]**2

    return ( X3 % p, Y3 % p, Z3 % p)

def point_double(P, p, c): #6M   3S   3add, consistent with the "9 multiplications" stated in 1986 Chudnovsky/Chudnovsky:
    
    if P is None:
        return None 
    
    X3 = P[1] * ( P[2]**3 - P[0]**3 )
    Y3 = P[0] * ( P[1]**3 - P[2]**3 )
    Z3 = P[2] * ( P[0]**3 - P[1]**3 )  

    return ( X3 % p, Y3 % p, Z3 % p)

def doubleAndAdd( G, k , p ,c):

    addend = G
    result = None
    
    for b in bits(k) :
        if b:
            result = point_add(result, addend, p)
        addend = point_double(addend, p, c)
    return result

def findOrder(P, POI, p,c):
    
    for i in range(2,1104601): # 1104601 upper range on the number of points 
        res = doubleAndAdd(P,i,p,c)
        if res == POI:
            print( "[",i,"]", P, "= ", res )
            

p = 1051
c = 1
d = 6
G = (4,2,6)  #base point

Pinfinity = (1,1050,0) #(1,-1,0) inverse of O itself, inverse of (U,V,W) is (V,U,W)

print ( "d^3 == 27c? False expected : ", (d**3) % p == (27 *c) % p)

print("is point on the curve?", checkPoint(G,p,c,d))

findOrder(G, Pinfinity, p,c)
  

Когда я запускаю этот код, результатом является

 [ 77400 ] (4, 2, 6) =  (1, 1050, 0)
[ 103500 ] (4, 2, 6) =  (1, 1050, 0)
[ 153540 ] (4, 2, 6) =  (1, 1050, 0)
[ 164340 ] (4, 2, 6) =  (1, 1050, 0)
[ 169290 ] (4, 2, 6) =  (1, 1050, 0)
[ 233640 ] (4, 2, 6) =  (1, 1050, 0)
  

Обычно, если точка P имеет порядок k , то [k]P=O где O — точка на бесконечности. И если вы продолжите добавлять P к самому себе, получится [2k]P=O , в более общем случае это [ x mod k]P

Итак, если 77400 — это порядок, P тогда [154800]P=0 , но это не так

  • чего здесь не хватает, чтобы результат не соответствовал ожидаемым значениям?

примечание: c=1 не имеет никакого эффекта. Это способствует только point_double тому, когда c>1

Ответ №1:

Я разобрался в проблеме, и реальное решение непросто. Порядок точек (4,2,6) является 77400 .

Проблема зависит от реализации doubleAndAdd алгоритма. Рассмотрим отправную точку с помощью G . Переменные addend и result во время запуска и во время второго посещения точки G не совпадают с момента addend обновления.

 def doubleAndAdd( G, k , p ,c):

    addend = G
    result = None
    
    for b in bits(k) :
        if b:
            result = point_add(result, addend, p)
        addend = point_double(addend, p, c)
    return result
  

Вместо этого я обновил findOrder

 def findOrder(P, POI, p,c):
    
    #for i in range(2,1104601): # 1104601 upper range on the number of points 
    for i in range(1104601):
        Gprime = doubleAndAdd(G,i,p,c)
        if Gprime == POI:
            print(i, " ", Gprime)
            return i
  

Таким образом, он возвращается при первом попадании в точку на бесконечности в качестве порядка точки.

Реальное решение требует предварительного определения порядка базовой точки или, что лучше, определения порядка кривой, поскольку порядок любого элемента изменяет порядок кривой по теореме Лагранжа. Как только он найден, мы можем использовать формулу [ x mod k]P в doubleAndAdd .

Примечание: для подсчета количества точек в Python существует алгоритм Шуфа, однако для этого необходимо изменить проективные координаты на аффинные координаты. Марк Джойеджан и Жак Кискватер предоставили формулы в