Blockchain 101 - Public key cryptography
Tags: blockchain, cryptography, web3, programming
Published: 2022-12-27 19:11:51

## **CONTEXT**

Public key cryptography is a fundamental part of modern digital security, and it plays a crucial role in ensuring the privacy and integrity of information transmitted over the internet. It allows individuals and organizations to communicate securely and authenticate the identity of users, without the need for a shared secret key.

## **THE PRINCIPLE**

The basic principle behind public key cryptography is that each user has a **pair of keys** - a public key and a private key - that are mathematically related. The public key is used to encrypt messages, while the private key is used to decrypt them. This means that anyone can use a user's public key to send an encrypted message, but only the user with the corresponding private key can decrypt and read the message.


## **ECDSA**

One important algorithm used in public key cryptography is the Elliptic Curve Digital Signature Algorithm (ECDSA). ECDSA is a cryptographic algorithm used to generate digital signatures, which are used to verify the authenticity of a message or document. It is based on the mathematical concept of elliptic curves and provides a high level of security.


## **ELLIPTIC CURVES**

Elliptic curves are a type of mathematical curve that can be defined over a finite field, such as the set of integers or the set of points on a plane. They have a number of interesting properties that make them well-suited for use in cryptography.

One of the key properties of elliptic curves is that they allow for the efficient generation of a large number of points that are very difficult to distinguish from each other. This makes them useful for **generating cryptographic keys**, as it ensures that the keys are effectively random and cannot be easily guessed or derived by an attacker.

In addition to their key generation capabilities, elliptic curves also allow for the **efficient implementation** of various cryptographic algorithms, such as the Elliptic Curve Digital Signature Algorithm (ECDSA). 

The security of ECDSA and other algorithms based on elliptic curves derives from the difficulty of solving certain mathematical problems that are related to elliptic curves. These problems are believed to be computationally infeasible to solve, even with the use of powerful computers, making it very difficult for an attacker to break the encryption or forge a digital signature.


When users want to send a message, they use their private key to create a digital signature. This signature is then attached to the message and sent along with it. When the recipient receives it, they use the sender's public key to verify the signature and confirm that the message is authentic. If the signature is valid, it indicates that the message was indeed sent by the user with the corresponding private key.

## **SIGNING A MESSAGE WITH secp256k1**

With secp256k1, the process of signing a message includes returning the signature along with the recovery bit. This allows us to recover the public key from the signature, enabling a blockchain node to identify the address that authenticated a given transaction based on the signature. This is a crucial aspect of blockchain transactions, as they not only demonstrate the intent of the signer but also authenticate their identity through public key cryptography.

## **noble-secp256k1: A JS LIBRARY**

The noble-secp256k1 library ([official Github here](https://github.com/paulmillr/noble-secp256k1#signmsghash-privatekey)) is a JavaScript implementation of the secp256k1 elliptic curve cryptography algorithm. 
It allows users to sign and verify messages, recover public keys from signatures, and transform public keys into Ethereum addresses. The library is designed to be fast and easy to use, with a simple API and no dependencies. It is tested and well-documented, with comprehensive documentation and examples provided. Overall, the noble-secp256k1 library is a reliable and convenient tool for working with secp256k1 in JavaScript applications.

## **Recovering the public key WITH secp256k1**

Recovering the public key from a signature is an important aspect of public key cryptography. It allows blockchain nodes to identify the user who signed a particular transaction, and to verify the authenticity of the transaction.

To recover the public key from a signature, you will need to have the signature itself, along with the recovery bit. The recovery bit is a piece of information included with the signature that allows the public key to be recovered. It is a single bit that indicates which of the two possible public keys corresponds to the private key used to generate the signature.

Once you have the signature and recovery bit, you can use the Elliptic Curve Digital Signature Algorithm (ECDSA) to reverse the process and extract the public key. This involves solving a mathematical problem related to the elliptic curve used in the ECDSA algorithm.

Here's a code example in JavaScript that demonstrates how to recover the public key from a signature using the noble-secp256k1 library:

```
const secp256k1 = require('noble-secp256k1');

const signature = '...'; // The signature, including the recovery bit
const messageHash = '...'; // The hash of the message that was signed

// Use the recover function to extract the public key from the signature
const publicKey = secp256k1.recover(messageHash, signature);

console.log(publicKey); // Outputs the public key in hexadecimal format
```
### Code explanation 
This code defines an async function called recoverKey that takes a message, signature, and recovery bit as input, and uses the recover function from the secp256k1 library to extract the public key. The function returns the public key in hexadecimal format.

The code also includes a test of the function, using sample values for the message, signature, and recovery bit. When the function is called, it returns the public key, which is then logged to the console.

Keep in mind that this code assumes you have already installed the secp256k1 library and imported it into your project. You can install it using npm by running npm install secp256k1.