<p>As all the other answers already outline: <code>v</code> is required to recover the correct public key for a signature because there are sometimes (even with low probability) more than one valid public key to be retrieved by a signature.</p>
<p>Here's a cheat sheet:</p>
<ul>
<li><code>27</code> uncompressed public key, y-parity <code>0</code>, magnitude of <code>x</code> lower than the curve order</li>
<li><code>28</code> uncompressed public key, y-parity <code>1</code>, magnitude of <code>x</code> lower than the curve order</li>
<li><code>29</code> uncompressed public key, y-parity <code>0</code>, magnitude of <code>x</code> <em>greater</em> than the curve order</li>
<li><code>30</code> uncompressed public key, y-parity <code>1</code>, magnitude of <code>x</code> <em>greater</em> than the curve order</li>
<li><code>31</code> <em>compressed</em> public key, y-parity <code>0</code>, magnitude of <code>x</code> lower than the curve order</li>
<li><code>32</code> <em>compressed</em> public key, y-parity <code>1</code>, magnitude of <code>x</code> lower than the curve order</li>
<li><code>33</code> <em>compressed</em> public key, y-parity <code>0</code>, magnitude of <code>x</code> <em>greater</em> than the curve order</li>
<li><code>34</code> <em>compressed</em> public key, y-parity <code>1</code>, magnitude of <code>x</code> <em>greater</em> than the curve order</li>
</ul>
<p>For any <code>v &gt;= 35</code> you might be dealing with Ethereum signatures as per <a href="https://eips.ethereum.org/EIPS/eip-155" rel="noreferrer">EIP-155</a>:</p>
<pre><code>v = recovery_id + CHAIN_ID * 2 + 35
</code></pre>

CC BY-SA 4.0
2022-02-18T16:46:20.997Z
2022-02-18T16:46:20.997Z
q9f
<p>I don't think that the <em>v</em> you describe is part of <a href="https://www.rfc-editor.org/rfc/rfc6979" rel="nofollow noreferrer">RFC6979</a> because I cannot find it in that document.  This <em>v</em> happens to be part of the <code>ecdsa_raw_sign</code> raw sign function in pybitcointools, which calls <code>deterministic_generate_k</code>, which is an implementation of RFC6979.</p>
<p>RFC6979 just helps you generate a deterministic <em>k</em> value for signing.  It does not help you generate <em>r</em> and <em>s</em>.  To generate <em>r</em> and <em>s</em>, you just use the normal ECDSA algorithm; you don't have to refer to RFC6979 after you have used it to generate <em>k</em>.  RFC6979 generates <em>k</em>, which is an input to the signing algorithm that can generate <em>r</em> and <em>s</em>.</p>

CC BY-SA 3.0
2015-07-02T00:42:13.057Z
Right, but does `v` appear across implementations? Pybitcointools isn't the only implementation to use it, I believe.
Wizard Of Ozzie
CC BY-SA 3.0
2015-07-02T01:33:13.580Z
The only other implementation I have seen is [libsecp256k1](https://github.com/bitcoin/secp256k1), which does not return a v number.  That library provides a function named `secp256k1_nonce_function_rfc6979` whose only output is a 32-byte buffer of data.
David Grayson
CC BY-SA 3.0
2015-07-31T23:10:41.360Z
secp256k1_ecdsa_sign_compact (old API) or secp256k1_pubkey_serialize_compact (new API) do return the recovery id (the value v, but without the 27 constant term). See my answer.
Pieter Wuille
CC BY-SA 3.0
2015-08-01T00:47:42.760Z
Yeah, so `v` has to do with signing, not RFC6979.
David Grayson
CC BY-SA 3.0
2015-08-01T11:04:26.493Z
@DavidGrayson yeah, have amended title :)
Wizard Of Ozzie
CC BY-SA 3.0
2015-07-01T21:36:49.980Z
2015-07-01T21:36:49.980Z
2021-10-07T07:34:52.683Z
David Grayson
<p><code>v</code> is needed to recover the public key. As a result of recovering the public key from ECDSA signature, 0, 1, or 2 points can be returned. In order to strictly indicate which point corresponds to the "original" public key, an additional byte is used</p>

CC BY-SA 4.0
2019-11-22T14:24:59.670Z
2019-11-22T14:24:59.670Z
viktor32
<p>This has nothing to do with RFC6979, but with ECDSA signing and public key recovery.</p>

<p>The (r, s) is the normal output of an ECDSA signature, where r is computed as the X coordinate of a point R, modulo the curve order n.</p>

<p>In Bitcoin, for message signatures, we use a trick called public key recovery. The fact is that if you have the full R point (not just its X coordinate) and s, and a message, you can compute for which public key this would be a valid signature. What this allows is to 'verify' a message with an address, without needing to know the full key (we just do public key recovery on the signature, and then hash the recovered key and compare it with the address).</p>

<p>However, this means we need the full R coordinates. There can be up to 4 different points with a given "X coordinate modulo n". (2 because each X coordinate has two possible Y coordinates, and 2 because r+n may still be a valid X coordinate). That number between 0 and 3 we call the recovery id, or recid. Therefore, we return an extra byte, which also functions as a header byte, by using 27+recid (for uncompressed recovered pubkeys) or 31+recid (for compressed recovered pubkeys).</p>

<p>Strictly speaking the recid is not necessary, as we can just cycle through all the possible coordinate pairs and check if any of them match the signature. The recid just speeds up this verification.</p>

<p>In general, if h is the cofactor, the maximum number of different points with given "X coordinate modulo n" will be 2(h+1). In the case of secp256k1, which has cofactor 1, we get 2(1+1) = 4.</p>

CC BY-SA 3.0
2015-08-01T06:21:04.363Z
Can you link to the code which implements this? I'm going to start learning C++ using functions like this which I understand
Wizard Of Ozzie
CC BY-SA 3.0
2015-08-01T09:42:03.893Z
The signing code is in libsecp256k1, which also has verification code, but that is not currently used. For verification, there is C code in Bitcoin Core (see pubkey.cpp) which does a series of OpenSSL calls to do the bulk of the work. I am not sure that reading cryptographic C code is the best way to learn C++ :)
Pieter Wuille
CC BY-SA 3.0
2015-08-02T09:00:43.053Z
It's more a way of learning things I understand pretty well already, and am interested in. I've learned Python that way and the ultimate goal is to know the core software too
Wizard Of Ozzie
CC BY-SA 3.0
2015-08-18T12:20:16.793Z
@PeterWuille `There can be up to 4 different points with a given "X coordinate modulo n". (2 because each X coordinate has two possible Y coordinates, and 2 because r+n may still be a valid X coordinate).` I understand the former (2 y values for each x, because of the symmetry)... But how does the latter work? ie `r+n may still be a valid X coordinate`??
Wizard Of Ozzie
CC BY-SA 3.0
2015-08-18T12:26:22.300Z
X and Y coordinates are numbers modulo p, the field size, which is around 2^256 - 2^32 for secp256k1. The value r and s in the signature however are modulo n, the group order, which is around 2^256 - 2^128. When R.x is between n and p, r is reduced to R.x-n. Thus, if you have an r value below 2^128-2^32, there may be 2 valid R.x values corresponding to it.
Pieter Wuille
CC BY-SA 3.0
2017-10-27T18:28:42.080Z
@PieterWuille - Is this specific for secp2561k, or can this be generalized for all elliptic curve signatures? Also, how does it relate to this answer on crypto SE - https://crypto.stackexchange.com/questions/18105/how-does-recovering-the-public-key-from-an-ecdsa-signature-work  ?
Karel Bílek
CC BY-SA 3.0
2017-10-27T21:00:04.480Z
ECDSA always supports public key, regardless of the curve. For curves with cofactor > 1 it is slightly more complicated. That linked answer explains the procedure.
Pieter Wuille
CC BY-SA 3.0
2018-01-10T15:09:38.837Z
Which, please, of the 4 possible output (27..30) corresponds to which of the possible results. Eg: 0 = positive Y and X1? where is this documented?
Sentinel
CC BY-SA 3.0
2018-02-10T00:14:28.493Z
@Sentinel You can get full information on the recovery method here: http://www.secg.org/sec1-v2.pdf
Souza
CC BY-SA 3.0
2018-02-10T00:19:22.213Z
27 = lower X even Y. 28 = lower X odd Y. 29 = higher X even Y. 30 = higher X odd Y. Note that 29 and 30 are exceedingly rarely, and will in practice only ever be seen in specifically generated examples. There are only two possible X values if r is between 1 and (p mod n), which has a chance of about 0.000000000000000000000000000000000000373 % to happen randomly.
Pieter Wuille
CC BY-SA 3.0
2018-02-10T11:42:22.937Z
@Souza / Pieter - Thanks. I had already managed to discover the answer to that - it took me forever! I did actually find that ASN.1 in sec1-v2.pdf after an enormous amount of digging. When I found it, I thought I'd struck gold. The problem is that the Ethereum documentation (I am implementing an Ethereum light client) does not include detailed protocol info, and official implementations tend to rely on libraries that go where Bitcoin already trod, so details like the 'v' parameter are lost/buried in very, very obscure code.
Sentinel
CC BY-SA 3.0
2018-02-10T16:04:22.673Z
@Sentinel my strugle's the same. I am working on top of Ethereum's protocol and they say little to nothing about this. And you're right, they both use libsecp256k1.
Souza
CC BY-SA 3.0
2018-02-11T15:18:03.863Z
@Souza - agreed. It is a struggle. I am trying to contact Ethereum foundation to put together accessible protocol documentation and get funding to do it. I am putting together a light client using reactive extensions and .NET, where I am treating all protocol messages as streams flowing through stack-layer adapters, and trying to insulate the top level protocol from lower level differences (discv4 vs v5 etc for example). By the time I am done I should be able to write a book on it.
Sentinel
CC BY-SA 4.0
2015-07-31T23:04:05.127Z
2018-08-19T16:59:44.873Z
2018-08-19T16:59:44.873Z
Pieter Wuille
<p>Deterministically signing a Tx with RFC6979 returns <code>v, r, s</code>, where <code>r</code> and <code>s</code> are the 2 values used in standard ECDSA signatures. <code>v = 27 + (y % 2)</code>, so 27 + the parity of <code>r</code>, <a href="https://github.com/simcity4242/pybitcointools/blob/9f79e2aa967a5c10a5a8ba16030c9b6fe0388c0e/bitcoin/main.py#L541-L542" rel="noreferrer">as pybitcointools indicates</a>. </p>

<p>So for even <code>r</code>, we get <code>v = 27</code>, odd <code>r</code> we get <code>v = 28</code>. </p>

<p>How is the value of <code>v</code> (27 or 28) important? Why is it necessary to have a <code>v</code> value? Also, why is it <code>27</code>? </p>

CC BY-SA 3.0
2015-07-01T15:04:11.540Z
Seems to be some sort of a version byte, similar to the version byte used in encoding addresses. Not sure of the significance of 27/28.
morsecoder
CC BY-SA 3.0
2015-07-01T16:41:38.593Z
Your link to github is broken; I would fix it but apparently I need to change at least 6 characters for it to be a valid edit.
David Grayson
CC BY-SA 3.0
2015-07-01T19:55:36.420Z
@DavidGrayson Link fixed. Perhaps Peter Wuille can comment, as I believe I've read that 27 was chosen arbitrarily because it was "halfway" between used version byte choices, though I can't find that source for the life of me
Wizard Of Ozzie
CC BY-SA 3.0
2015-07-02T11:37:16.987Z
That's correct. It was an arbitrary choice for a number at the time, because we needed a byte to convey public key recovery information. I'll try to write a full answer later.
Pieter Wuille
<signature><cryptography><ecdsa>
ECDSA: (v, r, s), what is v?
Wizard Of Ozzie
# ECDSA: (v, r, s), what is v?

(Asked by: username_0 on 2015-07-01)

Deterministically signing a Tx with RFC6979 returns `v, r, s`, where `r` and `s` are the 2 values used in standard ECDSA signatures. `v = 27 + (y % 2)`, so 27 + the parity of `r`, [as pybitcointools indicates](https://github.com/simcity4242/pybitcointools/blob/9f79e2aa967a5c10a5a8ba16030c9b6fe0388c0e/bitcoin/main.py#L541-L542).

So for even `r`, we get `v = 27`, odd `r` we get `v = 28`.

How is the value of `v` (27 or 28) important? Why is it necessary to have a `v` value? Also, why is it `27`?

**Tags:** signature, cryptography, ecdsa

> **Comments:**
> **username_1**: Seems to be some sort of a version byte, similar to the version byte used in encoding addresses. Not sure of the significance of 27/28.  
> **username_2**: Your link to github is broken; I would fix it but apparently I need to change at least 6 characters for it to be a valid edit.  
> **username_0**: @username_2 Link fixed. Perhaps Peter username_3 can comment, as I believe I've read that 27 was chosen arbitrarily because it was "halfway" between used version byte choices, though I can't find that source for the life of me  
> **username_3**: That's correct. It was an arbitrary choice for a number at the time, because we needed a byte to convey public key recovery information. I'll try to write a full answer later.  

---

## 4 answers

### Answer by username_3 on 2015-07-31. Score: 56 | Accepted answer

This has nothing to do with RFC6979, but with ECDSA signing and public key recovery.

The (r, s) is the normal output of an ECDSA signature, where r is computed as the X coordinate of a point R, modulo the curve order n.

In Bitcoin, for message signatures, we use a trick called public key recovery. The fact is that if you have the full R point (not just its X coordinate) and s, and a message, you can compute for which public key this would be a valid signature. What this allows is to 'verify' a message with an address, without needing to know the full key (we just do public key recovery on the signature, and then hash the recovered key and compare it with the address).

However, this means we need the full R coordinates. There can be up to 4 different points with a given "X coordinate modulo n". (2 because each X coordinate has two possible Y coordinates, and 2 because r+n may still be a valid X coordinate). That number between 0 and 3 we call the recovery id, or recid. Therefore, we return an extra byte, which also functions as a header byte, by using 27+recid (for uncompressed recovered pubkeys) or 31+recid (for compressed recovered pubkeys).

Strictly speaking the recid is not necessary, as we can just cycle through all the possible coordinate pairs and check if any of them match the signature. The recid just speeds up this verification.

In general, if h is the cofactor, the maximum number of different points with given "X coordinate modulo n" will be 2(h+1). In the case of secp256k1, which has cofactor 1, we get 2(1+1) = 4.

> **Comments:**
> **username_0**: Can you link to the code which implements this? I'm going to start learning C++ using functions like this which I understand  
> **username_3**: The signing code is in libsecp256k1, which also has verification code, but that is not currently used. For verification, there is C code in Bitcoin Core (see pubkey.cpp) which does a series of OpenSSL calls to do the bulk of the work. I am not sure that reading cryptographic C code is the best way to learn C++ :)  
> **username_0**: It's more a way of learning things I understand pretty well already, and am interested in. I've learned Python that way and the ultimate goal is to know the core software too  
> **username_0**: @PeterWuille `There can be up to 4 different points with a given "X coordinate modulo n". (2 because each X coordinate has two possible Y coordinates, and 2 because r+n may still be a valid X coordinate).` I understand the former (2 y values for each x, because of the symmetry)... But how does the latter work? ie `r+n may still be a valid X coordinate`??  
> **username_3**: X and Y coordinates are numbers modulo p, the field size, which is around 2^256 - 2^32 for secp256k1. The value r and s in the signature however are modulo n, the group order, which is around 2^256 - 2^128. When R.x is between n and p, r is reduced to R.x-n. Thus, if you have an r value below 2^128-2^32, there may be 2 valid R.x values corresponding to it.  
> **username_6**: @username_3 - Is this specific for secp2561k, or can this be generalized for all elliptic curve signatures? Also, how does it relate to this answer on crypto SE - https://crypto.stackexchange.com/questions/18105/how-does-recovering-the-public-key-from-an-ecdsa-signature-work  ?  
> **username_3**: ECDSA always supports public key, regardless of the curve. For curves with cofactor > 1 it is slightly more complicated. That linked answer explains the procedure.  
> **username_7**: Which, please, of the 4 possible output (27..30) corresponds to which of the possible results. Eg: 0 = positive Y and X1? where is this documented?  
> **username_8**: @username_7 You can get full information on the recovery method here: http://www.secg.org/sec1-v2.pdf  
> **username_3**: 27 = lower X even Y. 28 = lower X odd Y. 29 = higher X even Y. 30 = higher X odd Y. Note that 29 and 30 are exceedingly rarely, and will in practice only ever be seen in specifically generated examples. There are only two possible X values if r is between 1 and (p mod n), which has a chance of about 0.000000000000000000000000000000000000373 % to happen randomly.  
> **username_7**: @username_8 / username_3 - Thanks. I had already managed to discover the answer to that - it took me forever! I did actually find that ASN.1 in sec1-v2.pdf after an enormous amount of digging. When I found it, I thought I'd struck gold. The problem is that the Ethereum documentation (I am implementing an Ethereum light client) does not include detailed protocol info, and official implementations tend to rely on libraries that go where Bitcoin already trod, so details like the 'v' parameter are lost/buried in very, very obscure code.  
> **username_8**: @username_7 my strugle's the same. I am working on top of Ethereum's protocol and they say little to nothing about this. And you're right, they both use libsecp256k1.  
> **username_7**: @username_8 - agreed. It is a struggle. I am trying to contact Ethereum foundation to put together accessible protocol documentation and get funding to do it. I am putting together a light client using reactive extensions and .NET, where I am treating all protocol messages as streams flowing through stack-layer adapters, and trying to insulate the top level protocol from lower level differences (discv4 vs v5 etc for example). By the time I am done I should be able to write a book on it.  

---

### Answer by username_4 on 2022-02-18. Score: 6

As all the other answers already outline: `v` is required to recover the correct public key for a signature because there are sometimes (even with low probability) more than one valid public key to be retrieved by a signature.

Here's a cheat sheet:

* `27` uncompressed public key, y-parity `0`, magnitude of `x` lower than the curve order
* `28` uncompressed public key, y-parity `1`, magnitude of `x` lower than the curve order
* `29` uncompressed public key, y-parity `0`, magnitude of `x` *greater* than the curve order
* `30` uncompressed public key, y-parity `1`, magnitude of `x` *greater* than the curve order
* `31` *compressed* public key, y-parity `0`, magnitude of `x` lower than the curve order
* `32` *compressed* public key, y-parity `1`, magnitude of `x` lower than the curve order
* `33` *compressed* public key, y-parity `0`, magnitude of `x` *greater* than the curve order
* `34` *compressed* public key, y-parity `1`, magnitude of `x` *greater* than the curve order

For any `v >= 35` you might be dealing with Ethereum signatures as per [EIP-155](https://eips.ethereum.org/EIPS/eip-155):

```
v = recovery_id + CHAIN_ID * 2 + 35

```


---

### Answer by username_2 on 2015-07-01. Score: 3

I don't think that the *v* you describe is part of [RFC6979](https://www.rfc-editor.org/rfc/rfc6979) because I cannot find it in that document. This *v* happens to be part of the `ecdsa_raw_sign` raw sign function in pybitcointools, which calls `deterministic_generate_k`, which is an implementation of RFC6979.

RFC6979 just helps you generate a deterministic *k* value for signing. It does not help you generate *r* and *s*. To generate *r* and *s*, you just use the normal ECDSA algorithm; you don't have to refer to RFC6979 after you have used it to generate *k*. RFC6979 generates *k*, which is an input to the signing algorithm that can generate *r* and *s*.

> **Comments:**
> **username_0**: Right, but does `v` appear across implementations? Pybitcointools isn't the only implementation to use it, I believe.  
> **username_2**: The only other implementation I have seen is [libsecp256k1](https://github.com/bitcoin/secp256k1), which does not return a v number.  That library provides a function named `secp256k1_nonce_function_rfc6979` whose only output is a 32-byte buffer of data.  
> **username_3**: secp256k1_ecdsa_sign_compact (old API) or secp256k1_pubkey_serialize_compact (new API) do return the recovery id (the value v, but without the 27 constant term). See my answer.  
> **username_2**: Yeah, so `v` has to do with signing, not RFC6979.  
> **username_0**: @username_2 yeah, have amended title :)  

---

### Answer by username_5 on 2019-11-22. Score: 2

`v` is needed to recover the public key. As a result of recovering the public key from ECDSA signature, 0, 1, or 2 points can be returned. In order to strictly indicate which point corresponds to the "original" public key, an additional byte is used


---

