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.

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?

  • 2
    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. – StephenM347 Jul 1 '15 at 15:04
  • 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 Jul 1 '15 at 16:41
  • @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 Jul 1 '15 at 19:55
  • 4
    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 Jul 2 '15 at 11:37
up vote 20 down vote accepted

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).

  • 3
    @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 Aug 18 '15 at 12:20
  • 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. – Pieter Wuille Aug 18 '15 at 12:26
  • 1
    @Sentinel You can get full information on the recovery method here: – Souza Feb 10 at 0:14
  • 2
    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 Feb 10 at 0:19
  • 1
    @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 Feb 10 at 11:42

I don't think that the v you describe is part of 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.

  • Right, but does v appear across implementations? Pybitcointools isn't the only implementation to use it, I believe. – Wizard Of Ozzie Jul 2 '15 at 0:42
  • The only other implementation I have seen is libsecp256k1, 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 Jul 2 '15 at 1:33
  • 1
    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 Jul 31 '15 at 23:10
  • Yeah, so v has to do with signing, not RFC6979. – David Grayson Aug 1 '15 at 0:47
  • @DavidGrayson yeah, have amended title :) – Wizard Of Ozzie Aug 1 '15 at 11:04

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.