Wie wandle ich ganz konkret einen bestimmten privaten Bitcoin-Schlüssel in einen öffentlichen Bitcoin-Schlüssel um (Sprich mit mir, als wäre ich 5 und ich muss dies Schritt für Schritt tun, oder die böse Hexe wird mich lebendig in ihrem Ofen kochen). NICHT, wo kann ich ein Programm finden, das dies tut, aber wenn ich es selbst tun würde, was würde ich tun?
Privat Schlüssel:
18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725
ergibt angeblich den öffentlichen Schlüssel:
0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6
Andere haben gefragt, wie man privat öffentlich wird, ich habe keine wirklich spezifische Antwort gesehen, nur eine allgemeinere Richtung, aber keine Antworten erklären alle Variablen. Ich verstehe, dass dies ziemlich komplex ist, und wenn eine bestimmte Person denkt, dass es zu viel Arbeit ist, um darauf zu antworten, respektiere ich das vollkommen. Hinweis: Ich interessiere mich nicht für die Bitcoin-Adresse, ich interessiere mich nur für Privatekey zu Publickey und die Einzelheiten, wie.
Variablen wie das „a“ und „b“ im ECDSA-Kurvenalgorithmus werden bereits von Bitcoin bezeichnet (gemäß https://en.bitcoin.it/wiki/Secp256k1 ). Der "Basispunkt" alias "G" ist ebenfalls auf dieser Seite angegeben. Den "privaten Exponenten" oder "k" muss ich noch finden. Einige dieser Variablen sind angeblich "zufällig", was falsch erscheint, da jeder Generator, in den Sie einen privaten Schlüssel einfügen können, immer denselben öffentlichen Schlüssel auszuspucken scheint ... also ... alle Variablen sind entweder bereits voreingestellt oder werden aus dem privaten Schlüssel abgeleitet.
Danke für jede Hilfe dazu. Ich habe tagelang versucht, dies zu recherchieren und zu verstehen, aber es scheint, dass ich manchmal die Begriffe und / oder Notationen nicht verstehe, aber ich glaube, ich bin darüber hinweggekommen und jetzt fehlen nur noch Teile der Gleichung.
EDIT ADD:
Dies ist der zuvor angegebene private Schlüssel in Dezimal:
11253563012059685825953619222107823549092147699031672238385790369351542642469
Dies ist der zuvor angegebene öffentliche Schlüssel (x- und y-Werte) in Dezimalzahl:
36422191471907241029883925342251831624200921388586025344128047678873736520530
20277110887056303803699431755396003735040374760118964734768299847012543114150
Ich möchte nur wissen, wie ich von diesem privaten Schlüssel zum öffentlichen Schlüssel komme. Angeblich handelt es sich um eine einfache Gleichung, die keine Bitverschiebung oder xor usw. beinhaltet. Sie kann "Punktmultiplikation" enthalten (wobei ich nicht sehe, wie Sie einen Punkt multiplizieren können, der sowohl mit x als auch mit ay definiert ist). Niemand scheint die Feinheiten zu verstehen. Schlägt ihr vor, ich biete jedem, der es klar erklärt, tatsächlich einen Bruchteil einer Bitcoin an?
Ich werde versuchen, dies noch einmal anders zu beantworten, indem ich kleine Zahlen verwende, um es lesbar zu halten.
Konvertieren Sie den privaten Schlüssel in eine binäre Darstellung, sodass die Dezimalzahl 105, die 0x69 in Hex ist, zu 01101001 wird.
Berechnen Sie diese Liste von Punkten, indem Sie den Generatorpunkt G wiederholt verdoppeln:
1*G
2*G = G+G
4*G = 2*G + 2*G
8*G = 4*G + 4*G
16*G = 8*G + 8*G
32*G = 16*G + 16*G
64*G = 32*G + 32*G
Schreiben Sie die Bits des privaten Schlüssels wie folgt neben diese Liste:
privkey pointlist
1 1*G
0 2*G
0 4*G
1 8*G
0 16*G
1 32*G
1 64*G
Beginnen Sie nun damit, nur die Punkte hinzuzufügen, neben denen ein 1
geschrieben steht.
9*G = 1*G + 8*G
41*G = (9+32)*G = 9*G + 32*G
105*G = (41+64)*G = 41*G + 64*G
Jetzt haben Sie den öffentlichen Schlüssel für den privaten Schlüssel 105 berechnet, indem Sie nur Punktverdopplungs- und Punktadditionsoperationen verwendet haben.
Der tatsächliche Wert wird sein:
(0xf219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63,
0x4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1)
Der öffentliche Schlüssel liegt dann in einem von zwei Formaten vor:
0x04
Der vollständige öffentliche Schlüssel ist 0x04, gefolgt von 32 Bytes der x-Koordinate, gefolgt von 32 Bytes der y-Koordinate.
Der komprimierte öffentliche Schlüssel ist 0x02 oder 0x03, je nachdem, ob die y-Koordinate eine gerade oder ungerade Zahl ist, gefolgt von 32 Bytes der x-Koordinate.
Dann noch ein paar Anmerkungen zu deiner Frage:
In einigen älteren Texten wurde die Skalarpunktmultiplikation als Potenzierung bezeichnet, weshalb manchmal der private Schlüssel als privater Exponent bezeichnet wird.
die Parameter der Kurve wurden zufällig einmal gewählt. was bedeutet, dass die Designer der secp256k1-Kurve erfolglos versucht haben zu vermitteln, dass diese Kurve keine spezifische Struktur hat. Das bedeutet, dass die NSA eine mathematische Hintertür in die Kurvenparameter hätte einbauen können oder nicht.
Wenn Sie diese Kurve verwenden und Ihren öffentlichen Schlüssel generieren, müssen Sie Ihren privaten Schlüssel zufällig auswählen, so dass es unmöglich ist, ihn zu erraten.
Der Generator G
ist ein bestimmter Punkt auf der elliptischen Kurve, der in der Kurve secp256k1 definiert ist.
ecdsa.SigningKey.from_string(s.decode('hex'), curve=ecdsa.SECP256k1).verifying_key
Danke! Bitte posten Sie eine Bitcoin-Adresse! (Edit: auf deiner verlinkten Seite gefunden)Hier ist ein eigenständiges Python-Skript, das die Konvertierung durchführt. Sie können seine Funktion überprüfen, indem Sie Ihren privaten Schlüssel als "geheimen Exponenten" bei Brainwallet eingeben . Ich habe das Skript aus diesem Bitcointalk-Thread genommen und unnötige Dinge entfernt (wie den Code zur Verwendung des öffentlichen Schlüssels zum Signieren einer Nachricht und zum Überprüfen dieser Signatur).
Das Konvertieren von Python in Anweisungen für einen Menschen bleibt dem Leser als Übung überlassen (obwohl ich argumentieren würde, dass in einem Szenario wie diesem Python-Code mit entsprechender Dokumentation als Anweisungen für einen Menschen in Ordnung ist). Beachten Sie, dass es durchaus möglich ist, dies mit Stift und Papier zu berechnen, aber es kann eine Weile dauern, und Sie werden wahrscheinlich einen Fehler machen, weil Sie mit solch enormen Zahlen umgehen müssen.
Beachten Sie auch, dass es hier keine einzelnen Operationen gibt, die viel komplizierter sind, als Sie es in der Grundschule lernen würden. Es gibt grundlegende Vergleiche < > ==
, Arithmetik + - *
, Division, bei denen Sie sich um den Quotienten /
, den Rest %
oder beides kümmern divmod
, und bitweises UND ( &
, was ziemlich einfach ist, wenn Sie in Hex arbeiten; oder mit Arithmetik repliziert werden kann).
Ich glaube nicht, dass ein (ungenialer) 5-Jähriger es wirklich schaffen könnte (sorry, die böse Hexe gewinnt diese Runde), aber ich denke, ein durchschnittlicher Erwachsener mit genug Geduld könnte die erforderliche Mathematik in kürzester Zeit lernen (mit dem Python-Skript als ... naja ... Skript, folgt). Die tatsächliche Berechnung auch nur eines öffentlichen Schlüssels ohne die Hilfe elektronischer Rechengeräte könnte jedoch sehr lange dauern (geschätzt: Jahre).
#! /usr/bin/env python
# python 2.x
class CurveFp( object ):
def __init__( self, p, a, b ):
self.__p = p
self.__a = a
self.__b = b
def p( self ):
return self.__p
def a( self ):
return self.__a
def b( self ):
return self.__b
def contains_point( self, x, y ):
return ( y * y - ( x * x * x + self.__a * x + self.__b ) ) % self.__p == 0
class Point( object ):
def __init__( self, curve, x, y, order = None ):
self.__curve = curve
self.__x = x
self.__y = y
self.__order = order
if self.__curve: assert self.__curve.contains_point( x, y )
if order: assert self * order == INFINITY
def __add__( self, other ):
if other == INFINITY: return self
if self == INFINITY: return other
assert self.__curve == other.__curve
if self.__x == other.__x:
if ( self.__y + other.__y ) % self.__curve.p() == 0:
return INFINITY
else:
return self.double()
p = self.__curve.p()
l = ( ( other.__y - self.__y ) * \
inverse_mod( other.__x - self.__x, p ) ) % p
x3 = ( l * l - self.__x - other.__x ) % p
y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
return Point( self.__curve, x3, y3 )
def __mul__( self, other ):
def leftmost_bit( x ):
assert x > 0
result = 1L
while result <= x: result = 2 * result
return result / 2
e = other
if self.__order: e = e % self.__order
if e == 0: return INFINITY
if self == INFINITY: return INFINITY
assert e > 0
e3 = 3 * e
negative_self = Point( self.__curve, self.__x, -self.__y, self.__order )
i = leftmost_bit( e3 ) / 2
result = self
while i > 1:
result = result.double()
if ( e3 & i ) != 0 and ( e & i ) == 0: result = result + self
if ( e3 & i ) == 0 and ( e & i ) != 0: result = result + negative_self
i = i / 2
return result
def __rmul__( self, other ):
return self * other
def __str__( self ):
if self == INFINITY: return "infinity"
return "(%d,%d)" % ( self.__x, self.__y )
def double( self ):
if self == INFINITY:
return INFINITY
p = self.__curve.p()
a = self.__curve.a()
l = ( ( 3 * self.__x * self.__x + a ) * \
inverse_mod( 2 * self.__y, p ) ) % p
x3 = ( l * l - 2 * self.__x ) % p
y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
return Point( self.__curve, x3, y3 )
def x( self ):
return self.__x
def y( self ):
return self.__y
def curve( self ):
return self.__curve
def order( self ):
return self.__order
INFINITY = Point( None, None, None )
def inverse_mod( a, m ):
if a < 0 or m <= a: a = a % m
c, d = a, m
uc, vc, ud, vd = 1, 0, 0, 1
while c != 0:
q, c, d = divmod( d, c ) + ( c, )
uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc
assert d == 1
if ud > 0: return ud
else: return ud + m
# secp256k1
_p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL
_r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L
_b = 0x0000000000000000000000000000000000000000000000000000000000000007L
_a = 0x0000000000000000000000000000000000000000000000000000000000000000L
_Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L
_Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L
class Public_key( object ):
def __init__( self, generator, point ):
self.curve = generator.curve()
self.generator = generator
self.point = point
n = generator.order()
if not n:
raise RuntimeError, "Generator point must have order."
if not n * point == INFINITY:
raise RuntimeError, "Generator point order is bad."
if point.x() < 0 or n <= point.x() or point.y() < 0 or n <= point.y():
raise RuntimeError, "Generator point has x or y out of range."
curve_256 = CurveFp( _p, _a, _b )
generator_256 = Point( curve_256, _Gx, _Gy, _r )
g = generator_256
if __name__ == "__main__":
print '======================================================================='
### set privkey
# wiki
#secret = 0xE9873D79C6D87DC0FB6A5778633389F4453213303DA61F20BD67FC233AA33262L
# question
secret = 0x18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725L
### print privkey
print 'secret', hex(secret)
### generate pubkey
pubkey = Public_key( g, g * secret )
### print pubkey
print 'pubkey', hex(pubkey.point.x()), hex(pubkey.point.y())
print '======================================================================='
Sehen Sie sich auch eine noch abgespecktere Version an, die in C# geschrieben ist.
class CalcPub
{
public static void Main()
{
var p = BigInteger.Parse("0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", NumberStyles.HexNumber);
var b = (BigInteger)7;
var a = BigInteger.Zero;
var Gx = BigInteger.Parse("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", NumberStyles.HexNumber);
var Gy = BigInteger.Parse("483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", NumberStyles.HexNumber);
CurveFp curve256 = new CurveFp(p, a, b);
Point generator256 = new Point(curve256, Gx, Gy);
var secret = BigInteger.Parse("18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725", NumberStyles.HexNumber);
Console.WriteLine("secret {0}", secret.ToString("X"));
var pubkeyPoint = generator256 * secret;
Console.WriteLine("pubkey {0}{1}", pubkeyPoint.X.ToString("X"), pubkeyPoint.Y.ToString("X"));
}
}
class Point
{
public static readonly Point INFINITY = new Point(null, default(BigInteger), default(BigInteger));
public CurveFp Curve { get; private set; }
public BigInteger X { get; private set; }
public BigInteger Y { get; private set; }
public Point(CurveFp curve, BigInteger x, BigInteger y)
{
this.Curve = curve;
this.X = x;
this.Y = y;
}
public Point Double()
{
if (this == INFINITY)
return INFINITY;
BigInteger p = this.Curve.p;
BigInteger a = this.Curve.a;
BigInteger l = ((3 * this.X * this.X + a) * InverseMod(2 * this.Y, p)) % p;
BigInteger x3 = (l * l - 2 * this.X) % p;
BigInteger y3 = (l * (this.X - x3) - this.Y) % p;
return new Point(this.Curve, x3, y3);
}
public override string ToString()
{
if (this == INFINITY)
return "infinity";
return string.Format("({0},{1})", this.X, this.Y);
}
public static Point operator +(Point left, Point right)
{
if (right == INFINITY)
return left;
if (left == INFINITY)
return right;
if (left.X == right.X)
{
if ((left.Y + right.Y) % left.Curve.p == 0)
return INFINITY;
else
return left.Double();
}
var p = left.Curve.p;
var l = ((right.Y - left.Y) * InverseMod(right.X - left.X, p)) % p;
var x3 = (l * l - left.X - right.X) % p;
var y3 = (l * (left.X - x3) - left.Y) % p;
return new Point(left.Curve, x3, y3);
}
public static Point operator *(Point left, BigInteger right)
{
var e = right;
if (e == 0 || left == INFINITY)
return INFINITY;
var e3 = 3 * e;
var negativeLeft = new Point(left.Curve, left.X, -left.Y);
var i = LeftmostBit(e3) / 2;
var result = left;
while (i > 1)
{
result = result.Double();
if ((e3 & i) != 0 && (e & i) == 0)
result += left;
if ((e3 & i) == 0 && (e & i) != 0)
result += negativeLeft;
i /= 2;
}
return result;
}
private static BigInteger LeftmostBit(BigInteger x)
{
BigInteger result = 1;
while (result <= x)
result = 2 * result;
return result / 2;
}
private static BigInteger InverseMod(BigInteger a, BigInteger m)
{
while (a < 0) a += m;
if (a < 0 || m <= a)
a = a % m;
BigInteger c = a;
BigInteger d = m;
BigInteger uc = 1;
BigInteger vc = 0;
BigInteger ud = 0;
BigInteger vd = 1;
while (c != 0)
{
BigInteger r;
//q, c, d = divmod( d, c ) + ( c, );
var q = BigInteger.DivRem(d, c, out r);
d = c;
c = r;
//uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc;
var uct = uc;
var vct = vc;
var udt = ud;
var vdt = vd;
uc = udt - q * uct;
vc = vdt - q * vct;
ud = uct;
vd = vct;
}
if (ud > 0) return ud;
else return ud + m;
}
}
class CurveFp
{
public BigInteger p { get; private set; }
public BigInteger a { get; private set; }
public BigInteger b { get; private set; }
public CurveFp(BigInteger p, BigInteger a, BigInteger b)
{
this.p = p;
this.a = a;
this.b = b;
}
}
new CurveFp(p,a,b)
, werden die Nummern einfach gespeichert. Sie können sich eine Kurve als eine Paarung von drei Zahlen vorstellen. In ähnlicher Weise ist a Point
einfach eine Paarung aus a Curve
und zwei Zahlen. Alle diese Zahlen werden benötigt, um a mit einer Zahl zu multiplizieren Point
, was in geschieht generator256 * secret
. Das Ergebnis dieser (sehr komplizierten) Multiplikation ist ein Point
; sein X und Y, miteinander verkettet, sind der öffentliche Schlüssel. Und ich denke, der (C#)-Code trifft alles zu; Sie können C# in einem Debugger mit VS Express schrittweise durchgehen, um es anzuzeigen.p
), InverseMod usw. Code lesen ist gut für , "Es ist mir egal, warum oder wie es funktioniert, lass es einfach funktionieren". Diese Art von Forschung wäre besser, um die beteiligten Algorithmen zu verstehen.BigInteger
der Modulo-Operator %
einen negativen Wert zurückgeben. Einfügen if (y3 < 0) y3 += p;
nach den Berechnungen von y3
in beiden Double()
und operator +()
korrigierte die problematischen Testfälle, auf die ich gestoßen bin; obwohl meine Tests nicht erschöpfend waren und es möglicherweise andere problematische Verwendungen von %
hier gibt.Ich nahm die Antwort von Tim S und entfernte mehr Zeug, bis es für mich auf eine einzige Seite passte:
https://gist.github.com/dooglu/3b1fcbc2449063a1c3f7f1003ca26447
#! /usr/bin/env python
class Point(object):
def __init__(self, _x, _y, _order = None): self.x, self.y, self.order = _x, _y, _order
def calc(self, top, bottom, other_x):
l = (top * inverse_mod(bottom)) % p
x3 = (l * l - self.x - other_x) % p
return Point(x3, (l * (self.x - x3) - self.y) % p)
def double(self):
if self == INFINITY: return INFINITY
return self.calc(3 * self.x * self.x, 2 * self.y, self.x)
def __add__(self, other):
if other == INFINITY: return self
if self == INFINITY: return other
if self.x == other.x:
if (self.y + other.y) % p == 0: return INFINITY
return self.double()
return self.calc(other.y - self.y, other.x - self.x, other.x)
def __mul__(self, e):
if self.order: e %= self.order
if e == 0 or self == INFINITY: return INFINITY
result, q = INFINITY, self
while e:
if e&1: result += q
e, q = e >> 1, q.double()
return result
def __str__(self):
if self == INFINITY: return "infinity"
return "04 %x %x" % (self.x, self.y)
def inverse_mod(a):
if a < 0 or a >= p: a = a % p
c, d, uc, vc, ud, vd = a, p, 1, 0, 0, 1
while c:
q, c, d = divmod(d, c) + (c,)
uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc
if ud > 0: return ud
return ud + p
p, INFINITY = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL, Point(None, None) # secp256k1
g = Point(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L, 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L,
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L)
secret = 0x18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725L
print ' privkey: %x\n pubkey: %s' % (secret, g * secret)
Erzeugt diese Ausgabe:
privkey: 18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725
pubkey: 04 50863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352 2cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6
Ich kann jetzt fast verstehen, wie es funktioniert. :)
Die Beschreibung der Punktmultiplikation auf Wikipedia war hilfreich, um zu verstehen, woher die l
Werte kommen. l
steht für "Lambda".
Der öffentliche Schlüssel ist ein Punkt (x, y)
auf der secp256k1-Kurve, der berechnet werden kann, indem der Basispunkt G
mit dem geheimen Schlüssel multipliziert wird sk
. Hier ist eine in sich geschlossene prägnante Python-Funktion, die dies tut:
def sk_to_pk(sk):
"""
Derive the public key of a secret key on the secp256k1 curve.
Args:
sk: An integer representing the secret key (also known as secret
exponent).
Returns:
A coordinate (x, y) on the curve repesenting the public key
for the given secret key.
Raises:
ValueError: The secret key is not in the valid range [1,N-1].
"""
# base point (generator)
G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)
# field prime
P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
# order
N = (1 << 256) - 0x14551231950B75FC4402DA1732FC9BEBF
# check if the key is valid
if not(0 < sk < N):
msg = "{} is not a valid key (not in range [1, {}])"
raise ValueError(msg.format(hex(sk), hex(N-1)))
# addition operation on the elliptic curve
# see: https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Point_addition
# note that the coordinates need to be given modulo P and that division is
# done by computing the multiplicative inverse, which can be done with
# x^-1 = x^(P-2) mod P using fermat's little theorem (the pow function of
# python can do this efficiently even for very large P)
def add(p, q):
px, py = p
qx, qy = q
if p == q:
lam = (3 * px * px) * pow(2 * py, P - 2, P)
else:
lam = (qy - py) * pow(qx - px, P - 2, P)
rx = lam**2 - px - qx
ry = lam * (px - rx) - py
return rx % P, ry % P
# compute G * sk with repeated addition
# by using the binary representation of sk this can be done in 256
# iterations (double-and-add)
ret = None
for i in xrange(256):
if sk & (1 << i):
if ret is None:
ret = G
else:
ret = add(ret, G)
G = add(G, G)
return ret
Die erforderlichen Parameter ( G
, P
und N
) finden Sie in der Spezifikation: http://www.secg.org/sec2-v2.pdf#page=13 . Beachten Sie, dass diese Implementierung auf Klarheit abzielt. Es ist überhaupt nicht effizient und wahrscheinlich auch nicht sicher gegen Seitenkanal-Timing-Angriffe. Ein Angreifer könnte die Ausführungszeit eines Aufrufs dieser Funktion nutzen, um Informationen über den geheimen Schlüssel abzuleiten.
Ich hatte auf eine solche Antwort gehofft und sie nicht gesehen, also hier ist meine:
Eine elliptische Kurve ("EC") ist eine Funktion, bei der das Quadrat der y-Koordinate gleich einem Polynom dritten Grades der x-Koordinate ist.
So verstehe ich ECC, und es kann ungenau sein. Ich würde mich sehr über Korrekturen oder Fragen freuen, damit ich diese Beschreibung verfeinern kann. Angesichts der anderen Antworten hier bereits dachte ich, dass diese vielen Menschen helfen könnte.
**Es wäre schön, die Algebra zu sehen, die zeigt, wie man den Tangens des EC (für Verdopplungen) erhält, und auch für die Berechnung des Schnittpunkts zwischen einer durch zwei andere Punkte definierten Linie und der Kurve selbst.
Greg Hewgill
Mine
Felipe Voloch