> For the complete documentation index, see [llms.txt](https://mau-eth.gitbook.io/mau/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mau-eth.gitbook.io/mau/signature.md).

# Signature

### Private key and Public key&#x20;

The first and most crucial step in generating keys is to find a secure source of entropy, or randomness. Generating an Ethereum private key involves selecting a number between 1 and 2²⁵⁶.

A private key is a randomly generated 256-bit (32-byte) number.

The public key is set of x and y coordinates on an elliptic curve that satisfy the elliptic curve equation. It is derived from two numbers that are generated from the private key using **elliptic curve** multiplication. This process is irreversible, meaning that the private key cannot be derived from the public key.

To generate the public key, the private key is used in an equation involving **elliptic curve** multiplication, which is irreversible. The equation is: `K = k * G`, where K is the public key, k is the private key, and G is the constant point (generator point).

Ethereum uses the same **elliptic curve**, `secp256k1`, as Bitcoin.

<figure><img src="/files/BHbQ63t5eB6QAAmjtEzp" alt=""><figcaption></figcaption></figure>

Ethereum addresses are created by taking the Keccak-256 hash of the public key and representing it as a hexadecimal number. The last 20 bytes of the Keccak-256 hash are used to generate the address.

**Example:**

* Private Key (randomly generated): `0x3a1f59e7b9a7a27b3d905a1f0ce2b1dbdb16ee1e3a78384b6a9f3de75ef1e64a`
* Public Key (derived from private key): `0x04c7b5ba59e0581ad4f3a195790fda46d4e840da00aeb0eb06802b62c0ad22a1f8d1897bcbb15a4919a242d40d38c48b4fc3a029d270066a3b7ad6cc5c00ee66d9`
* Ethereum Address (last 20 bytes of public key hash): `0x2e0e4c47e30f71667a9f211bf2e870b6c309ae14`

### Signature Validation Process

To prove you are the true owner of an EOA, you need to sign a message with the corresponding private key. This means that only you have access to the funds on your account. When making a transaction sending 1 Ether to a contract to mint a new NFT, under the hood, Ethereum verifies the digital signature you created (using the private key) against the corresponding account’s public key hash (the address).

\
As we learned, public key cryptography (also known as asymmetric encryption) is a cryptographic method that uses a key pair system. The one key, called the private key, signs the message. The other key, called the public key, verifies the signature. When we sign any message, whether a transaction on Ethereum or any form of data, we create a digital signature. This is done by hashing the message and running the ECDSA algorithm to combine the hash with the private key, producing a signature. By doing this, any changes to the message will result in a different hash value.

As we can read from the [Mastering Ethereum book](https://github.com/ethereumbook/ethereumbook/blob/develop/04keys-addresses.asciidoc), “***A digital signature can be created to sign any message. For Ethereum transactions, the details of the transaction itself are used as the message. The mathematics of cryptography — in this case, elliptic curve cryptography — provides a way for the message (i.e., the transaction details) to be combined with the private key to create a code that can only be produced with knowledge of the private key. That code is called the digital signature.***”

Above is another explanation of digital signatures, but in the context of Ethereum transactions. This explanation introduces us to another, very important subject — elliptic curve cryptography.

<pre class="language-solidity"><code class="lang-solidity"><strong>// SPDX-License-Identifier: GPL-3.0
</strong>
pragma solidity 0.8.20;


/*
ethereum.enable()
account = "0x58aEdD5a35111f2DEFd03b14ae0020D8b5845902"
hash = "0x4198237100dd9ecd639492c23b05563d49df8207ee262a734b8dc52fdad61832"
ethereum.request({method: "personal_sign", params: [account, hash]})
PromiseResult is the signature (0xb031ddd7bf10556f227e93860b183368db6ccd080190c37e5b1d043e113cad0372b275f722f84ec642c9b7aeffa0c4e3d0a848b4daf4ab48a3e630bcf23eb8551b)
*/

contract VerifySignature {

    function verify(address _signer, string memory _message, bytes memory _sig)
        external pure returns (bool)
    {
        bytes32 messageHash = getMessageHash(_message);
        bytes32 ethSignedMessageHash = getEthSignedMessageHash(messageHash);

        return (recover(ethSignedMessageHash, _sig) == _signer);
    }

    function getMessageHash(
        string memory _message
    ) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(_message));
    }

    function getEthSignedMessageHash(bytes32 _messageHash) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(
            "\x19Ethereum Signed Message:\n32",
            _messageHash
        ));
    }

    function recover(bytes32 _ethSignedMessageHash, bytes memory _sig) public pure returns (address) {
        (bytes32 r, bytes32 s, uint8 v) = _split(_sig);
        return ecrecover(_ethSignedMessageHash, v, r, s);
    }

    function _split(bytes memory _sig) internal pure returns (bytes32 r, bytes32 s, uint8 v) {
        require (_sig.length == 65, "invalid signature length");
        assembly {
            /*
            First 32 bytes stores the length of the signature

            add(sig, 32) = pointer of sig + 32
            effectively, skips first 32 bytes of signature

            mload(p) loads next 32 bytes starting at the memory address p into memory
            */

            // first 32 bytes, after the length prefix
            r := mload(add(_sig, 32))
            // second 32 bytes
            s := mload(add(_sig, 64))
            // final byte (first byte of the next 32 bytes)
            v := byte(0, mload(add(_sig, 96)))
        }
    }
}
</code></pre>

<figure><img src="/files/PAcPTQIVdLJkFJrBYp9c" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/fGfUMY69X2zHiOEBF8Lq" alt=""><figcaption></figcaption></figure>

{% embed url="<https://www.youtube.com/watch?v=vYwYe-Gv_XI&t=77s>" %}

{% embed url="<https://medium.com/immunefi/intro-to-cryptography-and-signatures-in-ethereum-2025b6a4a33d>" %}
