From 6d42bc0c5b560f42c2b4c7ac459cfa3ee5cb3701 Mon Sep 17 00:00:00 2001 From: cgilliard Date: Mon, 18 Feb 2019 13:45:02 -0800 Subject: create new bip proposal --- bip-XXXX.mediawiki | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 bip-XXXX.mediawiki diff --git a/bip-XXXX.mediawiki b/bip-XXXX.mediawiki new file mode 100644 index 0000000..4a7524d --- /dev/null +++ b/bip-XXXX.mediawiki @@ -0,0 +1,121 @@ +
+  BIP: ???
+  Layer: Applications
+  Title: Signatures of Messages using Bitcoin Private Keys
+  Author: Christopher Gilliard <christopher.gilliard@gmail.com>
+  Comments-Summary: No comments yet.
+  Comments-URI: TBD
+  Status: Proposal
+  Type: Informational
+  Created: 2019-02-16
+  License: BSD-2-Clause
+
+ +# Abstract # + +This document describes a signature format for signing messages with Bitcoin private keys. + +The specification is intended to set a standard for signatures of messages that can be signed and verfied between different clients. + +One of the key problems in this area is that there are several different types of Bitcoin addresses and without introducing specific standards it is unclear which type of address format is being used. See [1]. This BIP will attempt to address these issues and define a clear and concise format for Bitcoin signatures. + +# Copyright # + +This BIP is licensed under the 2-clause BSD license. + +# Motivation # + +Since Bitcoin private keys can not only be used to sign Bitcoin transactions, but also any other message, it has become customary to use them to sign various messages for differing purposes. Some applications of signing messages with a Bitcoin private key are as follows: proof of funds for collateral, credit worthiness, enterence to events, airdrops, audits as well as other applications. While there was no BIP written for how to digitally sign messages with Bitcoin private keys with P2PKH addresses it is a fairly well understood process, however with the introduction of Segwit (both in the form of P2SH and bech32) addresses, it is unclear how to distinguish a P2PKH, P2SH, or bech32 address from one another. This BIP proposes a standard signature format that will allow clients to distinguish between the different address formats. + +# Specification # + +## Background on ECDSA Signatures ## + +Elliptic Curve Digital Signature Algorithm or ECDSA is a cryptographic algorithm used by Bitcoin to ensure that funds can only be spent by their rightful owners. + +A few concepts related to ECDSA: + +private key: A secret number, known only to the person that generated it. A private key is essentially a randomly generated number. In Bitcoin, someone with the private key that corresponds to funds on the block chain can spend the funds. In Bitcoin, a private key is a single unsigned 256 bit integer (32 bytes). +public key: A number that corresponds to a private key, but does not need to be kept secret. A public key can be calculated from a private key, but not vice versa. A public key can be used to determine if a signature is genuine (in other words, produced with the proper key) without requiring the private key to be divulged. In Bitcoin, public keys are either compressed or uncompressed. Compressed public keys are 33 bytes, consisting of a prefix either 0x02 or 0x03, and a 256-bit integer called x. The older uncompressed keys are 65 bytes, consisting of constant prefix (0x04), followed by two 256-bit integers called x and y (2 * 32 bytes). The prefix of a compressed key allows for the y value to be derived from the x value. +signature: A number that proves that a signing operation took place. A signature is mathematically generated from a hash of something to be signed, plus a private key. The signature itself is two numbers known as r and s. With the public key, a mathematical algorithm can be used on the signature to determine that it was originally produced from the hash and the private key, without needing to know the private key. Signatures are either 73, 72, or 71 bytes long, with probabilities approximately 25%, 50% and 25% respectively, although sizes even smaller than that are possible with exponentially decreasing probability. Source [2]. + +## Conventions with signatures used in Bitcoin ## + +Bitcoin signatures have the r and s values mentioned above, and a header. The header is a single byte and the r and s are each 32 bytes so a signature's size is 65 bytes. The header is used to specify information about the signature. It can be thought of as a bitmask with each bit in this byte having a meaning. The serialization format of a Bitcoin signature is as follows: + +[1 byte of header data][32 bytes for r value][32 bytes for s value] + +The header byte has a few components to it. First, it stores something known as the recId. This value is stored in the least significant 2 bits of the header. If the header is between a value of 31 and 34, this indicates that it is a compressed address. If the header value is between 35 and 38 inclusive, it is a p2sh segwit address. If the header value is between 39 and 42, it is a bech32 address. + +## Sample Code for processing a signature ## + +Note: this code is a modification of the BitcoinJ code which is written in java. + +```Java + public static ECKey signedMessageToKey(String message, String signatureBase64) throws SignatureException { + byte[] signatureEncoded; + try { + signatureEncoded = Base64.decode(signatureBase64); + } catch (RuntimeException e) { + // This is what you get back from Bouncy Castle if base64 doesn't decode :( + throw new SignatureException("Could not decode base64", e); + } + // Parse the signature bytes into r/s and the selector value. + if (signatureEncoded.length < 65) + throw new SignatureException("Signature truncated, expected 65 bytes and got " + signatureEncoded.length); + int header = signatureEncoded[0] & 0xFF; + // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, + // 0x1D = second key with even y, 0x1E = second key with odd y + if (header < 27 || header > 42) + throw new SignatureException("Header byte out of range: " + header); + BigInteger r = new BigInteger(1, Arrays.copyOfRange(signatureEncoded, 1, 33)); + BigInteger s = new BigInteger(1, Arrays.copyOfRange(signatureEncoded, 33, 65)); + ECDSASignature sig = new ECDSASignature(r, s); + byte[] messageBytes = formatMessageForSigning(message); + // Note that the C++ code doesn't actually seem to specify any character encoding. Presumably it's whatever + // JSON-SPIRIT hands back. Assume UTF-8 for now. + Sha256Hash messageHash = Sha256Hash.twiceOf(messageBytes); + boolean compressed = false; + + // this section is added to support new signature types + if(header>= 39) // this is a bech32 signature + { + header -= 12; + compressed = true; + } // this is a segwit p2sh signature + else if(header >= 35) + { + header -= 8; + compressed = true; + } // this is a compressed key signature + else if (header >= 31) { + compressed = true; + header -= 4; + } + + int recId = header - 27; + + ECKey key = ECKey.recoverFromSignature(recId, sig, messageHash, compressed); + if (key == null) + throw new SignatureException("Could not recover public key from signature"); + return key; + } +``` + +# Implications # + +Message signing is an important use case and potentially underused due to the fact that, up until now, there has not be a formal specification for how wallets can sign messages using Bitcoin private keys. Bitcoin wallets should be interoperable and use the same conventions for determing a signature's validity. This BIP can also be updated as new signature formats emerge. + +# Acknowledgements # + +* Konstantin Bay - review +* Holly Casaletto - review +* James Bryrer - review + +Note that the background on ECDSA signatures was taken from en.bitcoin.it and code sample modified from BitcoinJ. + +# References # + +[1] - https://github.com/bitcoin/bitcoin/issues/10542 + +[2] - https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm -- cgit v1.2.3 From f4a04d2bc6a50a52de291bfdf064557dd753ed4e Mon Sep 17 00:00:00 2001 From: cgilliard Date: Tue, 19 Feb 2019 16:50:30 -0800 Subject: Add P2PKH info, backwards compat, BIP 311 ref --- bip-XXXX.mediawiki | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/bip-XXXX.mediawiki b/bip-XXXX.mediawiki index 4a7524d..3575838 100644 --- a/bip-XXXX.mediawiki +++ b/bip-XXXX.mediawiki @@ -15,9 +15,9 @@ This document describes a signature format for signing messages with Bitcoin private keys. -The specification is intended to set a standard for signatures of messages that can be signed and verfied between different clients. +The specification is intended to describe the standard for signatures of messages that can be signed and verfied between different clients that exists in the field today. Note: that a new signature format has been definied which has a number of advantages over this BIP, but to be backwards compatible with existing implementings this BIP will be useful. See BIP 322 [1] for full details on the new signature scheme. -One of the key problems in this area is that there are several different types of Bitcoin addresses and without introducing specific standards it is unclear which type of address format is being used. See [1]. This BIP will attempt to address these issues and define a clear and concise format for Bitcoin signatures. +One of the key problems in this area is that there are several different types of Bitcoin addresses and without introducing specific standards it is unclear which type of address format is being used. See [2]. This BIP will attempt to address these issues and define a clear and concise format for Bitcoin signatures. # Copyright # @@ -31,13 +31,14 @@ Since Bitcoin private keys can not only be used to sign Bitcoin transactions, bu ## Background on ECDSA Signatures ## +(For readers who already understand how ECDSA signatures work, you can skip this section as this is only intended as background information.) Elliptic Curve Digital Signature Algorithm or ECDSA is a cryptographic algorithm used by Bitcoin to ensure that funds can only be spent by their rightful owners. A few concepts related to ECDSA: private key: A secret number, known only to the person that generated it. A private key is essentially a randomly generated number. In Bitcoin, someone with the private key that corresponds to funds on the block chain can spend the funds. In Bitcoin, a private key is a single unsigned 256 bit integer (32 bytes). public key: A number that corresponds to a private key, but does not need to be kept secret. A public key can be calculated from a private key, but not vice versa. A public key can be used to determine if a signature is genuine (in other words, produced with the proper key) without requiring the private key to be divulged. In Bitcoin, public keys are either compressed or uncompressed. Compressed public keys are 33 bytes, consisting of a prefix either 0x02 or 0x03, and a 256-bit integer called x. The older uncompressed keys are 65 bytes, consisting of constant prefix (0x04), followed by two 256-bit integers called x and y (2 * 32 bytes). The prefix of a compressed key allows for the y value to be derived from the x value. -signature: A number that proves that a signing operation took place. A signature is mathematically generated from a hash of something to be signed, plus a private key. The signature itself is two numbers known as r and s. With the public key, a mathematical algorithm can be used on the signature to determine that it was originally produced from the hash and the private key, without needing to know the private key. Signatures are either 73, 72, or 71 bytes long, with probabilities approximately 25%, 50% and 25% respectively, although sizes even smaller than that are possible with exponentially decreasing probability. Source [2]. +signature: A number that proves that a signing operation took place. A signature is mathematically generated from a hash of something to be signed, plus a private key. The signature itself is two numbers known as r and s. With the public key, a mathematical algorithm can be used on the signature to determine that it was originally produced from the hash and the private key, without needing to know the private key. Signatures are either 73, 72, or 71 bytes long, with probabilities approximately 25%, 50% and 25% respectively, although sizes even smaller than that are possible with exponentially decreasing probability. Source [3]. ## Conventions with signatures used in Bitcoin ## @@ -47,6 +48,16 @@ Bitcoin signatures have the r and s values mentioned above, and a header. The he The header byte has a few components to it. First, it stores something known as the recId. This value is stored in the least significant 2 bits of the header. If the header is between a value of 31 and 34, this indicates that it is a compressed address. If the header value is between 35 and 38 inclusive, it is a p2sh segwit address. If the header value is between 39 and 42, it is a bech32 address. +## Procedure for signing/verifying a signature ## + +As noted above the signature is composed of three components, the header, r and s values. r/s can be computed with standard ECDSA library functions. Part of the header includes something called a recId. This is part of every ECDSA signature and should be generated by the ECDSA library. The recId is a number between 0 and 3 inclusive. The header is the recId plus a constant which indicates what time of Bitcoin private key this is. For P2PKH uncompressed keys, this value is 27. For P2PKH compressed keys, this value is 31. For P2SH Segwit keys, this value is 35 and for bech32 keys, this value is 35. So, you have the following ranges: +27-30: P2PKH uncompressed +31-34: P2PKH compressed +35-38: Segwit P2SH +39-42: Segwit Bech32 + +To verify a signature, the recId is obtained by subtracting this constant from the header value. + ## Sample Code for processing a signature ## Note: this code is a modification of the BitcoinJ code which is written in java. @@ -102,6 +113,10 @@ Note: this code is a modification of the BitcoinJ code which is written in java. } ``` +# Backwards Compatibility # + +Since this format includes P2PKH keys, it is backwards compatible, but keep in mind some software has checks for ranges of headers and will report the newer segwit header types as errors. + # Implications # Message signing is an important use case and potentially underused due to the fact that, up until now, there has not be a formal specification for how wallets can sign messages using Bitcoin private keys. Bitcoin wallets should be interoperable and use the same conventions for determing a signature's validity. This BIP can also be updated as new signature formats emerge. @@ -116,6 +131,8 @@ Note that the background on ECDSA signatures was taken from en.bitcoin.it and co # References # -[1] - https://github.com/bitcoin/bitcoin/issues/10542 +[1] - https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki + +[2] - https://github.com/bitcoin/bitcoin/issues/10542 -[2] - https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm +[3] - https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm -- cgit v1.2.3 From dbaaab3abf2959fdf2e5aee4c4eb0256b95b2070 Mon Sep 17 00:00:00 2001 From: cgilliard Date: Tue, 19 Feb 2019 18:57:50 -0800 Subject: grammer fix --- bip-XXXX.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-XXXX.mediawiki b/bip-XXXX.mediawiki index 3575838..f3650dd 100644 --- a/bip-XXXX.mediawiki +++ b/bip-XXXX.mediawiki @@ -15,7 +15,7 @@ This document describes a signature format for signing messages with Bitcoin private keys. -The specification is intended to describe the standard for signatures of messages that can be signed and verfied between different clients that exists in the field today. Note: that a new signature format has been definied which has a number of advantages over this BIP, but to be backwards compatible with existing implementings this BIP will be useful. See BIP 322 [1] for full details on the new signature scheme. +The specification is intended to describe the standard for signatures of messages that can be signed and verfied between different clients that exist in the field today. Note: that a new signature format has been definied which has a number of advantages over this BIP, but to be backwards compatible with existing implementings this BIP will be useful. See BIP 322 [1] for full details on the new signature scheme. One of the key problems in this area is that there are several different types of Bitcoin addresses and without introducing specific standards it is unclear which type of address format is being used. See [2]. This BIP will attempt to address these issues and define a clear and concise format for Bitcoin signatures. -- cgit v1.2.3 From d4e0fc03f3873605294f8e30481e3a14d03a507d Mon Sep 17 00:00:00 2001 From: cgilliard Date: Tue, 19 Feb 2019 18:58:47 -0800 Subject: spelling fix --- bip-XXXX.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-XXXX.mediawiki b/bip-XXXX.mediawiki index f3650dd..5e28e93 100644 --- a/bip-XXXX.mediawiki +++ b/bip-XXXX.mediawiki @@ -15,7 +15,7 @@ This document describes a signature format for signing messages with Bitcoin private keys. -The specification is intended to describe the standard for signatures of messages that can be signed and verfied between different clients that exist in the field today. Note: that a new signature format has been definied which has a number of advantages over this BIP, but to be backwards compatible with existing implementings this BIP will be useful. See BIP 322 [1] for full details on the new signature scheme. +The specification is intended to describe the standard for signatures of messages that can be signed and verfied between different clients that exist in the field today. Note: that a new signature format has been definied which has a number of advantages over this BIP, but to be backwards compatible with existing implementations this BIP will be useful. See BIP 322 [1] for full details on the new signature scheme. One of the key problems in this area is that there are several different types of Bitcoin addresses and without introducing specific standards it is unclear which type of address format is being used. See [2]. This BIP will attempt to address these issues and define a clear and concise format for Bitcoin signatures. -- cgit v1.2.3 From fe6899a294c5d437f727981f69a660a833bcba6b Mon Sep 17 00:00:00 2001 From: cgilliard Date: Sat, 2 Mar 2019 14:50:23 -0800 Subject: fix typo --- bip-XXXX.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-XXXX.mediawiki b/bip-XXXX.mediawiki index 5e28e93..310ae21 100644 --- a/bip-XXXX.mediawiki +++ b/bip-XXXX.mediawiki @@ -15,7 +15,7 @@ This document describes a signature format for signing messages with Bitcoin private keys. -The specification is intended to describe the standard for signatures of messages that can be signed and verfied between different clients that exist in the field today. Note: that a new signature format has been definied which has a number of advantages over this BIP, but to be backwards compatible with existing implementations this BIP will be useful. See BIP 322 [1] for full details on the new signature scheme. +The specification is intended to describe the standard for signatures of messages that can be signed and verfied between different clients that exist in the field today. Note: that a new signature format has been defined which has a number of advantages over this BIP, but to be backwards compatible with existing implementations this BIP will be useful. See BIP 322 [1] for full details on the new signature scheme. One of the key problems in this area is that there are several different types of Bitcoin addresses and without introducing specific standards it is unclear which type of address format is being used. See [2]. This BIP will attempt to address these issues and define a clear and concise format for Bitcoin signatures. -- cgit v1.2.3 From 5a53d13b1c969b960dcd9bd12aa5ba1f031b87ea Mon Sep 17 00:00:00 2001 From: cgilliard Date: Sat, 2 Mar 2019 14:52:44 -0800 Subject: fix typo --- bip-XXXX.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-XXXX.mediawiki b/bip-XXXX.mediawiki index 310ae21..4d4b0b9 100644 --- a/bip-XXXX.mediawiki +++ b/bip-XXXX.mediawiki @@ -119,7 +119,7 @@ Since this format includes P2PKH keys, it is backwards compatible, but keep in m # Implications # -Message signing is an important use case and potentially underused due to the fact that, up until now, there has not be a formal specification for how wallets can sign messages using Bitcoin private keys. Bitcoin wallets should be interoperable and use the same conventions for determing a signature's validity. This BIP can also be updated as new signature formats emerge. +Message signing is an important use case and potentially underused due to the fact that, up until now, there has not been a formal specification for how wallets can sign messages using Bitcoin private keys. Bitcoin wallets should be interoperable and use the same conventions for determing a signature's validity. This BIP can also be updated as new signature formats emerge. # Acknowledgements # -- cgit v1.2.3 From 99f4211dde9f0b3ae31f366303c225e314638f1c Mon Sep 17 00:00:00 2001 From: cgilliard Date: Sat, 2 Mar 2019 14:55:38 -0800 Subject: bold three key words and add in empty lines --- bip-XXXX.mediawiki | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/bip-XXXX.mediawiki b/bip-XXXX.mediawiki index 4d4b0b9..1dbb9d5 100644 --- a/bip-XXXX.mediawiki +++ b/bip-XXXX.mediawiki @@ -36,9 +36,11 @@ Elliptic Curve Digital Signature Algorithm or ECDSA is a cryptographic algorithm A few concepts related to ECDSA: -private key: A secret number, known only to the person that generated it. A private key is essentially a randomly generated number. In Bitcoin, someone with the private key that corresponds to funds on the block chain can spend the funds. In Bitcoin, a private key is a single unsigned 256 bit integer (32 bytes). -public key: A number that corresponds to a private key, but does not need to be kept secret. A public key can be calculated from a private key, but not vice versa. A public key can be used to determine if a signature is genuine (in other words, produced with the proper key) without requiring the private key to be divulged. In Bitcoin, public keys are either compressed or uncompressed. Compressed public keys are 33 bytes, consisting of a prefix either 0x02 or 0x03, and a 256-bit integer called x. The older uncompressed keys are 65 bytes, consisting of constant prefix (0x04), followed by two 256-bit integers called x and y (2 * 32 bytes). The prefix of a compressed key allows for the y value to be derived from the x value. -signature: A number that proves that a signing operation took place. A signature is mathematically generated from a hash of something to be signed, plus a private key. The signature itself is two numbers known as r and s. With the public key, a mathematical algorithm can be used on the signature to determine that it was originally produced from the hash and the private key, without needing to know the private key. Signatures are either 73, 72, or 71 bytes long, with probabilities approximately 25%, 50% and 25% respectively, although sizes even smaller than that are possible with exponentially decreasing probability. Source [3]. +private key: A secret number, known only to the person that generated it. A private key is essentially a randomly generated number. In Bitcoin, someone with the private key that corresponds to funds on the block chain can spend the funds. In Bitcoin, a private key is a single unsigned 256 bit integer (32 bytes). + +public key: A number that corresponds to a private key, but does not need to be kept secret. A public key can be calculated from a private key, but not vice versa. A public key can be used to determine if a signature is genuine (in other words, produced with the proper key) without requiring the private key to be divulged. In Bitcoin, public keys are either compressed or uncompressed. Compressed public keys are 33 bytes, consisting of a prefix either 0x02 or 0x03, and a 256-bit integer called x. The older uncompressed keys are 65 bytes, consisting of constant prefix (0x04), followed by two 256-bit integers called x and y (2 * 32 bytes). The prefix of a compressed key allows for the y value to be derived from the x value. + +signature: A number that proves that a signing operation took place. A signature is mathematically generated from a hash of something to be signed, plus a private key. The signature itself is two numbers known as r and s. With the public key, a mathematical algorithm can be used on the signature to determine that it was originally produced from the hash and the private key, without needing to know the private key. Signatures are either 73, 72, or 71 bytes long, with probabilities approximately 25%, 50% and 25% respectively, although sizes even smaller than that are possible with exponentially decreasing probability. Source [3]. ## Conventions with signatures used in Bitcoin ## -- cgit v1.2.3 From a7136d5ca8f9fe251b8122b1b17fd274c7e50a7e Mon Sep 17 00:00:00 2001 From: cgilliard Date: Fri, 29 Mar 2019 09:03:01 -0700 Subject: use bip number 137 and use literal < and > --- bip-XXXX.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-XXXX.mediawiki b/bip-XXXX.mediawiki index 1dbb9d5..be39277 100644 --- a/bip-XXXX.mediawiki +++ b/bip-XXXX.mediawiki @@ -1,8 +1,8 @@
-  BIP: ???
+  BIP: 137
   Layer: Applications
   Title: Signatures of Messages using Bitcoin Private Keys
-  Author: Christopher Gilliard <christopher.gilliard@gmail.com>
+  Author: Christopher Gilliard 
   Comments-Summary: No comments yet.
   Comments-URI: TBD
   Status: Proposal
-- 
cgit v1.2.3


From cd1cb8f75402ddf9756f111a72c33d3fe4051936 Mon Sep 17 00:00:00 2001
From: cgilliard 
Date: Fri, 29 Mar 2019 09:04:27 -0700
Subject: update file name to bip 137

---
 bip-0137.mediawiki | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 bip-XXXX.mediawiki | 140 -----------------------------------------------------
 2 files changed, 140 insertions(+), 140 deletions(-)
 create mode 100644 bip-0137.mediawiki
 delete mode 100644 bip-XXXX.mediawiki

diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki
new file mode 100644
index 0000000..be39277
--- /dev/null
+++ b/bip-0137.mediawiki
@@ -0,0 +1,140 @@
+
+  BIP: 137
+  Layer: Applications
+  Title: Signatures of Messages using Bitcoin Private Keys
+  Author: Christopher Gilliard 
+  Comments-Summary: No comments yet.
+  Comments-URI: TBD
+  Status: Proposal
+  Type: Informational
+  Created: 2019-02-16
+  License: BSD-2-Clause
+
+ +# Abstract # + +This document describes a signature format for signing messages with Bitcoin private keys. + +The specification is intended to describe the standard for signatures of messages that can be signed and verfied between different clients that exist in the field today. Note: that a new signature format has been defined which has a number of advantages over this BIP, but to be backwards compatible with existing implementations this BIP will be useful. See BIP 322 [1] for full details on the new signature scheme. + +One of the key problems in this area is that there are several different types of Bitcoin addresses and without introducing specific standards it is unclear which type of address format is being used. See [2]. This BIP will attempt to address these issues and define a clear and concise format for Bitcoin signatures. + +# Copyright # + +This BIP is licensed under the 2-clause BSD license. + +# Motivation # + +Since Bitcoin private keys can not only be used to sign Bitcoin transactions, but also any other message, it has become customary to use them to sign various messages for differing purposes. Some applications of signing messages with a Bitcoin private key are as follows: proof of funds for collateral, credit worthiness, enterence to events, airdrops, audits as well as other applications. While there was no BIP written for how to digitally sign messages with Bitcoin private keys with P2PKH addresses it is a fairly well understood process, however with the introduction of Segwit (both in the form of P2SH and bech32) addresses, it is unclear how to distinguish a P2PKH, P2SH, or bech32 address from one another. This BIP proposes a standard signature format that will allow clients to distinguish between the different address formats. + +# Specification # + +## Background on ECDSA Signatures ## + +(For readers who already understand how ECDSA signatures work, you can skip this section as this is only intended as background information.) +Elliptic Curve Digital Signature Algorithm or ECDSA is a cryptographic algorithm used by Bitcoin to ensure that funds can only be spent by their rightful owners. + +A few concepts related to ECDSA: + +private key: A secret number, known only to the person that generated it. A private key is essentially a randomly generated number. In Bitcoin, someone with the private key that corresponds to funds on the block chain can spend the funds. In Bitcoin, a private key is a single unsigned 256 bit integer (32 bytes). + +public key: A number that corresponds to a private key, but does not need to be kept secret. A public key can be calculated from a private key, but not vice versa. A public key can be used to determine if a signature is genuine (in other words, produced with the proper key) without requiring the private key to be divulged. In Bitcoin, public keys are either compressed or uncompressed. Compressed public keys are 33 bytes, consisting of a prefix either 0x02 or 0x03, and a 256-bit integer called x. The older uncompressed keys are 65 bytes, consisting of constant prefix (0x04), followed by two 256-bit integers called x and y (2 * 32 bytes). The prefix of a compressed key allows for the y value to be derived from the x value. + +signature: A number that proves that a signing operation took place. A signature is mathematically generated from a hash of something to be signed, plus a private key. The signature itself is two numbers known as r and s. With the public key, a mathematical algorithm can be used on the signature to determine that it was originally produced from the hash and the private key, without needing to know the private key. Signatures are either 73, 72, or 71 bytes long, with probabilities approximately 25%, 50% and 25% respectively, although sizes even smaller than that are possible with exponentially decreasing probability. Source [3]. + +## Conventions with signatures used in Bitcoin ## + +Bitcoin signatures have the r and s values mentioned above, and a header. The header is a single byte and the r and s are each 32 bytes so a signature's size is 65 bytes. The header is used to specify information about the signature. It can be thought of as a bitmask with each bit in this byte having a meaning. The serialization format of a Bitcoin signature is as follows: + +[1 byte of header data][32 bytes for r value][32 bytes for s value] + +The header byte has a few components to it. First, it stores something known as the recId. This value is stored in the least significant 2 bits of the header. If the header is between a value of 31 and 34, this indicates that it is a compressed address. If the header value is between 35 and 38 inclusive, it is a p2sh segwit address. If the header value is between 39 and 42, it is a bech32 address. + +## Procedure for signing/verifying a signature ## + +As noted above the signature is composed of three components, the header, r and s values. r/s can be computed with standard ECDSA library functions. Part of the header includes something called a recId. This is part of every ECDSA signature and should be generated by the ECDSA library. The recId is a number between 0 and 3 inclusive. The header is the recId plus a constant which indicates what time of Bitcoin private key this is. For P2PKH uncompressed keys, this value is 27. For P2PKH compressed keys, this value is 31. For P2SH Segwit keys, this value is 35 and for bech32 keys, this value is 35. So, you have the following ranges: +27-30: P2PKH uncompressed +31-34: P2PKH compressed +35-38: Segwit P2SH +39-42: Segwit Bech32 + +To verify a signature, the recId is obtained by subtracting this constant from the header value. + +## Sample Code for processing a signature ## + +Note: this code is a modification of the BitcoinJ code which is written in java. + +```Java + public static ECKey signedMessageToKey(String message, String signatureBase64) throws SignatureException { + byte[] signatureEncoded; + try { + signatureEncoded = Base64.decode(signatureBase64); + } catch (RuntimeException e) { + // This is what you get back from Bouncy Castle if base64 doesn't decode :( + throw new SignatureException("Could not decode base64", e); + } + // Parse the signature bytes into r/s and the selector value. + if (signatureEncoded.length < 65) + throw new SignatureException("Signature truncated, expected 65 bytes and got " + signatureEncoded.length); + int header = signatureEncoded[0] & 0xFF; + // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, + // 0x1D = second key with even y, 0x1E = second key with odd y + if (header < 27 || header > 42) + throw new SignatureException("Header byte out of range: " + header); + BigInteger r = new BigInteger(1, Arrays.copyOfRange(signatureEncoded, 1, 33)); + BigInteger s = new BigInteger(1, Arrays.copyOfRange(signatureEncoded, 33, 65)); + ECDSASignature sig = new ECDSASignature(r, s); + byte[] messageBytes = formatMessageForSigning(message); + // Note that the C++ code doesn't actually seem to specify any character encoding. Presumably it's whatever + // JSON-SPIRIT hands back. Assume UTF-8 for now. + Sha256Hash messageHash = Sha256Hash.twiceOf(messageBytes); + boolean compressed = false; + + // this section is added to support new signature types + if(header>= 39) // this is a bech32 signature + { + header -= 12; + compressed = true; + } // this is a segwit p2sh signature + else if(header >= 35) + { + header -= 8; + compressed = true; + } // this is a compressed key signature + else if (header >= 31) { + compressed = true; + header -= 4; + } + + int recId = header - 27; + + ECKey key = ECKey.recoverFromSignature(recId, sig, messageHash, compressed); + if (key == null) + throw new SignatureException("Could not recover public key from signature"); + return key; + } +``` + +# Backwards Compatibility # + +Since this format includes P2PKH keys, it is backwards compatible, but keep in mind some software has checks for ranges of headers and will report the newer segwit header types as errors. + +# Implications # + +Message signing is an important use case and potentially underused due to the fact that, up until now, there has not been a formal specification for how wallets can sign messages using Bitcoin private keys. Bitcoin wallets should be interoperable and use the same conventions for determing a signature's validity. This BIP can also be updated as new signature formats emerge. + +# Acknowledgements # + +* Konstantin Bay - review +* Holly Casaletto - review +* James Bryrer - review + +Note that the background on ECDSA signatures was taken from en.bitcoin.it and code sample modified from BitcoinJ. + +# References # + +[1] - https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki + +[2] - https://github.com/bitcoin/bitcoin/issues/10542 + +[3] - https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm diff --git a/bip-XXXX.mediawiki b/bip-XXXX.mediawiki deleted file mode 100644 index be39277..0000000 --- a/bip-XXXX.mediawiki +++ /dev/null @@ -1,140 +0,0 @@ -
-  BIP: 137
-  Layer: Applications
-  Title: Signatures of Messages using Bitcoin Private Keys
-  Author: Christopher Gilliard 
-  Comments-Summary: No comments yet.
-  Comments-URI: TBD
-  Status: Proposal
-  Type: Informational
-  Created: 2019-02-16
-  License: BSD-2-Clause
-
- -# Abstract # - -This document describes a signature format for signing messages with Bitcoin private keys. - -The specification is intended to describe the standard for signatures of messages that can be signed and verfied between different clients that exist in the field today. Note: that a new signature format has been defined which has a number of advantages over this BIP, but to be backwards compatible with existing implementations this BIP will be useful. See BIP 322 [1] for full details on the new signature scheme. - -One of the key problems in this area is that there are several different types of Bitcoin addresses and without introducing specific standards it is unclear which type of address format is being used. See [2]. This BIP will attempt to address these issues and define a clear and concise format for Bitcoin signatures. - -# Copyright # - -This BIP is licensed under the 2-clause BSD license. - -# Motivation # - -Since Bitcoin private keys can not only be used to sign Bitcoin transactions, but also any other message, it has become customary to use them to sign various messages for differing purposes. Some applications of signing messages with a Bitcoin private key are as follows: proof of funds for collateral, credit worthiness, enterence to events, airdrops, audits as well as other applications. While there was no BIP written for how to digitally sign messages with Bitcoin private keys with P2PKH addresses it is a fairly well understood process, however with the introduction of Segwit (both in the form of P2SH and bech32) addresses, it is unclear how to distinguish a P2PKH, P2SH, or bech32 address from one another. This BIP proposes a standard signature format that will allow clients to distinguish between the different address formats. - -# Specification # - -## Background on ECDSA Signatures ## - -(For readers who already understand how ECDSA signatures work, you can skip this section as this is only intended as background information.) -Elliptic Curve Digital Signature Algorithm or ECDSA is a cryptographic algorithm used by Bitcoin to ensure that funds can only be spent by their rightful owners. - -A few concepts related to ECDSA: - -private key: A secret number, known only to the person that generated it. A private key is essentially a randomly generated number. In Bitcoin, someone with the private key that corresponds to funds on the block chain can spend the funds. In Bitcoin, a private key is a single unsigned 256 bit integer (32 bytes). - -public key: A number that corresponds to a private key, but does not need to be kept secret. A public key can be calculated from a private key, but not vice versa. A public key can be used to determine if a signature is genuine (in other words, produced with the proper key) without requiring the private key to be divulged. In Bitcoin, public keys are either compressed or uncompressed. Compressed public keys are 33 bytes, consisting of a prefix either 0x02 or 0x03, and a 256-bit integer called x. The older uncompressed keys are 65 bytes, consisting of constant prefix (0x04), followed by two 256-bit integers called x and y (2 * 32 bytes). The prefix of a compressed key allows for the y value to be derived from the x value. - -signature: A number that proves that a signing operation took place. A signature is mathematically generated from a hash of something to be signed, plus a private key. The signature itself is two numbers known as r and s. With the public key, a mathematical algorithm can be used on the signature to determine that it was originally produced from the hash and the private key, without needing to know the private key. Signatures are either 73, 72, or 71 bytes long, with probabilities approximately 25%, 50% and 25% respectively, although sizes even smaller than that are possible with exponentially decreasing probability. Source [3]. - -## Conventions with signatures used in Bitcoin ## - -Bitcoin signatures have the r and s values mentioned above, and a header. The header is a single byte and the r and s are each 32 bytes so a signature's size is 65 bytes. The header is used to specify information about the signature. It can be thought of as a bitmask with each bit in this byte having a meaning. The serialization format of a Bitcoin signature is as follows: - -[1 byte of header data][32 bytes for r value][32 bytes for s value] - -The header byte has a few components to it. First, it stores something known as the recId. This value is stored in the least significant 2 bits of the header. If the header is between a value of 31 and 34, this indicates that it is a compressed address. If the header value is between 35 and 38 inclusive, it is a p2sh segwit address. If the header value is between 39 and 42, it is a bech32 address. - -## Procedure for signing/verifying a signature ## - -As noted above the signature is composed of three components, the header, r and s values. r/s can be computed with standard ECDSA library functions. Part of the header includes something called a recId. This is part of every ECDSA signature and should be generated by the ECDSA library. The recId is a number between 0 and 3 inclusive. The header is the recId plus a constant which indicates what time of Bitcoin private key this is. For P2PKH uncompressed keys, this value is 27. For P2PKH compressed keys, this value is 31. For P2SH Segwit keys, this value is 35 and for bech32 keys, this value is 35. So, you have the following ranges: -27-30: P2PKH uncompressed -31-34: P2PKH compressed -35-38: Segwit P2SH -39-42: Segwit Bech32 - -To verify a signature, the recId is obtained by subtracting this constant from the header value. - -## Sample Code for processing a signature ## - -Note: this code is a modification of the BitcoinJ code which is written in java. - -```Java - public static ECKey signedMessageToKey(String message, String signatureBase64) throws SignatureException { - byte[] signatureEncoded; - try { - signatureEncoded = Base64.decode(signatureBase64); - } catch (RuntimeException e) { - // This is what you get back from Bouncy Castle if base64 doesn't decode :( - throw new SignatureException("Could not decode base64", e); - } - // Parse the signature bytes into r/s and the selector value. - if (signatureEncoded.length < 65) - throw new SignatureException("Signature truncated, expected 65 bytes and got " + signatureEncoded.length); - int header = signatureEncoded[0] & 0xFF; - // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, - // 0x1D = second key with even y, 0x1E = second key with odd y - if (header < 27 || header > 42) - throw new SignatureException("Header byte out of range: " + header); - BigInteger r = new BigInteger(1, Arrays.copyOfRange(signatureEncoded, 1, 33)); - BigInteger s = new BigInteger(1, Arrays.copyOfRange(signatureEncoded, 33, 65)); - ECDSASignature sig = new ECDSASignature(r, s); - byte[] messageBytes = formatMessageForSigning(message); - // Note that the C++ code doesn't actually seem to specify any character encoding. Presumably it's whatever - // JSON-SPIRIT hands back. Assume UTF-8 for now. - Sha256Hash messageHash = Sha256Hash.twiceOf(messageBytes); - boolean compressed = false; - - // this section is added to support new signature types - if(header>= 39) // this is a bech32 signature - { - header -= 12; - compressed = true; - } // this is a segwit p2sh signature - else if(header >= 35) - { - header -= 8; - compressed = true; - } // this is a compressed key signature - else if (header >= 31) { - compressed = true; - header -= 4; - } - - int recId = header - 27; - - ECKey key = ECKey.recoverFromSignature(recId, sig, messageHash, compressed); - if (key == null) - throw new SignatureException("Could not recover public key from signature"); - return key; - } -``` - -# Backwards Compatibility # - -Since this format includes P2PKH keys, it is backwards compatible, but keep in mind some software has checks for ranges of headers and will report the newer segwit header types as errors. - -# Implications # - -Message signing is an important use case and potentially underused due to the fact that, up until now, there has not been a formal specification for how wallets can sign messages using Bitcoin private keys. Bitcoin wallets should be interoperable and use the same conventions for determing a signature's validity. This BIP can also be updated as new signature formats emerge. - -# Acknowledgements # - -* Konstantin Bay - review -* Holly Casaletto - review -* James Bryrer - review - -Note that the background on ECDSA signatures was taken from en.bitcoin.it and code sample modified from BitcoinJ. - -# References # - -[1] - https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki - -[2] - https://github.com/bitcoin/bitcoin/issues/10542 - -[3] - https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm -- cgit v1.2.3 From a1cb694aa013ee3e71f113f092d5f8bb3ac36a4d Mon Sep 17 00:00:00 2001 From: cgilliard Date: Fri, 29 Mar 2019 09:47:53 -0700 Subject: Shorten name to pass build tests --- bip-0137.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki index be39277..89fc1dc 100644 --- a/bip-0137.mediawiki +++ b/bip-0137.mediawiki @@ -1,7 +1,7 @@
   BIP: 137
   Layer: Applications
-  Title: Signatures of Messages using Bitcoin Private Keys
+  Title: Signatures of Messages using Private Keys
   Author: Christopher Gilliard 
   Comments-Summary: No comments yet.
   Comments-URI: TBD
-- 
cgit v1.2.3


From 40cace6202ddfeaabfefee33c28d3561330f5d42 Mon Sep 17 00:00:00 2001
From: cgilliard 
Date: Fri, 29 Mar 2019 09:51:32 -0700
Subject: update first comment URI

---
 bip-0137.mediawiki | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki
index 89fc1dc..02ebe3d 100644
--- a/bip-0137.mediawiki
+++ b/bip-0137.mediawiki
@@ -1,11 +1,9 @@
 
-  BIP: 137
-  Layer: Applications
+https://github.com/bitcoin/bips/wiki/Comments:BIP-0137  Layer: Applications
   Title: Signatures of Messages using Private Keys
   Author: Christopher Gilliard 
   Comments-Summary: No comments yet.
-  Comments-URI: TBD
-  Status: Proposal
+  https://github.com/bitcoin/bips/wiki/Comments:BIP-0137  Status: Proposal
   Type: Informational
   Created: 2019-02-16
   License: BSD-2-Clause
-- 
cgit v1.2.3


From 0781e70e55d642abee201e1c568b297c6c68992c Mon Sep 17 00:00:00 2001
From: cgilliard 
Date: Fri, 29 Mar 2019 09:55:19 -0700
Subject: fix formatting

---
 bip-0137.mediawiki | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki
index 02ebe3d..2c8a270 100644
--- a/bip-0137.mediawiki
+++ b/bip-0137.mediawiki
@@ -1,9 +1,8 @@
 
-https://github.com/bitcoin/bips/wiki/Comments:BIP-0137  Layer: Applications
+  https://github.com/bitcoin/bips/wiki/Comments:BIP-0137  Status: Proposal
   Title: Signatures of Messages using Private Keys
   Author: Christopher Gilliard 
   Comments-Summary: No comments yet.
-  https://github.com/bitcoin/bips/wiki/Comments:BIP-0137  Status: Proposal
   Type: Informational
   Created: 2019-02-16
   License: BSD-2-Clause
-- 
cgit v1.2.3


From 01d1398c159d3260c98a3a4f7d22fc983756bfd6 Mon Sep 17 00:00:00 2001
From: cgilliard 
Date: Fri, 29 Mar 2019 10:00:10 -0700
Subject: formating fix

---
 bip-0137.mediawiki | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki
index 2c8a270..7e8d3be 100644
--- a/bip-0137.mediawiki
+++ b/bip-0137.mediawiki
@@ -1,9 +1,12 @@
 
-  https://github.com/bitcoin/bips/wiki/Comments:BIP-0137  Status: Proposal
+  BIP: 137
+  Layer: Wallet
   Title: Signatures of Messages using Private Keys
   Author: Christopher Gilliard 
   Comments-Summary: No comments yet.
-  Type: Informational
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0137
+  Status: Proposal
+  Type: Standards Track
   Created: 2019-02-16
   License: BSD-2-Clause
 
-- cgit v1.2.3 From 2d319e57982b6a6ac67be6941ac3f92cf23b90c2 Mon Sep 17 00:00:00 2001 From: cgilliard Date: Fri, 29 Mar 2019 10:42:41 -0700 Subject: Layer from Wallet -> Applications --- bip-0137.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki index 7e8d3be..52e77cd 100644 --- a/bip-0137.mediawiki +++ b/bip-0137.mediawiki @@ -1,6 +1,6 @@
   BIP: 137
-  Layer: Wallet
+  Layer: Applications
   Title: Signatures of Messages using Private Keys
   Author: Christopher Gilliard 
   Comments-Summary: No comments yet.
-- 
cgit v1.2.3


From 3140d5803ccf0bf7b5499a9414a3c625f91e34b1 Mon Sep 17 00:00:00 2001
From: cgilliard 
Date: Fri, 29 Mar 2019 10:44:16 -0700
Subject: status final

---
 bip-0137.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki
index 52e77cd..0bb5c60 100644
--- a/bip-0137.mediawiki
+++ b/bip-0137.mediawiki
@@ -5,7 +5,7 @@
   Author: Christopher Gilliard 
   Comments-Summary: No comments yet.
   Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0137
-  Status: Proposal
+  Status: Final
   Type: Standards Track
   Created: 2019-02-16
   License: BSD-2-Clause
-- 
cgit v1.2.3


From 5416afeff64b71c1de84ff5aa3a47f83a34b1bae Mon Sep 17 00:00:00 2001
From: cgilliard 
Date: Fri, 29 Mar 2019 17:15:18 -0700
Subject: add text to readme

---
 README.mediawiki | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/README.mediawiki b/README.mediawiki
index 9ba9615..9017b45 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -652,6 +652,13 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Informational
 | Draft
 |-
+| [[bip-0137.mediawiki|137]]
+| Applications
+| Signatures of Messages using Private Keys
+| Christopher Gilliard
+| Standard
+| Final
+|-
 | [[bip-0140.mediawiki|140]]
 | Consensus (soft fork)
 | Normalized TXID
-- 
cgit v1.2.3


From b6e43f2fb5f06cb9256f4c8f3c4339b4844748df Mon Sep 17 00:00:00 2001
From: cgilliard 
Date: Fri, 29 Mar 2019 17:18:00 -0700
Subject: include background color

---
 README.mediawiki | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.mediawiki b/README.mediawiki
index 9017b45..2060640 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -652,6 +652,7 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Informational
 | Draft
 |-
+|- style="background-color: #cfffcf"
 | [[bip-0137.mediawiki|137]]
 | Applications
 | Signatures of Messages using Private Keys
-- 
cgit v1.2.3


From 2a4ed6546fee884047f1212a26902e053b87ca2b Mon Sep 17 00:00:00 2001
From: cgilliard 
Date: Fri, 29 Mar 2019 17:20:51 -0700
Subject: Update README.mediawiki

---
 README.mediawiki | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/README.mediawiki b/README.mediawiki
index 2060640..9ba9615 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -652,14 +652,6 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Informational
 | Draft
 |-
-|- style="background-color: #cfffcf"
-| [[bip-0137.mediawiki|137]]
-| Applications
-| Signatures of Messages using Private Keys
-| Christopher Gilliard
-| Standard
-| Final
-|-
 | [[bip-0140.mediawiki|140]]
 | Consensus (soft fork)
 | Normalized TXID
-- 
cgit v1.2.3


From d5507296775c915068e147c2f73b1c7e8aef868c Mon Sep 17 00:00:00 2001
From: cgilliard 
Date: Fri, 29 Mar 2019 17:23:14 -0700
Subject: Update README.mediawiki

---
 README.mediawiki | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/README.mediawiki b/README.mediawiki
index 9ba9615..4e3e371 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -652,6 +652,13 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Informational
 | Draft
 |-
+|- style="background-color: #cfffcf"
+| [[bip-0137.mediawiki|137]]
+| Applications
+| Signatures of Messages using Private Keys
+| Christopher Gilliard
+| Standard
+| Final
 | [[bip-0140.mediawiki|140]]
 | Consensus (soft fork)
 | Normalized TXID
-- 
cgit v1.2.3


From 6a947027e813bec6360b129d47895b19d9ae057e Mon Sep 17 00:00:00 2001
From: cgilliard 
Date: Fri, 29 Mar 2019 17:25:03 -0700
Subject: Update README.mediawiki

---
 README.mediawiki | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.mediawiki b/README.mediawiki
index 4e3e371..2060640 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -659,6 +659,7 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Christopher Gilliard
 | Standard
 | Final
+|-
 | [[bip-0140.mediawiki|140]]
 | Consensus (soft fork)
 | Normalized TXID
-- 
cgit v1.2.3


From 09d4e8d7b902071a9e5ef0579a1694f49913f8a8 Mon Sep 17 00:00:00 2001
From: cgilliard 
Date: Fri, 29 Mar 2019 17:49:31 -0700
Subject: Update README.mediawiki

---
 README.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.mediawiki b/README.mediawiki
index 2060640..08c520b 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -651,9 +651,9 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Sancho Panza
 | Informational
 | Draft
-|-
 |- style="background-color: #cfffcf"
 | [[bip-0137.mediawiki|137]]
+|
 | Applications
 | Signatures of Messages using Private Keys
 | Christopher Gilliard
-- 
cgit v1.2.3


From 7f3c5e516bad6247dc126b1b9c09870ebcd6bdcd Mon Sep 17 00:00:00 2001
From: cgilliard 
Date: Fri, 29 Mar 2019 17:50:40 -0700
Subject: Update README.mediawiki

---
 README.mediawiki | 1 -
 1 file changed, 1 deletion(-)

diff --git a/README.mediawiki b/README.mediawiki
index 08c520b..1fb598d 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -653,7 +653,6 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Draft
 |- style="background-color: #cfffcf"
 | [[bip-0137.mediawiki|137]]
-|
 | Applications
 | Signatures of Messages using Private Keys
 | Christopher Gilliard
-- 
cgit v1.2.3


From e2e83ccdead546cdd5fe2b181e214242c255ed1d Mon Sep 17 00:00:00 2001
From: cgilliard 
Date: Fri, 29 Mar 2019 19:59:22 -0700
Subject: fix formatting

---
 bip-0137.mediawiki | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki
index 0bb5c60..9d4f90d 100644
--- a/bip-0137.mediawiki
+++ b/bip-0137.mediawiki
@@ -11,7 +11,7 @@
   License: BSD-2-Clause
 
-# Abstract # +==Abstract== This document describes a signature format for signing messages with Bitcoin private keys. @@ -19,17 +19,17 @@ The specification is intended to describe the standard for signatures of message One of the key problems in this area is that there are several different types of Bitcoin addresses and without introducing specific standards it is unclear which type of address format is being used. See [2]. This BIP will attempt to address these issues and define a clear and concise format for Bitcoin signatures. -# Copyright # +==Copyright== This BIP is licensed under the 2-clause BSD license. -# Motivation # +==Motivation== Since Bitcoin private keys can not only be used to sign Bitcoin transactions, but also any other message, it has become customary to use them to sign various messages for differing purposes. Some applications of signing messages with a Bitcoin private key are as follows: proof of funds for collateral, credit worthiness, enterence to events, airdrops, audits as well as other applications. While there was no BIP written for how to digitally sign messages with Bitcoin private keys with P2PKH addresses it is a fairly well understood process, however with the introduction of Segwit (both in the form of P2SH and bech32) addresses, it is unclear how to distinguish a P2PKH, P2SH, or bech32 address from one another. This BIP proposes a standard signature format that will allow clients to distinguish between the different address formats. -# Specification # +==Specification== -## Background on ECDSA Signatures ## +===Background on ECDSA Signatures=== (For readers who already understand how ECDSA signatures work, you can skip this section as this is only intended as background information.) Elliptic Curve Digital Signature Algorithm or ECDSA is a cryptographic algorithm used by Bitcoin to ensure that funds can only be spent by their rightful owners. @@ -42,7 +42,7 @@ A few concepts related to ECDSA: signature: A number that proves that a signing operation took place. A signature is mathematically generated from a hash of something to be signed, plus a private key. The signature itself is two numbers known as r and s. With the public key, a mathematical algorithm can be used on the signature to determine that it was originally produced from the hash and the private key, without needing to know the private key. Signatures are either 73, 72, or 71 bytes long, with probabilities approximately 25%, 50% and 25% respectively, although sizes even smaller than that are possible with exponentially decreasing probability. Source [3]. -## Conventions with signatures used in Bitcoin ## +===Conventions with signatures used in Bitcoin=== Bitcoin signatures have the r and s values mentioned above, and a header. The header is a single byte and the r and s are each 32 bytes so a signature's size is 65 bytes. The header is used to specify information about the signature. It can be thought of as a bitmask with each bit in this byte having a meaning. The serialization format of a Bitcoin signature is as follows: @@ -50,7 +50,7 @@ Bitcoin signatures have the r and s values mentioned above, and a header. The he The header byte has a few components to it. First, it stores something known as the recId. This value is stored in the least significant 2 bits of the header. If the header is between a value of 31 and 34, this indicates that it is a compressed address. If the header value is between 35 and 38 inclusive, it is a p2sh segwit address. If the header value is between 39 and 42, it is a bech32 address. -## Procedure for signing/verifying a signature ## +===Procedure for signing/verifying a signature=== As noted above the signature is composed of three components, the header, r and s values. r/s can be computed with standard ECDSA library functions. Part of the header includes something called a recId. This is part of every ECDSA signature and should be generated by the ECDSA library. The recId is a number between 0 and 3 inclusive. The header is the recId plus a constant which indicates what time of Bitcoin private key this is. For P2PKH uncompressed keys, this value is 27. For P2PKH compressed keys, this value is 31. For P2SH Segwit keys, this value is 35 and for bech32 keys, this value is 35. So, you have the following ranges: 27-30: P2PKH uncompressed @@ -60,7 +60,7 @@ As noted above the signature is composed of three components, the header, r and To verify a signature, the recId is obtained by subtracting this constant from the header value. -## Sample Code for processing a signature ## +===Sample Code for processing a signature=== Note: this code is a modification of the BitcoinJ code which is written in java. @@ -115,15 +115,15 @@ Note: this code is a modification of the BitcoinJ code which is written in java. } ``` -# Backwards Compatibility # +==Backwards Compatibility== Since this format includes P2PKH keys, it is backwards compatible, but keep in mind some software has checks for ranges of headers and will report the newer segwit header types as errors. -# Implications # +==Implications== Message signing is an important use case and potentially underused due to the fact that, up until now, there has not been a formal specification for how wallets can sign messages using Bitcoin private keys. Bitcoin wallets should be interoperable and use the same conventions for determing a signature's validity. This BIP can also be updated as new signature formats emerge. -# Acknowledgements # +==Acknowledgements== * Konstantin Bay - review * Holly Casaletto - review @@ -131,7 +131,7 @@ Message signing is an important use case and potentially underused due to the fa Note that the background on ECDSA signatures was taken from en.bitcoin.it and code sample modified from BitcoinJ. -# References # +==References== [1] - https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki -- cgit v1.2.3 From 6a181756e4ad96a5abccd5d625a26d00ae2ac225 Mon Sep 17 00:00:00 2001 From: cgilliard Date: Fri, 29 Mar 2019 20:02:35 -0700 Subject: Update bip-0137.mediawiki --- bip-0137.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki index 9d4f90d..536ca2d 100644 --- a/bip-0137.mediawiki +++ b/bip-0137.mediawiki @@ -64,7 +64,7 @@ To verify a signature, the recId is obtained by subtracting this constant from t Note: this code is a modification of the BitcoinJ code which is written in java. -```Java +``` public static ECKey signedMessageToKey(String message, String signatureBase64) throws SignatureException { byte[] signatureEncoded; try { -- cgit v1.2.3 From 95db88b5e8dad326a2b38629641fd729d6fd9161 Mon Sep 17 00:00:00 2001 From: cgilliard Date: Fri, 29 Mar 2019 20:10:30 -0700 Subject: media wiki format --- bip-0137.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki index 536ca2d..49e95c9 100644 --- a/bip-0137.mediawiki +++ b/bip-0137.mediawiki @@ -64,7 +64,7 @@ To verify a signature, the recId is obtained by subtracting this constant from t Note: this code is a modification of the BitcoinJ code which is written in java. -``` + public static ECKey signedMessageToKey(String message, String signatureBase64) throws SignatureException { byte[] signatureEncoded; try { @@ -113,7 +113,7 @@ Note: this code is a modification of the BitcoinJ code which is written in java. throw new SignatureException("Could not recover public key from signature"); return key; } -``` + ==Backwards Compatibility== -- cgit v1.2.3 From bebffb6ac8b3c26ca48962faac61579b9055442b Mon Sep 17 00:00:00 2001 From: cgilliard Date: Fri, 29 Mar 2019 20:11:51 -0700 Subject: move to code tag --- bip-0137.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki index 49e95c9..a367238 100644 --- a/bip-0137.mediawiki +++ b/bip-0137.mediawiki @@ -64,7 +64,7 @@ To verify a signature, the recId is obtained by subtracting this constant from t Note: this code is a modification of the BitcoinJ code which is written in java. - + public static ECKey signedMessageToKey(String message, String signatureBase64) throws SignatureException { byte[] signatureEncoded; try { @@ -113,7 +113,7 @@ Note: this code is a modification of the BitcoinJ code which is written in java. throw new SignatureException("Could not recover public key from signature"); return key; } - + ==Backwards Compatibility== -- cgit v1.2.3 From c823bb06386c30fd57077c20c9b73aa8da9ba3e9 Mon Sep 17 00:00:00 2001 From: cgilliard Date: Fri, 29 Mar 2019 20:17:02 -0700 Subject: Update bip-0137.mediawiki --- bip-0137.mediawiki | 2 -- 1 file changed, 2 deletions(-) diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki index a367238..a88342c 100644 --- a/bip-0137.mediawiki +++ b/bip-0137.mediawiki @@ -64,7 +64,6 @@ To verify a signature, the recId is obtained by subtracting this constant from t Note: this code is a modification of the BitcoinJ code which is written in java. - public static ECKey signedMessageToKey(String message, String signatureBase64) throws SignatureException { byte[] signatureEncoded; try { @@ -113,7 +112,6 @@ Note: this code is a modification of the BitcoinJ code which is written in java. throw new SignatureException("Could not recover public key from signature"); return key; } - ==Backwards Compatibility== -- cgit v1.2.3 From c6456f1607d0184cdd1b211a718bf38eb0328d7b Mon Sep 17 00:00:00 2001 From: cgilliard Date: Fri, 29 Mar 2019 20:17:48 -0700 Subject: Update bip-0137.mediawiki --- bip-0137.mediawiki | 3 --- 1 file changed, 3 deletions(-) diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki index a88342c..7ef89f4 100644 --- a/bip-0137.mediawiki +++ b/bip-0137.mediawiki @@ -88,7 +88,6 @@ Note: this code is a modification of the BitcoinJ code which is written in java. // JSON-SPIRIT hands back. Assume UTF-8 for now. Sha256Hash messageHash = Sha256Hash.twiceOf(messageBytes); boolean compressed = false; - // this section is added to support new signature types if(header>= 39) // this is a bech32 signature { @@ -104,9 +103,7 @@ Note: this code is a modification of the BitcoinJ code which is written in java. compressed = true; header -= 4; } - int recId = header - 27; - ECKey key = ECKey.recoverFromSignature(recId, sig, messageHash, compressed); if (key == null) throw new SignatureException("Could not recover public key from signature"); -- cgit v1.2.3