Bổ sung vào đường cong Elliptic


29

Bổ sung vào đường cong Elliptic

Disclaimer: Điều này không làm bất kỳ công lý về chủ đề phong phú của các đường cong elip. Nó được đơn giản hóa rất nhiều. Vì các đường cong elliptic gần đây đã nhận được rất nhiều sự chú ý của truyền thông trong bối cảnh mã hóa, tôi muốn cung cấp một số hiểu biết nhỏ về cách "tính toán" trên một đường cong elliptic thực sự hoạt động.

Giới thiệu

Đường cong elip là tập hợp các điểm (x,y)trong mặt phẳng có dạng y^2 = x^3+Ax+B. (Ngoài ra, 4A^3+27B^2 ≠ 0để tránh những điểm kỳ dị khó chịu.) Bạn có thể xem xét các đường cong này trong bất kỳ lĩnh vực nào. Nếu bạn sử dụng trường số thực, các đường cong có thể được hiển thị và chúng trông như thế này:

hai ví dụ về đường cong elip
Nguồn

Điều đặc biệt về các đường cong này là chúng có một phép toán số học được xây dựng tương tự như phép cộng. Bạn có thể cộng và trừ điểm, và thao tác này là cả kết hợp và giao hoán (một nhóm abelian).

Làm thế nào để bổ sung làm việc?

Lưu ý: việc thêm điểm trên các đường cong elip không trực quan. Loại bổ sung này được định nghĩa theo cách của nó bởi vì nó có các thuộc tính tốt nhất định. Thật lạ, nhưng nó hoạt động.

Khi các đường cong elip tạo thành một nhóm, có một danh tính phụ gia tương đương với 0. Nghĩa là, thêm 0vào bất kỳ điểm nào sẽ không thay đổi kết quả. Nhận dạng phụ gia này là "điểm" ở vô cực. Tất cả các dòng trên mặt phẳng bao gồm điểm này ở vô cực, vì vậy việc thêm nó không tạo ra sự khác biệt.

Giả sử rằng bất kỳ đường thẳng nào cũng cắt đường cong tại ba điểm, có thể là 0, và tổng của ba điểm này là 0. Giữ điều đó trong tâm trí, hãy xem hình ảnh này.

trường hợp đặc biệt bổ sung đường cong elip
Nguồn

Bây giờ, câu hỏi tự nhiên là, cái gì P+Q? Vâng, nếu P+Q+R = 0, sau đó P+Q = -R(viết thay thế là R'). Ở đâu -R? Đó là nơi R + (-R) = 0, mà là ở phía bên kia của trục x từ Rđể cho đường thẳng qua chúng là thẳng đứng, giao nhau chỉ R, -R0. Bạn có thể thấy điều này trong phần đầu tiên của hình ảnh này:

sơ đồ bổ sung khác nhau trên các đường cong elip Nguồn

Một điều khác bạn có thể thấy trong những hình ảnh này là tổng của một điểm có nghĩa là đường thẳng tiếp xúc với đường cong.

Làm thế nào để tìm giao điểm của đường và đường cong elip

Trong trường hợp có hai điểm khác biệt

Nói chung có chính xác một dòng qua hai điểm P=(x0,y0), Q=(x1,y1). Giả sử nó không thẳng đứng và hai điểm là khác biệt, chúng ta có thể viết nó là y = m*x+q. Khi chúng ta muốn tìm các điểm giao nhau với đường cong elip, chúng ta chỉ cần viết

0 = x^3+Ax+B-y^2 = x^3+Ax+B-(m*x+q)^2

đó là một đa thức bậc ba. Chúng thường không dễ giải quyết, nhưng chúng ta đã biết hai số không của đa thức này: Hai xtọa độ x0, x1của hai điểm chúng ta muốn thêm!

Đó là yếu tố cách chúng ta ra khỏi những yếu tố tuyến tính (x-x0)(x-x1)và chỉ còn lại một yếu tố tuyến tính thứ ba có gốc là xPhối của điểm R. ( -Rcũng vì tính đối xứng. Lưu ý rằng nếu R = (x2,y2)sau đó -R = (x2,-y2). -Đó là từ nhóm; nó không phải là một phép trừ véc tơ.)

Trong trường hợp thêm một điểm Pvào chính nó

Trong trường hợp này, chúng ta phải tính tiếp tuyến của đường cong tại P=(x0,y0). Chúng tôi có thể trực tiếp viết mqvề A,B,x0,y0:

     3*x0^2 + A
m = ------------
        2*y0

     -x0^3 + A*x0 + 2*B
q = --------------------
          2*y0

Chúng ta có được phương trình y = m*x+qvà có thể tiến hành tương tự như trong đoạn trên.

Cây hoàn chỉnh

Đây là danh sách đầy đủ về cách xử lý tất cả các trường hợp đó:

Gọi P,Qlà các điểm trên đường cong elip (bao gồm cả điểm "vô cực" 0)

  • Nếu P = 0hoặc Q = 0, sau đó P+Q = Q, hoặc P+Q = P, tương ứng
  • Khác P ≠ 0Q ≠ 0, vì vậy hãy P = (x0,y0)Q = (x1,y1):
    • Nếu P = -Q(có nghĩa là x0 = x1y0 = -y1) thìP+Q = 0
    • Khác P ≠ -Q
      • Nếu x0 = x1sau đó chúng ta có P=Qvà chúng ta tính toán tiếp tuyến (xem phần bên trên) để có được R. Sau đóP+Q = P+P = 2P = -R
      • Khác: Chúng ta có thể xây dựng một dòng của biểu mẫu y = m*x+ythông qua hai điểm đó (xem phần bên trên) để tính toán R. Sau đóP+Q=-R

Lĩnh vực hữu hạn

Đối với thách thức này, chúng ta sẽ chỉ xem xét lĩnh vực kích thước pplà số nguyên tố (và vì một số thông tin chi tiết p ≠ 2, p ≠ 3). Điều này có lợi thế mà bạn có thể chỉ cần tính toán mod p. Số học trong các lĩnh vực khác phức tạp hơn nhiều.

Điều này trong ví dụ này chúng tôi đặt ra p = 5và tất cả các đẳng thức ở đây là đồng đẳng mod 5.

2+4 ≡ 6 ≡ 1
2-4 ≡ -2 ≡ 3
2*4 ≡ 8 ≡ 3
2/4 ≡ 2*4 ≡ 3 because 4*4 ≡ 16 ≡ 1, therefore 1/4 ≡ 4

Thử thách

Cho các tham số A,Bcủa một đường cong elliptic, một đặc tính trường nguyên tố pvà hai điểm P,Qtrên đường cong elliptic, trả về tổng của chúng.

  • Bạn có thể giả sử rằng các tham số A,Bthực sự mô tả một đường cong elip, điều đó có nghĩa là 4A^3+27B^2 ≠ 0.
  • Bạn có thể giả sử rằng đó P,Qthực sự là các điểm trên đường cong elip hoặc 0điểm.
  • Bạn có thể cho rằng đó p ≠ 2,3là số nguyên tố.

Các trường hợp thử nghiệm

Tôi đã thực hiện một triển khai (không thanh lịch) trong MATLAB / Octave, mà bạn có thể sử dụng cho các trường hợp thử nghiệm của riêng mình: ideone.com Tôi hy vọng nó là chính xác. Nó ít nhất đã sao chép một vài tính toán tôi làm bằng tay.

Lưu ý các trường hợp thử nghiệm tầm thường hoạt động cho tất cả các đường cong mà chúng tôi xem xét ở đây:

Thêm số không: P+0 = P Thêm nghịch đảo:(x,y) + (x,-y) = 0


Cho p = 7, A = 0, B = 5hai điểm P = (3,2)Q = (6,2)nằm trên đường cong elip. Sau đó giữ:

2*Q = Q+Q = P
2*P = P+P = (5,2)
3*P = P+P+P = (5,2)+P = (6,5)
4*P = P+P+P+P = (5,2)+(5,2) = (6,5)+(5,2) = Q

Tất cả các chất độc trên đường cong elip là (3,2),(5,2),(6,2),(3,5),(5,5),(6,5),0


Cho p = 13, A = 3, B = 8chúng tôi nhận

(1,8)+(9,7) = (2,10)
(2,3)+(12,11) = (9,7)
2*(9,6) = (9,7)
3*(9,6) = 0

Cho p = 17, A = 2, B = 2P=(5,1) chúng tôi nhận được

2*P = (6,3)
3*P = (10,6)
4*P = (3,1)
5*P = (9,16)
6*P = (16,13)
7*P = (0,6)
8*P = (13,7)
9*P = (7,6)
10*P = (7,11)

Nếu bạn thực sự có tham vọng, hãy dùng

p = 1550031797834347859248576414813139942411
A = 1009296542191532464076260367525816293976
x0 = 1317953763239595888465524145589872695690
y0 = 434829348619031278460656303481105428081
x1 = 1247392211317907151303247721489640699240
y1 = 207534858442090452193999571026315995117

và cố gắng tìm một số tự nhiên nnhư vậy n*(x0,y0) = (x1,y1). Thêm thông tin ở đây.

ruột thừa

Trước hết, CẢM ƠN BẠN đã đến @ El'endiaStarman để xem xét và chỉnh sửa bản nháp của tôi!

Tại sao đường cong elip?

Chà nó có vẻ giống như một loại phương trình tùy ý, nhưng thực tế không phải vậy, nó khá chung chung: Nói chung chúng ta xem xét các "hình dạng" hình học đó trong mặt phẳng chiếu (đó là nơi "vô cực" xuất phát. Chúng ta xem xét tất cả sự đồng nhất Đa thức bậc ba (Những người có mức độ thấp hơn hoặc cao hơn sẽ quá khó khăn hoặc chỉ tầm thường để kiểm tra.) Sau khi áp dụng một số hạn chế để có được các tính chất tốt đẹp mà chúng ta muốn, và sau khi khử các đa thức đó (chiếu vào một trong ba mặt phẳng affine ) chúng tôi kết thúc với các phương trình nhưy^2+a*x*y+b*y = x^3+c*x^2+d*x+eĐây là một đường cong elip ở dạng Weierstrass dài. Về cơ bản, đây là những đường cong giống như chúng ta đã xem xét, nhưng chỉ hơi sai lệch. Với một phép biến đổi tọa độ tuyến tính, bạn có thể dễ dàng tạo ra một phương trình Weierstras ngắn từ đó. ví dụ , vẫn giữ tất cả các thuộc tính thú vị.

Tại sao chúng tôi loại trừ p=2,3?

Điều này có liên quan đến thực tế là đối với dạng Weierstrass ngắn, chúng ta cần hạn chế 4A^3+27B^2 ≠ 0để tránh các điểm kỳ dị (nhiều hơn về điều đó dưới đây). Trong một lĩnh vực của đặc tính 2 chúng ta có 4 = 0và trong một lĩnh vực của đặc tính 3 chúng ta có 27 = 0, điều này làm cho không thể có các đường cong ở dạng weierstrass ngắn cho các loại trường đó.

Điểm kỳ dị là gì?

Nếu phương trình đúng 4A^3+27B^2=0, chúng ta có các điểm kỳ dị như sau: Như bạn thấy tại các điểm đó, bạn không thể tìm thấy đạo hàm và do đó không có tiếp tuyến, "giết chết" phép toán. Bạn có thể nhìn vào các phương trình y^2 = x^3hoặcy^2 = x^3-3*x+2

Tại sao chúng được gọi là đường cong elliptic ?

Lý do là các phương trình của hình dạng này bật lên trong các tích phân elip, ví dụ, đó là những gì bạn nhận được khi bạn muốn tính toán ví dụ: ví dụ về hình elip. Một slideshow ngắn về nguồn gốc của tên.

Họ phải làm gì với mật mã?

Có nhiều cách để tính toán nP = P+P+...+Prất hiệu quả. Điều này có thể được sử dụng ví dụ trong trao đổi khóa Diffie Hellman . Số học mô-đun có thể được thay thế bằng việc thêm vào các nhóm con xoắn, đây chỉ là các điểm trên đường cong có thứ tự hữu hạn. (Điều đó có nghĩa là mP = 0đối với một số người m, về cơ bản chỉ là tính toán mod m).

Câu trả lời:


4

Bình thường, 105 100 byte

A,@Q3eQ?qGZH?qHZG?&=YqhHhGqeG%_eHhQZ_m%dhQ,-*J?Y*+*3^hG2@Q1^*2eG-hQ2*-eGeH^-hGhH-hQ2-hGK--^J2hGhHeGK

Đầu vào được dự kiến ​​là (p, A, P, Q), ở đâu PQlà hai điểm của biểu mẫu (x, y)hoặc, nếu chúng là 0điểm đặc biệt , giống như 0. Bạn có thể thử nó trực tuyến ở đây . Hai ví dụ cuối cùng cho thấy cách thức 0hoạt động đặc biệt .

Để tiết kiệm một vài byte, tôi chỉ sử dụng mod pcâu trả lời cuối cùng. Điều này có nghĩa là nó thực hiện mọi thứ như x0^pmột vài lần mà không thực hiện lũy thừa mô-đun, vì vậy nó có thể rất chậm.

Nó hoạt động bằng cách tuân theo logic gần giống như hàm Python này:

def add_ellip(p, A, P, Q): # points are in format (x, y)
    z = 0 # representing special 0 point

    if (P == z):
        return Q
    if (Q == z):
        return P

    if P[0] == Q[0]:
        if (P == (Q[0], -Q[1] % p)):
            return z
        else:
            m = ((3*pow(P[0], 2, p) + A)*pow(2*P[1], p-2, p)) % p
    else:
        m = (P[1] - Q[1])*pow(P[0] - Q[0], p-2, p) % p

    x = (pow(m, 2, p) - P[0] - Q[0]) % p
    y = (m*(P[0] - x) - P[1]) % p
    return (x, y)

Điều này phụ thuộc rất nhiều vào thực tế là nghịch đảo nhân mô-đun xbằng với x^(p-2) mod pnếu plà số nguyên tố. Do đó, chúng ta có thể tính toán mđộ dốc của đường bằng cách tìm nghịch đảo nhân mô đun của mẫu số và nhân nó với tử số. Khá tiện dụng. Hàm Python sẽ tính toán các vấn đề lớn hơn một chút hiệu quả hơn do sử dụng pow.

Tôi cũng đã sử dụng các phím tắt được hiển thị trên trang Wikipedia về chủ đề này . Thật thú vị khi tôi chỉ sử dụng Amột lần, và hoàn toàn Bkhông.

Cũng chỉ để cho vui:

def pow2floor(x):
    p = 1
    x >>= 1
    while (x > 0):
        x >>= 1
        p <<= 1
    return p

def multi_nP(p, A, n, P):
    d = {}

    def rec_helper(n, P):
        if (n == 0):
            return (0, 0)
        elif (n == 1):
            return P
        elif (n in d):
            return d[n]
        else:
            p2f = pow2floor(n)
            remainder = n - p2f

            lower_half = rec_helper(p2f//2, P)
            d[p2f//2] = lower_half
            nP = add_ellip(p, A, lower_half, lower_half)

            if (remainder):
                nP = add_ellip(p, A, nP, rec_helper(remainder, P))

            d[n] = nP
            return nP

    return rec_helper(n, P)

Các multi_nPchức năng tính toán n*Pcho một số nguyên cho nvà điểm P. Nó sử dụng một chiến lược đệ quy bằng cách chia nthành hai phần p2fremainderđó p2f + remainder = nvà đó p2f = 2^k. Sau đó, chúng ta gọi lại hàm trên các phần đó, thêm kết quả với add_ellip. Tôi cũng đã sử dụng phương pháp lập trình động cơ bản bằng cách lưu các giá trị đã được tính toán trong dict d.

Về mặt lý thuyết, chức năng tiếp theo sẽ giải quyết câu hỏi tiền thưởng bằng cách sử dụng cùng một chiến lược:

def find_nPQ(p, A, P, Q): # P is input point, Q is what we're looking for
    d = {}
    found_Q = False

    def rec_helper(n, P):
        if (n == 0):
            return (0, 0)
        elif (n == 1):
            return P
        elif (n in d):
            return d[n]
        else:
            p2f = pow2floor(n)
            remainder = n - p2f

            lower_half = rec_helper(p2f//2, P)
            d[p2f//2] = lower_half

            nP = add_ellip(p, A, lower_half, lower_half)

            if (remainder):
                nP = add_ellip(p, A, nP, rec_helper(remainder, P))

            d[n] = nP
            return nP


    for x in range(p):
        xP = rec_helper(x, P)
        if (xP == Q):
            return x

Thật không may, nó chạy đến nơi gần đủ nhanh để tính toán nó. Tôi đoán có thể có nhiều cách hiệu quả hơn để làm điều này, đặc biệt là nếu chúng ta không phải lặp đi lặp lại qua mọi giá trị có thể có n.


Tuyệt vời, tôi thực sự không mong đợi bất kỳ người vô địch nào nữa =) Làm thế nào để bạn xử lý điểm ở vô cực? (Lưu ý rằng đó y^2 = x^3 + xlà một đường cong elip hợp lệ và (0,0) ≠ 0là một điểm trên đường cong!)
flawr

Câu hỏi tuyệt vời ... Tôi đoán tôi đã không xử lý nó! : P Tôi xin lỗi, tôi nhớ đã nhìn thấy bức ảnh đầu tiên ở đâu B = 0và tự hỏi làm thế nào 0sẽ hoạt động ... và sau đó tôi quên nó. Tôi nghĩ rằng tôi giả sử Bkhông thể là 0 tại một số điểm vào đêm qua. Bạn có bất cứ đề xuất về những gì đầu vào nên thích cho điều này? Có lẽ nếu B = 0, sau đó xác định 0 = (-1, -1)? Tôi rất vui khi điều chỉnh mã của mình để xử lý nó, tôi chỉ nghĩ rằng nó sẽ tốt nếu nó được chuẩn hóa cho các bài nộp khác ...
Rhyzomatic

Vâng, tôi đã để lại rằng pont mở để các bài nộp có thể sử dụng bất cứ nơi nào thuận tiện cho họ. Nhưng tất nhiên bạn có thể nói rằng, ví dụ: tất cả các điểm hữu hạn trên đường cong đều có tọa độ không âm và mọi thứ khác được coi là điểm Vô cực hoặc một cái gì đó tương tự. Hoặc nếu dễ dàng hơn, bạn cũng có thể giả sử rằng đầu vào [0](chỉ có một tọa độ) là điểm vô cực, hoặc bất cứ điều gì tương tự!
flawr

Hãy cho tôi biết nếu điều đó không xử lý nó đủ tốt. Và cảm ơn, điều đó thực sự đã tiết kiệm cho tôi 5 byte!
Rhyzomatic

@flawr, bạn có thể cho tôi biết nếu tôi đang đi đúng hướng để tính toán hiệu quả nPkhông? Bạn có thể chỉ cho tôi bất kỳ tài nguyên nào về chủ đề này để khiến suy nghĩ trôi chảy không? Tôi đang có một thời gian khó khăn để tìm thấy bất cứ điều gì Google xung quanh. Cảm ơn!
Rhyzomatic

0

Python 3, 193 191 byte

Một giải pháp dựa trên câu trả lời Pyth của Rhyzomatic và logic Python của họ. Đặc biệt. Tôi thích cách họ tìm ra gốc thứ ba của một đa thức bậc ba monic x^3 + bx^2 + cx + dkhi bạn có hai gốc x_1x_2bằng cách lưu ý điều đó b == x_1 + x_2 + x_3và trừ đi cho phù hợp. Tôi dự định thêm một lời giải thích, đánh golf cái này, và có lẽ chuyển nó thành Ruby, nếu Ruby hóa ra ngắn hơn.

def e(p,A,B,P,Q):
 if P==0:return Q
 if Q==0:return P
 f,g=P;j,k=Q
 if f==j:
  if g==-k%p:return 0
  m=(3*f*f+A)*pow(2*j,p-2)
 else:m=(g-k)*pow(f-j,p-2)
 x=m*m-f-j;y=m*(f-x)-g;return(x%p,y%p)

Ungolfing:

def elliptic_curve_addition(p, A, B, P, Q):
    if P == 0:
        return Q
    if Q == 0:
        return P
    f,q = P
    j,k = Q
    if f==j:
        if g == (-k) % p:
            return 0
        m = (3 * f**2 + A) * pow(2*j, p-2)
    else:
        m = (g-k) * pow(f-j, p-2)
    x = m**2 - f - j
    y = m * (f-x) - g
    return (x%p, y%p)

Tôi ngạc nhiên khi Python dài hơn hai lần câu trả lời của Pyth!
flawr
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.