Addition auf elliptischen Kurven

29

Addition auf elliptischen Kurven

Haftungsausschluss: Dies wird dem reichen Thema der elliptischen Kurven nicht gerecht. Es ist sehr vereinfacht. Da elliptische Kurven in letzter Zeit im Zusammenhang mit der Verschlüsselung viel Medieninteresse fanden, wollte ich einen kleinen Einblick geben, wie das "Berechnen" auf einer elliptischen Kurve tatsächlich funktioniert.

Einführung

Elliptische Kurven sind Punktmengen (x,y)in der Ebene der Form y^2 = x^3+Ax+B. (Außerdem, 4A^3+27B^2 ≠ 0um unangenehme Singularitäten zu vermeiden.) Sie können diese Kurven in jedem Feld berücksichtigen. Wenn Sie das Feld der reellen Zahlen verwenden, können die Kurven visualisiert werden und sie sehen folgendermaßen aus:

zwei Beispiele für elliptische Kurven
Quelle

Das Besondere an diesen Kurven ist, dass sie eine eingebaute arithmetische Operation haben, die das Analogon der Addition ist. Sie können Punkte hinzufügen und subtrahieren. Diese Operation ist sowohl assoziativ als auch kommutativ (eine abelsche Gruppe).

Wie funktioniert die Addition?

Hinweis: Das Hinzufügen von Punkten auf elliptischen Kurven ist nicht intuitiv. Diese Art der Addition wird so definiert, wie sie ist, weil sie bestimmte schöne Eigenschaften hat. Es ist komisch, aber es funktioniert.

Da elliptische Kurven eine Gruppe bilden, gibt es eine additive Identität , die gleich 0 ist. Das Hinzufügen 0zu einem beliebigen Punkt ändert also nichts am Ergebnis. Diese additive Identität ist der "Punkt" im Unendlichen. Alle Linien in der Ebene enthalten diesen Punkt im Unendlichen. Das Hinzufügen macht also keinen Unterschied.

Nehmen wir an, dass eine gegebene Linie die Kurve an drei Punkten schneidet 0, und dass die Summe dieser drei Punkte ist 0. Beachten Sie dies, und schauen Sie sich dieses Bild an.

Spezialfälle für die Addition elliptischer Kurven
Quelle

Nun ist die natürliche Frage, was ist P+Q? Na ja, wenn P+Q+R = 0, dann P+Q = -R(alternativ geschrieben als R'). Wo liegt -R? Es ist , wo R + (-R) = 0, die auf der anderen Seite der x-Achse aus ist , Rso dass die Linie , die durch sie vertikal ist, nur sich schneidende R, -R, und 0. Sie können dies im ersten Teil dieses Bildes sehen:

Diagramm verschiedener Zusätze auf elliptischen Kurven Quelle

Eine andere Sache, die Sie in diesen Bildern sehen können, ist, dass die Summe eines Punktes mit sich selbst bedeutet, dass die Linie die Kurve tangiert.

So finden Sie Schnittpunkte von Linien und elliptischen Kurven

Im Fall von zwei verschiedenen Punkten

Im Allgemeinen gibt es genau eine Linie durch zwei Punkte P=(x0,y0), Q=(x1,y1). Vorausgesetzt, es ist nicht vertikal und die beiden Punkte sind verschieden, können wir es als schreiben y = m*x+q. Wenn wir die Schnittpunkte mit der elliptischen Kurve finden wollen, können wir einfach schreiben

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

Das ist ein Polynom dritten Grades. Diese sind im Allgemeinen nicht so einfach zu lösen, aber wir kennen bereits zwei Nullen dieses Polynoms: Die zwei xKoordinatenx0, x1 der beiden Punkte, die wir hinzufügen möchten!

Auf diese Weise bereinigen wir die linearen Faktoren (x-x0)und (x-x1)und erhalten einen dritten linearen Faktor, dessen Wurzel die xKoordinate des Punktes ist R. ( -RAuch wegen der Symmetrie. Man beachte , dass , wenn R = (x2,y2)dann -R = (x2,-y2). Die- aus der Gruppe ist; es ist kein vektorielles Minus.)

Im Falle des Hinzufügens eines Punktes P zu sich selbst

In diesem Fall müssen wir den Tangens der Kurve bei berechnen P=(x0,y0). Wir können direkt schreiben mund qin Bezug auf A,B,x0,y0:

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

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

Wir bekommen die Gleichung y = m*x+q und können genauso vorgehen wie im obigen Absatz.

Ein vollständiger Fallbaum

Dies ist eine vollständige Liste, wie mit all diesen Fällen umgegangen wird:

Sei P,QPunkte auf der elliptischen Kurve (einschließlich des "Unendlich" -Punkts 0)

  • Wenn P = 0oder Q = 0, dann P+Q = QoderP+Q = P jeweils
  • Sonst P ≠ 0und Q ≠ 0, also lass P = (x0,y0)undQ = (x1,y1) :
    • Wenn P = -Q(das bedeutet x0 = x1undy0 = -y1 ) dannP+Q = 0
    • Sonst P ≠ -Q
      • Wenn x0 = x1dann haben wir P=Qund berechnen wir den Tangens (siehe Abschnitt oben), um zu bekommenR . DannP+Q = P+P = 2P = -R
      • Sonst: Wir können eine Linie der Form y = m*x+ydurch diese beiden Punkte konstruieren (siehe Abschnitt oben), um zu berechnen R. DannP+Q=-R

Endliche Felder

Bei dieser Herausforderung werden nur Felder mit der Größe berücksichtigt, bei pdenen p(und wegen einiger Details p ≠ 2, p ≠ 3) die höchste Priorität vorliegt . Dies hat den Vorteil, dass Sie einfach rechnen können mod p. Die Arithmetik in anderen Bereichen ist viel komplizierter.

Dies setzen wir in diesem Beispiel p = 5und alle Gleichungen hier sind Kongruenzen 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

Herausforderung

Wenn die Parameter A,Beiner elliptischen Kurve gegeben sind, geben eine Hauptfeldcharakteristik pund zwei Punkte P,Qauf der elliptischen Kurve ihre Summe zurück.

  • Sie können davon ausgehen, dass die Parameter A,Btatsächlich eine elliptische Kurve beschreiben, das heißt, dass 4A^3+27B^2 ≠ 0.
  • Sie können davon ausgehen, dass P,Qes sich tatsächlich um Punkte auf der elliptischen Kurve oder dem 0-Punkt handelt.
  • Sie können davon ausgehen, dass dies p ≠ 2,3eine Primzahl ist.

Testfälle

Ich habe eine (nicht sehr elegante) Implementierung in MATLAB / Octave gemacht, die Sie für Ihre eigenen Testfälle verwenden können: ideone.com Ich hoffe, es ist richtig. Es hat zumindest ein paar Berechnungen reproduziert, die ich von Hand gemacht habe.

Beachten Sie die einfachen Testfälle, die für alle hier betrachteten Kurven funktionieren:

Null hinzufügen: P+0 = P Umgekehrtes hinzufügen:(x,y) + (x,-y) = 0


Für p = 7, A = 0, B = 5die beiden Punkte P = (3,2)und Q = (6,2)auf der elliptischen Kurve. Dann gilt folgendes:

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

Alle Punkte auf der elliptischen Kurve sind (3,2),(5,2),(6,2),(3,5),(5,5),(6,5),0


Denn p = 13, A = 3, B = 8wir bekommen

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

Für p = 17, A = 2, B = 2und P=(5,1) wir bekommen

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)

Wenn Sie wirklich ehrgeizig sind, nehmen Sie

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

und versuchen, eine natürliche Zahl zu finden, nso dass n*(x0,y0) = (x1,y1). Weitere Informationen hier.

Blinddarm

Zunächst ein großes Dankeschön an @ El'endiaStarman für die Überprüfung und Bearbeitung meines Entwurfs!

Warum elliptische Kurven?

Nun, es mag wie eine Art willkürliche Gleichung erscheinen, aber es ist nicht so, es ist ganz allgemein: Im Allgemeinen betrachten wir diese geometrischen "Formen" in der Projektionsebene (das ist, woher die "Unendlichkeit" kommt. Dort betrachten wir alle als homogen Polynome dritten Grades (Die Polynome niedrigeren oder höheren Grades wären zu schwierig oder nur trivial zu untersuchen.) Nachdem einige Einschränkungen angewendet wurden, um die gewünschten guten Eigenschaften zu erhalten, und nachdem diese Polynome dehomogenisiert wurden (Projektion in eine von drei affinen Ebenen) ) Am Ende haben wir Gleichungen wiey^2+a*x*y+b*y = x^3+c*x^2+d*x+eDies ist eine elliptische Kurve in der langen Weierstraßform. Dies sind im Grunde die gleichen Kurven, die wir betrachtet haben, aber nur etwas schief. Mit einer linearen Koordinatentransformation können Sie leicht eine kurze Weierstras-Gleichung daraus erstellen. B. die noch alle interessanten Eigenschaften enthalten.

Warum haben wir ausgeschlossen p=2,3?

Dies hat damit zu tun, dass wir für die kurze Weierstrass-Form die Einschränkung benötigen 4A^3+27B^2 ≠ 0, um Singularitäten zu vermeiden (dazu weiter unten mehr). In einem Feld des Merkmals 2 haben wir 4 = 0und in einem Feld des Merkmals 3 haben wir 27 = 0, macht es dies unmöglich, Kurven in kurzer Weierstrass-Form für diese Arten von Feldern zu haben.

Was sind Singularitäten?

Wenn die Gleichung 4A^3+27B^2=0gilt, haben wir folgende Singularitäten: Wie Sie an diesen Punkten sehen, können Sie keine Ableitung und daher keine Tangente finden, die die Operation "tötet". Sie könnten sich die Gleichungen y^2 = x^3oder anschaueny^2 = x^3-3*x+2

Warum heißen sie eigentlich elliptische Kurven ?

Der Grund ist, dass Gleichungen dieser Form in elliptischen Integralen auftauchen, z. B. welche, die Sie erhalten, wenn Sie z. B. die Bogenlänge einer Ellipse berechnen möchten. Eine kurze Diashow über die Herkunft des Namens.

Was haben sie mit Kryptographie zu tun?

Es gibt Möglichkeiten, nP = P+P+...+Psehr effizient zu rechnen . Dies kann beispielsweise im Diffie Hellman-Schlüsselaustausch verwendet werden . Die modulare Arithmetik kann durch das Hinzufügen von Torsionsuntergruppen ersetzt werden. Dies sind nur die Punkte auf der Kurve, die eine endliche Ordnung haben. (Das bedeutet, dass mP = 0für einige m, die im Grunde nur rechnen mod m).

fehlerhaft
quelle

Antworten:

4

Pyth, 105 100 Bytes

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

Die Eingabe wird erwartet als (p, A, P, Q), wo Pund Qsind die zwei Punkte des Formulars (x, y)oder, wenn es sich um den speziellen 0Punkt handelt, als 0. Sie können es online ausprobieren hier . Die letzten beiden Beispiele zeigen, wie das Special 0funktioniert.

Um ein paar Bytes zu sparen, verwende ich nur mod p die endgültige Antwort. Dies bedeutet, dass es Dinge wie x0^pein paar Mal tut, ohne modulare Exponentiation durchzuführen, so dass es sehr langsam sein kann.

Es funktioniert nach ungefähr der gleichen Logik wie diese Python-Funktion:

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)

Dies hängt stark von der Tatsache ab, dass das modulare multiplikative Inverse von xgleich ist, x^(p-2) mod pwenn pes eine Primzahl ist. So können wir rechnenm die Steigung der Linie , indem die modulare multiplikative Inverse des Nenners ermitteln und mit dem Zähler multiplizieren. Ziemlich praktisch. Die Python-Funktion sollte größere Probleme aufgrund der Verwendung von ein wenig effizienter berechnen pow.

Ich habe auch die Verknüpfungen verwendet, die auf der Wikipedia-Seite zu diesem Thema angezeigt werden . Es ist sehr interessant, dass ich am Ende nur Aeinmal benutze undB nicht .

Auch nur zum Spaß:

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)

Die multi_nPFunktion berechnet n*Pfür eine bestimmte Ganzzahl nund einen bestimmten Punkt P. Es verwendet eine rekursive Strategie durch Aufspaltung nin zwei Teile p2fund remainderso , dass p2f + remainder = nund dass p2f = 2^k. Dann rufen wir die Funktion für diese Teile erneut auf und addieren das Ergebnis mit add_ellip. Ich habe auch den grundlegenden Ansatz der dynamischen Programmierung verwendet, indem ich bereits berechnete Werte im Dikt gespeichert habe d.

Die nächste Funktion würde theoretisch die Bonusfrage mit derselben Strategie lösen:

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

Leider läuft es bei weitem nicht schnell genug, um es zu berechnen. Ich vermute, es gibt viel effizientere Möglichkeiten, dies zu tun, insbesondere wenn wir nicht jeden möglichen Wert für durchlaufen müssen n.

Rhyzomatic
quelle
Toll, ich habe ehrlich gesagt keine Antwort mehr erwartet =) Wie gehst du mit dem Punkt Unendlich um? (Beachten Sie, dass dies y^2 = x^3 + xeine gültige elliptische Kurve und (0,0) ≠ 0ein Punkt auf der Kurve ist!)
Fehler
Tolle Frage ... Ich denke, ich habe das nicht geschafft! : P Entschuldigung, ich erinnere mich, dass ich das erste Bild gesehen B = 0und mich gefragt habe, wie 0es funktionieren würde ... und dann habe ich es vergessen. Ich glaube, ich nahm an, dass ich Bletzte Nacht irgendwann nicht mehr 0 sein konnte. Haben Sie Vorschläge, wie der Input dafür aussehen soll? Vielleicht wenn B = 0, dann definieren 0 = (-1, -1)? Ich bin froh, meinen Code anzupassen, um damit
umzugehen.
Nun, ich habe das Fenster offen gelassen, sodass die Einsendungen alles verwenden können, was für sie am besten geeignet ist. Man kann aber natürlich sagen, dass zB alle endlichen Punkte auf der Kurve nichtnegative Koordinaten haben und alles andere als Unendlichkeitspunkt oder ähnliches betrachtet wird. Oder wenn es einfacher ist, können Sie auch annehmen, dass die Eingabe [0](nur eine Koordinate) der Unendlichkeitspunkt ist oder etwas Ähnliches!
Fehler
Lassen Sie mich wissen, wenn das nicht gut genug funktioniert. Und danke, das hat mir tatsächlich 5 Bytes gespart!
Rhyzomatic
@flawr, können Sie mir sagen, ob ich auf dem richtigen Weg bin, um effizient zu rechnen nP? Könnten Sie mich auf Ressourcen zu diesem Thema hinweisen, um die Gedanken zum Fließen zu bringen? Es fällt mir schwer, etwas zum googeln zu finden. Vielen Dank!
Rhyzomatic
0

Python 3, 193 - 191 Bytes

Eine Lösung, die auf der Pyth-Antwort von Rhyzomatic und ihrer Python-Logik basiert. Bestimmtes. Ich mochte, wie sie die dritte Wurzel eines monischen kubischen Polynoms fanden, x^3 + bx^2 + cx + dwenn Sie zwei Wurzeln habenx_1 und das x_2notierte b == x_1 + x_2 + x_3und dementsprechend subtrahierte. Ich habe vor, eine Erklärung hinzuzufügen, diese Golf zu spielen und sie vielleicht in Ruby umzuwandeln, falls sich herausstellt, dass Ruby kürzer ist.

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)
Sherlock9
quelle
Ich bin überrascht, dass Python weniger als doppelt so lang ist wie die Python-Antwort!
Fehler