user109850: I have seen many videos regarding the math behind the bitcoin elliptical curve but none of them show the public key generation. They are just defining few steps. I need the complete math behind the elliptical curve in which the generation of the public key is defined. Actually, I would like to see a visualization of the public key generation, could someone give me a link which explains the math behind elliptical curve?
What I understand that is k * n times G is equal to the public key but my question remains the same. If kn times G (where every point of G we get from point multiplication and point addition ) then at every multiplication of kG will result a different value then how can we combine them to get the public key?

user116164: For me, the key video explaining the math for bitcoin elliptic curve secp256k1 was this: Bitcoin 101 - Elliptic Curve Cryptography - Part 4 - Generating the Public Key (in Python)
And if you want to check with a python script I extracted from the video, you can use this:
#!/usr/bin/python3

# Super simple Elliptic Curve Presentation. No imported libraries, wrappers, nothing.
# For educational purposes only.
# Below are the public specs for Bitcoin's curve - the secp256k1

# webs for checking
# https://www.bitaddress.org/bitaddress.org-v3.3.0-SHA256-dec17c07685e1870960903d8f58090475b25af946fe95a734f88408cef4aa194.html
# https://www.mobilefish.com/services/cryptocurrency/cryptocurrency.html


# datos para usar la curva secp256k1
Pcurve = 2 ** 256 - 2 ** 32 - 2 ** 9 - 2 ** 8 - 2 ** 7 - 2 ** 6 - 2 ** 4 - 1  # The proven prime
N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141  # Number of points in the field
Acurve = 0
Bcurve = 7  # These two defines the elliptic curve. y^2 = x^3 + Acurve * x + Bcurve
Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240
Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424
GPoint = (Gx, Gy)  # This is our generator point. Trillions of dif ones possible

# Individual Transaction/Personal Information
privKey = 0x0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D


def modinv(a: int, n: int = Pcurve):  # MAXIMO COMUN DIVISOR: Extended Euclidean Algorithm/'division' in elliptic curves
    lm, hm = 1, 0
    resto = a % n
    high = n
    while resto > 1:
        ratio = high // resto
        nm = hm - lm * ratio
        new = high - resto * ratio
        lm, resto, hm, high = nm, new, lm, resto
    return lm % n


def ECadd(a, b):  # Not true addition, invented for EC. Could have been called anything.
    LamAdd = ((b[1] - a[1]) * modinv(b[0] - a[0], Pcurve)) % Pcurve
    x = (LamAdd * LamAdd - a[0] - b[0]) % Pcurve
    y = (LamAdd * (a[0] - x) - a[1]) % Pcurve
    return x, y


def ECdouble(a):  # This is called point doubling, also invented for EC.
    Lam = ((3 * a[0] * a[0] + Acurve) * modinv((2 * a[1]), Pcurve)) % Pcurve
    x = (Lam * Lam - 2 * a[0]) % Pcurve
    y = (Lam * (a[0] - x) - a[1]) % Pcurve
    return x, y


def EccMultiply(gen_point: tuple, scalar_hex: int):  # Double & add. Not true multiplication
    if scalar_hex == 0 or scalar_hex >= N:
        raise Exception("Invalid Scalar/Private Key")
    ScalarBin = str(bin(scalar_hex))[2:]  # string binario sin el comienzo 0b
    Q = gen_point  # esto es una tupla de dos  integer del punto de generacion de la curva
    for i in range(1, len(ScalarBin)):
        Q = ECdouble(Q)
        if ScalarBin[i] == "1":
            Q = ECadd(Q, gen_point)  #
    return Q


print("******* Public Key Generation *********")
print()
PublicKey = EccMultiply(GPoint, privKey)
print("the private key:")
print(privKey)
print()
print("the uncompressed public key (not address):")
print(PublicKey)
print()
x = hex(PublicKey[0])[2:].upper()
y = hex(PublicKey[1])[2:].upper()
print(f"The x: {x}")
print(f"The y: {y}")
print()
print("the uncompressed public key (HEX):")
pub_uncomp = f"04{hex(PublicKey[0])[2:].upper()}{hex(PublicKey[1])[2:].upper()}"
print(pub_uncomp)
print()
print("the official Public Key - compressed:")

if PublicKey[1] % 2 == 1:  # If the Y value for the Public Key is odd.
    print("03" + str(hex(PublicKey[0])[2:]).zfill(64).upper())
else:  # Or else, if the Y value is even.
    print("02" + str(hex(PublicKey[0])[2:]).zfill(64).upper())

Lastly you can see how to get the whole process, including WIF format and public addresses, check this.

user109932: Have you checked the "Keys, Addresses" chapter from "Mastering Bitcoin"?
You can read it for free here:
https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc
The Generating a Public Key section has also a visual representation for the "multiplication of a point G by an integer k on an elliptic curve"

user5406: In ECDSA, the private key is a scalar 256-bit number. The public key is a elliptic curve point on the secp256k1 curve. Elliptic curves are abelian groups made up of the set of points resulting from repeatedly applying its group operation starting with its base point G. The group operation is the addition of two points. So, starting with the base point as the first element, the second element is G+G, the addition of G to itself. The third element is G+G+G, etc. To enumerate all points of the curve would take eons, because the group order is 115792089237316195423570985008687907852837564279074904382605163141518161494337.
Anyway, to find the public key Q corresponding to a private key k, you have to "walk" k generator steps from the base point. We write this elliptic curve scalar multiplication as

Q = G+G+…+G [k-times] = kG

Now secp256k1 is defined as

y² = x³+7 mod P

where P is

P = 2256 - 232 - 29 - 28 - 27 - 26 - 24 - 1.

In secp256k1, the base point is G(Gx,Gy), where

Gx =
55066263022277343669578718895168534326250603453777594175500187360389116729240
Gy =
32670510020758816978083085130507043184471273380659243275938904335757337482424

The addition of two points is defined as

P + Q = R
(xp, yp) + (xq, yq) = (xr, yr)

Which works out to be

xr = (yq - yp) / (xq - xp) - xp - xq
yr = ((yq - yp) / (xq - xp)) × (xp - xr) - yp

Note that the values are limited to [mod P]. So, taking your private key k, you now add G k times. There are some recommended shortcuts like first splitting k into a sum of factors of 2 (e.g. 37 = 1 + 22 + 25), because it will speed up your calculation immensely. Since the numbers involved are kinda hard to keep track of manually, I'd recommend using a software library.

Sources:

Wikipedia: Elliptic Curve Digital Signature Algorithm
Crypto.SE: How to generate a public key from a private ECDSA key?
Jun Wang: ECDSA and Bitcoin II
Wikipedia: Elliptic Curve Point Multiplication


109850: <p>I have seen many videos regarding the math behind the bitcoin elliptical curve but none of them show the public key generation. They are just defining few steps. I need the complete math behind the elliptical curve in which the generation of the public key is defined. Actually, I would like to see a visualization of the public key generation, could someone give me a link which explains the math behind elliptical curve?</p>
<p>What I understand that is k * n times G is equal to the public key but my question remains the same. If kn times G (where every point of G we get from point multiplication and point addition ) then at every multiplication of kG will result a different value then how can we combine them to get the public key?</p>
 116164: <p>For me, the key video explaining the math for bitcoin elliptic curve secp256k1 was this: <a href="https://www.youtube.com/watch?v=iB3HcPgm_FI" rel="nofollow noreferrer">Bitcoin 101 - Elliptic Curve Cryptography - Part 4 - Generating the Public Key (in Python)</a></p>
<p>And if you want to check with a python script I extracted from the video, you can use this:</p>
<pre><code>#!/usr/bin/python3

# Super simple Elliptic Curve Presentation. No imported libraries, wrappers, nothing.
# For educational purposes only.
# Below are the public specs for Bitcoin's curve - the secp256k1

# webs for checking
# https://www.bitaddress.org/bitaddress.org-v3.3.0-SHA256-dec17c07685e1870960903d8f58090475b25af946fe95a734f88408cef4aa194.html
# https://www.mobilefish.com/services/cryptocurrency/cryptocurrency.html


# datos para usar la curva secp256k1
Pcurve = 2 ** 256 - 2 ** 32 - 2 ** 9 - 2 ** 8 - 2 ** 7 - 2 ** 6 - 2 ** 4 - 1  # The proven prime
N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141  # Number of points in the field
Acurve = 0
Bcurve = 7  # These two defines the elliptic curve. y^2 = x^3 + Acurve * x + Bcurve
Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240
Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424
GPoint = (Gx, Gy)  # This is our generator point. Trillions of dif ones possible

# Individual Transaction/Personal Information
privKey = 0x0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D


def modinv(a: int, n: int = Pcurve):  # MAXIMO COMUN DIVISOR: Extended Euclidean Algorithm/'division' in elliptic curves
    lm, hm = 1, 0
    resto = a % n
    high = n
    while resto &gt; 1:
        ratio = high // resto
        nm = hm - lm * ratio
        new = high - resto * ratio
        lm, resto, hm, high = nm, new, lm, resto
    return lm % n


def ECadd(a, b):  # Not true addition, invented for EC. Could have been called anything.
    LamAdd = ((b[1] - a[1]) * modinv(b[0] - a[0], Pcurve)) % Pcurve
    x = (LamAdd * LamAdd - a[0] - b[0]) % Pcurve
    y = (LamAdd * (a[0] - x) - a[1]) % Pcurve
    return x, y


def ECdouble(a):  # This is called point doubling, also invented for EC.
    Lam = ((3 * a[0] * a[0] + Acurve) * modinv((2 * a[1]), Pcurve)) % Pcurve
    x = (Lam * Lam - 2 * a[0]) % Pcurve
    y = (Lam * (a[0] - x) - a[1]) % Pcurve
    return x, y


def EccMultiply(gen_point: tuple, scalar_hex: int):  # Double &amp; add. Not true multiplication
    if scalar_hex == 0 or scalar_hex &gt;= N:
        raise Exception(&quot;Invalid Scalar/Private Key&quot;)
    ScalarBin = str(bin(scalar_hex))[2:]  # string binario sin el comienzo 0b
    Q = gen_point  # esto es una tupla de dos  integer del punto de generacion de la curva
    for i in range(1, len(ScalarBin)):
        Q = ECdouble(Q)
        if ScalarBin[i] == &quot;1&quot;:
            Q = ECadd(Q, gen_point)  #
    return Q


print(&quot;******* Public Key Generation *********&quot;)
print()
PublicKey = EccMultiply(GPoint, privKey)
print(&quot;the private key:&quot;)
print(privKey)
print()
print(&quot;the uncompressed public key (not address):&quot;)
print(PublicKey)
print()
x = hex(PublicKey[0])[2:].upper()
y = hex(PublicKey[1])[2:].upper()
print(f&quot;The x: {x}&quot;)
print(f&quot;The y: {y}&quot;)
print()
print(&quot;the uncompressed public key (HEX):&quot;)
pub_uncomp = f&quot;04{hex(PublicKey[0])[2:].upper()}{hex(PublicKey[1])[2:].upper()}&quot;
print(pub_uncomp)
print()
print(&quot;the official Public Key - compressed:&quot;)

if PublicKey[1] % 2 == 1:  # If the Y value for the Public Key is odd.
    print(&quot;03&quot; + str(hex(PublicKey[0])[2:]).zfill(64).upper())
else:  # Or else, if the Y value is even.
    print(&quot;02&quot; + str(hex(PublicKey[0])[2:]).zfill(64).upper())
</code></pre>
<p>Lastly you can see how to get the whole process, including WIF format and public addresses, check <a href="https://bitcoin.stackexchange.com/questions/102994/how-convert-bitcoin-privat-key-compression-to-public-address/103046#103046">this</a>.</p>
 109932: <p>Have you checked the &quot;Keys, Addresses&quot; chapter from &quot;Mastering Bitcoin&quot;?</p>
<p>You can read it for free here:
<a href="https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc" rel="nofollow noreferrer">https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc</a></p>
<p>The <a href="https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc#generating-a-public-key" rel="nofollow noreferrer">Generating a Public Key</a> section has also a visual representation for the &quot;multiplication of a point G by an integer k on an elliptic curve&quot;</p>
 5406: <p>In ECDSA, the private key is a scalar 256-bit number. The public key is a elliptic curve point on the secp256k1 curve. Elliptic curves are abelian groups made up of the set of points resulting from repeatedly applying its group operation starting with its base point <em>G</em>. The group operation is the addition of two points. So, starting with the base point as the first element, the second element is <em>G+G</em>, the addition of G to itself. The third element is <em>G+G+G</em>, etc. To enumerate all points of the curve would take eons, because the group order is <a href="https://jun-wang-2018.github.io/MyBlog/en/ECDSA-and-Bitcoin-II/" rel="nofollow noreferrer">115792089237316195423570985008687907852837564279074904382605163141518161494337</a>.</p>
<p>Anyway, to find the public key <em>Q</em> corresponding to a private key <em>k</em>, you have to &quot;walk&quot; <em>k</em> generator steps from the base point. We write this <em>elliptic curve scalar multiplication</em> as</p>
<blockquote>
<p>Q = G+G+…+G [k-times] = kG</p>
</blockquote>
<p>Now <em>secp256k1</em> is defined as</p>
<blockquote>
<p>y² = x³+7 mod P</p>
</blockquote>
<p>where <a href="https://jun-wang-2018.github.io/MyBlog/en/ECDSA-and-Bitcoin-II/" rel="nofollow noreferrer">P</a> is</p>
<blockquote>
<p>P = 2<sup>256</sup> - 2<sup>32</sup> - 2<sup>9</sup> - 2<sup>8</sup> - 2<sup>7</sup> - 2<sup>6</sup> - 2<sup>4</sup> - 1.</p>
</blockquote>
<p>In secp256k1, the <a href="https://jun-wang-2018.github.io/MyBlog/en/ECDSA-and-Bitcoin-II/" rel="nofollow noreferrer">base point</a> is <em>G(Gx,Gy)</em>, where</p>
<blockquote>
<p>G<sub>x</sub> =
55066263022277343669578718895168534326250603453777594175500187360389116729240</p>
<p>G<sub>y</sub> =
32670510020758816978083085130507043184471273380659243275938904335757337482424</p>
</blockquote>
<p>The <a href="https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Point_addition" rel="nofollow noreferrer">addition</a> of two points is defined as</p>
<blockquote>
<p>P + Q = R</p>
<p>(x<sub>p</sub>, y<sub>p</sub>) + (x<sub>q</sub>, y<sub>q</sub>) = (x<sub>r</sub>, y<sub>r</sub>)</p>
</blockquote>
<p>Which works out to be</p>
<blockquote>
<p>x<sub>r</sub> = (y<sub>q</sub> - y<sub>p</sub>) / (x<sub>q</sub> - x<sub>p</sub>) - x<sub>p</sub> - x<sub>q</sub></p>
<p>y<sub>r</sub> = ((y<sub>q</sub> - y<sub>p</sub>) / (x<sub>q</sub> - x<sub>p</sub>)) × (x<sub>p</sub> - x<sub>r</sub>) - y<sub>p</sub></p>
</blockquote>
<p>Note that the values are limited to [mod P]. So, taking your private key <em>k</em>, you now add <em>G</em> <em>k</em> times. There are some recommended shortcuts like first splitting <em>k</em> into a sum of factors of 2 (e.g. 37 = 1 + 2<sup>2</sup> + 2<sup>5</sup>), because it will speed up your calculation immensely. Since the numbers involved are kinda hard to keep track of manually, I'd recommend using a software library.</p>
<hr />
<p>Sources:</p>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm" rel="nofollow noreferrer">Wikipedia: Elliptic Curve Digital Signature Algorithm</a></li>
<li><a href="https://crypto.stackexchange.com/q/5756/8801">Crypto.SE: How to generate a public key from a private ECDSA key?</a></li>
<li><a href="https://jun-wang-2018.github.io/MyBlog/en/ECDSA-and-Bitcoin-II/" rel="nofollow noreferrer">Jun Wang: ECDSA and Bitcoin II</a></li>
<li><a href="https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication" rel="nofollow noreferrer">Wikipedia: Elliptic Curve Point Multiplication</a></li>
</ul>
