<p>There are different formats used to encode public keys and signatures into binary (octet-streams). They are defined in <a href="https://secg.org/sec1-v2.pdf#subsubsection.2.3.3" rel="nofollow noreferrer">Standards for Efficient Cryptography 1</a> (SEC).</p>

<p>A public key is a point on an elliptic curve, consisting of an <code>x</code> and <code>y</code> coordinate. There needs to be a standard way for serializing these parts and deserializing them later. The standard defines a uncompressed and a compressed format for this serialization. Roughly, the uncompressed format uses the prefix byte <code>0x04</code> followed by the serialized <code>x</code> coordinate, followed by the serialized <code>y</code> coordinate. The lengths of <code>x</code> and <code>y</code> are determined by the curve. For bitcoin, the curve <code>secp256k1</code> is always used, so the coordinates are 32 bytes. The resulting uncompressed public key is 65 bytes total.</p>

<p>The compressed version prefixes the octet-stream with <code>0x02</code> if the y coordinate is even and <code>0x03</code> if the y coordinate is odd. The <code>x</code> coordinate is serialized after it, resulting in a 33 byte public key. This information is sufficient because the <code>y</code> coordinate can be recovered if <code>x</code> is known and the sign is known. (Technically, we don't need the sign either).</p>

<p>Signatures consist of an <code>r</code> value (the <code>x</code> coordinate of a point on the curve), and an <code>s</code> value, which is an integer (32-bytes for secp256k1). The signature can be encoded in just 64 bytes in this compact form.</p>

<p>The paper previously linked also gives descriptions of these formats in ASN.1 (Abstract Syntax Notation 1). This is a textual interface description language which has been used to describe protocols for interoperability for a long time. Another standard, DER, or Distinguished Encoding Rules, describes a process for serializing data into octet-streams according to the ASN.1 specification for the data type.</p>

<p>The ASN.1 for signatures is (simplified):</p>

<pre><code>ECDSA-Sig-Value ::= SEQUENCE {
    r INTEGER,
    s INTEGER
}
</code></pre>

<p>According to the DER rules: a SEQUENCE is of type <code>0x30</code> and is followed by a length (1 byte for length &lt; 128), then the data for the sequence itself. INTEGER has type type <code>0x02</code> followed by its length, followed by the integer in binary. These integers are also signed, which means that if their value is >= 2^31 an additional zero valued byte must be prefixed to them. The resulting DER encoding for a Secp256k1 signature looks something like (assuming 32-byte r and s):</p>

<pre><code>0x30 0x44 0x02 0x20 &lt;r[32]&gt; 0x02 0x20 &lt;s[32]&gt;
</code></pre>

<p>As you can see, this is pretty wasteful compared to the concise 64-byte serialization of (r,s). The uncompressed version of public keys is also very wasteful because every byte in a transaction is valuable. The Segwit upgrade to bitcoin introduced some restrictions on which formats can be used, and additionally, the upcoming Taproot upgrade will require 32-byte (x-only) public keys, which are not part of the SEC standard.</p>

CC BY-SA 4.0
2020-01-05T22:45:51.537Z
2020-01-05T22:45:51.537Z
Mark H
<h2>DER</h2>

<p>The Distinguished Encoding Rules (DER) format is used to encode ECDSA signatures in Bitcoin. An ECDSA signature is generated using a private key and a hash of the signed message. It consists of two 32-byte numbers <code>(r,s)</code>. As <a href="https://bitcoin.stackexchange.com/a/12556/5406">described by Pieter here</a> the DER signature format has the following components:</p>

<ol>
<li><code>0x30</code> byte: header byte to indicate compound structure</li>
<li>one byte to encode the length of the following data</li>
<li><code>0x02</code>: header byte indicating an integer</li>
<li>one byte to encode the length of the following <code>r</code> value</li>
<li>the <code>r</code> value as a big-endian integer</li>
<li><code>0x02</code>: header byte indicating an integer</li>
<li>one byte to encode the length of the following <code>s</code> value</li>
<li>the <code>s</code> value as a big-endian integer</li>
</ol>

<p>Note that the <code>r</code> and <code>s</code> value must be prepended with <code>0x00</code> if their first byte is greater than <code>0x7F</code>. This causes variable signature lengths in the case that the <code>r</code> value is in the upper half of the range (referred to as "high <code>r</code>"). Signatures with high <code>s</code> values are non-standard and usually don't appear in the wild.
Also note that in rare cases <a href="https://bitcoin.stackexchange.com/a/38521/5406"><code>r</code> or <code>s</code> can be shorter than 32 bytes</a> which is legal and leads to shorter signatures.
Note that in bitcoin transactions a byte is added at the end of a DER signature denoting the SigHash type used.</p>

<h2>SEC</h2>

<p>The Standards of Efficient Cryptography (SEC) encoding is used to serialize ECDSA public keys. Public keys in Bitcoin are ECDSA points consisting of two coordinates <code>(x,y)</code>. <code>x</code> and <code>y</code> may be smaller than 32 bytes in which case they must be padded with zeros to 32 bytes (H/T Coding Enthusiast). Bitcoin uses two formats, uncompressed and compressed:</p>

<p><strong>Uncompressed:</strong></p>

<ol>
<li><code>0x04</code> byte: header byte to indicate ECDSA point</li>
<li>the <code>x</code> coordinate as a 32-byte big-endian integer</li>
<li>the <code>y</code> coordinate as a 32-byte big-endian integer</li>
</ol>

<p><strong>Compressed:</strong></p>

<p>As the coordinates <code>(x,y)</code> must satisfy the secp256k1 curve equation <code>y² = x³ + 7</code>, the two possible values for <code>y</code> can be calculated from the <code>x</code> value. Thus, we can express a public key just as the <code>x</code> coordinate in combination with an indicator which of the two <code>y</code> values to use.</p>

<ol>
<li><code>0x02</code>/<code>0x03</code> byte: header byte to indicate compressed ECDSA point, <code>0x02</code> for even <code>y</code>, <code>0x03</code> for odd <code>y</code></li>
<li>the <code>x</code> coordinate as a 32-byte big-endian integer</li>
</ol>

<hr>

<p>The above is more comprehensively explained e.g. in <a href="https://www.oreilly.com/library/view/programming-bitcoin/9781492031482/ch04.html" rel="noreferrer">Jimmy Song's Programming Bitcoin: Ch4. Serialization</a>.</p>

CC BY-SA 4.0
2021-04-07T07:31:19.907Z
Great answer thanks, what are `r` and `s` derived from?
nanobar
CC BY-SA 4.0
2023-05-27T13:51:18.573Z
@Dominic: That’s the signature. The signature uses the Elliptic Curve Digital Signing Algorithm and the secp256k1 curve to commit to a Bitcoin transaction as the message. The “r” value commits to a random curve point, and the “s” value commits to the transaction and the random point in a manner that requires the knowledge of the relevant private key in the construction. See e.g. Stepan Snigirev’s blog post here for a longer explanation: https://medium.com/cryptoadvance/how-schnorr-signatures-may-improve-bitcoin-91655bcb4744
Murch
CC BY-SA 4.0
2020-01-05T22:47:34.753Z
2020-05-22T14:45:27.580Z
2020-05-22T14:45:27.580Z
Murch
<p>I often see those 2 elements in bitcoin documentations and tutorials but I have not yet find a proper definition on the internet for DER signature and SEC format.</p>

CC BY-SA 4.0
2023-09-06T08:48:56.800Z
For reference, DER encoding is defined in [ITU-T X.690](https://www.itu.int/rec/T-REC-X.680-X.693-202102-I/en) (part of ASN.1)
Lee
<public-key><signature><encoding>
What are the DER signature and SEC format
Saxtheowl
# What are the DER signature and SEC format

(Asked by: username_0 on 2020-01-05)

I often see those 2 elements in bitcoin documentations and tutorials but I have not yet find a proper definition on the internet for DER signature and SEC format.

**Tags:** public-key, signature, encoding

> **Comments:**
> **username_1**: For reference, DER encoding is defined in [ITU-T X.690](https://www.itu.int/rec/T-REC-X.680-X.693-202102-I/en) (part of ASN.1)  

---

## 2 answers

### Answer by username_3 on 2020-01-05. Score: 22 | Accepted answer

## DER

The Distinguished Encoding Rules (DER) format is used to encode ECDSA signatures in Bitcoin. An ECDSA signature is generated using a private key and a hash of the signed message. It consists of two 32-byte numbers `(r,s)`. As [described by Pieter here](https://bitcoin.stackexchange.com/a/12556/5406) the DER signature format has the following components:

1. `0x30` byte: header byte to indicate compound structure
2. one byte to encode the length of the following data
3. `0x02`: header byte indicating an integer
4. one byte to encode the length of the following `r` value
5. the `r` value as a big-endian integer
6. `0x02`: header byte indicating an integer
7. one byte to encode the length of the following `s` value
8. the `s` value as a big-endian integer

Note that the `r` and `s` value must be prepended with `0x00` if their first byte is greater than `0x7F`. This causes variable signature lengths in the case that the `r` value is in the upper half of the range (referred to as "high `r`"). Signatures with high `s` values are non-standard and usually don't appear in the wild.
Also note that in rare cases [`r` or `s` can be shorter than 32 bytes](https://bitcoin.stackexchange.com/a/38521/5406) which is legal and leads to shorter signatures.
Note that in bitcoin transactions a byte is added at the end of a DER signature denoting the SigHash type used.

## SEC

The Standards of Efficient Cryptography (SEC) encoding is used to serialize ECDSA public keys. Public keys in Bitcoin are ECDSA points consisting of two coordinates `(x,y)`. `x` and `y` may be smaller than 32 bytes in which case they must be padded with zeros to 32 bytes (H/T Coding Enthusiast). Bitcoin uses two formats, uncompressed and compressed:

**Uncompressed:**

1. `0x04` byte: header byte to indicate ECDSA point
2. the `x` coordinate as a 32-byte big-endian integer
3. the `y` coordinate as a 32-byte big-endian integer

**Compressed:**

As the coordinates `(x,y)` must satisfy the secp256k1 curve equation `y² = x³ + 7`, the two possible values for `y` can be calculated from the `x` value. Thus, we can express a public key just as the `x` coordinate in combination with an indicator which of the two `y` values to use.

1. `0x02`/`0x03` byte: header byte to indicate compressed ECDSA point, `0x02` for even `y`, `0x03` for odd `y`
2. the `x` coordinate as a 32-byte big-endian integer

---

The above is more comprehensively explained e.g. in [Jimmy Song's Programming Bitcoin: Ch4. Serialization](https://www.oreilly.com/library/view/programming-bitcoin/9781492031482/ch04.html).

> **Comments:**
> **username_4**: Great answer thanks, what are `r` and `s` derived from?  
> **username_3**: @Dominic: That’s the signature. The signature uses the Elliptic Curve Digital Signing Algorithm and the secp256k1 curve to commit to a Bitcoin transaction as the message. The “r” value commits to a random curve point, and the “s” value commits to the transaction and the random point in a manner that requires the knowledge of the relevant private key in the construction. See e.g. Stepan Snigirev’s blog post here for a longer explanation: https://medium.com/cryptoadvance/how-schnorr-signatures-may-improve-bitcoin-91655bcb4744  

---

### Answer by username_2 on 2020-01-05. Score: 3

There are different formats used to encode public keys and signatures into binary (octet-streams). They are defined in [Standards for Efficient Cryptography 1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.3) (SEC).

A public key is a point on an elliptic curve, consisting of an `x` and `y` coordinate. There needs to be a standard way for serializing these parts and deserializing them later. The standard defines a uncompressed and a compressed format for this serialization. Roughly, the uncompressed format uses the prefix byte `0x04` followed by the serialized `x` coordinate, followed by the serialized `y` coordinate. The lengths of `x` and `y` are determined by the curve. For bitcoin, the curve `secp256k1` is always used, so the coordinates are 32 bytes. The resulting uncompressed public key is 65 bytes total.

The compressed version prefixes the octet-stream with `0x02` if the y coordinate is even and `0x03` if the y coordinate is odd. The `x` coordinate is serialized after it, resulting in a 33 byte public key. This information is sufficient because the `y` coordinate can be recovered if `x` is known and the sign is known. (Technically, we don't need the sign either).

Signatures consist of an `r` value (the `x` coordinate of a point on the curve), and an `s` value, which is an integer (32-bytes for secp256k1). The signature can be encoded in just 64 bytes in this compact form.

The paper previously linked also gives descriptions of these formats in ASN.1 (Abstract Syntax Notation 1). This is a textual interface description language which has been used to describe protocols for interoperability for a long time. Another standard, DER, or Distinguished Encoding Rules, describes a process for serializing data into octet-streams according to the ASN.1 specification for the data type.

The ASN.1 for signatures is (simplified):

```
ECDSA-Sig-Value ::= SEQUENCE {
    r INTEGER,
    s INTEGER
}

```

According to the DER rules: a SEQUENCE is of type `0x30` and is followed by a length (1 byte for length < 128), then the data for the sequence itself. INTEGER has type type `0x02` followed by its length, followed by the integer in binary. These integers are also signed, which means that if their value is >= 2^31 an additional zero valued byte must be prefixed to them. The resulting DER encoding for a Secp256k1 signature looks something like (assuming 32-byte r and s):

```
0x30 0x44 0x02 0x20 <r[32]> 0x02 0x20 <s[32]>

```

As you can see, this is pretty wasteful compared to the concise 64-byte serialization of (r,s). The uncompressed version of public keys is also very wasteful because every byte in a transaction is valuable. The Segwit upgrade to bitcoin introduced some restrictions on which formats can be used, and additionally, the upcoming Taproot upgrade will require 32-byte (x-only) public keys, which are not part of the SEC standard.


---

