<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Mikhail Karavaev</title>
    <description>The latest articles on Forem by Mikhail Karavaev (@exemak).</description>
    <link>https://forem.com/exemak</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F938505%2F7a20691f-bb45-4c00-8dc7-a5f119449c73.jpg</url>
      <title>Forem: Mikhail Karavaev</title>
      <link>https://forem.com/exemak</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/exemak"/>
    <language>en</language>
    <item>
      <title>How to exchange a secret key over an insecure network (EC-Diffie-Hellman algorithm)</title>
      <dc:creator>Mikhail Karavaev</dc:creator>
      <pubDate>Thu, 15 Dec 2022 18:25:44 +0000</pubDate>
      <link>https://forem.com/exemak/how-to-exchange-a-secret-key-over-an-insecure-network-ec-diffie-hellman-algorithm-1gj2</link>
      <guid>https://forem.com/exemak/how-to-exchange-a-secret-key-over-an-insecure-network-ec-diffie-hellman-algorithm-1gj2</guid>
      <description>&lt;p&gt;Let's say you want to send an encrypted message to your friend in order to avoid it being intercepted and read by a third party. You just generate a random secret key and encrypt the message with it. Let's say you are using &lt;a href="https://en.wikipedia.org/wiki/Advanced_Encryption_Standard"&gt;AES&lt;/a&gt;. But how do you let your friend know the key to decrypt it?&lt;/p&gt;

&lt;p&gt;You could give the key to your friend offline. Just write it on paper and give it to him/her. But what if it's not an option? &lt;/p&gt;

&lt;p&gt;What if you can only use an &lt;strong&gt;insecure&lt;/strong&gt; data communication channel with a middleman intercepting the messages?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5JX8xOjW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1r596errijc25y0rith5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5JX8xOjW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1r596errijc25y0rith5.png" alt="Source: https://www.treinaweb.com.br/blog/termos-comuns-de-seguranca-man-in-the-middle" width="880" height="495"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Source of the image: &lt;a href="https://www.treinaweb.com.br/blog/termos-comuns-de-seguranca-man-in-the-middle"&gt;https://www.treinaweb.com.br/blog/termos-comuns-de-seguranca-man-in-the-middle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There is a way to securely exchange secret keys even in the presence of a third party!&lt;/strong&gt;&lt;br&gt;
You just exchange some information with your friend and &lt;strong&gt;both of you come up with the same key&lt;/strong&gt;. The middleman also sees the messages you've exchanged. But he will never be able to guess the secret key. Does it sound exciting? Let's see how it's possible.&lt;/p&gt;
&lt;h2&gt;
  
  
  Diffie-Hellman Algorithm
&lt;/h2&gt;

&lt;p&gt;The algorithm is based on an extremely simple algebraic feature that we are all familiar with.&lt;br&gt;
&lt;strong&gt;The commutative property of multiplication&lt;/strong&gt;. In other words:&lt;br&gt;
A * B * C = B * A * C = C * A * B, …&lt;br&gt;
I know, it doesn't seem relevant to anything yet.&lt;/p&gt;
&lt;h3&gt;
  
  
  A very rough (and incomplete) example
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Let's &lt;em&gt;imagine&lt;/em&gt;, the &lt;strong&gt;division&lt;/strong&gt; operation &lt;strong&gt;doesn't exist&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You and your friend &lt;strong&gt;both know&lt;/strong&gt; some number, let's say, &lt;strong&gt;12345&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You generate some random Private key, let's say, &lt;strong&gt;23456&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Your friend generates a random Private key too, let's say &lt;strong&gt;34567&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You multiply your Private key &lt;strong&gt;23456&lt;/strong&gt; by &lt;strong&gt;12345&lt;/strong&gt; = &lt;strong&gt;289564320&lt;/strong&gt; (Public key)&lt;/li&gt;
&lt;li&gt;Your friend multiplies his/her Private key &lt;strong&gt;34567&lt;/strong&gt; by &lt;strong&gt;12345&lt;/strong&gt; = &lt;strong&gt;426729615&lt;/strong&gt; (Public key)&lt;/li&gt;
&lt;li&gt;!!! &lt;em&gt;at this point, we just imagine the division operation doesn't exist&lt;/em&gt; !!!&lt;/li&gt;
&lt;li&gt;You and your friend send the results of multiplication (the Public keys) to each other (&lt;strong&gt;289564320&lt;/strong&gt; and &lt;strong&gt;426729615&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;Your friend multiplies your Public key &lt;strong&gt;289564320&lt;/strong&gt; by his Private key &lt;strong&gt;34567&lt;/strong&gt; = &lt;strong&gt;10009369849440&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You multiply your friend's Public key &lt;strong&gt;426729615&lt;/strong&gt; by your Private key &lt;strong&gt;23456&lt;/strong&gt; = &lt;strong&gt;10009369849440&lt;/strong&gt;, and this is the shared key&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Profit! You came up with the same value!&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But… the only problem is that the division operation actually exists, so it's extremely easy to extract the Private key from a Public key.&lt;/p&gt;

&lt;p&gt;A middleman could just divide Public keys by &lt;strong&gt;12345&lt;/strong&gt;, and extract the Private keys: &lt;strong&gt;289564320/12345 = 23456&lt;/strong&gt;, &lt;strong&gt;426729615/12345 = 34567&lt;/strong&gt;, and then  just multiply the private keys by the shared number: &lt;strong&gt;23456 * 34567 * 12345 = 10009369849440&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That was the general idea of the Diffie Hellman, and now let's focus on an actual form.&lt;/p&gt;

&lt;p&gt;Let’s combine the &lt;strong&gt;Diffie-Hellman&lt;/strong&gt; idea with &lt;strong&gt;Elliptic Curve Cryptography&lt;/strong&gt; as it’s the most used implementation nowadays. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To fully understand the topic, I highly recommend checking &lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-14-the-magic-of-elliptic-curves-2n7h"&gt;my article on Elliptic Curve Cryptography&lt;/a&gt;. It requires no more than middle-school math.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Very short: Essentials of Elliptic Curves cryptography
&lt;/h2&gt;

&lt;p&gt;I don’t think it’s possible to explain how the Elliptic curves are used in cryptography briefly. But here are the most important properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can multiply any point lying on a curve by a scalar value&lt;/li&gt;
&lt;li&gt;There is no feasible way to extract the scalar value back (to divide a point by a scalar value or by another point)&lt;/li&gt;
&lt;li&gt;A private key in elliptic curve cryptography is just a random value that’s kept secret&lt;/li&gt;
&lt;li&gt;The corresponding Public key is just a result of the multiplication of some certain point G by the Private key (PublicKey = PrivateKey * G)&lt;/li&gt;
&lt;li&gt;The G point is standardized and everyone uses it&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  How to securely exchange the keys over a public network?
&lt;/h3&gt;

&lt;p&gt;Let’s suppose we have two parties: Alice and Bob (&lt;a href="http://cryptocouple.com/"&gt;why again these names?&lt;/a&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Here is a &lt;strong&gt;[way too] colorful&lt;/strong&gt; explanation of the Diffie-Hellman key exchange mechanism. It may not look too pretty, but the colors which occur as the results of multiplication are actually the mixes of original colors. &lt;strong&gt;Squares&lt;/strong&gt; indicate &lt;strong&gt;scalar&lt;/strong&gt; values, and the &lt;strong&gt;circles&lt;/strong&gt; indicate &lt;strong&gt;points&lt;/strong&gt; on an Elliptic curve.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Both Alice and Bob generate &lt;strong&gt;big random numbers&lt;/strong&gt;, and we call these numbers the &lt;strong&gt;Private Keys&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JX8zjEET--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xptakiwy8hnx2stoarwd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JX8zjEET--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xptakiwy8hnx2stoarwd.png" alt="Image description" width="880" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then Alice &lt;strong&gt;multiplies&lt;/strong&gt; her &lt;strong&gt;Private&lt;/strong&gt; Key by the publicly known &lt;strong&gt;G&lt;/strong&gt; point in order to get her &lt;strong&gt;Public&lt;/strong&gt; Key:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aFFa-4ra--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pw5gbye8foiytzjuo9lq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aFFa-4ra--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pw5gbye8foiytzjuo9lq.png" alt="Image description" width="880" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And Bob &lt;strong&gt;multiplies&lt;/strong&gt; his &lt;strong&gt;Private&lt;/strong&gt; Key by the same point &lt;strong&gt;G&lt;/strong&gt; to get his &lt;strong&gt;Public&lt;/strong&gt; Key:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T_NQIh77--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zd7ow9tu4tsih53f6tqu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T_NQIh77--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zd7ow9tu4tsih53f6tqu.png" alt="Image description" width="880" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now they both have their pairs of PrivateKey-PublicKey:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UexCgoKE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/df780f650iu98qa4yo5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UexCgoKE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/df780f650iu98qa4yo5z.png" alt="Image description" width="880" height="294"&gt;&lt;/a&gt;&lt;br&gt;
The next step is to exchange the public keys. &lt;/p&gt;

&lt;p&gt;Alice &lt;strong&gt;sends&lt;/strong&gt; her &lt;strong&gt;Public&lt;/strong&gt; Key to Bob. And Bob &lt;strong&gt;sends&lt;/strong&gt; his &lt;strong&gt;Public&lt;/strong&gt; Key to Alice:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--84LkKzo2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zojxvkj456gsczv13xf3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--84LkKzo2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zojxvkj456gsczv13xf3.png" alt="Image description" width="880" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, Alice and Bob have each other’s &lt;strong&gt;Public&lt;/strong&gt; keys, but a &lt;strong&gt;middleman&lt;/strong&gt; &lt;strong&gt;also&lt;/strong&gt; potentially knows their &lt;strong&gt;Public&lt;/strong&gt; keys:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ARCh3k7l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c5y60g2mvgl3ida4o58b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ARCh3k7l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c5y60g2mvgl3ida4o58b.png" alt="Image description" width="880" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you remember, &lt;strong&gt;Private&lt;/strong&gt; Key &lt;strong&gt;can’t be extracted&lt;/strong&gt; back from the &lt;strong&gt;Public&lt;/strong&gt; key. So knowing the &lt;strong&gt;Public keys&lt;/strong&gt; is o*&lt;em&gt;f no use&lt;/em&gt;* to a middleman.&lt;/p&gt;
&lt;h3&gt;
  
  
  Then the magic happens.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Alice&lt;/strong&gt; takes &lt;strong&gt;Bob’s Public Key&lt;/strong&gt; (a point on an Elliptic curve) and &lt;strong&gt;multiplies&lt;/strong&gt; it into her &lt;strong&gt;Private&lt;/strong&gt; Key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wVYYdqwY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jt17bia7jgv89qht9ny3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wVYYdqwY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jt17bia7jgv89qht9ny3.png" alt="Image description" width="880" height="566"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Bob&lt;/strong&gt; does the same. He takes &lt;strong&gt;Alice’s Public Key&lt;/strong&gt; and &lt;strong&gt;multiplies&lt;/strong&gt; it into his own &lt;strong&gt;Private&lt;/strong&gt; Key:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_nv3xYX4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/onckmsus6o453avlnpki.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_nv3xYX4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/onckmsus6o453avlnpki.png" alt="Image description" width="880" height="558"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  They end up with the same Secret key without explicitly exchanging it
&lt;/h3&gt;

&lt;p&gt;Actually, it’s a very simple math trick. &lt;br&gt;
Let’s take a look at how their &lt;strong&gt;Public keys&lt;/strong&gt; are calculated:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rSDWd9gZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ut7mkoxbhh79yobho4n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rSDWd9gZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ut7mkoxbhh79yobho4n.png" alt="Image description" width="880" height="166"&gt;&lt;/a&gt;&lt;br&gt;
Not let’s look at how both parties calculate the shared keys:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TR11GSol--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o1sgc96wjrb6ynrkrxun.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TR11GSol--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o1sgc96wjrb6ynrkrxun.png" alt="Image description" width="880" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s see if &lt;strong&gt;BobSecretKey&lt;/strong&gt; = &lt;strong&gt;AliceSecretKey&lt;/strong&gt; by comparing their definitions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1l6G_yz3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7re78inny0783ykjn9g2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1l6G_yz3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7re78inny0783ykjn9g2.png" alt="Image description" width="880" height="86"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s substitute &lt;strong&gt;AlicePublicKey&lt;/strong&gt; and &lt;strong&gt;BobPublicKey&lt;/strong&gt; with their definitions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0j6kGcas--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e9uk53jf7fwwo06u6tyy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0j6kGcas--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e9uk53jf7fwwo06u6tyy.png" alt="Image description" width="880" height="75"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The expressions are the same.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you don’t yet understand why and how we are able to multiply points on Elliptic curves like numbers, I recommend &lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-14-the-magic-of-elliptic-curves-2n7h"&gt;reading the article&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Both Alice and Bob now have ended up with the same &lt;strong&gt;SecretKey&lt;/strong&gt; (point on a curve), which they didn’t expose to a middleman.&lt;/p&gt;

&lt;p&gt;And the middleman can do nothing with their &lt;strong&gt;Public Keys&lt;/strong&gt; which he has potentially intercepted.&lt;/p&gt;
&lt;h3&gt;
  
  
  Let’s implement it in Python
&lt;/h3&gt;

&lt;p&gt;In my article on Elliptic curves, I have a code snippet for using the secp256k1 elliptic curve, written in Python. For more details on how it works, check the &lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-44-ecdsa-implementation-in-python-using-zero-dependencies-410c"&gt;article's PART 4&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What’s important is that we have the &lt;em&gt;g_point&lt;/em&gt; instance, which has the .multiply method for multiplying the point by any scalar value. The return value of this method is also a point.&lt;/p&gt;

&lt;p&gt;Let’s pick random private keys for Alice and bob:&lt;br&gt;
&lt;code&gt;alice_private_key = 4115217275797054326758545175592171983915694080873854598446270747 #any random number&lt;br&gt;
bob_private_key = 4954095651507529369947464574074855803473979998363142920136936367 #any random number&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then let’s calculate the public keys for both of them:&lt;br&gt;
&lt;code&gt;alice_public_key = g_point.multiply(alice_private_key)&lt;br&gt;
bob_public_key = g_point.multiply(bob_private_key)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now let’s imagine they have sent the private keys to each other. Alice calculates the secret key on her side:&lt;br&gt;
&lt;code&gt;alice_secret_key = bob_public_key.multiply(alice_private_key)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Bob calculates his secret key on his side:&lt;br&gt;
&lt;code&gt;bob_secret_key = alice_public_key.multiply(bob_private_key)&lt;/code&gt;&lt;br&gt;
Now let’s print the secret keys:&lt;br&gt;
&lt;code&gt;print(bob_secret_key.x, bob_secret_key.y)&lt;br&gt;
print(alice_secret_key.x, alice_secret_key.y)&lt;/code&gt;&lt;br&gt;
The result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kXezkF3H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jafvgvg4ev5s3j4zna7b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kXezkF3H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jafvgvg4ev5s3j4zna7b.png" alt="Image description" width="880" height="52"&gt;&lt;/a&gt;&lt;br&gt;
It works!&lt;/p&gt;
&lt;h3&gt;
  
  
  Here is the complete Python code using zero dependencies for you to try it yourself
&lt;/h3&gt;

&lt;p&gt;Complete code: &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In case you might need it, here is an &lt;a href="https://www.programiz.com/python-programming/online-compiler/"&gt;online tool for running Python code right in your browser&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="mailto:exemak@gmail.com"&gt;exemak@gmail.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://t.me/exemak"&gt;t.me/exemak&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mikhail Karavaev&lt;/p&gt;

</description>
      <category>python</category>
      <category>security</category>
      <category>programming</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>Bitcoin Signatures From Scratch (4/4): ECDSA Implementation in Python Using Zero Dependencies</title>
      <dc:creator>Mikhail Karavaev</dc:creator>
      <pubDate>Mon, 17 Oct 2022 20:18:43 +0000</pubDate>
      <link>https://forem.com/exemak/bitcoin-signatures-from-scratch-44-ecdsa-implementation-in-python-using-zero-dependencies-410c</link>
      <guid>https://forem.com/exemak/bitcoin-signatures-from-scratch-44-ecdsa-implementation-in-python-using-zero-dependencies-410c</guid>
      <description>&lt;p&gt;The series consists of four parts; each part uses the concepts discovered in the previous parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-14-the-magic-of-elliptic-curves-2n7h"&gt;The Magic of Elliptic Curves&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-24-the-magic-of-elliptic-curves-combined-with-finite-fields-249o"&gt;The Magic of Elliptic Curves Combined with Finite Fields&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-34-using-the-magic-of-elliptic-curves-to-sign-and-verify-messages-41i2"&gt;Using The Magic of Elliptic Curves to Sign and Verify Messages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ECDSA Implementation in Python Using Zero Dependencies&lt;/strong&gt; [you're here]&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The bottlenecks:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;We need to be able to perform basic arithmetical operations on very large numbers. In programming we can easily operate on large numbers, using &lt;a href="https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic"&gt;bignum arithmetic&lt;/a&gt;. Just google it, and you will find out how easy it is. 
So our programming language must support it, or we should use some external package to work with it.
In the examples of this part, I will use &lt;strong&gt;Python&lt;/strong&gt;, which supports bignum arithmetic out of the box. 
For the Live Demo, I will use JavaScript, and there we will need the &lt;a href="https://www.npmjs.com/package/bignumber.js"&gt;BigNumber.js package&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The other bottleneck that we will encounter is &lt;strong&gt;finding the multiplicative inverse&lt;/strong&gt; of a very large number. Obviously, brute force is not going to work. 
The multiplicative inverse can be found by the &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm"&gt;Extended Euclidean algorithm&lt;/a&gt;, which has the complexity of O(log(n))&lt;/strong&gt;. Python (3.8+) can do it out of the box with its built-in &lt;strong&gt;pow&lt;/strong&gt; function:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;modulus&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;modulus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;If you need the actual implementation of the algorithm, check my Live Demo!&lt;/strong&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Let’s start writing our code!
&lt;/h3&gt;

&lt;p&gt;We need one simple thing, related to the elliptic curve: &lt;strong&gt;Point&lt;/strong&gt;. Let’s define a class &lt;strong&gt;Point&lt;/strong&gt;.  In its constructor, we should make check, whether the point lies on the curve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The point is not on the curve"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curve_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to be able to &lt;strong&gt;compare two points&lt;/strong&gt;, &lt;strong&gt;add them together&lt;/strong&gt;, and &lt;strong&gt;multiply them by an integer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s add a method to check if two points are equal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_equal_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s implement &lt;strong&gt;add&lt;/strong&gt; method, which returns a new Point as the result of addition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_equal_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;

        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
        &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the formulas are listed in &lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-24-the-magic-of-elliptic-curves-combined-with-finite-fields-249o"&gt;Part 2&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now let’s implement the &lt;strong&gt;multiply&lt;/strong&gt; method: &lt;/p&gt;

&lt;p&gt;The most straightforward implementation would be this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But let’s say we need to multiply our point by a big number: 115792089237316195. Even if we had the speed of 1 billion additions per second, this would take &lt;strong&gt;3.6 years to calculate this point&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And this is not even a big number for us!&lt;/strong&gt; Here is a big number:&lt;/p&gt;

&lt;p&gt;115792089237316195423570985008687907852837564279074904382605163141518161494337&lt;/p&gt;

&lt;p&gt;Calculating the point in this way would take &lt;strong&gt;billions of billions of billions of billions… of years&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;We can define that the efficiency of this algorithm above is O(n), which is of no use for our purposes. If you remember, there is an easy way to achieve &lt;strong&gt;O(log2(n))&lt;/strong&gt; complexity by continuously doubling our point:&lt;/p&gt;

&lt;p&gt;2P = P+P&lt;/p&gt;

&lt;p&gt;4P = 2P + 2P&lt;/p&gt;

&lt;p&gt;8P = 4P + 4P&lt;/p&gt;

&lt;p&gt;16P = 8P + 8P&lt;/p&gt;

&lt;p&gt;32P= 16P + 16P&lt;/p&gt;

&lt;p&gt;64P = 32P + 32P&lt;/p&gt;

&lt;p&gt;And so &lt;strong&gt;log2(115792089237316195) =&lt;/strong&gt; &lt;strong&gt;56&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;log2(115792089237316195423570985008687907852837564279074904382605163141518161494337)&lt;/strong&gt; = &lt;strong&gt;256&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So we don’t need billions of billions of billions… of years. &lt;strong&gt;We just need 256 operations to get to this large point&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Just one moment: to efficiently multiply by values that are not a degree of 2, it’s reasonable to store all the previous values, and then combine the results together.&lt;/p&gt;

&lt;p&gt;For example, if we need to get 100P, we can no longer double 64P. Neither we can add points one by one: potentially this would take billions of billions of years on larger numbers. What’s reasonable to do instead, is:&lt;/p&gt;

&lt;p&gt;96P = 64P + 32P&lt;/p&gt;

&lt;p&gt;100P = 96P + 4P&lt;/p&gt;

&lt;p&gt;So for that purpose, we need to store all the previous P’s and afterwards efficiently use them.&lt;/p&gt;

&lt;p&gt;So here is an efficient implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;current_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;
        &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

        &lt;span class="n"&gt;pervious_points&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# store current point as a previous point
&lt;/span&gt;            &lt;span class="n"&gt;pervious_points&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;current_coefficient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="c1"&gt;# if we can multiply our current point by 2, do it
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;current_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt;
            &lt;span class="c1"&gt;# if we can't multiply our current point by 2, let's find the biggest previous point to add to our point
&lt;/span&gt;            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;next_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;
                &lt;span class="n"&gt;next_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;previous_coefficient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;previous_point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;pervious_points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;previous_coefficient&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;previous_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                            &lt;span class="n"&gt;next_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;previous_coefficient&lt;/span&gt;
                            &lt;span class="n"&gt;next_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;previous_point&lt;/span&gt;
                &lt;span class="n"&gt;current_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;next_coefficient&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thus we’ve got a super efficient implementation! And now we can perform all the needed operations on an elliptic curve.&lt;/p&gt;

&lt;p&gt;Let’s define secp256k1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;secp256k1_curve_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;115792089237316195423570985008687907853269984665640564039457584007908834671663&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;55066263022277343669578718895168534326250603453777594175500187360389116729240&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;32670510020758816978083085130507043184471273380659243275938904335757337482424&lt;/span&gt;
&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;115792089237316195423570985008687907852837564279074904382605163141518161494337&lt;/span&gt;
&lt;span class="n"&gt;g_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secp256k1_curve_config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’m using only decimal numbers in our examples because they’re intuitive for a human. &lt;/p&gt;

&lt;h3&gt;
  
  
  So far we’ve implemented everything that we discussed in &lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-24-the-magic-of-elliptic-curves-combined-with-finite-fields-249o"&gt;Part 2&lt;/a&gt;. Now let’s implement the actual digital signature algorithm, described in the &lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-34-using-the-magic-of-elliptic-curves-to-sign-and-verify-messages-41i2"&gt;Part 3&lt;/a&gt;.
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Sign method of ECDSA:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sign_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sign_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;k_inverse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;k_inverse&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify method of ECDSA:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verify_signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;
    &lt;span class="n"&gt;s_inverse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;s_inverse&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;s_inverse&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="n"&gt;c_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;c_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s pick some random number as our private key, for example, &lt;strong&gt;123456789012345&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let our message be 12345.&lt;/p&gt;

&lt;p&gt;Do you remember how to get &lt;strong&gt;PublicKey&lt;/strong&gt; from &lt;strong&gt;PrivateKey&lt;/strong&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;private_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123456789012345&lt;/span&gt;  &lt;span class="c1"&gt;# any random integer
&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12345&lt;/span&gt;  &lt;span class="c1"&gt;# any integer
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s sign and try to verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sign_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Signature: '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Is valid: '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verify_signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works! You can try to corrupt the signature or the original message and make sure that our algorithm works properly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Here is the complete code:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;random&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;modulus&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;modulus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The point is not on the curve"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curve_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_equal_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_equal_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;

        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
        &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;current_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;
        &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

        &lt;span class="n"&gt;pervious_points&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# store current point as a previous point
&lt;/span&gt;            &lt;span class="n"&gt;pervious_points&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;current_coefficient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="c1"&gt;# if we can multiply our current point by 2, do it
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;current_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt;
            &lt;span class="c1"&gt;# if we can't multiply our current point by 2, let's find the biggest previous point to add to our point
&lt;/span&gt;            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;next_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;
                &lt;span class="n"&gt;next_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;previous_coefficient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;previous_point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;pervious_points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;previous_coefficient&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;previous_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                            &lt;span class="n"&gt;next_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;previous_coefficient&lt;/span&gt;
                            &lt;span class="n"&gt;next_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;previous_point&lt;/span&gt;
                &lt;span class="n"&gt;current_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;next_coefficient&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;

&lt;span class="n"&gt;secp256k1_curve_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;115792089237316195423570985008687907853269984665640564039457584007908834671663&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;55066263022277343669578718895168534326250603453777594175500187360389116729240&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;32670510020758816978083085130507043184471273380659243275938904335757337482424&lt;/span&gt;
&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;115792089237316195423570985008687907852837564279074904382605163141518161494337&lt;/span&gt;
&lt;span class="n"&gt;g_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secp256k1_curve_config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sign_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sign_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;k_inverse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;k_inverse&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verify_signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;
    &lt;span class="n"&gt;s_inverse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;s_inverse&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;s_inverse&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="n"&gt;c_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;c_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;

&lt;span class="c1"&gt;# test starts here
&lt;/span&gt;&lt;span class="n"&gt;private_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123456789012345&lt;/span&gt;  &lt;span class="c1"&gt;# any random integer
&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12345&lt;/span&gt;  &lt;span class="c1"&gt;# any integer
&lt;/span&gt;
&lt;span class="n"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sign_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Signature: '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Is valid: '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verify_signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  So the implementation of the entire ECDSA algorithm took just 100 lines of code! And it’s perfectly working. This is absolutely the same algorithm as the one used in Bitcoin!
&lt;/h3&gt;

&lt;h1&gt;
  
  
  Live Demo
&lt;/h1&gt;

&lt;p&gt;As I promised at the beginning of this article, here is the live demo using &lt;strong&gt;only&lt;/strong&gt; the concepts and formulas described in the article. Just a couple of notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initially, we could only sign integer messages. But in the demo, you can &lt;strong&gt;choose&lt;/strong&gt; to apply a &lt;strong&gt;hash&lt;/strong&gt; function (&lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/SHA-2"&gt;sha256&lt;/a&gt;&lt;/strong&gt;) to your message. Thanks to it, a message can be a string.&lt;/li&gt;
&lt;li&gt;Bitcoin uses slightly different formats of &lt;a href="https://river.com/learn/terms/s/sec-format/"&gt;public keys&lt;/a&gt; and &lt;a href="https://river.com/learn/terms/d/der/"&gt;signatures&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never&lt;/strong&gt; use it in a production environment! &lt;strong&gt;It is not safe&lt;/strong&gt;. For production, you must &lt;strong&gt;only&lt;/strong&gt; use &lt;a href="https://www.openssl.org/"&gt;well-tested solutions&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/k6s7uo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  The end of the series
&lt;/h1&gt;

&lt;p&gt;I hope this series of articles was very useful for you. At least, I did my best to make it useful. Feel free to share it with friends or use any piece of it anywhere. Just please leave a link to the original article.&lt;/p&gt;




&lt;p&gt;Feel free to contact me and ask questions: &lt;/p&gt;

&lt;p&gt;&lt;a href="mailto:exemak@gmail.com"&gt;exemak@gmail.com&lt;/a&gt;&lt;br&gt;
t.me/exemak&lt;br&gt;
Mikhail Karavaev&lt;/p&gt;

</description>
      <category>programming</category>
      <category>blockchain</category>
      <category>python</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Bitcoin Signatures From Scratch (3/4): Using The Magic of Elliptic Curves to Sign and Verify Messages</title>
      <dc:creator>Mikhail Karavaev</dc:creator>
      <pubDate>Mon, 17 Oct 2022 20:08:12 +0000</pubDate>
      <link>https://forem.com/exemak/bitcoin-signatures-from-scratch-34-using-the-magic-of-elliptic-curves-to-sign-and-verify-messages-41i2</link>
      <guid>https://forem.com/exemak/bitcoin-signatures-from-scratch-34-using-the-magic-of-elliptic-curves-to-sign-and-verify-messages-41i2</guid>
      <description>&lt;p&gt;The series consists of four parts; each part uses the concepts discovered in the previous parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-14-the-magic-of-elliptic-curves-2n7h"&gt;The Magic of Elliptic Curves&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-24-the-magic-of-elliptic-curves-combined-with-finite-fields-249o"&gt;The Magic of Elliptic Curves Combined with Finite Fields&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using The Magic of Elliptic Curves to Sign and Verify Messages&lt;/strong&gt; [you're here]&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-44-ecdsa-implementation-in-python-using-zero-dependencies-410c"&gt;ECDSA Implementation in Python Using Zero Dependencies&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Let's start here!
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm"&gt;Elliptic Curves Digital Signature Algorithm&lt;/a&gt; works exactly over the algebra that we’ve just discovered in the &lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-24-the-magic-of-elliptic-curves-combined-with-finite-fields-249o"&gt;previous part&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This algorithm allows a person to &lt;strong&gt;sign&lt;/strong&gt; a &lt;strong&gt;message&lt;/strong&gt; using his or her &lt;strong&gt;PrivateKey&lt;/strong&gt;, so that anyone else can &lt;strong&gt;verify&lt;/strong&gt; that the &lt;strong&gt;signature&lt;/strong&gt; actually &lt;strong&gt;belongs&lt;/strong&gt; to that person, knowing their &lt;strong&gt;PublicKey&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  This is what actually happens when you &lt;strong&gt;sign&lt;/strong&gt; a &lt;strong&gt;message&lt;/strong&gt; in blockchains:
&lt;/h3&gt;

&lt;p&gt;You have a pair of keys: &lt;strong&gt;PrivateKey&lt;/strong&gt; — &lt;strong&gt;PublicKey&lt;/strong&gt;. Everyone knows your &lt;strong&gt;PublicKey&lt;/strong&gt;, but no one except you knows your &lt;strong&gt;PrivateKey&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You just generate some &lt;strong&gt;message&lt;/strong&gt; like “&lt;strong&gt;I want to send X amount of crypto to address Y&lt;/strong&gt;”, and then you &lt;strong&gt;sign&lt;/strong&gt; that message (using exactly the algorithm discovered in this article).  Other parties can &lt;strong&gt;verify&lt;/strong&gt; that the &lt;strong&gt;message&lt;/strong&gt; was actually &lt;strong&gt;signed&lt;/strong&gt; by you.&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;

&lt;p&gt;Everything spins around one certain &lt;strong&gt;predefined&lt;/strong&gt; &lt;strong&gt;point&lt;/strong&gt; &lt;strong&gt;G&lt;/strong&gt;, lying on a &lt;strong&gt;predefined&lt;/strong&gt; &lt;strong&gt;elliptic curve&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We can generate any &lt;strong&gt;random integer&lt;/strong&gt; and call it our &lt;strong&gt;PrivateKey.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If we multiply this PrivateKey to point G, we will get the PublicKey. &lt;br&gt;
So PublicKey = PrivateKey * G:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CCV8Jsoc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ytqlau21yavqgbgu4x8c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CCV8Jsoc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ytqlau21yavqgbgu4x8c.png" alt="" width="880" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes, &lt;strong&gt;PublicKey&lt;/strong&gt; is just a point on a curve.&lt;/p&gt;

&lt;p&gt;As we already know, we can't divide point by point or point by a scalar value. All possible operations are listed at the end of &lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-14-the-magic-of-elliptic-curves-2n7h"&gt;Part 1&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So there is &lt;strong&gt;no efficient way&lt;/strong&gt; to get the &lt;strong&gt;PrivateKey&lt;/strong&gt; back because we can't divide &lt;strong&gt;PublicKey&lt;/strong&gt; by &lt;strong&gt;G&lt;/strong&gt;. This operation doesn't exist. Brute-forcing potentially works, but when there is really giant number of possible points, for example, that giant:&lt;/p&gt;

&lt;p&gt;115792089237316195423570985008687907852837564279074904382605163141518161494337&lt;/p&gt;

&lt;h3&gt;
  
  
  Even if someone uses all the existing computing power in the world, this would take billions of billions of billions… of years to find the &lt;strong&gt;PrivateKey&lt;/strong&gt;.
&lt;/h3&gt;

&lt;p&gt;In ECDSA we have this set of “global” public variables. &lt;strong&gt;They are specified by standards&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elliptic curve with some config (&lt;strong&gt;a&lt;/strong&gt;, &lt;strong&gt;b&lt;/strong&gt;, &lt;strong&gt;p&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;Point &lt;strong&gt;G&lt;/strong&gt;, which lies on the curve (its &lt;strong&gt;x&lt;/strong&gt; and &lt;strong&gt;y&lt;/strong&gt; coordinates). This is called the &lt;strong&gt;Generator Point&lt;/strong&gt;. This point is standardized.&lt;/li&gt;
&lt;li&gt;Order &lt;strong&gt;n&lt;/strong&gt; of point &lt;strong&gt;G&lt;/strong&gt;. As we know, order &lt;strong&gt;n&lt;/strong&gt; is the property for point &lt;strong&gt;G,&lt;/strong&gt; so as G*(n+1) = G, G*(n+2) = 2G, and so on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are the variables that belong to a certain owner:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PrivateKey&lt;/strong&gt; - kept secret by the owner&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PublicKey&lt;/strong&gt; - shared with the public&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And, variables that are specific to one &lt;strong&gt;signing&lt;/strong&gt; operation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;message&lt;/strong&gt; itself: any integer that is not larger than order n. &lt;strong&gt;Usually&lt;/strong&gt;, a &lt;strong&gt;hash&lt;/strong&gt; of string is used. But for simplicity reasons, we will use pure integers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;K&lt;/strong&gt; - random integer, that is generated when signing a message, exactly for that signature. This is kept secret and there is no way to find it by a third party.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the complete picture. Green stickers indicate that the variable is shared with the public, and the red ones indicate the variables that are kept secret.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I3d8jsyM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8tpcz0pfek1jvmywqml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I3d8jsyM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8tpcz0pfek1jvmywqml.png" alt="" width="880" height="1173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Way too many variables!&lt;br&gt;
Here are the algorithms for &lt;strong&gt;signing&lt;/strong&gt; and &lt;strong&gt;verifying&lt;/strong&gt; a message:&lt;/p&gt;

&lt;h3&gt;
  
  
  The algorithm for signing a message:
&lt;/h3&gt;

&lt;p&gt;We have our &lt;strong&gt;PrivateKey&lt;/strong&gt; and &lt;strong&gt;message&lt;/strong&gt;. To sign a message, we should*&lt;em&gt;:&lt;/em&gt;*&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate a random integer &lt;strong&gt;k&lt;/strong&gt;. This should be a big number. [1, &lt;strong&gt;n&lt;/strong&gt;-1]&lt;/li&gt;
&lt;li&gt;Calculate point &lt;strong&gt;R = G * k&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calculate &lt;strong&gt;r&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6avZnhb---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5yjxoe4rodstruvodsga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6avZnhb---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5yjxoe4rodstruvodsga.png" alt="" width="880" height="170"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calculate &lt;strong&gt;s:&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8vZC5bsy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8jfbz876umyx5gt5e8v5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8vZC5bsy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8jfbz876umyx5gt5e8v5.png" alt="" width="880" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it. &lt;strong&gt;The signature is a pair of points (r, s).&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Here is the visual representation of the algorithm:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MENwzGI---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fb0x3n6jya57wtlmzcg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MENwzGI---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fb0x3n6jya57wtlmzcg.png" alt="" width="880" height="682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The algorithm for verifying a signature
&lt;/h3&gt;

&lt;p&gt;We have the signer’s &lt;strong&gt;PublicKey&lt;/strong&gt;, &lt;strong&gt;message&lt;/strong&gt;, and &lt;strong&gt;signature(r, s).&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Calculate &lt;strong&gt;U&lt;/strong&gt;: &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FzJ-zJEV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g2wx160ppl8w0nd0ukk1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FzJ-zJEV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g2wx160ppl8w0nd0ukk1.png" alt="" width="880" height="161"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calculate &lt;strong&gt;V&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gbaO5jts--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wpth9gx00hnnrpb45q2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gbaO5jts--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wpth9gx00hnnrpb45q2q.png" alt="" width="880" height="158"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calculate point &lt;strong&gt;C&lt;/strong&gt; = &lt;strong&gt;U&lt;/strong&gt; * &lt;strong&gt;G&lt;/strong&gt; + &lt;strong&gt;V&lt;/strong&gt; * &lt;strong&gt;PublicKey&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If &lt;strong&gt;C&lt;/strong&gt;.x mod &lt;strong&gt;n&lt;/strong&gt; = &lt;strong&gt;r&lt;/strong&gt;, then the signature is valid. Invalid otherwise.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--knP0iSMx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s7z1d5njog4ll5eb60cg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--knP0iSMx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s7z1d5njog4ll5eb60cg.png" alt="" width="880" height="734"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not obvious at all!&lt;/p&gt;

&lt;p&gt;Actually, this is just a mathematical trick.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let’s play with our formulas and prove that it works!
&lt;/h3&gt;

&lt;p&gt;In step 3 of our &lt;strong&gt;verification&lt;/strong&gt; algorithm we have a point &lt;strong&gt;C = U * G + V * PublicKey:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H4kgIhzR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ufphupqj4u6l6imtnlbu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H4kgIhzR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ufphupqj4u6l6imtnlbu.png" alt="" width="880" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s substitute the variables &lt;strong&gt;U, V, and PublicKey&lt;/strong&gt; with their definitions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fw_DhclG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hb6hn2ub04av938c6xs4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fw_DhclG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hb6hn2ub04av938c6xs4.png" alt="" width="880" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q2S2x9CT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iq2u24or0416hslglfq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q2S2x9CT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iq2u24or0416hslglfq8.png" alt="" width="880" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that G * s^-1 is duplicated. Let’s simplify the formula:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4BP8sYKY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fo33kpikci3eb8m2ts1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4BP8sYKY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fo33kpikci3eb8m2ts1.png" alt="" width="880" height="117"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s see the definition of s in step &lt;strong&gt;4&lt;/strong&gt; of the &lt;strong&gt;signing&lt;/strong&gt; algorithm:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--POn2-qgf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pvlt9mau9c2yiv5hujrg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--POn2-qgf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pvlt9mau9c2yiv5hujrg.png" alt="" width="880" height="165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s substitute s^-1 in our formula:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hB6mxRoL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9dztc0lt8xdj398uz6lx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hB6mxRoL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9dztc0lt8xdj398uz6lx.png" alt="" width="880" height="112"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s simplify this part:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GaQpqp8w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yuzmyb4kc7846crhagzo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GaQpqp8w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yuzmyb4kc7846crhagzo.png" alt="" width="880" height="71"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_4C09sHC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zqmtg3c63a3uhsthyum5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_4C09sHC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zqmtg3c63a3uhsthyum5.png" alt="" width="880" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thus, if the signature is correct, the &lt;strong&gt;x&lt;/strong&gt; coordinate of &lt;strong&gt;C mod n&lt;/strong&gt; is equal to &lt;strong&gt;r&lt;/strong&gt; (which is, by its definition, the same &lt;strong&gt;x&lt;/strong&gt; coordinate of &lt;strong&gt;G * k&lt;/strong&gt;). &lt;/p&gt;

&lt;h3&gt;
  
  
  Secp256k1 standardized variables:
&lt;/h3&gt;

&lt;p&gt;For the elliptic curve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a=0&lt;/li&gt;
&lt;li&gt;b=7&lt;/li&gt;
&lt;li&gt;p=&lt;code&gt;115792089237316195423570985008687907853269984665640564039457584007908834671663&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For point G:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;x coordinate = &lt;code&gt;55066263022277343669578718895168534326250603453777594175500187360389116729240&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;y coordinate = &lt;code&gt;32670510020758816978083085130507043184471273380659243275938904335757337482424&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Order n = &lt;code&gt;115792089237316195423570985008687907852837564279074904382605163141518161494337&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Done! Now we know absolutely EVERYTHING essential!
&lt;/h3&gt;

&lt;p&gt;The next part is going to be the easiest part for programmers. For everyone else, it’s not necessary to follow. Just proceed to the &lt;strong&gt;Live Demo&lt;/strong&gt; at the end of the next part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next part: &lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-44-ecdsa-implementation-in-python-using-zero-dependencies-410c"&gt;ECDSA Implementation in Python Using Zero Dependencies&lt;/a&gt;
&lt;/h2&gt;




&lt;p&gt;Feel free to contact me and ask questions: &lt;/p&gt;

&lt;p&gt;&lt;a href="mailto:exemak@gmail.com"&gt;exemak@gmail.com&lt;/a&gt;&lt;br&gt;
t.me/exemak&lt;br&gt;
Mikhail Karavaev&lt;/p&gt;

</description>
      <category>programming</category>
      <category>computerscience</category>
      <category>blockchain</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Bitcoin Signatures From Scratch (2/4): The Magic of Elliptic Curves Combined with Finite Fields</title>
      <dc:creator>Mikhail Karavaev</dc:creator>
      <pubDate>Mon, 17 Oct 2022 19:55:21 +0000</pubDate>
      <link>https://forem.com/exemak/bitcoin-signatures-from-scratch-24-the-magic-of-elliptic-curves-combined-with-finite-fields-249o</link>
      <guid>https://forem.com/exemak/bitcoin-signatures-from-scratch-24-the-magic-of-elliptic-curves-combined-with-finite-fields-249o</guid>
      <description>&lt;p&gt;The series consists of four parts; each part uses the concepts discovered in the previous parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-14-the-magic-of-elliptic-curves-2n7h"&gt;The Magic of Elliptic Curves&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Magic of Elliptic Curves Combined with Finite Fields&lt;/strong&gt; [you’re here]&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-34-using-the-magic-of-elliptic-curves-to-sign-and-verify-messages-41i2"&gt;Using The Magic of Elliptic Curves to Sign and Verify Messages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-44-ecdsa-implementation-in-python-using-zero-dependencies-410c"&gt;ECDSA Implementation in Python Using Zero Dependencies&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  The Essentials of Finite Fields
&lt;/h1&gt;

&lt;p&gt;We don’t need to study everything about &lt;a href="http://web.stanford.edu/~marykw/classes/CS250_W19/readings/Forney_Introduction_to_Finite_Fields.pdf"&gt;finite fields&lt;/a&gt;. All we need here is to understand a couple of essential properties to move on and be able to operate on a certain “algebra” of finite fields.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To simplify, finite field is an algebraic concept where we have a &lt;strong&gt;finite&lt;/strong&gt; number of elements, which we can add, subtract, multiply, or divide, and the &lt;strong&gt;algebra will continue working properly&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Have you heard of the &lt;strong&gt;modulus&lt;/strong&gt; operation? If you’re a programmer, probably you did. This is just a &lt;strong&gt;reminder of division&lt;/strong&gt;, and in programming languages, it’s usually expressed as a &lt;strong&gt;%&lt;/strong&gt; (or &lt;strong&gt;mod&lt;/strong&gt;) operator. For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2  mod 11 = 2&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;10 mod 11 = 10&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;11 mod 11 = 0&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;13 mod 11 = 2&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;14 mod 11 = 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If we try numbers from &lt;strong&gt;0&lt;/strong&gt; to &lt;strong&gt;33 mod 11&lt;/strong&gt;, we will get these numbers: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It works &lt;strong&gt;like a clock&lt;/strong&gt;. &lt;code&gt;We can call this a finite field of order 11&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  We need to know just 4 properties:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The order of multiplication doesn’t matter.&lt;/strong&gt; &lt;br&gt;
&lt;strong&gt;a*b*c&lt;/strong&gt; mod n &lt;strong&gt;is the same as&lt;/strong&gt;  (&lt;strong&gt;a&lt;/strong&gt; mod n) * (&lt;strong&gt;b&lt;/strong&gt; mod n) * (&lt;strong&gt;c&lt;/strong&gt; mod n) mod n, &lt;strong&gt;which is the same as&lt;/strong&gt; (&lt;strong&gt;a*b&lt;/strong&gt; mod n) * &lt;strong&gt;c&lt;/strong&gt; mod n&lt;br&gt;
Example:&lt;br&gt;
&lt;strong&gt;6 * 7 * 8&lt;/strong&gt; mod 11 = &lt;strong&gt;336&lt;/strong&gt; mod 11 = &lt;strong&gt;6, same as:&lt;/strong&gt;&lt;br&gt;
(&lt;strong&gt;6 * 7&lt;/strong&gt; mod 11) * &lt;strong&gt;8&lt;/strong&gt; mod 11 = (&lt;strong&gt;42&lt;/strong&gt; mod 11) * &lt;strong&gt;9&lt;/strong&gt; mod 11 = &lt;strong&gt;9 * 8&lt;/strong&gt; mod 11 = &lt;strong&gt;72&lt;/strong&gt; mod 11 = &lt;strong&gt;6&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Negative number&lt;/strong&gt; &lt;strong&gt;mod n is the&lt;/strong&gt; &lt;strong&gt;same as n-(|negative number| mod n&lt;/strong&gt;). &lt;br&gt;
Examples:&lt;br&gt;
&lt;strong&gt;-4 mod 11&lt;/strong&gt; = 11-(4 mod 11) = &lt;strong&gt;11-4 = 7&lt;br&gt;
-7 mod 11&lt;/strong&gt; = 11 - (7 mod 11) = &lt;strong&gt;11 - 7 = 4&lt;br&gt;
-9 mod 11&lt;/strong&gt; = 11 - (9 mod 11) = &lt;strong&gt;11-9 = 2&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;-2 mod 11&lt;/strong&gt; = 11 - (2 mod 11) = &lt;strong&gt;11 - 2 = 9&lt;br&gt;
-13 mod 11&lt;/strong&gt; = 11 - (13 mod 11) = &lt;strong&gt;11 - 2 = 9&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;“Multiplicative inverse”: for any a, there is a number b, such as a*b mod n = 1.&lt;br&gt;
If a * b mod 11 = 1,&lt;/strong&gt; &lt;strong&gt;a&lt;/strong&gt; is called the &lt;strong&gt;multiplicative inverse of b&lt;/strong&gt; &lt;strong&gt;modulo&lt;/strong&gt; &lt;strong&gt;n&lt;/strong&gt;, and &lt;strong&gt;vice versa&lt;/strong&gt;: &lt;strong&gt;b&lt;/strong&gt; is called the &lt;a href="https://en.wikipedia.org/wiki/Multiplicative_inverse"&gt;multiplicative inverse&lt;/a&gt; of &lt;strong&gt;a&lt;/strong&gt; modulo n. &lt;br&gt;
Example:&lt;br&gt;
1) &lt;strong&gt;5 * x mod 11&lt;/strong&gt; = 1. Let’s try values for x one by one, and we will find out &lt;strong&gt;x = 9&lt;/strong&gt;. So &lt;strong&gt;9 is the multiplicative inverse of 5 modulo 11&lt;/strong&gt;.&lt;br&gt;
2) &lt;strong&gt;7 * x mod 11 = 1&lt;/strong&gt;. Let’s try our brute force again and we will find out &lt;strong&gt;x = 8&lt;/strong&gt;. 8 is the multiplicative inverse of 7 modulo 11.&lt;br&gt;
3) &lt;strong&gt;10 * x mod 11 = 1. x = 10.&lt;/strong&gt; So 10 is the multiplicative inverse of 10 modulo 11.&lt;br&gt;
Usually, it’s done by the &lt;a href="https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm"&gt;extended Euclidean algorithm&lt;/a&gt;, but it’s a matter of a separate article. So for now, let’s just use brute force.&lt;br&gt;
Also, &lt;strong&gt;n&lt;/strong&gt; must be a prime number!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The division is the same operation as multiplication by the multiplicative inverse!&lt;/strong&gt; Last and the most important property:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fGHKbFGi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bqavopj2t2z4hseh3mxy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fGHKbFGi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bqavopj2t2z4hseh3mxy.png" alt="" width="880" height="156"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, when we need to deal with division mod n, we can easily calculate it.&lt;/p&gt;

&lt;p&gt;Let’s see an example: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q4y_GoZC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/occrvwwlme85bdce55lg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q4y_GoZC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/occrvwwlme85bdce55lg.png" alt="" width="880" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why is &lt;strong&gt;2&lt;/strong&gt; the &lt;strong&gt;multiplicative inverse&lt;/strong&gt; of &lt;strong&gt;6 mod 11&lt;/strong&gt;? Because &lt;strong&gt;6&lt;/strong&gt; * &lt;strong&gt;2&lt;/strong&gt; = 12, 12 mod 11 = &lt;strong&gt;1&lt;/strong&gt;. &lt;/p&gt;
&lt;h3&gt;
  
  
  That’s it! Now we know how to operate on finite fields “algebra”.
&lt;/h3&gt;
&lt;h1&gt;
  
  
  Elliptic Curves Over Finite Fields
&lt;/h1&gt;

&lt;p&gt;Here’s where it becomes less obvious and a little harder to understand. &lt;strong&gt;But this is exactly how elliptic curves are used in cryptography&lt;/strong&gt;. What we need to do is exactly what is said in the title: "put our elliptic curve over a finite field."&lt;/p&gt;

&lt;p&gt;So, here is how our formula changes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TInz8WTf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4kk1ox2j1fxpz6uvbxhw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TInz8WTf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4kk1ox2j1fxpz6uvbxhw.png" alt="" width="880" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything is the same as in the original formula but now both parts of the equation are now under the modulo p. &lt;/p&gt;

&lt;p&gt;Let’s use the elliptic curve with the following configuration for our examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a = 0&lt;/li&gt;
&lt;li&gt;b = 7&lt;/li&gt;
&lt;li&gt;p = 11&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s find all the points on this curve running this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the result: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(2, 2), (2, 9), (3, 1), (3, 10), (4, 4), (4, 7), (5, 0), (5,11), (6, 5), (6, 6), (7, 3), (7, 8)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s see what it looks like on a coordinate grid:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3Pp8XNHI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4z305nrg0j7d2yjt4t35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3Pp8XNHI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4z305nrg0j7d2yjt4t35.png" alt="" width="880" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s try a=0, b=7, p=23:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--55ds8Izk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9w47jtozapkrsnu8so4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--55ds8Izk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9w47jtozapkrsnu8so4g.png" alt="" width="880" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Doesn’t look like anything, right? No distinguishable shape.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  But! What turns out is that it preserves all the properties and formulas of the “original” elliptic curve!
&lt;/h3&gt;

&lt;p&gt;So now we’ve got an elliptic curve, that &lt;strong&gt;doesn’t look like an elliptic curve.&lt;/strong&gt; But! It has a finite set of points, and most importantly, &lt;strong&gt;works like an elliptic curve&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  We need to slightly modify our formulas from PART I with respect to mod p:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multiplying a point by -1&lt;/strong&gt;:&lt;br&gt;
If we have a point &lt;strong&gt;A(x, y),&lt;/strong&gt; we can easily get &lt;strong&gt;-A&lt;/strong&gt; by multiplying its &lt;strong&gt;y&lt;/strong&gt; coordinate by &lt;strong&gt;-1 modulo p&lt;/strong&gt;.&lt;br&gt;
&lt;strong&gt;Example:&lt;br&gt;
-1 * A(2, 2) → -A(2, -2 mod 11) = -A(2, 9)&lt;br&gt;
-1 * A(2, 9) → -A(2, -9 mod 11) = -A(2, 2)&lt;br&gt;
-1 * A(6, 5) → -A(6, -5 mod 11) = -A(6, 6)&lt;br&gt;
-1 * A(6, 6) → -A(6, -6 mod 11) = -A(6, 5)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adding two points together&lt;/strong&gt;:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fBZnMtsP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/al272xm89jttc9r19a7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fBZnMtsP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/al272xm89jttc9r19a7w.png" alt="" width="880" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Adding a point to itself&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mfFFkfes--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/scoiyz5v2aehl9uq78t4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mfFFkfes--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/scoiyz5v2aehl9uq78t4.png" alt="" width="880" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don’t yet understand the concept of multiplicative inverse, please, go back to PART II and check it once more.&lt;/p&gt;

&lt;h3&gt;
  
  
  That’s it! Time to practice!
&lt;/h3&gt;

&lt;p&gt;For our examples, we will use the elliptic curve with &lt;strong&gt;a=0, b=7, and order p=11&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let’s pick a point &lt;strong&gt;C(7, 8)&lt;/strong&gt; and calculate &lt;strong&gt;2C&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ArUVK7uj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/959qlbwohw9ip63w2wvx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ArUVK7uj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/959qlbwohw9ip63w2wvx.png" alt="" width="880" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can now easily calculate 4C:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---GKDSXJ8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pnltg8q4w127zwk4er8t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---GKDSXJ8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pnltg8q4w127zwk4er8t.png" alt="" width="880" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s calculate &lt;strong&gt;4C - C&lt;/strong&gt;, which is essentially &lt;strong&gt;3C = 4C + (-C)&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xn7AAGiy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7cq5gb4mxe1gt4nvpq84.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xn7AAGiy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7cq5gb4mxe1gt4nvpq84.png" alt="" width="880" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s add &lt;strong&gt;3C = C + 2C&lt;/strong&gt; and see if the result is the same:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R5hvkVfp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/38iz9hczqghmdwyzrv57.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R5hvkVfp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/38iz9hczqghmdwyzrv57.png" alt="" width="880" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The math perfectly works here!
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;One super important property&lt;/strong&gt;: Every point on a curve has its own &lt;strong&gt;order n&lt;/strong&gt;!&lt;br&gt;
It works like a modulo. For example, if the &lt;strong&gt;order n&lt;/strong&gt; of point &lt;strong&gt;C&lt;/strong&gt; is &lt;strong&gt;12&lt;/strong&gt;, it means that 12*C = 0(the point doesn’t exist), &lt;strong&gt;13*C = C&lt;/strong&gt;,  &lt;strong&gt;16*C = 4C&lt;/strong&gt;, &lt;strong&gt;27*C = 3C&lt;/strong&gt;. This property is &lt;strong&gt;predefined&lt;/strong&gt; for a point.&lt;/p&gt;

&lt;p&gt;You can practice and make sure it works. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The order of our point C is actually 12.&lt;/strong&gt; I suggest a task for you: try calculating &lt;strong&gt;8C&lt;/strong&gt; by adding &lt;strong&gt;4C + 4C&lt;/strong&gt;. Then try adding &lt;strong&gt;8C + 8C&lt;/strong&gt;. You will get &lt;strong&gt;16C&lt;/strong&gt;, which will be the same point as &lt;strong&gt;4C&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It works like a clock:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9IFIoTl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/700q40tt961c2mmykekx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9IFIoTl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/700q40tt961c2mmykekx.png" alt="" width="880" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we know &lt;strong&gt;absolutely everything essential&lt;/strong&gt; for using the elliptic curves in cryptography.&lt;/p&gt;

&lt;h3&gt;
  
  
  To recap
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;All formulas work fine. We can still calculate &lt;strong&gt;any integer x * Point&lt;/strong&gt;. We still need approximately log2(x) operations!&lt;/li&gt;
&lt;li&gt;Elliptic curves have now a finite set of points&lt;/li&gt;
&lt;li&gt;Points now have their own &lt;strong&gt;order n&lt;/strong&gt;, so they tend to repeat themselves like in a clock.&lt;/li&gt;
&lt;li&gt;To define an elliptic curve, we now need three variables: &lt;strong&gt;a&lt;/strong&gt;, &lt;strong&gt;b&lt;/strong&gt;, and &lt;strong&gt;p&lt;/strong&gt;. &lt;strong&gt;p&lt;/strong&gt; is called the order of an elliptic curve.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How do we know, which &lt;strong&gt;a&lt;/strong&gt;, &lt;strong&gt;b&lt;/strong&gt;, and &lt;strong&gt;p&lt;/strong&gt; to use? It’s standardized! There are many standards out there.&lt;/p&gt;

&lt;h3&gt;
  
  
  What do Bitcoin and Ethereum use?
&lt;/h3&gt;

&lt;p&gt;They use the &lt;strong&gt;standardized elliptic curve&lt;/strong&gt; called &lt;strong&gt;secp256k1&lt;/strong&gt;. It has the following variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a=&lt;strong&gt;0&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;b=&lt;strong&gt;7&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;p=&lt;strong&gt;115792089237316195423570985008687907853269984665640564039457584007908834671663&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quite a big number! I think you’re starting to guess why elliptic curves are so good for cryptography.&lt;/p&gt;

&lt;p&gt;Now that we know everything essential, let’s use it in cryptography in the next part!&lt;/p&gt;

&lt;h2&gt;
  
  
  Next part: &lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-34-using-the-magic-of-elliptic-curves-to-sign-and-verify-messages-41i2"&gt;Using The Magic of Elliptic Curves to Sign and Verify Messages&lt;/a&gt;
&lt;/h2&gt;




&lt;p&gt;Feel free to contact me and ask questions: &lt;/p&gt;

&lt;p&gt;&lt;a href="mailto:exemak@gmail.com"&gt;exemak@gmail.com&lt;/a&gt;&lt;br&gt;
t.me/exemak&lt;br&gt;
Mikhail Karavaev&lt;/p&gt;

</description>
      <category>programming</category>
      <category>algorithms</category>
      <category>blockchain</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Bitcoin Signatures From Scratch (1/4): The Magic of Elliptic Curves</title>
      <dc:creator>Mikhail Karavaev</dc:creator>
      <pubDate>Mon, 17 Oct 2022 19:41:49 +0000</pubDate>
      <link>https://forem.com/exemak/bitcoin-signatures-from-scratch-14-the-magic-of-elliptic-curves-2n7h</link>
      <guid>https://forem.com/exemak/bitcoin-signatures-from-scratch-14-the-magic-of-elliptic-curves-2n7h</guid>
      <description>&lt;h2&gt;
  
  
  Intro to Series
&lt;/h2&gt;

&lt;p&gt;Elliptic curves are very simple. The Elliptic Curves Digital Signature Algorithm (ECDSA) is the crucial element of most blockchains like Bitcoin, Ethereum, etc. It is essentially a couple of simple formulas working on top of the properties of elliptic curves.&lt;/p&gt;

&lt;p&gt;Yet it isn’t easy to find a good explanation on the internet and build all the pieces together. But here it is! In this short series of articles, we will.&lt;/p&gt;

&lt;p&gt;The series requires knowing &lt;strong&gt;no more than middle-school math&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Only the last part&lt;/strong&gt; of the series is intended for programmers.&lt;br&gt;
There we will implement ECDSA using zero dependencies, and it will take &lt;strong&gt;only 100 lines of code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In parts 1, 2, and 3, we will discover &lt;strong&gt;all&lt;/strong&gt; the concepts and formulas needed to completely understand and implement the algorithm — one by one. At the end of this series, we will have a fully functioning &lt;strong&gt;demo&lt;/strong&gt; implemented from scratch, using &lt;strong&gt;only&lt;/strong&gt; the concepts and formulas discovered here. We will be able to &lt;strong&gt;extract the public key&lt;/strong&gt; from the private key, &lt;strong&gt;sign a message&lt;/strong&gt;, and &lt;strong&gt;verify&lt;/strong&gt; that the signature is correct.&lt;/p&gt;




&lt;p&gt;The series consists of four parts; each part uses the concepts discovered in the previous parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Magic of Elliptic Curves&lt;/strong&gt; [you’re here]&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-24-the-magic-of-elliptic-curves-combined-with-finite-fields-249o"&gt;The Magic of Elliptic Curves Combined with Finite Fields&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-34-using-the-magic-of-elliptic-curves-to-sign-and-verify-messages-41i2"&gt;Using The Magic of Elliptic Curves to Sign and Verify Messages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-44-ecdsa-implementation-in-python-using-zero-dependencies-410c"&gt;ECDSA Implementation in Python Using Zero Dependencies&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Let’s start here!
&lt;/h3&gt;

&lt;p&gt;We’re all probably familiar with all those graphs on coordinate grids, where the y variable somehow depends on x. For example, y = x, y = x^2, and so on. Most probably we all have some experience with it. Let’s look at them: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zcDTwzn0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6zaqztvvchr18ytfvww.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zcDTwzn0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6zaqztvvchr18ytfvww.png" alt="" width="880" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The equation for an elliptic curve is not much different!&lt;/strong&gt; It has the form of y^2 = x^3 + a*x + b. What’s &lt;strong&gt;a&lt;/strong&gt; and &lt;strong&gt;b&lt;/strong&gt;? Just some arbitrary constants. Let’s see how it looks with a = 0, b = 7, just like in the Bitcoin curve:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MLdU-LR5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ooff282mxor0o30ydhkc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MLdU-LR5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ooff282mxor0o30ydhkc.png" alt="" width="880" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  It has the following 3 super important properties, upon which everything works:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;This is where it may get hard to follow and understand &lt;a href="https://www.youtube.com/watch?v=6eZQu120A80"&gt;why&lt;/a&gt;. You may even think this is something incoherent and irrelevant. But please trust me. These properties will lead us to a very amazing result! But now let’s pretend that we’re just having fun without a purpose.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;The elliptic curve is symmetric along the &lt;strong&gt;x-&lt;/strong&gt;axis. It means that &lt;strong&gt;for any point on the curve A&lt;/strong&gt;, we can get its mirror point, called &lt;strong&gt;-A&lt;/strong&gt;, by simply mirroring its &lt;strong&gt;y&lt;/strong&gt; coordinate:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8XIzMoev--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v583p3itsxffygxtj9i5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8XIzMoev--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v583p3itsxffygxtj9i5.png" alt="" width="880" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If we draw a line through &lt;strong&gt;any of two points not lying on a vertical line&lt;/strong&gt;, it will &lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=6eZQu120A80"&gt;intersect&lt;/a&gt;&lt;/strong&gt; the &lt;strong&gt;curve at exactly one more point&lt;/strong&gt;! 
Let’s draw a line through the &lt;strong&gt;A&lt;/strong&gt; and &lt;strong&gt;B&lt;/strong&gt; points, and call the third point &lt;strong&gt;—C&lt;/strong&gt;. Then let’s reflect it to get point &lt;strong&gt;C&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HDst0Nzi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oo3c1g6wtnnboxcirzzz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HDst0Nzi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oo3c1g6wtnnboxcirzzz.png" alt="" width="880" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--95R28jM7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r4hxunh6enz048pl5a6s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--95R28jM7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r4hxunh6enz048pl5a6s.png" alt="" width="880" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This C point is called the sum of A and B. So A + B = C.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If we draw a &lt;strong&gt;tangent&lt;/strong&gt; &lt;strong&gt;line&lt;/strong&gt; through any point &lt;strong&gt;A&lt;/strong&gt; lying on a curve, it will intersect the curve at &lt;strong&gt;exactly one point&lt;/strong&gt;. We will call this point &lt;strong&gt;-2A.&lt;/strong&gt; We already know how to get &lt;strong&gt;2A&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VyO1Bju9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vaiyefi6ljt4zwd8kyew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VyO1Bju9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vaiyefi6ljt4zwd8kyew.png" alt="" width="880" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The easiest way to think about a tangent line is to imagine that it intersects A point twice. As if it intersects the curve not at two points, but at three: &lt;strong&gt;A&lt;/strong&gt;, &lt;strong&gt;A&lt;/strong&gt;, &lt;strong&gt;-2A&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  That’s it! We defined three mathematical operations on the elliptic curve: multiplying the point by -1, adding two points together, and doubling the point.
&lt;/h3&gt;

&lt;h3&gt;
  
  
  And here is where the algebra of elliptic curves starts working.
&lt;/h3&gt;

&lt;p&gt;Now we have the following picture with points &lt;strong&gt;A&lt;/strong&gt;, &lt;strong&gt;2A&lt;/strong&gt;, and &lt;strong&gt;-2A&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uSkXx9l4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f0mej196zeo1zjp3ga8c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uSkXx9l4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f0mej196zeo1zjp3ga8c.png" alt="" width="880" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s draw a line through &lt;strong&gt;A&lt;/strong&gt; and &lt;strong&gt;2A&lt;/strong&gt;. The third point that we’ll get is &lt;strong&gt;-3A&lt;/strong&gt;. Then just reflect it to get &lt;strong&gt;3A&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cBBwEPs7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z9lh9ep8bbugfe5gmmx3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cBBwEPs7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z9lh9ep8bbugfe5gmmx3.png" alt="" width="880" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You probably don’t yet understand why we’re doing all of it. Just look at one more step.&lt;/p&gt;

&lt;p&gt;What if we try drawing a line between &lt;strong&gt;3A&lt;/strong&gt; and &lt;strong&gt;-2A&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2tKgNZb8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cuzcqutpsu2urx04ubuq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2tKgNZb8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cuzcqutpsu2urx04ubuq.png" alt="" width="880" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you see the magic?&lt;/strong&gt; By drawing a line between &lt;strong&gt;3A&lt;/strong&gt; and &lt;strong&gt;-2A&lt;/strong&gt; we’re getting the &lt;strong&gt;-A&lt;/strong&gt; point, which is the reflection of our original &lt;strong&gt;A&lt;/strong&gt; point along the x-axis!&lt;/p&gt;

&lt;h3&gt;
  
  
  What we just defined in the three points above, is the algebra of elliptic curves.
&lt;/h3&gt;

&lt;p&gt;Just try to understand the power of those three operations: essentially now we can perform operations on the points lying on a curve &lt;strong&gt;as if they’re not points, but just numbers&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;What we &lt;strong&gt;can&lt;/strong&gt; do with points on a curve: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Addition of two points &lt;strong&gt;(A + B)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Subtraction of two points &lt;strong&gt;A - B&lt;/strong&gt; = &lt;strong&gt;(A + (-B))&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Doubling of the point (multiplication by two) &lt;strong&gt;2*A&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multiplying by any integer (by combining the previous operations together, we can get any integer * Point)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What we &lt;strong&gt;can’t&lt;/strong&gt; do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiplication of two points&lt;/li&gt;
&lt;li&gt;Division of a point over another point&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Division of a point over a scalar value&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, to get &lt;strong&gt;10A&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;2*A = 2A&lt;br&gt;
2*2A = 4A&lt;br&gt;
2*4A = 8A&lt;br&gt;
8A + 2A = 10A&lt;/p&gt;

&lt;p&gt;It’s also good to notice that the calculation may be performed in a logarithmic amount of operations. So the approximate amount of operations needed for calculating &lt;strong&gt;n * Point&lt;/strong&gt; is &lt;strong&gt;O(log2(n))&lt;/strong&gt;!&lt;/p&gt;

&lt;h3&gt;
  
  
  Eventually, we can multiply a point by any integer, but there is no way to get the integer back! This is the gist of it! And this is what makes the elliptic curves very good for cryptography. This algebra works for infinitely large numbers.
&lt;/h3&gt;

&lt;h3&gt;
  
  
  The only drawback, for now, is the need to draw it. But of course, there are mathematical formulas for reflecting a point, for addition, and for doubling a point:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multiplying the point by -1&lt;/strong&gt;. &lt;br&gt;
If we have a point &lt;strong&gt;A(x, y)&lt;/strong&gt;, we can easily get &lt;strong&gt;-A&lt;/strong&gt; by multiplying its &lt;strong&gt;y&lt;/strong&gt; coordinate by &lt;strong&gt;-1.&lt;/strong&gt; -A(x, -y).&lt;br&gt;
&lt;strong&gt;Example&lt;/strong&gt;:&lt;br&gt;
-1 * A(2, 2) → -A(2, -2)&lt;br&gt;
-1 * A(1, -1) → -A(1, 1)&lt;br&gt;
-1 * A(5, 8) → -A(5, -8)&lt;br&gt;
-1 * A(5, -8) → -A(5, 8)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adding two points together.&lt;/strong&gt;&lt;br&gt;
We can add two points together, but with one condition: they should not lie on a vertical line (their x coordinates should not be equal). This is the formula for adding &lt;strong&gt;A&lt;/strong&gt; and &lt;strong&gt;B (A + B = C)&lt;/strong&gt;:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B0TI7sTz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/62w7l2ux6q2ymkxmap43.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B0TI7sTz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/62w7l2ux6q2ymkxmap43.png" alt="" width="880" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Adding a point to itself&lt;/strong&gt; (multiplying a point by 2). This is a very similar operation to the addition of two points, but slightly different:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C4klKnl3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u05iq4nz9n6bq4suqaec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C4klKnl3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u05iq4nz9n6bq4suqaec.png" alt="" width="880" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  That’s it! Time to practice!
&lt;/h3&gt;

&lt;p&gt;Let’s try adding A and B here (let’s use approximation to 3 points after a comma):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IRYNt0iP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uijmoztgt13c93875hf0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IRYNt0iP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uijmoztgt13c93875hf0.png" alt="" width="880" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;According to the formula defined above for adding two points,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9SJVAeIo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u68wnhc00rr5kvewkxug.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9SJVAeIo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u68wnhc00rr5kvewkxug.png" alt="" width="880" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s find our point &lt;strong&gt;C&lt;/strong&gt; graphically:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6xv3QqUZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6khlvne69razfxg2rkj8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6xv3QqUZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6khlvne69razfxg2rkj8.png" alt="" width="880" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It works!&lt;/strong&gt; Yes, with a small proximity issue, because of rounding. But it works!&lt;/p&gt;

&lt;p&gt;For better understanding, I recommend you try to perform all those operations on your own.&lt;/p&gt;

&lt;h3&gt;
  
  
  This was all we need to know about elliptic curves and the operations on them that we need to be able to perform!
&lt;/h3&gt;

&lt;p&gt;Everything is fine, but we need a couple more properties for building a cryptography system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next part: &lt;a href="https://dev.to/exemak/bitcoin-signatures-from-scratch-24-the-magic-of-elliptic-curves-combined-with-finite-fields-249o"&gt;The Magic of Elliptic Curves Combined with Finite Fields&lt;/a&gt;
&lt;/h2&gt;




&lt;p&gt;Feel free to contact me and ask questions: &lt;/p&gt;

&lt;p&gt;&lt;a href="mailto:exemak@gmail.com"&gt;exemak@gmail.com&lt;/a&gt;&lt;br&gt;
t.me/exemak&lt;br&gt;
Mikhail Karavaev&lt;/p&gt;

</description>
      <category>programming</category>
      <category>blockchain</category>
      <category>algorithms</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Elliptic curves and ECDSA: everything to know to sign a transaction in Bitcoin from scratch</title>
      <dc:creator>Mikhail Karavaev</dc:creator>
      <pubDate>Thu, 06 Oct 2022 22:33:31 +0000</pubDate>
      <link>https://forem.com/exemak/elliptic-curves-and-ecdsa-from-understanding-the-concept-to-signing-a-transaction-in-bitcoin-1gpg</link>
      <guid>https://forem.com/exemak/elliptic-curves-and-ecdsa-from-understanding-the-concept-to-signing-a-transaction-in-bitcoin-1gpg</guid>
      <description>&lt;p&gt;The elliptic curve is a pretty simple concept. The Elliptic Curves Digital Signature Algorithm (ECDSA), which works on top of its properties, is used in most blockchains like Bitcoin, Ethereum, etc., and is even simpler. But it’s difficult to find a good explanation on the internet and build all the pieces together. But here it is! In this article, we will.&lt;/p&gt;

&lt;p&gt;We will go through all the concepts needed to understand and implement this algorithm—one by one. By the end of this article, we will have a fully functioning demo &lt;strong&gt;from scratch&lt;/strong&gt;, which can extract the &lt;strong&gt;public key&lt;/strong&gt; from the &lt;strong&gt;private key&lt;/strong&gt;, &lt;strong&gt;sign&lt;/strong&gt; a message, and &lt;strong&gt;verify&lt;/strong&gt; that the signature is correct. This implementation will &lt;strong&gt;only&lt;/strong&gt; use the concepts described in this article. Moreover, it will take less than 100 lines of code.&lt;/p&gt;

&lt;p&gt;This article is targeted mainly at developers like myself, who want to finally understand ECDSA, but it will also be very useful for everyone else. It requires knowing no more than middle school math. &lt;/p&gt;

&lt;p&gt;I highly recommend following it step by step. If you want, you can grab a piece of paper and a pen, and repeat all the steps in this article. It would be even better! If you’re not a programmer, you can ignore some pieces of code. If you are, I recommend re-writing the code on your own and practicing!&lt;/p&gt;

&lt;p&gt;The article consists of 6 parts, each part uses the concepts of the previous parts (except part 2):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I: The essentials of elliptic curves&lt;/li&gt;
&lt;li&gt;II: The essentials of finite fields&lt;/li&gt;
&lt;li&gt;III: Elliptic curves over finite fields&lt;/li&gt;
&lt;li&gt;IV: Practical use of it: ECDSA&lt;/li&gt;
&lt;li&gt;V: The implementation&lt;/li&gt;
&lt;li&gt;VI: Live Demo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s start here!&lt;/p&gt;

&lt;h2&gt;
  
  
  PART I: The Essentials of Elliptic Curves
&lt;/h2&gt;

&lt;p&gt;We’re all probably familiar with all those graphs on coordinate grids, where the y variable somehow depends on x. For example, y = x, y = x^2, and so on. Most probably we all have some experience with it. Let’s look at them: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zcDTwzn0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6zaqztvvchr18ytfvww.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zcDTwzn0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6zaqztvvchr18ytfvww.png" alt="" width="880" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The equation for an elliptic curve is not much different!&lt;/strong&gt; It has the form of y^2 = x^3 + a*x + b. What’s a and b? Just some arbitrary constants. Let’s see how it looks with a = 0, b = 7, just like in the Bitcoin curve:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MLdU-LR5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ooff282mxor0o30ydhkc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MLdU-LR5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ooff282mxor0o30ydhkc.png" alt="" width="880" height="429"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  It has the following 3 super important properties, upon which all works:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;This is where it may get hard to follow and understand &lt;a href="https://www.youtube.com/watch?v=6eZQu120A80"&gt;why&lt;/a&gt;. You may even think this is something incoherent and irrelevant. But please trust me. These properties will lead us to a very amazing result! But now let’s pretend that we’re just having fun without a purpose.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;The elliptic curve is symmetric along the &lt;strong&gt;x-&lt;/strong&gt;axis. It means that &lt;strong&gt;for any point on the curve A&lt;/strong&gt;, we can get its mirror point, called &lt;strong&gt;-A&lt;/strong&gt;, by simply mirroring its &lt;strong&gt;y&lt;/strong&gt; coordinate:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8XIzMoev--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v583p3itsxffygxtj9i5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8XIzMoev--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v583p3itsxffygxtj9i5.png" alt="" width="880" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If we draw a line through &lt;strong&gt;any of two points not lying on a vertical line&lt;/strong&gt;, it will &lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=6eZQu120A80"&gt;intersect&lt;/a&gt;&lt;/strong&gt; the &lt;strong&gt;curve at exactly one more point&lt;/strong&gt;! 
Let’s draw a line through the &lt;strong&gt;A&lt;/strong&gt; and &lt;strong&gt;B&lt;/strong&gt; points, and call the third point &lt;strong&gt;—C&lt;/strong&gt;. Then let’s reflect it to get point &lt;strong&gt;C&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HDst0Nzi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oo3c1g6wtnnboxcirzzz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HDst0Nzi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oo3c1g6wtnnboxcirzzz.png" alt="" width="880" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--95R28jM7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r4hxunh6enz048pl5a6s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--95R28jM7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r4hxunh6enz048pl5a6s.png" alt="" width="880" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This C point is called the sum of A and B. So A + B = C.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If we draw a &lt;strong&gt;tangent&lt;/strong&gt; &lt;strong&gt;line&lt;/strong&gt; through any point &lt;strong&gt;A&lt;/strong&gt; lying on a curve, it will intersect the curve at &lt;strong&gt;exactly one point&lt;/strong&gt;. We will call this point &lt;strong&gt;-2A.&lt;/strong&gt; We already know how to get &lt;strong&gt;2A&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VyO1Bju9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vaiyefi6ljt4zwd8kyew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VyO1Bju9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vaiyefi6ljt4zwd8kyew.png" alt="" width="880" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The easiest way to think about a tangent line is to imagine that it intersects A point twice. As if it intersects the curve not at two points, but at three: A, A, -2A.&lt;/p&gt;
&lt;h3&gt;
  
  
  That’s it! We defined three mathematical operations on the elliptic curve: multiplying the point by -1, adding two points together, and doubling the point.
&lt;/h3&gt;
&lt;h3&gt;
  
  
  And here is where the algebra of elliptic curves starts working.
&lt;/h3&gt;

&lt;p&gt;Now we have the following picture with points &lt;strong&gt;A&lt;/strong&gt;, &lt;strong&gt;2A&lt;/strong&gt;, and &lt;strong&gt;-2A&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uSkXx9l4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f0mej196zeo1zjp3ga8c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uSkXx9l4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f0mej196zeo1zjp3ga8c.png" alt="" width="880" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s draw a line through &lt;strong&gt;A&lt;/strong&gt; and &lt;strong&gt;2A&lt;/strong&gt;. The third point that we’ll get is &lt;strong&gt;-3A&lt;/strong&gt;. Then just reflect it to get &lt;strong&gt;3A&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cBBwEPs7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z9lh9ep8bbugfe5gmmx3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cBBwEPs7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z9lh9ep8bbugfe5gmmx3.png" alt="" width="880" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You probably don’t yet understand why we’re doing all of it. Just look at one more step.&lt;/p&gt;

&lt;p&gt;What if we try drawing a line between &lt;strong&gt;3A&lt;/strong&gt; and &lt;strong&gt;-2A&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2tKgNZb8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cuzcqutpsu2urx04ubuq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2tKgNZb8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cuzcqutpsu2urx04ubuq.png" alt="" width="880" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you see the magic?&lt;/strong&gt; By drawing a line between &lt;strong&gt;3A&lt;/strong&gt; and &lt;strong&gt;-2A&lt;/strong&gt; we’re getting the &lt;strong&gt;-A&lt;/strong&gt; point, which is the reflection of our original &lt;strong&gt;A&lt;/strong&gt; point along the x-axis!&lt;/p&gt;
&lt;h3&gt;
  
  
  What we just defined in the three points above, is the algebra of elliptic curves.
&lt;/h3&gt;

&lt;p&gt;Just try to understand the power of those three operations: essentially now we can perform operations on the points lying on a curve &lt;strong&gt;as if they’re not points, but just numbers&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;What we &lt;strong&gt;can&lt;/strong&gt; do with points on a curve: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Addition of two points &lt;strong&gt;(A + B)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Subtraction of two points &lt;strong&gt;A - B&lt;/strong&gt; = &lt;strong&gt;(A + (-B))&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Doubling of the point (multiplication by two) &lt;strong&gt;2*A&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multiplying by any integer (by combining the previous operations together, we can get any integer * Point)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What we &lt;strong&gt;can’t&lt;/strong&gt; do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiplication of two points&lt;/li&gt;
&lt;li&gt;Division of a point over another point&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Division of a point over a scalar value&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, to get &lt;strong&gt;10A&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;2*A = 2A&lt;br&gt;
2*2A = 4A&lt;br&gt;
2*4A = 8A&lt;br&gt;
8A + 2A = 10A&lt;/p&gt;

&lt;p&gt;It’s also good to notice that the calculation may be performed in a logarithmic amount of operations. So the approximate amount of operations needed for calculating &lt;strong&gt;n * Point&lt;/strong&gt; is &lt;strong&gt;O(log2(n))&lt;/strong&gt;!&lt;/p&gt;
&lt;h3&gt;
  
  
  Eventually, we can multiply a point by any integer, but there is no way to get the integer back! This is the gist of it! And this is what makes the elliptic curves very good for cryptography. This algebra works for infinitely large numbers.
&lt;/h3&gt;
&lt;h3&gt;
  
  
  The only drawback, for now, is the need to draw it. But of course, there are mathematical formulas for reflecting a point, for addition, and for doubling a point:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multiplying the point by -1&lt;/strong&gt;. &lt;br&gt;
If we have a point &lt;strong&gt;A(x, y)&lt;/strong&gt;, we can easily get &lt;strong&gt;-A&lt;/strong&gt; by multiplying its &lt;strong&gt;y&lt;/strong&gt; coordinate by &lt;strong&gt;-1.&lt;/strong&gt; -A(x, -y).&lt;br&gt;
&lt;strong&gt;Example&lt;/strong&gt;:&lt;br&gt;
-1 * A(2, 2) → -A(2, -2)&lt;br&gt;
-1 * A(1, -1) → -A(1, 1)&lt;br&gt;
-1 * A(5, 8) → -A(5, -8)&lt;br&gt;
-1 * A(5, -8) → -A(5, 8)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adding two points together.&lt;/strong&gt;&lt;br&gt;
We can add two points together, but with one condition: they should not lie on a vertical line (their x coordinates should not be equal). This is the formula for adding &lt;strong&gt;A&lt;/strong&gt; and &lt;strong&gt;B (A + B = C)&lt;/strong&gt;:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B0TI7sTz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/62w7l2ux6q2ymkxmap43.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B0TI7sTz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/62w7l2ux6q2ymkxmap43.png" alt="" width="880" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Adding a point to itself&lt;/strong&gt; (multiplying a point by 2). This is a very similar operation to the addition of two points, but slightly different:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C4klKnl3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u05iq4nz9n6bq4suqaec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C4klKnl3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u05iq4nz9n6bq4suqaec.png" alt="" width="880" height="528"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  That’s it! Time to practice!
&lt;/h3&gt;

&lt;p&gt;Let’s try adding A and B here (let’s use approximation to 3 points after a comma):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IRYNt0iP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uijmoztgt13c93875hf0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IRYNt0iP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uijmoztgt13c93875hf0.png" alt="" width="880" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;According to the formula defined above for adding two points,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9SJVAeIo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u68wnhc00rr5kvewkxug.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9SJVAeIo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u68wnhc00rr5kvewkxug.png" alt="" width="880" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s find our point &lt;strong&gt;C&lt;/strong&gt; graphically:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6xv3QqUZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6khlvne69razfxg2rkj8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6xv3QqUZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6khlvne69razfxg2rkj8.png" alt="" width="880" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It works!&lt;/strong&gt; Yes, with a small proximity issue, because of rounding. But it works!&lt;/p&gt;

&lt;p&gt;For better understanding, I recommend you try to perform all those operations on your own.&lt;/p&gt;
&lt;h3&gt;
  
  
  This was all we need to know about elliptic curves and the operations on them that we need to be able to perform!
&lt;/h3&gt;

&lt;p&gt;Everything is fine, but we need a couple more properties for building a cryptography system.&lt;/p&gt;
&lt;h1&gt;
  
  
  Part II: Finite fields
&lt;/h1&gt;

&lt;p&gt;We don’t need to study everything about &lt;a href="http://web.stanford.edu/~marykw/classes/CS250_W19/readings/Forney_Introduction_to_Finite_Fields.pdf"&gt;finite fields&lt;/a&gt;. All we need here is to understand a couple of essential properties to move on and be able to operate on a certain “algebra” of finite fields.&lt;/p&gt;

&lt;p&gt;Have you heard of the &lt;strong&gt;modulus&lt;/strong&gt; operation? If you’re a programmer, probably you did. This is just a &lt;strong&gt;reminder of division&lt;/strong&gt;, and in programming languages, it’s usually expressed as a &lt;strong&gt;%&lt;/strong&gt; (or &lt;strong&gt;mod&lt;/strong&gt;) operator. For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2  mod 11 = 2&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;10 mod 11 = 10&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;11 mod 11 = 0&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;13 mod 11 = 2&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;14 mod 11 = 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If we try numbers from &lt;strong&gt;0&lt;/strong&gt; to &lt;strong&gt;33 mod 11&lt;/strong&gt;, we will get these numbers: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It works &lt;strong&gt;like a clock&lt;/strong&gt;. &lt;code&gt;We can call this a finite field of order 11&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  We need to know just 4 properties:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The order of multiplication doesn’t matter.&lt;/strong&gt; &lt;br&gt;
&lt;strong&gt;a*b*c&lt;/strong&gt; mod n &lt;strong&gt;is the same as&lt;/strong&gt;  (&lt;strong&gt;a&lt;/strong&gt; mod n) * (&lt;strong&gt;b&lt;/strong&gt; mod n) * (&lt;strong&gt;c&lt;/strong&gt; mod n) mod n, &lt;strong&gt;which is the same as&lt;/strong&gt; (&lt;strong&gt;a*b&lt;/strong&gt; mod n) * &lt;strong&gt;c&lt;/strong&gt; mod n&lt;br&gt;
Example:&lt;br&gt;
&lt;strong&gt;6 * 7 * 8&lt;/strong&gt; mod 11 = &lt;strong&gt;336&lt;/strong&gt; mod 11 = &lt;strong&gt;6, same as:&lt;/strong&gt;&lt;br&gt;
(&lt;strong&gt;6 * 7&lt;/strong&gt; mod 11) * &lt;strong&gt;8&lt;/strong&gt; mod 11 = (&lt;strong&gt;42&lt;/strong&gt; mod 11) * &lt;strong&gt;9&lt;/strong&gt; mod 11 = &lt;strong&gt;9 * 8&lt;/strong&gt; mod 11 = &lt;strong&gt;72&lt;/strong&gt; mod 11 = &lt;strong&gt;6&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Negative number&lt;/strong&gt; &lt;strong&gt;mod n is the&lt;/strong&gt; &lt;strong&gt;same as n-(|negative number| mod n&lt;/strong&gt;). &lt;br&gt;
Examples:&lt;br&gt;
&lt;strong&gt;-4 mod 11&lt;/strong&gt; = 11-(4 mod 11) = &lt;strong&gt;11-4 = 7&lt;br&gt;
-7 mod 11&lt;/strong&gt; = 11 - (7 mod 11) = &lt;strong&gt;11 - 7 = 4&lt;br&gt;
-9 mod 11&lt;/strong&gt; = 11 - (9 mod 11) = &lt;strong&gt;11-9 = 2&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;-2 mod 11&lt;/strong&gt; = 11 - (2 mod 11) = &lt;strong&gt;11 - 2 = 9&lt;br&gt;
-13 mod 11&lt;/strong&gt; = 11 - (13 mod 11) = &lt;strong&gt;11 - 2 = 9&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;“Multiplicative inverse”: for any a, there is a number b, such as a*b mod n = 1.&lt;br&gt;
If a * b mod 11 = 1,&lt;/strong&gt; &lt;strong&gt;a&lt;/strong&gt; is called the &lt;strong&gt;multiplicative inverse of b&lt;/strong&gt; &lt;strong&gt;modulo&lt;/strong&gt; &lt;strong&gt;n&lt;/strong&gt;, and &lt;strong&gt;vice versa&lt;/strong&gt;: &lt;strong&gt;b&lt;/strong&gt; is called the &lt;a href="https://en.wikipedia.org/wiki/Multiplicative_inverse"&gt;multiplicative inverse&lt;/a&gt; of &lt;strong&gt;a&lt;/strong&gt; modulo n. &lt;br&gt;
Example:&lt;br&gt;
1) &lt;strong&gt;5 * x mod 11&lt;/strong&gt; = 1. Let’s try values for x one by one, and we will find out &lt;strong&gt;x = 9&lt;/strong&gt;. So &lt;strong&gt;9 is the multiplicative inverse of 5 modulo 11&lt;/strong&gt;.&lt;br&gt;
2) &lt;strong&gt;7 * x mod 11 = 1&lt;/strong&gt;. Let’s try our brute force again and we will find out &lt;strong&gt;x = 8&lt;/strong&gt;. 8 is the multiplicative inverse of 7 modulo 11.&lt;br&gt;
3) &lt;strong&gt;10 * x mod 11 = 1. x = 10.&lt;/strong&gt; So 10 is the multiplicative inverse of 10 modulo 11.&lt;br&gt;
Usually, it’s done by the &lt;a href="https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm"&gt;extended Euclidean algorithm&lt;/a&gt;, but it’s a matter of a separate article. So for now, let’s just use brute force.&lt;br&gt;
Also, &lt;strong&gt;n&lt;/strong&gt; must be a prime number!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The division is the same operation as multiplication by the multiplicative inverse!&lt;/strong&gt; Last and the most important property:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fGHKbFGi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bqavopj2t2z4hseh3mxy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fGHKbFGi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bqavopj2t2z4hseh3mxy.png" alt="" width="880" height="156"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, when we need to deal with division mod n, we can easily calculate it.&lt;/p&gt;

&lt;p&gt;Let’s see an example: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q4y_GoZC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/occrvwwlme85bdce55lg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q4y_GoZC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/occrvwwlme85bdce55lg.png" alt="" width="880" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why is &lt;strong&gt;2&lt;/strong&gt; the &lt;strong&gt;multiplicative inverse&lt;/strong&gt; of &lt;strong&gt;6 mod 11&lt;/strong&gt;? Because &lt;strong&gt;6&lt;/strong&gt; * &lt;strong&gt;2&lt;/strong&gt; = 12, 12 mod 11 = &lt;strong&gt;1&lt;/strong&gt;. &lt;/p&gt;
&lt;h3&gt;
  
  
  That’s it! Now we know how to operate on finite fields “algebra”.
&lt;/h3&gt;
&lt;h1&gt;
  
  
  Part III: Elliptic curves over finite fields
&lt;/h1&gt;

&lt;p&gt;Here’s where it becomes less obvious and a little harder to understand. &lt;strong&gt;But this is exactly how elliptic curves are used in cryptography&lt;/strong&gt;. What we need to do is exactly what is said in the title: put our elliptic curve over a finite field.&lt;/p&gt;

&lt;p&gt;So, here is how our formula changes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TInz8WTf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4kk1ox2j1fxpz6uvbxhw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TInz8WTf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4kk1ox2j1fxpz6uvbxhw.png" alt="" width="880" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything is the same as in the original formula but now both parts of the equation are now under the modulo p. &lt;/p&gt;

&lt;p&gt;Let’s use the elliptic curve with the following configuration for our examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a = 0&lt;/li&gt;
&lt;li&gt;b = 7&lt;/li&gt;
&lt;li&gt;p = 11&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s find all the points on this curve running this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the result: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(2, 2), (2, 9), (3, 1), (3, 10), (4, 4), (4, 7), (5, 0), (5,11), (6, 5), (6, 6), (7, 3), (7, 8)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s see what it looks like on a coordinate grid:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3Pp8XNHI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4z305nrg0j7d2yjt4t35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3Pp8XNHI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4z305nrg0j7d2yjt4t35.png" alt="" width="880" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s try a=0, b=7, p=23:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--55ds8Izk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9w47jtozapkrsnu8so4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--55ds8Izk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9w47jtozapkrsnu8so4g.png" alt="" width="880" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Doesn’t look like anything, right? No distinguishable shape.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  But! What turns out is that it preserves all the properties and formulas of the “original” elliptic curve!
&lt;/h3&gt;

&lt;p&gt;So now we’ve got an elliptic curve, that &lt;strong&gt;doesn’t look like an elliptic curve.&lt;/strong&gt; But! It has a finite set of points, and most importantly, &lt;strong&gt;works like an elliptic curve&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  We need to slightly modify our formulas from PART I with respect to mod p:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multiplying a point by -1&lt;/strong&gt;:&lt;br&gt;
If we have a point &lt;strong&gt;A(x, y),&lt;/strong&gt; we can easily get &lt;strong&gt;-A&lt;/strong&gt; by multiplying its &lt;strong&gt;y&lt;/strong&gt; coordinate by &lt;strong&gt;-1 modulo p&lt;/strong&gt;.&lt;br&gt;
&lt;strong&gt;Example:&lt;br&gt;
-1 * A(2, 2) → -A(2, -2 mod 11) = -A(2, 9)&lt;br&gt;
-1 * A(2, 9) → -A(2, -9 mod 11) = -A(2, 2)&lt;br&gt;
-1 * A(6, 5) → -A(6, -5 mod 11) = -A(6, 6)&lt;br&gt;
-1 * A(6, 6) → -A(6, -6 mod 11) = -A(6, 5)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adding two points together&lt;/strong&gt;:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fBZnMtsP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/al272xm89jttc9r19a7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fBZnMtsP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/al272xm89jttc9r19a7w.png" alt="" width="880" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Adding a point to itself&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mfFFkfes--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/scoiyz5v2aehl9uq78t4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mfFFkfes--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/scoiyz5v2aehl9uq78t4.png" alt="" width="880" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don’t yet understand the concept of multiplicative inverse, please, go back to PART II and check it once more.&lt;/p&gt;

&lt;h3&gt;
  
  
  That’s it! Time to practice!
&lt;/h3&gt;

&lt;p&gt;For our examples, we will use the elliptic curve with &lt;strong&gt;a=0, b=7, and order p=11&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let’s pick a point &lt;strong&gt;C(7, 8)&lt;/strong&gt; and calculate &lt;strong&gt;2C&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ArUVK7uj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/959qlbwohw9ip63w2wvx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ArUVK7uj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/959qlbwohw9ip63w2wvx.png" alt="" width="880" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can now easily calculate 4C:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---GKDSXJ8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pnltg8q4w127zwk4er8t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---GKDSXJ8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pnltg8q4w127zwk4er8t.png" alt="" width="880" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s calculate &lt;strong&gt;4C - C&lt;/strong&gt;, which is essentially &lt;strong&gt;3C = 4C + (-C)&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xn7AAGiy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7cq5gb4mxe1gt4nvpq84.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xn7AAGiy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7cq5gb4mxe1gt4nvpq84.png" alt="" width="880" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s add &lt;strong&gt;3C = C + 2C&lt;/strong&gt; and see if the result is the same:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R5hvkVfp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/38iz9hczqghmdwyzrv57.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R5hvkVfp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/38iz9hczqghmdwyzrv57.png" alt="" width="880" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The math perfectly works here!
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;One super important property&lt;/strong&gt;: Every point on a curve has its own &lt;strong&gt;order n&lt;/strong&gt;!&lt;br&gt;
It works like a modulo. For example, if the &lt;strong&gt;order n&lt;/strong&gt; of point &lt;strong&gt;C&lt;/strong&gt; is &lt;strong&gt;12&lt;/strong&gt;, it means that 12*C = 0(the point doesn’t exist), &lt;strong&gt;13*C = C&lt;/strong&gt;,  &lt;strong&gt;16*C = 4C&lt;/strong&gt;, &lt;strong&gt;27*C = 3C&lt;/strong&gt;. This property is &lt;strong&gt;predefined&lt;/strong&gt; for a point.&lt;/p&gt;

&lt;p&gt;You can practice and make sure it works. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The order of our point C is actually 12.&lt;/strong&gt; I suggest a task for you: try calculating &lt;strong&gt;8C&lt;/strong&gt; by adding &lt;strong&gt;4C + 4C&lt;/strong&gt;. Then try adding &lt;strong&gt;8C + 8C&lt;/strong&gt;. You will get &lt;strong&gt;16C&lt;/strong&gt;, which will be the same point as &lt;strong&gt;4C&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It works like a clock:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9IFIoTl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/700q40tt961c2mmykekx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9IFIoTl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/700q40tt961c2mmykekx.png" alt="" width="880" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we know &lt;strong&gt;absolutely everything essential&lt;/strong&gt; for using the elliptic curves in cryptography.&lt;/p&gt;
&lt;h3&gt;
  
  
  To recap
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;All formulas work fine. We can still calculate &lt;strong&gt;any integer x * Point&lt;/strong&gt;. We still need approximately log2(x) operations!&lt;/li&gt;
&lt;li&gt;Elliptic curves have now a finite set of points&lt;/li&gt;
&lt;li&gt;Points now have their own &lt;strong&gt;order n&lt;/strong&gt;, so they tend to repeat themselves like in a clock.&lt;/li&gt;
&lt;li&gt;To define an elliptic curve, we now need three variables: &lt;strong&gt;a&lt;/strong&gt;, &lt;strong&gt;b&lt;/strong&gt;, and &lt;strong&gt;p&lt;/strong&gt;. &lt;strong&gt;p&lt;/strong&gt; is called the order of an elliptic curve.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How do we know, which &lt;strong&gt;a&lt;/strong&gt;, &lt;strong&gt;b&lt;/strong&gt;, and &lt;strong&gt;p&lt;/strong&gt; to use? It’s standardized! There are many standards out there.&lt;/p&gt;
&lt;h3&gt;
  
  
  What do Bitcoin and Ethereum use?
&lt;/h3&gt;

&lt;p&gt;They use the &lt;strong&gt;standardized elliptic curve&lt;/strong&gt; called &lt;strong&gt;secp256k1&lt;/strong&gt;. It has the following variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a=&lt;strong&gt;0&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;b=&lt;strong&gt;7&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;p=&lt;strong&gt;115792089237316195423570985008687907853269984665640564039457584007908834671663&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quite a big number! I think you’re starting to guess why elliptic curves are so good for cryptography.&lt;/p&gt;

&lt;p&gt;Now that we know everything important, let’s apply it somewhere!&lt;/p&gt;
&lt;h1&gt;
  
  
  Part IV: Practical use of it: ECDSA
&lt;/h1&gt;

&lt;p&gt;The &lt;strong&gt;Elliptic Curves Digital Signature Algorithm&lt;/strong&gt; works exactly over the algebra that we’ve just discovered in the previous parts.&lt;/p&gt;

&lt;p&gt;This algorithm allows a person to &lt;strong&gt;sign&lt;/strong&gt; a &lt;strong&gt;message&lt;/strong&gt; using his or her &lt;strong&gt;PrivateKey&lt;/strong&gt;, so that anyone else can &lt;strong&gt;verify&lt;/strong&gt; that the &lt;strong&gt;signature&lt;/strong&gt; actually &lt;strong&gt;belongs&lt;/strong&gt; to that person, knowing their &lt;strong&gt;PublicKey&lt;/strong&gt;. &lt;/p&gt;
&lt;h3&gt;
  
  
  This is what actually happens when you &lt;strong&gt;sign&lt;/strong&gt; a &lt;strong&gt;message&lt;/strong&gt; in blockchains:
&lt;/h3&gt;

&lt;p&gt;You just generate some &lt;strong&gt;message&lt;/strong&gt; like “&lt;strong&gt;I want to send X amount of crypto to address Y&lt;/strong&gt;”, and then you &lt;strong&gt;sign&lt;/strong&gt; that message (using exactly the algorithm discovered in this article).  Other parties can &lt;strong&gt;verify&lt;/strong&gt; that the &lt;strong&gt;message&lt;/strong&gt; was actually &lt;strong&gt;signed&lt;/strong&gt; by you.&lt;/p&gt;
&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;

&lt;p&gt;Everything spins around one certain &lt;strong&gt;predefined&lt;/strong&gt; &lt;strong&gt;point&lt;/strong&gt; &lt;strong&gt;G&lt;/strong&gt;, lying on a &lt;strong&gt;predefined&lt;/strong&gt; &lt;strong&gt;elliptic curve&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We can generate any &lt;strong&gt;random integer&lt;/strong&gt; and call it our &lt;strong&gt;PrivateKey.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If we multiply this PrivateKey to point G, we will get the PublicKey. &lt;br&gt;
So PublicKey = PrivateKey * G:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CCV8Jsoc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ytqlau21yavqgbgu4x8c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CCV8Jsoc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ytqlau21yavqgbgu4x8c.png" alt="" width="880" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes, &lt;strong&gt;PublicKey&lt;/strong&gt; is just a point on a curve.&lt;/p&gt;

&lt;p&gt;As we already know, we can’t divide point by point, or point by a scalar value. All possible operations are listed at the end of PART I.&lt;/p&gt;

&lt;p&gt;So, there is &lt;strong&gt;no&lt;/strong&gt; &lt;strong&gt;efficient way&lt;/strong&gt; to extract &lt;strong&gt;PrivateKey&lt;/strong&gt; from &lt;strong&gt;PublicKey&lt;/strong&gt;, even though we know point &lt;strong&gt;G&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;We can’t divide &lt;strong&gt;PublicKey&lt;/strong&gt; by &lt;strong&gt;G&lt;/strong&gt;. This &lt;strong&gt;operation doesn’t exist&lt;/strong&gt;. Brute-forcing potentially works, but when there are really giant amount of points, for example, that giant: &lt;/p&gt;

&lt;p&gt;115792089237316195423570985008687907852837564279074904382605163141518161494337&lt;/p&gt;
&lt;h3&gt;
  
  
  Even if someone uses all the existing computing power in the world, this would take billions of billions of billions… of years to find the &lt;strong&gt;PrivateKey&lt;/strong&gt;.
&lt;/h3&gt;

&lt;p&gt;In ECDSA we have this set of “global” public variables. &lt;strong&gt;They are specified by standards&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elliptic curve with some config (&lt;strong&gt;a&lt;/strong&gt;, &lt;strong&gt;b&lt;/strong&gt;, &lt;strong&gt;p&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;Point &lt;strong&gt;G&lt;/strong&gt;, which lies on the curve (its &lt;strong&gt;x&lt;/strong&gt; and &lt;strong&gt;y&lt;/strong&gt; coordinates). This is called the &lt;strong&gt;Generator Point&lt;/strong&gt;. This point is standardized.&lt;/li&gt;
&lt;li&gt;Order &lt;strong&gt;n&lt;/strong&gt; of point &lt;strong&gt;G&lt;/strong&gt;. As we know, order &lt;strong&gt;n&lt;/strong&gt; is the property for point &lt;strong&gt;G,&lt;/strong&gt; so as G*(n+1) = G, G*(n+2) = 2G, and so on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are the variables that belong to a certain owner:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PrivateKey&lt;/strong&gt; - kept secret by the owner&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PublicKey&lt;/strong&gt; - shared with the public&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And, variables that are specific to one &lt;strong&gt;signing&lt;/strong&gt; operation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;message&lt;/strong&gt; itself: any integer that is not larger than order n. &lt;strong&gt;Usually&lt;/strong&gt;, a &lt;strong&gt;hash&lt;/strong&gt; of string is used. But for simplicity reasons, we will use pure integers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;K&lt;/strong&gt; - random integer, that is generated when signing a message, exactly for that signature. This is kept secret and there is no way to find it by a third party.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the complete picture. Green stickers indicate that the variable is shared with the public, and the red ones indicate the variables that are kept secret.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I3d8jsyM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8tpcz0pfek1jvmywqml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I3d8jsyM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8tpcz0pfek1jvmywqml.png" alt="" width="880" height="1173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Way too many variables!&lt;br&gt;
Here are the algorithms for &lt;strong&gt;signing&lt;/strong&gt; and &lt;strong&gt;verifying&lt;/strong&gt; a message:&lt;/p&gt;
&lt;h3&gt;
  
  
  The algorithm for signing a message:
&lt;/h3&gt;

&lt;p&gt;We have our &lt;strong&gt;PrivateKey&lt;/strong&gt; and &lt;strong&gt;message&lt;/strong&gt;. To sign a message, we should*&lt;em&gt;:&lt;/em&gt;*&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate a random integer &lt;strong&gt;k&lt;/strong&gt;. This should be a big number. [1, &lt;strong&gt;n&lt;/strong&gt;-1]&lt;/li&gt;
&lt;li&gt;Calculate point &lt;strong&gt;R = G * k&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calculate &lt;strong&gt;r&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6avZnhb---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5yjxoe4rodstruvodsga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6avZnhb---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5yjxoe4rodstruvodsga.png" alt="" width="880" height="170"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calculate &lt;strong&gt;s:&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8vZC5bsy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8jfbz876umyx5gt5e8v5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8vZC5bsy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8jfbz876umyx5gt5e8v5.png" alt="" width="880" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it. &lt;strong&gt;The signature is a pair of points (r, s).&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Here is the visual representation of the algorithm:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MENwzGI---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fb0x3n6jya57wtlmzcg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MENwzGI---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fb0x3n6jya57wtlmzcg.png" alt="" width="880" height="682"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The algorithm for verifying a signature
&lt;/h3&gt;

&lt;p&gt;We have the signer’s &lt;strong&gt;PublicKey&lt;/strong&gt;, &lt;strong&gt;message&lt;/strong&gt;, and &lt;strong&gt;signature(r, s).&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Calculate &lt;strong&gt;U&lt;/strong&gt;: &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FzJ-zJEV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g2wx160ppl8w0nd0ukk1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FzJ-zJEV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g2wx160ppl8w0nd0ukk1.png" alt="" width="880" height="161"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calculate &lt;strong&gt;V&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gbaO5jts--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wpth9gx00hnnrpb45q2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gbaO5jts--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wpth9gx00hnnrpb45q2q.png" alt="" width="880" height="158"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calculate point &lt;strong&gt;C&lt;/strong&gt; = &lt;strong&gt;U&lt;/strong&gt; * &lt;strong&gt;G&lt;/strong&gt; + &lt;strong&gt;V&lt;/strong&gt; * &lt;strong&gt;PublicKey&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If &lt;strong&gt;C&lt;/strong&gt;.x mod &lt;strong&gt;n&lt;/strong&gt; = &lt;strong&gt;r&lt;/strong&gt;, then the signature is valid. Invalid otherwise.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--knP0iSMx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s7z1d5njog4ll5eb60cg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--knP0iSMx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s7z1d5njog4ll5eb60cg.png" alt="" width="880" height="734"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not obvious at all!&lt;/p&gt;

&lt;p&gt;Actually, this is just a mathematical trick.&lt;/p&gt;
&lt;h3&gt;
  
  
  Let’s play with our formulas and prove that it works!
&lt;/h3&gt;

&lt;p&gt;In step 3 of our &lt;strong&gt;verification&lt;/strong&gt; algorithm we have a point &lt;strong&gt;C = U * G + V * PublicKey:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H4kgIhzR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ufphupqj4u6l6imtnlbu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H4kgIhzR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ufphupqj4u6l6imtnlbu.png" alt="" width="880" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s substitute the variables &lt;strong&gt;U, V, and PublicKey&lt;/strong&gt; with their definitions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fw_DhclG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hb6hn2ub04av938c6xs4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fw_DhclG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hb6hn2ub04av938c6xs4.png" alt="" width="880" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q2S2x9CT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iq2u24or0416hslglfq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q2S2x9CT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iq2u24or0416hslglfq8.png" alt="" width="880" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that G * s^-1 is duplicated. Let’s simplify the formula:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4BP8sYKY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fo33kpikci3eb8m2ts1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4BP8sYKY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fo33kpikci3eb8m2ts1.png" alt="" width="880" height="117"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s see the definition of s in step &lt;strong&gt;4&lt;/strong&gt; of the &lt;strong&gt;signing&lt;/strong&gt; algorithm:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--POn2-qgf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pvlt9mau9c2yiv5hujrg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--POn2-qgf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pvlt9mau9c2yiv5hujrg.png" alt="" width="880" height="165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s substitute s^-1 in our formula:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hB6mxRoL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9dztc0lt8xdj398uz6lx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hB6mxRoL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9dztc0lt8xdj398uz6lx.png" alt="" width="880" height="112"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s simplify this part:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GaQpqp8w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yuzmyb4kc7846crhagzo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GaQpqp8w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yuzmyb4kc7846crhagzo.png" alt="" width="880" height="71"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_4C09sHC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zqmtg3c63a3uhsthyum5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_4C09sHC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zqmtg3c63a3uhsthyum5.png" alt="" width="880" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thus, if the signature is correct, the &lt;strong&gt;x&lt;/strong&gt; coordinate of &lt;strong&gt;C mod n&lt;/strong&gt; is equal to &lt;strong&gt;r&lt;/strong&gt; (which is, by its definition, the same &lt;strong&gt;x&lt;/strong&gt; coordinate of &lt;strong&gt;G * k&lt;/strong&gt;). &lt;/p&gt;
&lt;h3&gt;
  
  
  Secp256k1 standardized variables:
&lt;/h3&gt;

&lt;p&gt;For the elliptic curve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a=0&lt;/li&gt;
&lt;li&gt;b=7&lt;/li&gt;
&lt;li&gt;p=&lt;code&gt;115792089237316195423570985008687907853269984665640564039457584007908834671663&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For point G:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;x coordinate = &lt;code&gt;55066263022277343669578718895168534326250603453777594175500187360389116729240&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;y coordinate = &lt;code&gt;32670510020758816978083085130507043184471273380659243275938904335757337482424&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Order n = &lt;code&gt;115792089237316195423570985008687907852837564279074904382605163141518161494337&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Done! Now we know absolutely EVERYTHING essential!
&lt;/h3&gt;

&lt;p&gt;The next part is going to be the easiest part for programmers. For everyone else, it’s not necessary to follow. Just proceed to the Live Demo.&lt;/p&gt;
&lt;h1&gt;
  
  
  Part V: The implementation
&lt;/h1&gt;

&lt;p&gt;This part is intended for programmers only.&lt;/p&gt;

&lt;p&gt;The bottlenecks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We need to be able to perform basic arithmetical operations on very large numbers. In programming we can easily operate on large numbers, using &lt;strong&gt;[bignum&lt;/strong&gt; arithmetic](&lt;a href="https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic"&gt;https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic&lt;/a&gt;). Just google it, and you will find out how easy it is. 
So our programming language must support it, or we should use some external package to work with it.
In the examples of this part, I will use &lt;strong&gt;Python&lt;/strong&gt;, which supports bignum arithmetic out of the box. 
For the Live Demo (next part), I will use JavaScript, and there we will need the &lt;a href="https://www.npmjs.com/package/bignumber.js"&gt;BigNumber.js package&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The other bottleneck that we will encounter is &lt;strong&gt;finding the multiplicative inverse&lt;/strong&gt; of a very large number. Obviously, brute force is not going to work. 
The multiplicative inverse can be found by the &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm"&gt;Extended Euclidean algorithm&lt;/a&gt;, which has the complexity of O(log(n))&lt;/strong&gt;. Python (3.8+) can do it out of the box with its built-in &lt;strong&gt;pow&lt;/strong&gt; function:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;modulus&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;modulus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;If you need the actual implementation of the algorithm, check my Live Demo!&lt;/strong&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  Let’s start writing our code!
&lt;/h3&gt;

&lt;p&gt;We need one simple thing, related to the elliptic curve: &lt;strong&gt;Point&lt;/strong&gt;. Let’s define a class &lt;strong&gt;Point&lt;/strong&gt;.  In its constructor, we should make check, whether the point lies on the curve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The point is not on the curve"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curve_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to be able to &lt;strong&gt;compare two points&lt;/strong&gt;, &lt;strong&gt;add them together&lt;/strong&gt;, and &lt;strong&gt;multiply them by an integer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s add a method to check if two points are equal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_equal_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s implement &lt;strong&gt;add&lt;/strong&gt; method, which returns a new Point as the result of addition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_equal_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;

        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
        &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the formulas are listed in PART III.&lt;/p&gt;

&lt;p&gt;Now let’s implement the &lt;strong&gt;multiply&lt;/strong&gt; method: &lt;/p&gt;

&lt;p&gt;The most straightforward implementation would be this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But let’s say we need to multiply our point by a big number: 115792089237316195. Even if we had the speed of 1 billion additions per second, this would take &lt;strong&gt;3.6 years to calculate this point&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And this is not even a big number for us!&lt;/strong&gt; Here is a big number:&lt;/p&gt;

&lt;p&gt;115792089237316195423570985008687907852837564279074904382605163141518161494337&lt;/p&gt;

&lt;p&gt;Calculating the point in this way would take &lt;strong&gt;billions of billions of billions of billions… of years&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;We can define that the efficiency of this algorithm above is O(n), which is of no use for our purposes. If you remember, there is an easy way to achieve &lt;strong&gt;O(log2(n))&lt;/strong&gt; complexity by continuously doubling our point:&lt;/p&gt;

&lt;p&gt;2P = P+P&lt;/p&gt;

&lt;p&gt;4P = 2P + 2P&lt;/p&gt;

&lt;p&gt;8P = 4P + 4P&lt;/p&gt;

&lt;p&gt;16P = 8P + 8P&lt;/p&gt;

&lt;p&gt;32P= 16P + 16P&lt;/p&gt;

&lt;p&gt;64P = 32P + 32P&lt;/p&gt;

&lt;p&gt;And so &lt;strong&gt;log2(115792089237316195) =&lt;/strong&gt; &lt;strong&gt;56&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;log2(115792089237316195423570985008687907852837564279074904382605163141518161494337)&lt;/strong&gt; = &lt;strong&gt;256&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So we don’t need billions of billions of billions… of years. &lt;strong&gt;We just need 256 operations to get to this large point&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Just one moment: to efficiently multiply by values that are not a degree of 2, it’s reasonable to store all the previous values, and then combine the results together.&lt;/p&gt;

&lt;p&gt;For example, if we need to get 100P, we can no longer double 64P. Neither we can add points one by one: potentially this would take billions of billions of years on larger numbers. What’s reasonable to do instead, is:&lt;/p&gt;

&lt;p&gt;96P = 64P + 32P&lt;/p&gt;

&lt;p&gt;100P = 96P + 4P&lt;/p&gt;

&lt;p&gt;So for that purpose, we need to store all the previous P’s and afterwards efficiently use them.&lt;/p&gt;

&lt;p&gt;So here is an efficient implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;current_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;
        &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

        &lt;span class="n"&gt;pervious_points&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# store current point as a previous point
&lt;/span&gt;            &lt;span class="n"&gt;pervious_points&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;current_coefficient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="c1"&gt;# if we can multiply our current point by 2, do it
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;current_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt;
            &lt;span class="c1"&gt;# if we can't multiply our current point by 2, let's find the biggest previous point to add to our point
&lt;/span&gt;            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;next_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;
                &lt;span class="n"&gt;next_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;previous_coefficient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;previous_point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;pervious_points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;previous_coefficient&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;previous_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                            &lt;span class="n"&gt;next_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;previous_coefficient&lt;/span&gt;
                            &lt;span class="n"&gt;next_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;previous_point&lt;/span&gt;
                &lt;span class="n"&gt;current_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;next_coefficient&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thus we’ve got a super efficient implementation! And now we can perform all the needed operations on an elliptic curve.&lt;/p&gt;

&lt;p&gt;Let’s define secp256k1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;secp256k1_curve_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;115792089237316195423570985008687907853269984665640564039457584007908834671663&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;55066263022277343669578718895168534326250603453777594175500187360389116729240&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;32670510020758816978083085130507043184471273380659243275938904335757337482424&lt;/span&gt;
&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;115792089237316195423570985008687907852837564279074904382605163141518161494337&lt;/span&gt;
&lt;span class="n"&gt;g_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secp256k1_curve_config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’m using only decimal numbers in our examples because they’re intuitive for a human. &lt;/p&gt;

&lt;h3&gt;
  
  
  So far we’ve implemented everything that we discussed prior to PART IV. Now let’s implement the actual digital signature algorithm, described in PART IV.
&lt;/h3&gt;

&lt;p&gt;Sign method of ECDSA:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sign_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sign_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;k_inverse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;k_inverse&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify method of ECDSA:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verify_signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;
    &lt;span class="n"&gt;s_inverse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;s_inverse&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;s_inverse&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="n"&gt;c_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;c_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s pick some random number as our private key, for example, &lt;strong&gt;123456789012345&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let our message be 12345.&lt;/p&gt;

&lt;p&gt;Do you remember how to get &lt;strong&gt;PublicKey&lt;/strong&gt; from &lt;strong&gt;PrivateKey&lt;/strong&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;private_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123456789012345&lt;/span&gt;  &lt;span class="c1"&gt;# any random integer
&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12345&lt;/span&gt;  &lt;span class="c1"&gt;# any integer
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s sign and try to verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sign_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Signature: '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Is valid: '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verify_signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works! You can try to corrupt the signature or the original message and make sure that our algorithm works properly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Here is the complete code:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;random&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;modulus&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;modulus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The point is not on the curve"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curve_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curve_config&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_equal_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_equal_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;

        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
        &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slope&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curve_config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;current_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;
        &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

        &lt;span class="n"&gt;pervious_points&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# store current point as a previous point
&lt;/span&gt;            &lt;span class="n"&gt;pervious_points&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;current_coefficient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="c1"&gt;# if we can multiply our current point by 2, do it
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;current_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt;
            &lt;span class="c1"&gt;# if we can't multiply our current point by 2, let's find the biggest previous point to add to our point
&lt;/span&gt;            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;next_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;
                &lt;span class="n"&gt;next_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;previous_coefficient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;previous_point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;pervious_points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;previous_coefficient&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;previous_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                            &lt;span class="n"&gt;next_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;previous_coefficient&lt;/span&gt;
                            &lt;span class="n"&gt;next_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;previous_point&lt;/span&gt;
                &lt;span class="n"&gt;current_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_coefficient&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;next_coefficient&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;current_point&lt;/span&gt;

&lt;span class="n"&gt;secp256k1_curve_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;115792089237316195423570985008687907853269984665640564039457584007908834671663&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;55066263022277343669578718895168534326250603453777594175500187360389116729240&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;32670510020758816978083085130507043184471273380659243275938904335757337482424&lt;/span&gt;
&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;115792089237316195423570985008687907852837564279074904382605163141518161494337&lt;/span&gt;
&lt;span class="n"&gt;g_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secp256k1_curve_config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sign_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sign_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;k_inverse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;k_inverse&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verify_signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;
    &lt;span class="n"&gt;s_inverse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_inverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;s_inverse&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;s_inverse&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="n"&gt;c_point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;c_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;

&lt;span class="c1"&gt;# test starts here
&lt;/span&gt;&lt;span class="n"&gt;private_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123456789012345&lt;/span&gt;  &lt;span class="c1"&gt;# any random integer
&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g_point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12345&lt;/span&gt;  &lt;span class="c1"&gt;# any integer
&lt;/span&gt;
&lt;span class="n"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sign_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Signature: '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Is valid: '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verify_signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  So the implementation of the entire ECDSA algorithm took just 100 lines of code! And it’s perfectly working. This is absolutely the same algorithm as the one used in Bitcoin!
&lt;/h3&gt;

&lt;h1&gt;
  
  
  PartVI: Live Demo
&lt;/h1&gt;

&lt;p&gt;As I promised at the beginning of this article, here is the live demo using &lt;strong&gt;only&lt;/strong&gt; the concepts and formulas described in the article. Just a couple of notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initially, we could only sign integer messages. But in the demo, you can &lt;strong&gt;choose&lt;/strong&gt; to apply a &lt;strong&gt;hash&lt;/strong&gt; function (&lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/SHA-2"&gt;sha256&lt;/a&gt;&lt;/strong&gt;) to your message. Thanks to it, a message can be a string.&lt;/li&gt;
&lt;li&gt;Bitcoin uses slightly different formats of &lt;a href="https://river.com/learn/terms/s/sec-format/"&gt;public keys&lt;/a&gt; and &lt;a href="https://river.com/learn/terms/d/der/"&gt;signatures&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never&lt;/strong&gt; use it in a production environment! &lt;strong&gt;It is not safe&lt;/strong&gt;. For production, you must &lt;strong&gt;only&lt;/strong&gt; use &lt;a href="https://www.openssl.org/"&gt;well-tested solutions&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/k6s7uo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I hope this article was very useful for you. I did my best to make it useful. Feel free to share it with friends or use any piece of it anywhere. Just please leave a link to the original article.&lt;/p&gt;

&lt;p&gt;Feel free to contact me and ask questions: &lt;/p&gt;

&lt;p&gt;&lt;a href="mailto:exemak@gmail.com"&gt;exemak@gmail.com&lt;/a&gt;&lt;br&gt;
t.me/exemak&lt;br&gt;
Mikhail Karavaev&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
