<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>

CC BY-SA 4.0
2021-02-25T10:32:59.333Z
Thank you for you reply, what i understand that k * n times G is equals to public key but question is remain same if k*n times G (where every point of G we get from point multiplication and point addition ) then at every multiplication of k*G will result a different value then how can we combine them get the public key
Muhammad Adnan Alam
CC BY-SA 4.0
2021-02-25T12:52:36.427Z
G - is a contant point, always the same accros all implementations; k - is a 256 bit number (private key); K = k * G;



More about G here: https://bitcoin.stackexchange.com/questions/29904/what-exactly-is-generator-g-in-bitcoins-elliptical-curve-algorithm
Vlad Stan
CC BY-SA 4.0
2021-02-23T11:59:10.343Z
2021-02-23T11:59:10.343Z
Vlad Stan
<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>

CC BY-SA 4.0
2021-02-26T11:38:56.333Z
2021-02-26T11:38:56.333Z
Nand0san
<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>

CC BY-SA 4.0
2021-02-26T04:59:28.043Z
Mentioning that elliptic curves are not “continuous” is kind of a red-herring, in a truly mathematical sense. Elliptic curves are typically not expressed as functions, thus it doesn’t make sense to talk about continuity. Using the implicit function theorem, we actually can talk about continuity and even differentiability for most EC’s, though as you say, what’s more important is their group structure.
Prince M
CC BY-SA 4.0
2021-02-26T13:27:37.833Z
Thanks, I dropped that phrase! :)
Murch
CC BY-SA 4.0
2021-02-26T21:19:10.380Z
As is usual for you, the rest of the answer is great and I enjoyed reading. I only mentioned that bit since OP was specifically asking about the mathematics :)
Prince M
CC BY-SA 4.0
2021-02-26T21:28:53.910Z
Thank you for the praise. If you have other suggestions, please let them be heard, I'm not a mathematician and did feel a bit out of my element writing this one.
Murch
CC BY-SA 4.0
2021-02-25T15:18:07.110Z
2022-04-26T11:24:38.593Z
2022-04-26T11:24:38.593Z
Murch
<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>

CC BY-SA 4.0
2021-02-25T19:36:58.667Z
I recommend reading [SEC 1](https://www.secg.org/sec1-v2.pdf), the official document that defines the math of ECDSA.  Then you might want to look at my [Ruby ECDSA](https://github.com/DavidEGrayson/ruby_ecdsa) gem, which is a straight-forward implementation of the math.
David Grayson
<private-key><public-key><ecdsa><secp256k1>
What is the math behind Bitcoin's elliptic curve?
Muhammad Adnan Alam
# What is the math behind Bitcoin's elliptic curve?

(Asked by: username_0 on 2021-02-23)

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?

**Tags:** private-key, public-key, ecdsa, secp256k1

> **Comments:**
> **username_1**: I recommend reading [SEC 1](https://www.secg.org/sec1-v2.pdf), the official document that defines the math of ECDSA.  Then you might want to look at my [Ruby ECDSA](https://github.com/DavidEGrayson/ruby_ecdsa) gem, which is a straight-forward implementation of the math.  

---

## 3 answers

### Answer by username_4 on 2021-02-25. Score: 4 | Accepted answer

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](https://jun-wang-2018.github.io/MyBlog/en/ECDSA-and-Bitcoin-II/).

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](https://jun-wang-2018.github.io/MyBlog/en/ECDSA-and-Bitcoin-II/) is

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

In secp256k1, the [base point](https://jun-wang-2018.github.io/MyBlog/en/ECDSA-and-Bitcoin-II/) is *G(Gx,Gy)*, where

> Gx =
> 55066263022277343669578718895168534326250603453777594175500187360389116729240
>
> Gy =
> 32670510020758816978083085130507043184471273380659243275938904335757337482424

The [addition](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Point_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](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)
* [Crypto.SE: How to generate a public key from a private ECDSA key?](https://crypto.stackexchange.com/q/5756/8801)
* [Jun Wang: ECDSA and Bitcoin II](https://jun-wang-2018.github.io/MyBlog/en/ECDSA-and-Bitcoin-II/)
* [Wikipedia: Elliptic Curve Point Multiplication](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication)

> **Comments:**
> **username_5**: Mentioning that elliptic curves are not “continuous” is kind of a red-herring, in a truly mathematical sense. Elliptic curves are typically not expressed as functions, thus it doesn’t make sense to talk about continuity. Using the implicit function theorem, we actually can talk about continuity and even differentiability for most EC’s, though as you say, what’s more important is their group structure.  
> **username_4**: Thanks, I dropped that phrase! :)  
> **username_5**: As is usual for you, the rest of the answer is great and I enjoyed reading. I only mentioned that bit since OP was specifically asking about the mathematics :)  
> **username_4**: Thank you for the praise. If you have other suggestions, please let them be heard, I'm not a mathematician and did feel a bit out of my element writing this one.  

---

### Answer by username_2 on 2021-02-23. Score: 2

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](https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc#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"

> **Comments:**
> **username_0**: Thank you for you reply, what i understand that k * n times G is equals to public key but question is remain same if k*n times G (where every point of G we get from point multiplication and point addition ) then at every multiplication of k*G will result a different value then how can we combine them get the public key  
> **username_2**: G - is a contant point, always the same accros all implementations; k - is a 256 bit number (private key); K = k * G;    More about G here: https://bitcoin.stackexchange.com/questions/29904/what-exactly-is-generator-g-in-bitcoins-elliptical-curve-algorithm  

---

### Answer by username_3 on 2021-02-26. Score: 1

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)](https://www.youtube.com/watch?v=iB3HcPgm_FI)

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](https://bitcoin.stackexchange.com/questions/102994/how-convert-bitcoin-privat-key-compression-to-public-address/103046#103046).


---

