<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://en.bitcoin.it/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vbuterin</id>
	<title>Bitcoin Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://en.bitcoin.it/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vbuterin"/>
	<link rel="alternate" type="text/html" href="https://en.bitcoin.it/wiki/Special:Contributions/Vbuterin"/>
	<updated>2026-04-17T12:03:58Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=30179</id>
		<title>User:Vbuterin/K of N redundant offline private key proposal</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=30179"/>
		<updated>2012-08-28T08:48:38Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is an important tradeoff between security and recoverability when storing an offline wallet. The simplest setup, storing the entire private key in a single place in a lockbox, provides medium security but is vulnerable to accidental loss or destruction through accidents such as fire. Storing a simple backup of the key mitigates this risk, but at the same time decreases security, and the opposite strategy, splitting the key into multiple pieces, all of which must somehow be combined to retrieve the original key, increases security but makes the accidental loss problem even worse. The optimal solution is a setup which combines the two strategies, allowing the key to easily be split up into n pieces, any k of which can be used to recover the original key. The simplest such setup is storing k parts of the key and then an XOR of all k parts, but that approach is limiting as it only allows for n = k+1. What this document proposes is a setup which allows &#039;&#039;any&#039;&#039; n and k to be used. The steps are the following:&lt;br /&gt;
&lt;br /&gt;
===1. K-piece key splitting===&lt;br /&gt;
This proposal provides a scheme where a key can be broken into up to 8 parts, and each part is serialized as a 59-character Base58Check-encoded message that starts with the characters &amp;quot;6s&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To start off, generate K-1 random values, with the ith value (1-indexed) being taken from the range [0,min(2^280/k^n,2^256)], then XOR them all together along with the specific key to get one more value. This last value followed by all of the random values make up the k-pieces that will go into the next step. The reason why the k-pieces need to be sampled from progressively smaller ranges is that the base58check format imposes a maximum value of 2^280 - 1, and the algorithm for generating the higher-valued final key pieces will cause overflow if the full range of [0...2^256) is allowed for all of the intermediate k-pieces.&lt;br /&gt;
&lt;br /&gt;
Note that implementations which use a different formula than min(2^280/k^n,2^256) to find the random k-piece generator&#039;s maxima are perfectly compatible with the original provided that the formula actually works to keep the size of the final output of the algorithm below 2^280.&lt;br /&gt;
&lt;br /&gt;
Nearly all 256-bit values are valid Bitcoin private keys - the set of 256-bit values constituting invalid private keys all start with 127 or more consecutive 0 or 1 bits and are extremely unlikely to be encountered by accident with an appropriate source of random numbers.&lt;br /&gt;
&lt;br /&gt;
===2. N piece generation===&lt;br /&gt;
&lt;br /&gt;
The next step will transform these &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces, once again referred to as &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;, into &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; pieces, any &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; of which can be used to find the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; will have the following format:&lt;br /&gt;
&lt;br /&gt;
* This message contains a 39-byte payload.&lt;br /&gt;
* Each message representing a single part will be 59 base58 characters starting with &#039;6s&#039;.&lt;br /&gt;
* Byte 0: &amp;lt;code&amp;gt;0x4f&amp;lt;/code&amp;gt; (unique &amp;quot;format&amp;quot; identifier to make keyparts in base 58 start with &#039;6s&#039; to be recognizable visually, when used properly in combination with byte 1)&lt;br /&gt;
* Byte 1: 0x93+k where k = 1...16.  This will result in the third character being a digit 1 thru 8 so the user can see the value of k. (e.g. 6s1, 6s2, 6s3, 6s4, 6s5, 6s6, 6s7, 6s8 prefixes).&lt;br /&gt;
* Bytes 2,3 = Bitmapped:&lt;br /&gt;
** bit 15...13 (MSB): The fixed value 011.  This is necessary for the user-visible prefix to work as intended.&lt;br /&gt;
** bit 12: compression flag (0=none, 1=compressed)&lt;br /&gt;
** bits 11...8: the x coordinate assigned to this key part, taken from the range 0...15 excluding 1&lt;br /&gt;
** bits 7...0: SHA256(private key)[0], for the purpose of matching parts together&lt;br /&gt;
* Bytes 4 thru 38: The number &amp;lt;code&amp;gt;v(1) + v(2)*x + v(3)*x^2 + v(4)*x^3 + ...&amp;lt;/code&amp;gt;. This is equivalent to Shamir&#039;s secret sharing scheme.&lt;br /&gt;
&lt;br /&gt;
===Ideas for another iteration===&lt;br /&gt;
# An ideal target for a k-of-n scheme is a deterministic wallet, not just a single address.  There should be a field in the message to specify what kind of deterministic wallet is being targeted with respect to the list at [[Deterministic wallet]].&lt;br /&gt;
# The current scheme correctly rejects parts that belong to the wrong address, but doesn&#039;t reject incompatible parts if the same addresses is encoded twice (with new random values for v(1...8) and then the parts mixed together.  Some bits should be dedicated to checksumming the chosen values of v(1...8).&lt;br /&gt;
# Avoiding the constraint that v(8) start with a zero bit would be nice&lt;br /&gt;
# Using something like AES instead of XOR might increase security without sacrificing reversibility (which is necessary when making K-of-N of a known, non-random key)&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
For example, if you want your private key to require three out of five pieces to reconstitute, the final pieces will be (byte lengths will depend on exactly what &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v(3)&amp;lt;/code&amp;gt; are):&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;4f9360?? v(1)&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;4f9362?? v(1) + v(2)*2 + v(3)*4&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;4f9363?? v(1) + v(2)*3 + v(3)*9&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;4f9364?? v(1) + v(2)*4 + v(3)*16&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;4f9365?? v(1) + v(2)*5 + v(3)*25&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And you&#039;re done. Any three of these pieces will be able to be used to reconstitute the original private key, and can be distributed as you like. You might, for example, store one in a safe at home, another at a safety deposit box at the local bank, a third on your computer, a fourth with a friend and memorize the fifth.&lt;br /&gt;
&lt;br /&gt;
===Key Reconstitution===&lt;br /&gt;
&lt;br /&gt;
To reconstitute the private key, simply solve the linear system from any three pieces, inferring from the second byte of the pieces what all the coefficients are, to get the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;. Once you have these values, XOR all of them to get your final result.&lt;br /&gt;
&lt;br /&gt;
For example imagine that you have pieces 2, 3 and 5 from above, letting &amp;lt;code&amp;gt;pc(i)&amp;lt;/code&amp;gt; be the value from piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; not including the three byte prefix. You thus have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  v(1) + v(2)*2 + v(3)*4  = pc(2)&lt;br /&gt;
  v(1) + v(2)*3 + v(3)*9  = pc(3)&lt;br /&gt;
  v(1) + v(2)*5 + v(3)*25 = pc(5)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The simplest method to solve linear systems is elimination, which would work as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    v(1) + v(2)*3  + v(3)*9  =  pc(3)&lt;br /&gt;
  - v(1) - v(2)*2  - v(3)*4  = -pc(2)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)    + v(3)*5  =  pc(3) - pc(2)&lt;br /&gt;
&lt;br /&gt;
    v(1) + v(2)*5   + v(3)*25 =  pc(5)&lt;br /&gt;
  - v(1) - v(2)*2   - v(3)*9  = -pc(2)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*3   + v(3)*16 =  pc(5) - pc(2)&lt;br /&gt;
&lt;br /&gt;
    v(2)*3   + v(3)*16  =  pc(5) - pc(2)&lt;br /&gt;
  - v(2)     - v(3)*5   = -pc(3) + pc(2)&lt;br /&gt;
                      |  &lt;br /&gt;
                      v&lt;br /&gt;
    v(2)*3   + v(3)*16  =  pc(5)   - pc(2)&lt;br /&gt;
  - v(2)*3   - v(3)*15  = -pc(3)*3 + pc(2)*3&lt;br /&gt;
  .----------------------------------------&lt;br /&gt;
               v(3)     = pc(5) - pc(3)*3   + pc(2)*2&lt;br /&gt;
                      &lt;br /&gt;
  v(2) = -v(3)*16/3 + pc(5) - pc(2)&lt;br /&gt;
  v(1) = pc(3) - v(2)*3 - v(3)*9&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The general pattern is to take &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; equations, combine all adjacent pairs to get &amp;lt;code&amp;gt;k-1&amp;lt;/code&amp;gt; equations without any coefficient for &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; and repeat the process until you&#039;re down to a single equation of the form &amp;lt;code&amp;gt;v(k)*a = b&amp;lt;/code&amp;gt;. From there, just work your way back up the chain of intermediate equations to get all the other values.&lt;br /&gt;
&lt;br /&gt;
You actually don&#039;t have to know what &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is because you can simply assume that &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is the number of pieces that you have, and if you have too many pieces solving the linear system will simply lead you to discover that the &amp;lt;code&amp;gt;n+1&amp;lt;/code&amp;gt;st, &amp;lt;code&amp;gt;n+2&amp;lt;/code&amp;gt;nd, etc pieces are all equal to zero.&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=30170</id>
		<title>User:Vbuterin/K of N redundant offline private key proposal</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=30170"/>
		<updated>2012-08-28T00:30:24Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is an important tradeoff between security and recoverability when storing an offline wallet. The simplest setup, storing the entire private key in a single place in a lockbox, provides medium security but is vulnerable to accidental loss or destruction through accidents such as fire. Storing a simple backup of the key mitigates this risk, but at the same time decreases security, and the opposite strategy, splitting the key into multiple pieces, all of which must somehow be combined to retrieve the original key, increases security but makes the accidental loss problem even worse. The optimal solution is a setup which combines the two strategies, allowing the key to easily be split up into n pieces, any k of which can be used to recover the original key. The simplest such setup is storing k parts of the key and then an XOR of all k parts, but that approach is limiting as it only allows for n = k+1. What this document proposes is a setup which allows &#039;&#039;any&#039;&#039; n and k to be used. The steps are the following:&lt;br /&gt;
&lt;br /&gt;
===1. K-piece key splitting===&lt;br /&gt;
This proposal provides a scheme where a key can be broken into up to 8 parts, and each part is serialized as a 59-character Base58Check-encoded message that starts with the characters &amp;quot;6s&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To start off, generate K-1 random values, with the ith value (1-indexed) being taken from the range [0,min(2^280/k^n,2^256)], then XOR them all together along with the specific key to get one more value. This last value followed by all of the random values make up the k-pieces that will go into the next step. The reason why the k-pieces need to be sampled from progressively smaller ranges is that the base58check format imposes a maximum value of 2^280 - 1, and the algorithm for generating the higher-valued final key pieces will cause overflow if the full range of [0...2^256) is allowed for all of the intermediate k-pieces.&lt;br /&gt;
&lt;br /&gt;
Nearly all 256-bit values are valid Bitcoin private keys - the set of 256-bit values constituting invalid private keys all start with 127 or more consecutive 0 or 1 bits and are extremely unlikely to be encountered by accident with an appropriate source of random numbers.&lt;br /&gt;
&lt;br /&gt;
===2. N piece generation===&lt;br /&gt;
&lt;br /&gt;
The next step will transform these &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces, once again referred to as &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;, into &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; pieces, any &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; of which can be used to find the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; will have the following format:&lt;br /&gt;
&lt;br /&gt;
* This message contains a 39-byte payload.&lt;br /&gt;
* Each message representing a single part will be 59 base58 characters starting with &#039;6s&#039;.&lt;br /&gt;
* Byte 0: &amp;lt;code&amp;gt;0x4f&amp;lt;/code&amp;gt; (unique &amp;quot;format&amp;quot; identifier to make keyparts in base 58 start with &#039;6s&#039; to be recognizable visually, when used properly in combination with byte 1)&lt;br /&gt;
* Byte 1: 0x93+k where k = 1...16.  This will result in the third character being a digit 1 thru 8 so the user can see the value of k. (e.g. 6s1, 6s2, 6s3, 6s4, 6s5, 6s6, 6s7, 6s8 prefixes).&lt;br /&gt;
* Bytes 2,3 = Bitmapped:&lt;br /&gt;
** bit 15...13 (MSB): The fixed value 011.  This is necessary for the user-visible prefix to work as intended.&lt;br /&gt;
** bit 12: compression flag (0=none, 1=compressed)&lt;br /&gt;
** bits 11...8: the x coordinate assigned to this key part, taken from the range 0...15 excluding 1&lt;br /&gt;
** bits 7...0: SHA256(private key)[0], for the purpose of matching parts together&lt;br /&gt;
* Bytes 4 thru 38: The number &amp;lt;code&amp;gt;v(1) + v(2)*x + v(3)*x^2 + v(4)*x^3 + ...&amp;lt;/code&amp;gt;. This is equivalent to Shamir&#039;s secret sharing scheme.&lt;br /&gt;
&lt;br /&gt;
===Ideas for another iteration===&lt;br /&gt;
# An ideal target for a k-of-n scheme is a deterministic wallet, not just a single address.  There should be a field in the message to specify what kind of deterministic wallet is being targeted with respect to the list at [[Deterministic wallet]].&lt;br /&gt;
# The current scheme correctly rejects parts that belong to the wrong address, but doesn&#039;t reject incompatible parts if the same addresses is encoded twice (with new random values for v(1...8) and then the parts mixed together.  Some bits should be dedicated to checksumming the chosen values of v(1...8).&lt;br /&gt;
# Avoiding the constraint that v(8) start with a zero bit would be nice&lt;br /&gt;
# Using something like AES instead of XOR might increase security without sacrificing reversibility (which is necessary when making K-of-N of a known, non-random key)&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
For example, if you want your private key to require three out of five pieces to reconstitute, the final pieces will be (byte lengths will depend on exactly what &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v(3)&amp;lt;/code&amp;gt; are):&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;4f9360?? v(1)&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;4f9362?? v(1) + v(2)*2 + v(3)*4&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;4f9363?? v(1) + v(2)*3 + v(3)*9&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;4f9364?? v(1) + v(2)*4 + v(3)*16&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;4f9365?? v(1) + v(2)*5 + v(3)*25&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And you&#039;re done. Any three of these pieces will be able to be used to reconstitute the original private key, and can be distributed as you like. You might, for example, store one in a safe at home, another at a safety deposit box at the local bank, a third on your computer, a fourth with a friend and memorize the fifth.&lt;br /&gt;
&lt;br /&gt;
===Key Reconstitution===&lt;br /&gt;
&lt;br /&gt;
To reconstitute the private key, simply solve the linear system from any three pieces, inferring from the second byte of the pieces what all the coefficients are, to get the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;. Once you have these values, XOR all of them to get your final result.&lt;br /&gt;
&lt;br /&gt;
For example imagine that you have pieces 2, 3 and 5 from above, letting &amp;lt;code&amp;gt;pc(i)&amp;lt;/code&amp;gt; be the value from piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; not including the three byte prefix. You thus have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  v(1) + v(2)*2 + v(3)*4  = pc(2)&lt;br /&gt;
  v(1) + v(2)*3 + v(3)*9  = pc(3)&lt;br /&gt;
  v(1) + v(2)*5 + v(3)*25 = pc(5)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The simplest method to solve linear systems is elimination, which would work as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    v(1) + v(2)*3  + v(3)*9  =  pc(3)&lt;br /&gt;
  - v(1) - v(2)*2  - v(3)*4  = -pc(2)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)    + v(3)*5  =  pc(3) - pc(2)&lt;br /&gt;
&lt;br /&gt;
    v(1) + v(2)*5   + v(3)*25 =  pc(5)&lt;br /&gt;
  - v(1) - v(2)*2   - v(3)*9  = -pc(2)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*3   + v(3)*16 =  pc(5) - pc(2)&lt;br /&gt;
&lt;br /&gt;
    v(2)*3   + v(3)*16  =  pc(5) - pc(2)&lt;br /&gt;
  - v(2)     - v(3)*5   = -pc(3) + pc(2)&lt;br /&gt;
                      |  &lt;br /&gt;
                      v&lt;br /&gt;
    v(2)*3   + v(3)*16  =  pc(5)   - pc(2)&lt;br /&gt;
  - v(2)*3   - v(3)*15  = -pc(3)*3 + pc(2)*3&lt;br /&gt;
  .----------------------------------------&lt;br /&gt;
               v(3)     = pc(5) - pc(3)*3   + pc(2)*2&lt;br /&gt;
                      &lt;br /&gt;
  v(2) = -v(3)*16/3 + pc(5) - pc(2)&lt;br /&gt;
  v(1) = pc(3) - v(2)*3 - v(3)*9&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The general pattern is to take &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; equations, combine all adjacent pairs to get &amp;lt;code&amp;gt;k-1&amp;lt;/code&amp;gt; equations without any coefficient for &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; and repeat the process until you&#039;re down to a single equation of the form &amp;lt;code&amp;gt;v(k)*a = b&amp;lt;/code&amp;gt;. From there, just work your way back up the chain of intermediate equations to get all the other values.&lt;br /&gt;
&lt;br /&gt;
You actually don&#039;t have to know what &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is because you can simply assume that &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is the number of pieces that you have, and if you have too many pieces solving the linear system will simply lead you to discover that the &amp;lt;code&amp;gt;n+1&amp;lt;/code&amp;gt;st, &amp;lt;code&amp;gt;n+2&amp;lt;/code&amp;gt;nd, etc pieces are all equal to zero.&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User_talk:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29739</id>
		<title>User talk:Vbuterin/K of N redundant offline private key proposal</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User_talk:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29739"/>
		<updated>2012-08-13T11:34:32Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: Created page with &amp;quot;There is NO reason why this needs to be limited to 8 keys. I understand that the exponentiation causes overflow if you generate all 8 pieces from [0,2^256), but there is no ne...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is NO reason why this needs to be limited to 8 keys. I understand that the exponentiation causes overflow if you generate all 8 pieces from [0,2^256), but there is no need to do that. There is nothing wrong with generating the pieces in reverse order and just limiting the higher ones to progressively decreasing maxima.&lt;br /&gt;
&lt;br /&gt;
[[User:Vbuterin|Vbuterin]] ([[User talk:Vbuterin|talk]]) 11:34, 13 August 2012 (GMT)&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User_talk:Vbuterin&amp;diff=29542</id>
		<title>User talk:Vbuterin</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User_talk:Vbuterin&amp;diff=29542"/>
		<updated>2012-08-07T23:25:13Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: /* K_of_N_redundant_offline_private_key_proposal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==K_of_N_redundant_offline_private_key_proposal==&lt;br /&gt;
&lt;br /&gt;
[[User:Vbuterin/K_of_N_redundant_offline_private_key_proposal]]&lt;br /&gt;
&lt;br /&gt;
I just checked Recent Changes and was excited to see you putting this together!  A few things:&lt;br /&gt;
&lt;br /&gt;
# Does this bear any similarity to &amp;quot;Shamir&#039;s secret-sharing scheme&amp;quot;? (which I know little about other than having skimmed the Wikipedia article)&lt;br /&gt;
# Your proposal points out that the payload will have varying lengths, but the same time, stipulates a prefix of 0x86 for the benefit of the user.  Off the top of your head, how much do the lengths vary?  The reason I ask is that the prefix on the base58 string as seen by the user only stays constant when the number of bytes in the message is constant.  If the variation isn&#039;t that much, then adding padding bytes might work.  For example, the private key that starts with &#039;5&#039; suddenly starts with a &#039;K&#039; or &#039;L&#039; when an extra byte is added.  If it isn&#039;t clear why, a simple analogy can be made for hexadecimal vs. decimal: all four-digit decimal numbers that start with 5 (i.e. decimal numbers between 5000 and 5999) will have a hex equivalent that starts with 1, but it&#039;s not true for non-4-digit numbers: 50000 and 59999 will have a hex equivalent that starts not with 1, but instead, C, D, or E.&lt;br /&gt;
# Somewhere in the message, there should be a 1-bit flag that tells whether to create the bitcoin address from the uncompressed vs. compressed public key.&lt;br /&gt;
# Somewhere in the message, there ought to be a small handful of bits taken from the resulting bitcoin address, so a user interface accepting parts one by one can reliably detect and complain: &amp;quot;The last part you entered does not belong to the part(s) you entered before&amp;quot;.&lt;br /&gt;
# Somewhere in the message, there should be a count that tells the UI how many total parts are needed and how many exist. (e.g. the values of K and N)&lt;br /&gt;
&lt;br /&gt;
[[User:Casascius|Casascius]] ([[User talk:Casascius|talk]]) 19:54, 5 August 2012 (GMT)&lt;br /&gt;
&lt;br /&gt;
# @1 I came up with the idea myself, so it wasn&#039;t inspired by Shamir&#039;s scheme.  &lt;br /&gt;
# @2 The longest piece should be 256 + n*log2(k) bits long, so 257 for the degenerate (1,1) case, 264 for (5,3) and 292 for (12,8). Thus, for high values of i, as it seems that you have already realized, the randomly chosen values do need to get progressively smaller if you want to impose a maximum size limit on the pieces. Making each piece random(0,min(2^256,2^288/k^(3*k))) rather than random (0,2^256) might be a good idea.  &lt;br /&gt;
# @3,4 Sure, sounds good  &lt;br /&gt;
# @5 Neither N nor K is strictly necessary, but I can see how it would be nice to have for usability purposes.   &lt;br /&gt;
&lt;br /&gt;
[[User:Vbuterin|Vbuterin]] ([[User talk:Vbuterin|talk]]) 23:25, 7 August 2012 (GMT)&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29532</id>
		<title>User:Vbuterin/K of N redundant offline private key proposal</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29532"/>
		<updated>2012-08-07T13:43:44Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: /* 1. K-piece key splitting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is an important tradeoff between security and recoverability when storing an offline wallet. The simplest setup, storing the entire private key in a single place in a lockbox, provides medium security but is vulnerable to accidental loss or destruction through accidents such as fire. Storing a simple backup of the key mitigates this risk, but at the same time decreases security, and the opposite strategy, splitting the key into multiple pieces, all of which must somehow be combined to retrieve the original key, increases security but makes the accidental loss problem even worse. The optimal solution is a setup which combines the two strategies, allowing the key to easily be split up into n pieces, any k of which can be used to recover the original key. The simplest such setup is storing k parts of the key and then an XOR of all k parts, but that approach is limiting as it only allows for n = k+1. What this document proposes is a setup which allows &#039;&#039;any&#039;&#039; n and k to be used. The steps are the following:&lt;br /&gt;
&lt;br /&gt;
===1. K-piece key splitting===&lt;br /&gt;
This proposal provides a scheme where a key can be broken into up to 8 parts, and each part is serialized as a 59-character Base58Check-encoded message that starts with the characters &amp;quot;6s&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
If generating a new random key, simply generate K random 256-bit values.  If N and K are both 8, then the 8th randomly-generated value needs to have its most significant bit set to zero to prevent an overflow condition described later.&lt;br /&gt;
&lt;br /&gt;
If splitting a specific key, then simply generate K-1 random 256-bit values, taking care that the value to be used in position #8 has its most significant bit set to zero, then XOR them all together along with the specific key.  The result of the XOR operation should be used in a position other than the one with a constraint on the highest bit.&lt;br /&gt;
&lt;br /&gt;
Nearly all 256-bit values are valid Bitcoin private keys - the set of 256-bit values constituting invalid private keys all start with 127 or more consecutive 0 or 1 bits and are extremely unlikely to be encountered by accident with an appropriate source of random numbers.&lt;br /&gt;
&lt;br /&gt;
===2. N piece generation===&lt;br /&gt;
&lt;br /&gt;
The next step will transform these &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces, once again referred to as &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;, into &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; pieces, any &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; of which can be used to find the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; will have the following format:&lt;br /&gt;
&lt;br /&gt;
* This message contains a 39-byte payload.&lt;br /&gt;
* Each message representing a single part will be 59 base58 characters starting with &#039;6s&#039;.&lt;br /&gt;
* Byte 0: &amp;lt;code&amp;gt;0x4f&amp;lt;/code&amp;gt; (unique &amp;quot;format&amp;quot; identifier to make keyparts in base 58 start with &#039;6s&#039; to be recognizable visually, when used properly in combination with byte 1)&lt;br /&gt;
* Byte 1: 0x93+k where k = 1...8.  This will result in the third character being a digit 1 thru 8 so the user can see the value of k. (e.g. 6s1, 6s2, 6s3, 6s4, 6s5, 6s6, 6s7, 6s8 prefixes).  Highest allowable value: 0x9c&lt;br /&gt;
* Bytes 2,3 = Bitmapped:&lt;br /&gt;
** bit 15...13 (MSB): The fixed value 011.  This is necessary for the user-visible prefix to work as intended.&lt;br /&gt;
** bit 12: compression flag (0=none, 1=compressed)&lt;br /&gt;
** bits 11...9: which key part this is, minus 1&lt;br /&gt;
** bits 8...0: SHA256(resulting bitcoin address)[0...1] &amp;amp; 0x01FF, for the purpose matching parts together and verification they produce the correct address&lt;br /&gt;
* Bytes 4 thru 38: The number &amp;lt;code&amp;gt;v(1) + v(2)*2^i + v(3)*3^i + v(4)*4^i + ...&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are 280 bits allocated to the number (35 bytes).  This will fit all of the 256-bit numbers generated in the scheme, multiplied by their respective factors.  However, there is one exception: if a user generates an 8-of-8 code, then the factors used to create the eighth code will overflow and require 281 bits whenever v(8) exceeds a certain threshold.  In order to prevent this, the value for v(8) needs to be chosen  with its eight most significant bits set to zero.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
For example, if you want your private key to require three out of five pieces to reconstitute, the final pieces will be (byte lengths will depend on exactly what &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v(3)&amp;lt;/code&amp;gt; are):&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 1 33 v(1) + v(2)*2 + v(3)*3&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 2 33 v(1) + v(2)*4 + v(3)*9&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 3 33 v(1) + v(2)*8 + v(3)*27&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 4 33 v(1) + v(2)*16 + v(3)*81&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 5 34 v(1) + v(2)*32 + v(3)*243&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you&#039;re done, the pieces can be kept as hex or base58 - either format works fine, and stored wherever you want. You might, for example, store one in a safe at home, another at a safety deposit box at the local bank, a third on your computer, a fourth with a friend and memorize the fifth.&lt;br /&gt;
&lt;br /&gt;
===Key Reconstitution===&lt;br /&gt;
&lt;br /&gt;
To reconstitute the private key, simply solve the linear system from any three pieces, inferring from the second byte of the pieces what all the coefficients are, to get the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;. Once you have these values, XOR all of them to get your final result.&lt;br /&gt;
&lt;br /&gt;
For example imagine that you have pieces 1, 3 and 4 from above, letting &amp;lt;code&amp;gt;pc(i)&amp;lt;/code&amp;gt; be the value from piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; not including the three byte prefix. You thus have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  v(1) + v(2)*2  + v(3)*3  = pc(1)&lt;br /&gt;
  v(1) + v(2)*8  + v(3)*27 = pc(2)&lt;br /&gt;
  v(1) + v(2)*16 + v(3)*81 = pc(3)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The simplest method to solve linear systems is elimination, which would work as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    v(1) + v(2)*8  + v(3)*27 =  pc(2)&lt;br /&gt;
  - v(1) - v(2)*2  - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*6  + v(3)*24 =  pc(2) - pc(1)&lt;br /&gt;
&lt;br /&gt;
    v(1) + v(2)*16  + v(3)*81 =  pc(3)&lt;br /&gt;
  - v(1) - v(2)*2   - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*14  + v(3)*78 =  pc(3) - pc(1)&lt;br /&gt;
&lt;br /&gt;
    v(2)*14  + v(3)*78  =  pc(3) - pc(1)&lt;br /&gt;
  - v(2)*6   - v(3)*24  = -pc(2) + pc(1)&lt;br /&gt;
                      |  &lt;br /&gt;
                      v&lt;br /&gt;
    v(2)*84  + v(3)*468 =  pc(3)*6  - pc(1)*6&lt;br /&gt;
  - v(2)*84  - v(3)*336 = -pc(2)*14 + pc(1)*14&lt;br /&gt;
  .----------------------------------------&lt;br /&gt;
               v(3)*132 =  pc(3)*6  - pc(2)*14   + pc(1)*8&lt;br /&gt;
               v(3)     = (pc(3)*6  - pc(2)*14   + pc(1)*8) / 132&lt;br /&gt;
                      &lt;br /&gt;
  v(2) = -v(3)*78/14 + pc(3) - pc(1)&lt;br /&gt;
  v(1) = pc(2) - v(2)*8 - v(3)*27&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The general pattern is to take &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; equations, combine all adjacent pairs to get &amp;lt;code&amp;gt;k-1&amp;lt;/code&amp;gt; equations without any coefficient for &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; and repeat the process until you&#039;re down to a single equation of the form &amp;lt;code&amp;gt;v(k)*a = b&amp;lt;/code&amp;gt;. From there, just work your way back up the chain of intermediate equations to get all the other values.&lt;br /&gt;
&lt;br /&gt;
You actually don&#039;t have to know what &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is because you can simply assume that &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is the number of pieces that you have, and if you have too many pieces solving the linear system will simply lead you to discover that the &amp;lt;code&amp;gt;n+1&amp;lt;/code&amp;gt;st, &amp;lt;code&amp;gt;n+2&amp;lt;/code&amp;gt;nd, etc pieces are all equal to zero.&lt;br /&gt;
&lt;br /&gt;
The scheme can easily be adapted to make the private key the EC product of &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt;, etc rather than an XOR, and even the linear systems can be changed to an multiplicative/exponential equivalent if desired, so it&#039;s pretty adaptable.&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29531</id>
		<title>User:Vbuterin/K of N redundant offline private key proposal</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29531"/>
		<updated>2012-08-07T13:43:06Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is an important tradeoff between security and recoverability when storing an offline wallet. The simplest setup, storing the entire private key in a single place in a lockbox, provides medium security but is vulnerable to accidental loss or destruction through accidents such as fire. Storing a simple backup of the key mitigates this risk, but at the same time decreases security, and the opposite strategy, splitting the key into multiple pieces, all of which must somehow be combined to retrieve the original key, increases security but makes the accidental loss problem even worse. The optimal solution is a setup which combines the two strategies, allowing the key to easily be split up into n pieces, any k of which can be used to recover the original key. The simplest such setup is storing k parts of the key and then an XOR of all k parts, but that approach is limiting as it only allows for n = k+1. What this document proposes is a setup which allows &#039;&#039;any&#039;&#039; n and k to be used. The steps are the following:&lt;br /&gt;
&lt;br /&gt;
===1. K-piece key splitting===&lt;br /&gt;
This proposal provides a scheme where a key can be broken into up to 8 parts, and each part is serialized as a 59-character Base58Check-encoded message that starts with the characters &amp;quot;6s&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
If generating a new random key, simply generate K random 256-bit values.  If N and K are both 8, then the 8th randomly-generated value needs to have its most significant bit set to zero to prevent an overflow condition described later.&lt;br /&gt;
&lt;br /&gt;
If splitting a specific key, then simply generate K-1 random 256-bit values, taking care that the value to be used in position #8 has its most significant bit set to zero, then XOR them all together along with the specific key.  The result of the XOR operation should be used in a position other than the one with a constraint on the highest bit.&lt;br /&gt;
&lt;br /&gt;
Nearly all 256-bit values are valid Bitcoin private keys - the set of 256-bit values constituting invalid private keys all start with 127 or more consecutive 0 or 1 bits and are extremely unlikely to be encountered by accident with an appropriate source of random numbers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pseudocode implementation (doesn&#039;t apply anymore)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def generate(P,k):&lt;br /&gt;
  v = array(k)&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    while hex(sha256(v[i]))[0:2] != &#039;00&#039;:&lt;br /&gt;
      v[i] = random(1,2^256)&lt;br /&gt;
  remainder = P&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    remainder = remainder XOR v[i]&lt;br /&gt;
  while hex(sha256(v[k-2]))[0:2] != &#039;00&#039; or hex(sha256(v[k-1]))[0:2] != &#039;00&#039;:&lt;br /&gt;
    v[k-2] = random(1,2^256)&lt;br /&gt;
    v[k-1] = remainder XOR v[k-2]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far, what we have are &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces that can be trivially recombined (through XOR) into the original private key, and all of which have a basic checksum to provide some protection against mistakes.&lt;br /&gt;
&lt;br /&gt;
===2. N piece generation===&lt;br /&gt;
&lt;br /&gt;
The next step will transform these &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces, once again referred to as &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;, into &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; pieces, any &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; of which can be used to find the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; will have the following format:&lt;br /&gt;
&lt;br /&gt;
* This message contains a 39-byte payload.&lt;br /&gt;
* Each message representing a single part will be 59 base58 characters starting with &#039;6s&#039;.&lt;br /&gt;
* Byte 0: &amp;lt;code&amp;gt;0x4f&amp;lt;/code&amp;gt; (unique &amp;quot;format&amp;quot; identifier to make keyparts in base 58 start with &#039;6s&#039; to be recognizable visually, when used properly in combination with byte 1)&lt;br /&gt;
* Byte 1: 0x93+k where k = 1...8.  This will result in the third character being a digit 1 thru 8 so the user can see the value of k. (e.g. 6s1, 6s2, 6s3, 6s4, 6s5, 6s6, 6s7, 6s8 prefixes).  Highest allowable value: 0x9c&lt;br /&gt;
* Bytes 2,3 = Bitmapped:&lt;br /&gt;
** bit 15...13 (MSB): The fixed value 011.  This is necessary for the user-visible prefix to work as intended.&lt;br /&gt;
** bit 12: compression flag (0=none, 1=compressed)&lt;br /&gt;
** bits 11...9: which key part this is, minus 1&lt;br /&gt;
** bits 8...0: SHA256(resulting bitcoin address)[0...1] &amp;amp; 0x01FF, for the purpose matching parts together and verification they produce the correct address&lt;br /&gt;
* Bytes 4 thru 38: The number &amp;lt;code&amp;gt;v(1) + v(2)*2^i + v(3)*3^i + v(4)*4^i + ...&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are 280 bits allocated to the number (35 bytes).  This will fit all of the 256-bit numbers generated in the scheme, multiplied by their respective factors.  However, there is one exception: if a user generates an 8-of-8 code, then the factors used to create the eighth code will overflow and require 281 bits whenever v(8) exceeds a certain threshold.  In order to prevent this, the value for v(8) needs to be chosen  with its eight most significant bits set to zero.&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
For example, if you want your private key to require three out of five pieces to reconstitute, the final pieces will be (byte lengths will depend on exactly what &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v(3)&amp;lt;/code&amp;gt; are):&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 1 33 v(1) + v(2)*2 + v(3)*3&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 2 33 v(1) + v(2)*4 + v(3)*9&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 3 33 v(1) + v(2)*8 + v(3)*27&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 4 33 v(1) + v(2)*16 + v(3)*81&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 5 34 v(1) + v(2)*32 + v(3)*243&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you&#039;re done, the pieces can be kept as hex or base58 - either format works fine, and stored wherever you want. You might, for example, store one in a safe at home, another at a safety deposit box at the local bank, a third on your computer, a fourth with a friend and memorize the fifth.&lt;br /&gt;
&lt;br /&gt;
===Key Reconstitution===&lt;br /&gt;
&lt;br /&gt;
To reconstitute the private key, simply solve the linear system from any three pieces, inferring from the second byte of the pieces what all the coefficients are, to get the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;. Once you have these values, XOR all of them to get your final result.&lt;br /&gt;
&lt;br /&gt;
For example imagine that you have pieces 1, 3 and 4 from above, letting &amp;lt;code&amp;gt;pc(i)&amp;lt;/code&amp;gt; be the value from piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; not including the three byte prefix. You thus have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  v(1) + v(2)*2  + v(3)*3  = pc(1)&lt;br /&gt;
  v(1) + v(2)*8  + v(3)*27 = pc(2)&lt;br /&gt;
  v(1) + v(2)*16 + v(3)*81 = pc(3)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The simplest method to solve linear systems is elimination, which would work as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    v(1) + v(2)*8  + v(3)*27 =  pc(2)&lt;br /&gt;
  - v(1) - v(2)*2  - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*6  + v(3)*24 =  pc(2) - pc(1)&lt;br /&gt;
&lt;br /&gt;
    v(1) + v(2)*16  + v(3)*81 =  pc(3)&lt;br /&gt;
  - v(1) - v(2)*2   - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*14  + v(3)*78 =  pc(3) - pc(1)&lt;br /&gt;
&lt;br /&gt;
    v(2)*14  + v(3)*78  =  pc(3) - pc(1)&lt;br /&gt;
  - v(2)*6   - v(3)*24  = -pc(2) + pc(1)&lt;br /&gt;
                      |  &lt;br /&gt;
                      v&lt;br /&gt;
    v(2)*84  + v(3)*468 =  pc(3)*6  - pc(1)*6&lt;br /&gt;
  - v(2)*84  - v(3)*336 = -pc(2)*14 + pc(1)*14&lt;br /&gt;
  .----------------------------------------&lt;br /&gt;
               v(3)*132 =  pc(3)*6  - pc(2)*14   + pc(1)*8&lt;br /&gt;
               v(3)     = (pc(3)*6  - pc(2)*14   + pc(1)*8) / 132&lt;br /&gt;
                      &lt;br /&gt;
  v(2) = -v(3)*78/14 + pc(3) - pc(1)&lt;br /&gt;
  v(1) = pc(2) - v(2)*8 - v(3)*27&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The general pattern is to take &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; equations, combine all adjacent pairs to get &amp;lt;code&amp;gt;k-1&amp;lt;/code&amp;gt; equations without any coefficient for &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; and repeat the process until you&#039;re down to a single equation of the form &amp;lt;code&amp;gt;v(k)*a = b&amp;lt;/code&amp;gt;. From there, just work your way back up the chain of intermediate equations to get all the other values.&lt;br /&gt;
&lt;br /&gt;
You actually don&#039;t have to know what &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is because you can simply assume that &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is the number of pieces that you have, and if you have too many pieces solving the linear system will simply lead you to discover that the &amp;lt;code&amp;gt;n+1&amp;lt;/code&amp;gt;st, &amp;lt;code&amp;gt;n+2&amp;lt;/code&amp;gt;nd, etc pieces are all equal to zero.&lt;br /&gt;
&lt;br /&gt;
The scheme can easily be adapted to make the private key the EC product of &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt;, etc rather than an XOR, and even the linear systems can be changed to an multiplicative/exponential equivalent if desired, so it&#039;s pretty adaptable.&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29438</id>
		<title>User:Vbuterin/K of N redundant offline private key proposal</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29438"/>
		<updated>2012-08-05T12:22:58Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: /* 2. N piece generation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is an important tradeoff between security and recoverability when storing an offline wallet. The simplest setup, storing the entire private key in a single place in a lockbox, provides medium security but is vulnerable to accidental loss or destruction through accidents such as fire. Storing a simple backup of the key mitigates this risk, but at the same time decreases security, and the opposite strategy, splitting the key into multiple pieces, all of which must somehow be combined to retrieve the original key, increases security but makes the accidental loss problem even worse. The optimal solution is a setup which combines the two strategies, allowing the key to easily be split up into n pieces, any k of which can be used to recover the original key. The simplest such setup is storing k parts of the key and then an XOR of all k parts, but that approach is limiting as it only allows for n = k+1. What this document proposes is a setup which allows &#039;&#039;any&#039;&#039; n and k to be used. The steps are the following:&lt;br /&gt;
&lt;br /&gt;
===1. K-piece key splitting===&lt;br /&gt;
&lt;br /&gt;
Take your private key, &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;, and find &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; values (which we&#039;ll call&amp;lt;code&amp;gt; v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;) which meet the following conditions:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;hex(SHA256(i))&amp;lt;/code&amp;gt; starts with &amp;lt;code&amp;gt;&#039;00&#039;&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; - this is the checksum&lt;br /&gt;
# &amp;lt;code&amp;gt;XOR&amp;lt;/code&amp;gt;(&amp;lt;code&amp;gt;v(i)&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt;) = the original private key&lt;br /&gt;
&lt;br /&gt;
Pseudocode implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def generate(P,k):&lt;br /&gt;
  v = array(k)&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    while hex(sha256(v[i]))[0:2] != &#039;00&#039;:&lt;br /&gt;
      v[i] = random(1,2^256)&lt;br /&gt;
  remainder = P&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    remainder = remainder XOR v[i]&lt;br /&gt;
  while hex(sha256(v[k-2]))[0:2] != &#039;00&#039; or hex(sha256(v[k-1]))[0:2] != &#039;00&#039;:&lt;br /&gt;
    v[k-2] = random(1,2^256)&lt;br /&gt;
    v[k-1] = remainder XOR v[k-2]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far, what we have are &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces that can be trivially recombined (through XOR) into the original private key, and all of which have a basic checksum to provide some protection against mistakes.&lt;br /&gt;
&lt;br /&gt;
===2. N piece generation===&lt;br /&gt;
&lt;br /&gt;
The next step will transform these &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces, once again referred to as &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;, into &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; pieces, any &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; of which can be used to find the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; will have the following format:&lt;br /&gt;
&lt;br /&gt;
* Byte 0 = &amp;lt;code&amp;gt;0x86&amp;lt;/code&amp;gt; (unique &amp;quot;format&amp;quot; identifier to make keyparts in base 58 recognizable to the untrained eye)&lt;br /&gt;
* Byte 1 =&amp;lt;code&amp;gt; i&amp;lt;/code&amp;gt;&lt;br /&gt;
* Byte 2 = byte length of everything coming after it (leave this blank at first, and calculate it at the end).&lt;br /&gt;
* Bytes 3-whatever = &amp;lt;code&amp;gt;v(1) + v(2)*2^i + v(3)*3^i + v(4)*4^i + ...&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, if you want your private key to require three out of five pieces to reconstitute, the final pieces will be (byte lengths will depend on exactly what &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v(3)&amp;lt;/code&amp;gt; are):&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 1 33 v(1) + v(2)*2 + v(3)*3&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 2 33 v(1) + v(2)*4 + v(3)*9&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 3 33 v(1) + v(2)*8 + v(3)*27&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 4 33 v(1) + v(2)*16 + v(3)*81&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 5 34 v(1) + v(2)*32 + v(3)*243&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you&#039;re done, the pieces can be kept as hex or base58 - either format works fine, and stored wherever you want. You might, for example, store one in a safe at home, another at a safety deposit box at the local bank, a third on your computer, a fourth with a friend and memorize the fifth.&lt;br /&gt;
&lt;br /&gt;
===Key Reconstitution===&lt;br /&gt;
&lt;br /&gt;
To reconstitute the private key, simply solve the linear system from any three pieces, inferring from the second byte of the pieces what all the coefficients are, to get the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;. Once you have these values, XOR all of them to get your final result.&lt;br /&gt;
&lt;br /&gt;
For example imagine that you have pieces 1, 3 and 4 from above, letting &amp;lt;code&amp;gt;pc(i)&amp;lt;/code&amp;gt; be the value from piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; not including the three byte prefix. You thus have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  v(1) + v(2)*2  + v(3)*3  = pc(1)&lt;br /&gt;
  v(1) + v(2)*8  + v(3)*27 = pc(2)&lt;br /&gt;
  v(1) + v(2)*16 + v(3)*81 = pc(3)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The simplest method to solve linear systems is elimination, which would work as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    v(1) + v(2)*8  + v(3)*27 =  pc(2)&lt;br /&gt;
  - v(1) - v(2)*2  - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*6  + v(3)*24 =  pc(2) - pc(1)&lt;br /&gt;
&lt;br /&gt;
    v(1) + v(2)*16  + v(3)*81 =  pc(3)&lt;br /&gt;
  - v(1) - v(2)*2   - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*14  + v(3)*78 =  pc(3) - pc(1)&lt;br /&gt;
&lt;br /&gt;
  v(2)*14  + v(3)*78  = pc(3) - pc(1)&lt;br /&gt;
  v(2)*6   - v(3)*24  = pc(2) - pc(1)&lt;br /&gt;
                      |  &lt;br /&gt;
                      v&lt;br /&gt;
  v(2)*84  + v(3)*468 = pc(3)*6  - pc(1)*6&lt;br /&gt;
  v(2)*84  - v(3)*336 = pc(2)*14 - pc(1)*14&lt;br /&gt;
  .----------------------------------------&lt;br /&gt;
             v(3)*132 = pc(3)*6  - pc(2)*14   + pc(1)*8&lt;br /&gt;
             v(3)     = (pc(3)*6  - pc(2)*14   + pc(1)*8) / 132&lt;br /&gt;
                      &lt;br /&gt;
  v(2) = -v(3)*78/14 + pc(3) - pc(1)&lt;br /&gt;
  v(1) = pc(2) - v(2)*8 - v(3)*27&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The general pattern is to take &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; equations, combine all adjacent pairs to get &amp;lt;code&amp;gt;k-1&amp;lt;/code&amp;gt; equations without any coefficient for &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; and repeat the process until you&#039;re down to a single equation of the form &amp;lt;code&amp;gt;v(k)*a = b&amp;lt;/code&amp;gt;. From there, just work your way back up the chain of intermediate equations to get all the other values.&lt;br /&gt;
&lt;br /&gt;
You actually don&#039;t have to know what &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is because you can simply assume that &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is the number of pieces that you have, and if you have too many pieces solving the linear system will simply lead you to discover that the &amp;lt;code&amp;gt;n+1&amp;lt;/code&amp;gt;st, &amp;lt;code&amp;gt;n+2&amp;lt;/code&amp;gt;nd, etc pieces are all equal to zero.&lt;br /&gt;
&lt;br /&gt;
The scheme can easily be adapted to make the private key the EC product of &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt;, etc rather than an XOR, and even the linear systems can be changed to an multiplicative/exponential equivalent if desired, so it&#039;s pretty adaptable.&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29437</id>
		<title>User:Vbuterin/K of N redundant offline private key proposal</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29437"/>
		<updated>2012-08-05T12:20:43Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: /* Key Reconstitution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is an important tradeoff between security and recoverability when storing an offline wallet. The simplest setup, storing the entire private key in a single place in a lockbox, provides medium security but is vulnerable to accidental loss or destruction through accidents such as fire. Storing a simple backup of the key mitigates this risk, but at the same time decreases security, and the opposite strategy, splitting the key into multiple pieces, all of which must somehow be combined to retrieve the original key, increases security but makes the accidental loss problem even worse. The optimal solution is a setup which combines the two strategies, allowing the key to easily be split up into n pieces, any k of which can be used to recover the original key. The simplest such setup is storing k parts of the key and then an XOR of all k parts, but that approach is limiting as it only allows for n = k+1. What this document proposes is a setup which allows &#039;&#039;any&#039;&#039; n and k to be used. The steps are the following:&lt;br /&gt;
&lt;br /&gt;
===1. K-piece key splitting===&lt;br /&gt;
&lt;br /&gt;
Take your private key, &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;, and find &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; values (which we&#039;ll call&amp;lt;code&amp;gt; v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;) which meet the following conditions:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;hex(SHA256(i))&amp;lt;/code&amp;gt; starts with &amp;lt;code&amp;gt;&#039;00&#039;&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; - this is the checksum&lt;br /&gt;
# &amp;lt;code&amp;gt;XOR&amp;lt;/code&amp;gt;(&amp;lt;code&amp;gt;v(i)&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt;) = the original private key&lt;br /&gt;
&lt;br /&gt;
Pseudocode implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def generate(P,k):&lt;br /&gt;
  v = array(k)&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    while hex(sha256(v[i]))[0:2] != &#039;00&#039;:&lt;br /&gt;
      v[i] = random(1,2^256)&lt;br /&gt;
  remainder = P&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    remainder = remainder XOR v[i]&lt;br /&gt;
  while hex(sha256(v[k-2]))[0:2] != &#039;00&#039; or hex(sha256(v[k-1]))[0:2] != &#039;00&#039;:&lt;br /&gt;
    v[k-2] = random(1,2^256)&lt;br /&gt;
    v[k-1] = remainder XOR v[k-2]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far, what we have are &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces that can be trivially recombined (through XOR) into the original private key, and all of which have a basic checksum to provide some protection against mistakes.&lt;br /&gt;
&lt;br /&gt;
===2. N piece generation===&lt;br /&gt;
&lt;br /&gt;
The next step will transform these &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces, once again referred to as &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;, into n pieces, any k of which can be used to find the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; will have the following format:&lt;br /&gt;
&lt;br /&gt;
* Byte 0 = &amp;lt;code&amp;gt;0x86&amp;lt;/code&amp;gt; (unique &amp;quot;format&amp;quot; identifier to make keyparts in base 58 recognizable to the untrained eye)&lt;br /&gt;
* Byte 1 =&amp;lt;code&amp;gt; i&amp;lt;/code&amp;gt;&lt;br /&gt;
* Byte 2 = byte length of everything coming after it (leave this blank at first, and calculate it at the end).&lt;br /&gt;
* Bytes 3-whatever = &amp;lt;code&amp;gt;v(1) + v(2)*2^i + v(3)*3^i + v(4)*4^i + ...&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, if you want your private key to require three out of five pieces to reconstitute, the final pieces will be (byte lengths will depend on exactly what &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v(3)&amp;lt;/code&amp;gt; are):&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 1 33 v(1) + v(2)*2 + v(3)*3&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 2 33 v(1) + v(2)*4 + v(3)*9&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 3 33 v(1) + v(2)*8 + v(3)*27&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 4 33 v(1) + v(2)*16 + v(3)*81&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 5 34 v(1) + v(2)*32 + v(3)*243&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you&#039;re done, the pieces can be kept as hex or base58 - either format works fine, and stored wherever you want. You might, for example, store one in a safe at home, another at a safety deposit box at the local bank, a third on your computer, a fourth with a friend and memorize the fifth.&lt;br /&gt;
&lt;br /&gt;
===Key Reconstitution===&lt;br /&gt;
&lt;br /&gt;
To reconstitute the private key, simply solve the linear system from any three pieces, inferring from the second byte of the pieces what all the coefficients are, to get the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;. Once you have these values, XOR all of them to get your final result.&lt;br /&gt;
&lt;br /&gt;
For example imagine that you have pieces 1, 3 and 4 from above, letting &amp;lt;code&amp;gt;pc(i)&amp;lt;/code&amp;gt; be the value from piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; not including the three byte prefix. You thus have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  v(1) + v(2)*2  + v(3)*3  = pc(1)&lt;br /&gt;
  v(1) + v(2)*8  + v(3)*27 = pc(2)&lt;br /&gt;
  v(1) + v(2)*16 + v(3)*81 = pc(3)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The simplest method to solve linear systems is elimination, which would work as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    v(1) + v(2)*8  + v(3)*27 =  pc(2)&lt;br /&gt;
  - v(1) - v(2)*2  - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*6  + v(3)*24 =  pc(2) - pc(1)&lt;br /&gt;
&lt;br /&gt;
    v(1) + v(2)*16  + v(3)*81 =  pc(3)&lt;br /&gt;
  - v(1) - v(2)*2   - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*14  + v(3)*78 =  pc(3) - pc(1)&lt;br /&gt;
&lt;br /&gt;
  v(2)*14  + v(3)*78  = pc(3) - pc(1)&lt;br /&gt;
  v(2)*6   - v(3)*24  = pc(2) - pc(1)&lt;br /&gt;
                      |  &lt;br /&gt;
                      v&lt;br /&gt;
  v(2)*84  + v(3)*468 = pc(3)*6  - pc(1)*6&lt;br /&gt;
  v(2)*84  - v(3)*336 = pc(2)*14 - pc(1)*14&lt;br /&gt;
  .----------------------------------------&lt;br /&gt;
             v(3)*132 = pc(3)*6  - pc(2)*14   + pc(1)*8&lt;br /&gt;
             v(3)     = (pc(3)*6  - pc(2)*14   + pc(1)*8) / 132&lt;br /&gt;
                      &lt;br /&gt;
  v(2) = -v(3)*78/14 + pc(3) - pc(1)&lt;br /&gt;
  v(1) = pc(2) - v(2)*8 - v(3)*27&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The general pattern is to take &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; equations, combine all adjacent pairs to get &amp;lt;code&amp;gt;k-1&amp;lt;/code&amp;gt; equations without any coefficient for &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; and repeat the process until you&#039;re down to a single equation of the form &amp;lt;code&amp;gt;v(k)*a = b&amp;lt;/code&amp;gt;. From there, just work your way back up the chain of intermediate equations to get all the other values.&lt;br /&gt;
&lt;br /&gt;
You actually don&#039;t have to know what &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is because you can simply assume that &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is the number of pieces that you have, and if you have too many pieces solving the linear system will simply lead you to discover that the &amp;lt;code&amp;gt;n+1&amp;lt;/code&amp;gt;st, &amp;lt;code&amp;gt;n+2&amp;lt;/code&amp;gt;nd, etc pieces are all equal to zero.&lt;br /&gt;
&lt;br /&gt;
The scheme can easily be adapted to make the private key the EC product of &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt;, etc rather than an XOR, and even the linear systems can be changed to an multiplicative/exponential equivalent if desired, so it&#039;s pretty adaptable.&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29436</id>
		<title>User:Vbuterin/K of N redundant offline private key proposal</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29436"/>
		<updated>2012-08-05T12:17:41Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: /* Key Reconstitution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is an important tradeoff between security and recoverability when storing an offline wallet. The simplest setup, storing the entire private key in a single place in a lockbox, provides medium security but is vulnerable to accidental loss or destruction through accidents such as fire. Storing a simple backup of the key mitigates this risk, but at the same time decreases security, and the opposite strategy, splitting the key into multiple pieces, all of which must somehow be combined to retrieve the original key, increases security but makes the accidental loss problem even worse. The optimal solution is a setup which combines the two strategies, allowing the key to easily be split up into n pieces, any k of which can be used to recover the original key. The simplest such setup is storing k parts of the key and then an XOR of all k parts, but that approach is limiting as it only allows for n = k+1. What this document proposes is a setup which allows &#039;&#039;any&#039;&#039; n and k to be used. The steps are the following:&lt;br /&gt;
&lt;br /&gt;
===1. K-piece key splitting===&lt;br /&gt;
&lt;br /&gt;
Take your private key, &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;, and find &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; values (which we&#039;ll call&amp;lt;code&amp;gt; v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;) which meet the following conditions:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;hex(SHA256(i))&amp;lt;/code&amp;gt; starts with &amp;lt;code&amp;gt;&#039;00&#039;&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; - this is the checksum&lt;br /&gt;
# &amp;lt;code&amp;gt;XOR&amp;lt;/code&amp;gt;(&amp;lt;code&amp;gt;v(i)&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt;) = the original private key&lt;br /&gt;
&lt;br /&gt;
Pseudocode implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def generate(P,k):&lt;br /&gt;
  v = array(k)&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    while hex(sha256(v[i]))[0:2] != &#039;00&#039;:&lt;br /&gt;
      v[i] = random(1,2^256)&lt;br /&gt;
  remainder = P&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    remainder = remainder XOR v[i]&lt;br /&gt;
  while hex(sha256(v[k-2]))[0:2] != &#039;00&#039; or hex(sha256(v[k-1]))[0:2] != &#039;00&#039;:&lt;br /&gt;
    v[k-2] = random(1,2^256)&lt;br /&gt;
    v[k-1] = remainder XOR v[k-2]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far, what we have are &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces that can be trivially recombined (through XOR) into the original private key, and all of which have a basic checksum to provide some protection against mistakes.&lt;br /&gt;
&lt;br /&gt;
===2. N piece generation===&lt;br /&gt;
&lt;br /&gt;
The next step will transform these &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces, once again referred to as &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;, into n pieces, any k of which can be used to find the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; will have the following format:&lt;br /&gt;
&lt;br /&gt;
* Byte 0 = &amp;lt;code&amp;gt;0x86&amp;lt;/code&amp;gt; (unique &amp;quot;format&amp;quot; identifier to make keyparts in base 58 recognizable to the untrained eye)&lt;br /&gt;
* Byte 1 =&amp;lt;code&amp;gt; i&amp;lt;/code&amp;gt;&lt;br /&gt;
* Byte 2 = byte length of everything coming after it (leave this blank at first, and calculate it at the end).&lt;br /&gt;
* Bytes 3-whatever = &amp;lt;code&amp;gt;v(1) + v(2)*2^i + v(3)*3^i + v(4)*4^i + ...&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, if you want your private key to require three out of five pieces to reconstitute, the final pieces will be (byte lengths will depend on exactly what &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v(3)&amp;lt;/code&amp;gt; are):&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 1 33 v(1) + v(2)*2 + v(3)*3&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 2 33 v(1) + v(2)*4 + v(3)*9&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 3 33 v(1) + v(2)*8 + v(3)*27&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 4 33 v(1) + v(2)*16 + v(3)*81&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 5 34 v(1) + v(2)*32 + v(3)*243&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you&#039;re done, the pieces can be kept as hex or base58 - either format works fine, and stored wherever you want. You might, for example, store one in a safe at home, another at a safety deposit box at the local bank, a third on your computer, a fourth with a friend and memorize the fifth.&lt;br /&gt;
&lt;br /&gt;
===Key Reconstitution===&lt;br /&gt;
&lt;br /&gt;
To reconstitute the private key, simply solve the linear system from any three pieces, inferring from the second byte of the pieces what all the coefficients are, to get the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;. Once you have these values, XOR all of them to get your final result.&lt;br /&gt;
&lt;br /&gt;
For example imagine that you have pieces 1, 3 and 4 from above, letting &amp;lt;code&amp;gt;pc(i)&amp;lt;/code&amp;gt; be the value from piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; not including the three byte prefix. You thus have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  v(1) + v(2)*2  + v(3)*3  = pc(1)&lt;br /&gt;
  v(1) + v(2)*8  + v(3)*27 = pc(2)&lt;br /&gt;
  v(1) + v(2)*16 + v(3)*81 = pc(3)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Elimination goes as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    v(1) + v(2)*8  + v(3)*27 =  pc(2)&lt;br /&gt;
  - v(1) - v(2)*2  - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*6  + v(3)*24 =  pc(2) - pc(1)&lt;br /&gt;
&lt;br /&gt;
    v(1) + v(2)*16  + v(3)*81 =  pc(3)&lt;br /&gt;
  - v(1) - v(2)*2   - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*14  + v(3)*78 =  pc(3) - pc(1)&lt;br /&gt;
&lt;br /&gt;
  v(2)*14  + v(3)*78  = pc(3) - pc(1)&lt;br /&gt;
  v(2)*6   - v(3)*24  = pc(2) - pc(1)&lt;br /&gt;
                      |  &lt;br /&gt;
                      v&lt;br /&gt;
  v(2)*84  + v(3)*468 = pc(3)*6  - pc(1)*6&lt;br /&gt;
  v(2)*84  - v(3)*336 = pc(2)*14 - pc(1)*14&lt;br /&gt;
  .----------------------------------------&lt;br /&gt;
             v(3)*132 = pc(3)*6  - pc(2)*14   + pc(1)*8&lt;br /&gt;
             v(3)     = (pc(3)*6  - pc(2)*14   + pc(1)*8) / 132&lt;br /&gt;
                      &lt;br /&gt;
  v(2) = -v(3)*78/14 + pc(3) - pc(1)&lt;br /&gt;
  v(1) = pc(2) - v(2)*8 - v(3)*27&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The general pattern is to take &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; equations, combine all adjacent pairs to get &amp;lt;code&amp;gt;k-1&amp;lt;/code&amp;gt; equations without any coefficient for &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; and repeat the process until you&#039;re down to a single equation of the form &amp;lt;code&amp;gt;v(k)*a = b&amp;lt;/code&amp;gt;. From there, just work your way back up the chain of intermediate equations to get all the other values.&lt;br /&gt;
&lt;br /&gt;
You actually don&#039;t have to know what &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is because you can simply assume that &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is the number of pieces that you have, and if you have too many pieces solving the linear system will simply lead you to discover that the &amp;lt;code&amp;gt;n+1&amp;lt;/code&amp;gt;st, &amp;lt;code&amp;gt;n+2&amp;lt;/code&amp;gt;nd, etc pieces are all equal to zero.&lt;br /&gt;
&lt;br /&gt;
The scheme can easily be adapted to make the private key the EC product of &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt;, etc rather than an XOR, and even the linear systems can be changed to an multiplicative/exponential equivalent if desired, so it&#039;s pretty adaptable.&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29435</id>
		<title>User:Vbuterin/K of N redundant offline private key proposal</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29435"/>
		<updated>2012-08-05T12:17:24Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: /* Key Reconstitution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is an important tradeoff between security and recoverability when storing an offline wallet. The simplest setup, storing the entire private key in a single place in a lockbox, provides medium security but is vulnerable to accidental loss or destruction through accidents such as fire. Storing a simple backup of the key mitigates this risk, but at the same time decreases security, and the opposite strategy, splitting the key into multiple pieces, all of which must somehow be combined to retrieve the original key, increases security but makes the accidental loss problem even worse. The optimal solution is a setup which combines the two strategies, allowing the key to easily be split up into n pieces, any k of which can be used to recover the original key. The simplest such setup is storing k parts of the key and then an XOR of all k parts, but that approach is limiting as it only allows for n = k+1. What this document proposes is a setup which allows &#039;&#039;any&#039;&#039; n and k to be used. The steps are the following:&lt;br /&gt;
&lt;br /&gt;
===1. K-piece key splitting===&lt;br /&gt;
&lt;br /&gt;
Take your private key, &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;, and find &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; values (which we&#039;ll call&amp;lt;code&amp;gt; v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;) which meet the following conditions:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;hex(SHA256(i))&amp;lt;/code&amp;gt; starts with &amp;lt;code&amp;gt;&#039;00&#039;&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; - this is the checksum&lt;br /&gt;
# &amp;lt;code&amp;gt;XOR&amp;lt;/code&amp;gt;(&amp;lt;code&amp;gt;v(i)&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt;) = the original private key&lt;br /&gt;
&lt;br /&gt;
Pseudocode implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def generate(P,k):&lt;br /&gt;
  v = array(k)&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    while hex(sha256(v[i]))[0:2] != &#039;00&#039;:&lt;br /&gt;
      v[i] = random(1,2^256)&lt;br /&gt;
  remainder = P&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    remainder = remainder XOR v[i]&lt;br /&gt;
  while hex(sha256(v[k-2]))[0:2] != &#039;00&#039; or hex(sha256(v[k-1]))[0:2] != &#039;00&#039;:&lt;br /&gt;
    v[k-2] = random(1,2^256)&lt;br /&gt;
    v[k-1] = remainder XOR v[k-2]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far, what we have are &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces that can be trivially recombined (through XOR) into the original private key, and all of which have a basic checksum to provide some protection against mistakes.&lt;br /&gt;
&lt;br /&gt;
===2. N piece generation===&lt;br /&gt;
&lt;br /&gt;
The next step will transform these &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces, once again referred to as &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;, into n pieces, any k of which can be used to find the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; will have the following format:&lt;br /&gt;
&lt;br /&gt;
* Byte 0 = &amp;lt;code&amp;gt;0x86&amp;lt;/code&amp;gt; (unique &amp;quot;format&amp;quot; identifier to make keyparts in base 58 recognizable to the untrained eye)&lt;br /&gt;
* Byte 1 =&amp;lt;code&amp;gt; i&amp;lt;/code&amp;gt;&lt;br /&gt;
* Byte 2 = byte length of everything coming after it (leave this blank at first, and calculate it at the end).&lt;br /&gt;
* Bytes 3-whatever = &amp;lt;code&amp;gt;v(1) + v(2)*2^i + v(3)*3^i + v(4)*4^i + ...&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, if you want your private key to require three out of five pieces to reconstitute, the final pieces will be (byte lengths will depend on exactly what &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v(3)&amp;lt;/code&amp;gt; are):&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 1 33 v(1) + v(2)*2 + v(3)*3&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 2 33 v(1) + v(2)*4 + v(3)*9&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 3 33 v(1) + v(2)*8 + v(3)*27&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 4 33 v(1) + v(2)*16 + v(3)*81&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 5 34 v(1) + v(2)*32 + v(3)*243&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you&#039;re done, the pieces can be kept as hex or base58 - either format works fine, and stored wherever you want. You might, for example, store one in a safe at home, another at a safety deposit box at the local bank, a third on your computer, a fourth with a friend and memorize the fifth.&lt;br /&gt;
&lt;br /&gt;
===Key Reconstitution===&lt;br /&gt;
&lt;br /&gt;
To reconstitute the private key, simply solve the linear system from any three pieces, inferring from the second byte of the pieces what all the coefficients are, to get the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;. Once you have these values, XOR all of them to get your final result.&lt;br /&gt;
&lt;br /&gt;
For example imagine that you have pieces 1, 3 and 4 from above, letting &amp;lt;code&amp;gt;pc(i)&amp;lt;/code&amp;gt; be the value from piece i not including the three byte prefix. You thus have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  v(1) + v(2)*2  + v(3)*3  = pc(1)&lt;br /&gt;
  v(1) + v(2)*8  + v(3)*27 = pc(2)&lt;br /&gt;
  v(1) + v(2)*16 + v(3)*81 = pc(3)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Elimination goes as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    v(1) + v(2)*8  + v(3)*27 =  pc(2)&lt;br /&gt;
  - v(1) - v(2)*2  - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*6  + v(3)*24 =  pc(2) - pc(1)&lt;br /&gt;
&lt;br /&gt;
    v(1) + v(2)*16  + v(3)*81 =  pc(3)&lt;br /&gt;
  - v(1) - v(2)*2   - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*14  + v(3)*78 =  pc(3) - pc(1)&lt;br /&gt;
&lt;br /&gt;
  v(2)*14  + v(3)*78  = pc(3) - pc(1)&lt;br /&gt;
  v(2)*6   - v(3)*24  = pc(2) - pc(1)&lt;br /&gt;
                      |  &lt;br /&gt;
                      v&lt;br /&gt;
  v(2)*84  + v(3)*468 = pc(3)*6  - pc(1)*6&lt;br /&gt;
  v(2)*84  - v(3)*336 = pc(2)*14 - pc(1)*14&lt;br /&gt;
  .----------------------------------------&lt;br /&gt;
             v(3)*132 = pc(3)*6  - pc(2)*14   + pc(1)*8&lt;br /&gt;
             v(3)     = (pc(3)*6  - pc(2)*14   + pc(1)*8) / 132&lt;br /&gt;
                      &lt;br /&gt;
  v(2) = -v(3)*78/14 + pc(3) - pc(1)&lt;br /&gt;
  v(1) = pc(2) - v(2)*8 - v(3)*27&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The general pattern is to take &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; equations, combine all adjacent pairs to get &amp;lt;code&amp;gt;k-1&amp;lt;/code&amp;gt; equations without any coefficient for &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; and repeat the process until you&#039;re down to a single equation of the form &amp;lt;code&amp;gt;v(k)*a = b&amp;lt;/code&amp;gt;. From there, just work your way back up the chain of intermediate equations to get all the other values.&lt;br /&gt;
&lt;br /&gt;
You actually don&#039;t have to know what &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is because you can simply assume that &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is the number of pieces that you have, and if you have too many pieces solving the linear system will simply lead you to discover that the &amp;lt;code&amp;gt;n+1&amp;lt;/code&amp;gt;st, &amp;lt;code&amp;gt;n+2&amp;lt;/code&amp;gt;nd, etc pieces are all equal to zero.&lt;br /&gt;
&lt;br /&gt;
The scheme can easily be adapted to make the private key the EC product of &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt;, etc rather than an XOR, and even the linear systems can be changed to an multiplicative/exponential equivalent if desired, so it&#039;s pretty adaptable.&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29434</id>
		<title>User:Vbuterin/K of N redundant offline private key proposal</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29434"/>
		<updated>2012-08-05T12:14:27Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: /* Key Reconstitution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is an important tradeoff between security and recoverability when storing an offline wallet. The simplest setup, storing the entire private key in a single place in a lockbox, provides medium security but is vulnerable to accidental loss or destruction through accidents such as fire. Storing a simple backup of the key mitigates this risk, but at the same time decreases security, and the opposite strategy, splitting the key into multiple pieces, all of which must somehow be combined to retrieve the original key, increases security but makes the accidental loss problem even worse. The optimal solution is a setup which combines the two strategies, allowing the key to easily be split up into n pieces, any k of which can be used to recover the original key. The simplest such setup is storing k parts of the key and then an XOR of all k parts, but that approach is limiting as it only allows for n = k+1. What this document proposes is a setup which allows &#039;&#039;any&#039;&#039; n and k to be used. The steps are the following:&lt;br /&gt;
&lt;br /&gt;
===1. K-piece key splitting===&lt;br /&gt;
&lt;br /&gt;
Take your private key, &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;, and find &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; values (which we&#039;ll call&amp;lt;code&amp;gt; v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;) which meet the following conditions:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;hex(SHA256(i))&amp;lt;/code&amp;gt; starts with &amp;lt;code&amp;gt;&#039;00&#039;&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; - this is the checksum&lt;br /&gt;
# &amp;lt;code&amp;gt;XOR&amp;lt;/code&amp;gt;(&amp;lt;code&amp;gt;v(i)&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt;) = the original private key&lt;br /&gt;
&lt;br /&gt;
Pseudocode implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def generate(P,k):&lt;br /&gt;
  v = array(k)&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    while hex(sha256(v[i]))[0:2] != &#039;00&#039;:&lt;br /&gt;
      v[i] = random(1,2^256)&lt;br /&gt;
  remainder = P&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    remainder = remainder XOR v[i]&lt;br /&gt;
  while hex(sha256(v[k-2]))[0:2] != &#039;00&#039; or hex(sha256(v[k-1]))[0:2] != &#039;00&#039;:&lt;br /&gt;
    v[k-2] = random(1,2^256)&lt;br /&gt;
    v[k-1] = remainder XOR v[k-2]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far, what we have are &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces that can be trivially recombined (through XOR) into the original private key, and all of which have a basic checksum to provide some protection against mistakes.&lt;br /&gt;
&lt;br /&gt;
===2. N piece generation===&lt;br /&gt;
&lt;br /&gt;
The next step will transform these &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces, once again referred to as &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;, into n pieces, any k of which can be used to find the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; will have the following format:&lt;br /&gt;
&lt;br /&gt;
* Byte 0 = &amp;lt;code&amp;gt;0x86&amp;lt;/code&amp;gt; (unique &amp;quot;format&amp;quot; identifier to make keyparts in base 58 recognizable to the untrained eye)&lt;br /&gt;
* Byte 1 =&amp;lt;code&amp;gt; i&amp;lt;/code&amp;gt;&lt;br /&gt;
* Byte 2 = byte length of everything coming after it (leave this blank at first, and calculate it at the end).&lt;br /&gt;
* Bytes 3-whatever = &amp;lt;code&amp;gt;v(1) + v(2)*2^i + v(3)*3^i + v(4)*4^i + ...&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, if you want your private key to require three out of five pieces to reconstitute, the final pieces will be (byte lengths will depend on exactly what &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v(3)&amp;lt;/code&amp;gt; are):&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 1 33 v(1) + v(2)*2 + v(3)*3&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 2 33 v(1) + v(2)*4 + v(3)*9&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 3 33 v(1) + v(2)*8 + v(3)*27&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 4 33 v(1) + v(2)*16 + v(3)*81&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 5 34 v(1) + v(2)*32 + v(3)*243&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you&#039;re done, the pieces can be kept as hex or base58 - either format works fine, and stored wherever you want. You might, for example, store one in a safe at home, another at a safety deposit box at the local bank, a third on your computer, a fourth with a friend and memorize the fifth.&lt;br /&gt;
&lt;br /&gt;
===Key Reconstitution===&lt;br /&gt;
&lt;br /&gt;
To reconstitute the private key, simply solve the linear system from any three pieces, inferring from the second byte of the pieces what all the coefficients are, to get the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;. Once you have these values, XOR all of them to get your final result.&lt;br /&gt;
&lt;br /&gt;
For example imagine that you have pieces 1, 3 and 4 from above. You thus have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  v(1) + v(2)*2  + v(3)*3  = pc(1)&lt;br /&gt;
  v(1) + v(2)*8  + v(3)*27 = pc(2)&lt;br /&gt;
  v(1) + v(2)*16 + v(3)*81 = pc(3)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Elimination goes as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    v(1) + v(2)*8  + v(3)*27 =  pc(2)&lt;br /&gt;
  - v(1) - v(2)*2  - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*6  + v(3)*24 =  pc(2) - pc(1)&lt;br /&gt;
&lt;br /&gt;
    v(1) + v(2)*16  + v(3)*81 =  pc(3)&lt;br /&gt;
  - v(1) - v(2)*2   - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*14  + v(3)*78 =  pc(3) - pc(1)&lt;br /&gt;
&lt;br /&gt;
  v(2)*14  + v(3)*78  = pc(3) - pc(1)&lt;br /&gt;
  v(2)*6   - v(3)*24  = pc(2) - pc(1)&lt;br /&gt;
                      |  &lt;br /&gt;
                      v&lt;br /&gt;
  v(2)*84  + v(3)*468 = pc(3)*6  - pc(1)*6&lt;br /&gt;
  v(2)*84  - v(3)*336 = pc(2)*14 - pc(1)*14&lt;br /&gt;
  .----------------------------------------&lt;br /&gt;
             v(3)*132 = pc(3)*6  - pc(2)*14   + pc(1)*8&lt;br /&gt;
             v(3)     = (pc(3)*6  - pc(2)*14   + pc(1)*8) / 132&lt;br /&gt;
                      &lt;br /&gt;
  v(2) = -v(3)*78/14 + pc(3) - pc(1)&lt;br /&gt;
  v(1) = pc(2) - v(2)*8 - v(3)*27&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The general pattern is to take &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; equations, combine all adjacent pairs to get &amp;lt;code&amp;gt;k-1&amp;lt;/code&amp;gt; equations without any coefficient for &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; and repeat the process until you&#039;re down to a single equation of the form &amp;lt;code&amp;gt;v(k)*a = b&amp;lt;/code&amp;gt;. From there, just work your way back up the chain of intermediate equations to get all the other values.&lt;br /&gt;
&lt;br /&gt;
You actually don&#039;t have to know what &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is because you can simply assume that &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is the number of pieces that you have, and if you have too many pieces solving the linear system will simply lead you to discover that the &amp;lt;code&amp;gt;n+1&amp;lt;/code&amp;gt;st, &amp;lt;code&amp;gt;n+2&amp;lt;/code&amp;gt;nd, etc pieces are all equal to zero.&lt;br /&gt;
&lt;br /&gt;
The scheme can easily be adapted to make the private key the EC product of &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt;, etc rather than an XOR, and even the linear systems can be changed to an multiplicative/exponential equivalent if desired, so it&#039;s pretty adaptable.&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29433</id>
		<title>User:Vbuterin/K of N redundant offline private key proposal</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29433"/>
		<updated>2012-08-05T12:10:02Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: /* 2. N piece generation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is an important tradeoff between security and recoverability when storing an offline wallet. The simplest setup, storing the entire private key in a single place in a lockbox, provides medium security but is vulnerable to accidental loss or destruction through accidents such as fire. Storing a simple backup of the key mitigates this risk, but at the same time decreases security, and the opposite strategy, splitting the key into multiple pieces, all of which must somehow be combined to retrieve the original key, increases security but makes the accidental loss problem even worse. The optimal solution is a setup which combines the two strategies, allowing the key to easily be split up into n pieces, any k of which can be used to recover the original key. The simplest such setup is storing k parts of the key and then an XOR of all k parts, but that approach is limiting as it only allows for n = k+1. What this document proposes is a setup which allows &#039;&#039;any&#039;&#039; n and k to be used. The steps are the following:&lt;br /&gt;
&lt;br /&gt;
===1. K-piece key splitting===&lt;br /&gt;
&lt;br /&gt;
Take your private key, &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;, and find &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; values (which we&#039;ll call&amp;lt;code&amp;gt; v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;) which meet the following conditions:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;hex(SHA256(i))&amp;lt;/code&amp;gt; starts with &amp;lt;code&amp;gt;&#039;00&#039;&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; - this is the checksum&lt;br /&gt;
# &amp;lt;code&amp;gt;XOR&amp;lt;/code&amp;gt;(&amp;lt;code&amp;gt;v(i)&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt;) = the original private key&lt;br /&gt;
&lt;br /&gt;
Pseudocode implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def generate(P,k):&lt;br /&gt;
  v = array(k)&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    while hex(sha256(v[i]))[0:2] != &#039;00&#039;:&lt;br /&gt;
      v[i] = random(1,2^256)&lt;br /&gt;
  remainder = P&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    remainder = remainder XOR v[i]&lt;br /&gt;
  while hex(sha256(v[k-2]))[0:2] != &#039;00&#039; or hex(sha256(v[k-1]))[0:2] != &#039;00&#039;:&lt;br /&gt;
    v[k-2] = random(1,2^256)&lt;br /&gt;
    v[k-1] = remainder XOR v[k-2]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far, what we have are &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces that can be trivially recombined (through XOR) into the original private key, and all of which have a basic checksum to provide some protection against mistakes.&lt;br /&gt;
&lt;br /&gt;
===2. N piece generation===&lt;br /&gt;
&lt;br /&gt;
The next step will transform these &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces, once again referred to as &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;, into n pieces, any k of which can be used to find the original values &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; will have the following format:&lt;br /&gt;
&lt;br /&gt;
* Byte 0 = &amp;lt;code&amp;gt;0x86&amp;lt;/code&amp;gt; (unique &amp;quot;format&amp;quot; identifier to make keyparts in base 58 recognizable to the untrained eye)&lt;br /&gt;
* Byte 1 =&amp;lt;code&amp;gt; i&amp;lt;/code&amp;gt;&lt;br /&gt;
* Byte 2 = byte length of everything coming after it (leave this blank at first, and calculate it at the end).&lt;br /&gt;
* Bytes 3-whatever = &amp;lt;code&amp;gt;v(1) + v(2)*2^i + v(3)*3^i + v(4)*4^i + ...&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, if you want your private key to require three out of five pieces to reconstitute, the final pieces will be (byte lengths will depend on exactly what &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v(3)&amp;lt;/code&amp;gt; are):&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 1 33 v(1) + v(2)*2 + v(3)*3&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 2 33 v(1) + v(2)*4 + v(3)*9&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 3 33 v(1) + v(2)*8 + v(3)*27&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 4 33 v(1) + v(2)*16 + v(3)*81&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 5 34 v(1) + v(2)*32 + v(3)*243&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you&#039;re done, the pieces can be kept as hex or base58 - either format works fine, and stored wherever you want. You might, for example, store one in a safe at home, another at a safety deposit box at the local bank, a third on your computer, a fourth with a friend and memorize the fifth.&lt;br /&gt;
&lt;br /&gt;
===Key Reconstitution===&lt;br /&gt;
&lt;br /&gt;
To reconstitute the private key, simply solve the linear system from any three pieces, inferring from the second byte of the pieces what all the coefficients are, and XOR all the results. &lt;br /&gt;
&lt;br /&gt;
For example imagine that you have pieces 1, 3 and 4 from above. You thus have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  v(1) + v(2)*2  + v(3)*3  = pc(1)&lt;br /&gt;
  v(1) + v(2)*8  + v(3)*27 = pc(2)&lt;br /&gt;
  v(1) + v(2)*16 + v(3)*81 = pc(3)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Elimination goes as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    v(1) + v(2)*8  + v(3)*27 =  pc(2)&lt;br /&gt;
  - v(1) - v(2)*2  - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*6  + v(3)*24 =  pc(2) - pc(1)&lt;br /&gt;
&lt;br /&gt;
    v(1) + v(2)*16  + v(3)*81 =  pc(3)&lt;br /&gt;
  - v(1) - v(2)*2   - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*14  + v(3)*78 =  pc(3) - pc(1)&lt;br /&gt;
&lt;br /&gt;
  v(2)*14  + v(3)*78  = pc(3) - pc(1)&lt;br /&gt;
  v(2)*6   - v(3)*24  = pc(2) - pc(1)&lt;br /&gt;
                      |  &lt;br /&gt;
                      v&lt;br /&gt;
  v(2)*84  + v(3)*468 = pc(3)*6  - pc(1)*6&lt;br /&gt;
  v(2)*84  - v(3)*336 = pc(2)*14 - pc(1)*14&lt;br /&gt;
  .----------------------------------------&lt;br /&gt;
             v(3)*132 = pc(3)*6  - pc(2)*14   + pc(1)*8&lt;br /&gt;
             v(3)     = pc(3)/22 - pc(2)*7/66 + pc(1)*2/33&lt;br /&gt;
                      &lt;br /&gt;
  v(2) = -v(3)*78/14 + pc(3) - pc(1)&lt;br /&gt;
  v(1) = pc(2) - v(2)*8 - v(3)*27&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You actually don&#039;t have to know what &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is because you can simply assume that &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is the number of pieces that you have, and if you have too many pieces solving the linear system will simply lead you to discover that the &amp;lt;code&amp;gt;n+1&amp;lt;/code&amp;gt;st, &amp;lt;code&amp;gt;n+2&amp;lt;/code&amp;gt;nd, etc pieces are all equal to zero.&lt;br /&gt;
&lt;br /&gt;
The scheme can easily be adapted to make the private key the EC product of &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt;, etc rather than an XOR, and even the linear systems can be changed to an multiplicative/exponential equivalent if desired, so it&#039;s pretty adaptable.&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29432</id>
		<title>User:Vbuterin/K of N redundant offline private key proposal</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29432"/>
		<updated>2012-08-05T12:06:09Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: /* 1. K-piece key splitting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is an important tradeoff between security and recoverability when storing an offline wallet. The simplest setup, storing the entire private key in a single place in a lockbox, provides medium security but is vulnerable to accidental loss or destruction through accidents such as fire. Storing a simple backup of the key mitigates this risk, but at the same time decreases security, and the opposite strategy, splitting the key into multiple pieces, all of which must somehow be combined to retrieve the original key, increases security but makes the accidental loss problem even worse. The optimal solution is a setup which combines the two strategies, allowing the key to easily be split up into n pieces, any k of which can be used to recover the original key. The simplest such setup is storing k parts of the key and then an XOR of all k parts, but that approach is limiting as it only allows for n = k+1. What this document proposes is a setup which allows &#039;&#039;any&#039;&#039; n and k to be used. The steps are the following:&lt;br /&gt;
&lt;br /&gt;
===1. K-piece key splitting===&lt;br /&gt;
&lt;br /&gt;
Take your private key, &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;, and find &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; values (which we&#039;ll call&amp;lt;code&amp;gt; v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;) which meet the following conditions:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;hex(SHA256(i))&amp;lt;/code&amp;gt; starts with &amp;lt;code&amp;gt;&#039;00&#039;&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; - this is the checksum&lt;br /&gt;
# &amp;lt;code&amp;gt;XOR&amp;lt;/code&amp;gt;(&amp;lt;code&amp;gt;v(i)&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt;) = the original private key&lt;br /&gt;
&lt;br /&gt;
Pseudocode implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def generate(P,k):&lt;br /&gt;
  v = array(k)&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    while hex(sha256(v[i]))[0:2] != &#039;00&#039;:&lt;br /&gt;
      v[i] = random(1,2^256)&lt;br /&gt;
  remainder = P&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    remainder = remainder XOR v[i]&lt;br /&gt;
  while hex(sha256(v[k-2]))[0:2] != &#039;00&#039; or hex(sha256(v[k-1]))[0:2] != &#039;00&#039;:&lt;br /&gt;
    v[k-2] = random(1,2^256)&lt;br /&gt;
    v[k-1] = remainder XOR v[k-2]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far, what we have are &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; pieces that can be trivially recombined (through XOR) into the original private key, and all of which have a basic checksum to provide some protection against mistakes.&lt;br /&gt;
&lt;br /&gt;
===2. N piece generation===&lt;br /&gt;
&lt;br /&gt;
Piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; will have the following format:&lt;br /&gt;
&lt;br /&gt;
* Byte 0 = &amp;lt;code&amp;gt;0x86&amp;lt;/code&amp;gt; (unique &amp;quot;format&amp;quot; identifier to make keyparts in base 58 recognizable to the untrained eye)&lt;br /&gt;
* Byte 1 =&amp;lt;code&amp;gt; i&amp;lt;/code&amp;gt;&lt;br /&gt;
* Byte 2 = byte length of everything coming after it (leave this blank at first, and calculate it at the end).&lt;br /&gt;
* Bytes 3-whatever = &amp;lt;code&amp;gt;v(1) + v(2)*2^i + v(3)*3^i + v(4)*4^i + ...&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, if you want your private key to require three out of five pieces to reconstitute, the final pieces will be (string lengths will depend on exactly what &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v(3)&amp;lt;/code&amp;gt; are):&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 1 45 v(1) + v(2)*2 + v(3)*3&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 2 45 v(1) + v(2)*4 + v(3)*9&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 3 46 v(1) + v(2)*8 + v(3)*27&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 4 46 v(1) + v(2)*16 + v(3)*81&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 5 46 v(1) + v(2)*32 + v(3)*243&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you&#039;re done, the pieces can be kept as hex of base58 - either format works fine, and stored wherever you want.&lt;br /&gt;
&lt;br /&gt;
===Key Reconstitution===&lt;br /&gt;
&lt;br /&gt;
To reconstitute the private key, simply solve the linear system from any three pieces, inferring from the second byte of the pieces what all the coefficients are, and XOR all the results. &lt;br /&gt;
&lt;br /&gt;
For example imagine that you have pieces 1, 3 and 4 from above. You thus have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  v(1) + v(2)*2  + v(3)*3  = pc(1)&lt;br /&gt;
  v(1) + v(2)*8  + v(3)*27 = pc(2)&lt;br /&gt;
  v(1) + v(2)*16 + v(3)*81 = pc(3)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Elimination goes as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    v(1) + v(2)*8  + v(3)*27 =  pc(2)&lt;br /&gt;
  - v(1) - v(2)*2  - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*6  + v(3)*24 =  pc(2) - pc(1)&lt;br /&gt;
&lt;br /&gt;
    v(1) + v(2)*16  + v(3)*81 =  pc(3)&lt;br /&gt;
  - v(1) - v(2)*2   - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*14  + v(3)*78 =  pc(3) - pc(1)&lt;br /&gt;
&lt;br /&gt;
  v(2)*14  + v(3)*78  = pc(3) - pc(1)&lt;br /&gt;
  v(2)*6   - v(3)*24  = pc(2) - pc(1)&lt;br /&gt;
                      |  &lt;br /&gt;
                      v&lt;br /&gt;
  v(2)*84  + v(3)*468 = pc(3)*6  - pc(1)*6&lt;br /&gt;
  v(2)*84  - v(3)*336 = pc(2)*14 - pc(1)*14&lt;br /&gt;
  .----------------------------------------&lt;br /&gt;
             v(3)*132 = pc(3)*6  - pc(2)*14   + pc(1)*8&lt;br /&gt;
             v(3)     = pc(3)/22 - pc(2)*7/66 + pc(1)*2/33&lt;br /&gt;
                      &lt;br /&gt;
  v(2) = -v(3)*78/14 + pc(3) - pc(1)&lt;br /&gt;
  v(1) = pc(2) - v(2)*8 - v(3)*27&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You actually don&#039;t have to know what &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is because you can simply assume that &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is the number of pieces that you have, and if you have too many pieces solving the linear system will simply lead you to discover that the &amp;lt;code&amp;gt;n+1&amp;lt;/code&amp;gt;st, &amp;lt;code&amp;gt;n+2&amp;lt;/code&amp;gt;nd, etc pieces are all equal to zero.&lt;br /&gt;
&lt;br /&gt;
The scheme can easily be adapted to make the private key the EC product of &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt;, etc rather than an XOR, and even the linear systems can be changed to an multiplicative/exponential equivalent if desired, so it&#039;s pretty adaptable.&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29431</id>
		<title>User:Vbuterin/K of N redundant offline private key proposal</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29431"/>
		<updated>2012-08-05T12:03:08Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: /* 2. N piece generation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is an important tradeoff between security and recoverability when storing an offline wallet. The simplest setup, storing the entire private key in a single place in a lockbox, provides medium security but is vulnerable to accidental loss or destruction through accidents such as fire. Storing a simple backup of the key mitigates this risk, but at the same time decreases security, and the opposite strategy, splitting the key into multiple pieces, all of which must somehow be combined to retrieve the original key, increases security but makes the accidental loss problem even worse. The optimal solution is a setup which combines the two strategies, allowing the key to easily be split up into n pieces, any k of which can be used to recover the original key. The simplest such setup is storing k parts of the key and then an XOR of all k parts, but that approach is limiting as it only allows for n = k+1. What this document proposes is a setup which allows &#039;&#039;any&#039;&#039; n and k to be used. The steps are the following:&lt;br /&gt;
&lt;br /&gt;
===1. K-piece key splitting===&lt;br /&gt;
&lt;br /&gt;
Take your private key, &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;, and find &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; values (which we&#039;ll call&amp;lt;code&amp;gt; v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;) which meet the following conditions:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;hex(SHA256(i))&amp;lt;/code&amp;gt; starts with &amp;lt;code&amp;gt;&#039;00&#039;&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; - this is the checksum&lt;br /&gt;
# &amp;lt;code&amp;gt;XOR&amp;lt;/code&amp;gt;(&amp;lt;code&amp;gt;v(i)&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt;) = the original private key&lt;br /&gt;
&lt;br /&gt;
Pseudocode implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def generate(P,k):&lt;br /&gt;
  v = array(k)&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    while hex(sha256(v[i]))[0:2] != &#039;00&#039;:&lt;br /&gt;
      v[i] = random(1,2^256)&lt;br /&gt;
  remainder = P&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    remainder = remainder XOR v[i]&lt;br /&gt;
  while hex(sha256(v[k-2]))[0:2] != &#039;00&#039; or hex(sha256(v[k-1]))[0:2] != &#039;00&#039;:&lt;br /&gt;
    v[k-2] = random(1,2^256)&lt;br /&gt;
    v[k-1] = remainder XOR v[k-2]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===2. N piece generation===&lt;br /&gt;
&lt;br /&gt;
Piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; will have the following format:&lt;br /&gt;
&lt;br /&gt;
* Byte 0 = &amp;lt;code&amp;gt;0x86&amp;lt;/code&amp;gt; (unique &amp;quot;format&amp;quot; identifier to make keyparts in base 58 recognizable to the untrained eye)&lt;br /&gt;
* Byte 1 =&amp;lt;code&amp;gt; i&amp;lt;/code&amp;gt;&lt;br /&gt;
* Byte 2 = byte length of everything coming after it (leave this blank at first, and calculate it at the end).&lt;br /&gt;
* Bytes 3-whatever = &amp;lt;code&amp;gt;v(1) + v(2)*2^i + v(3)*3^i + v(4)*4^i + ...&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, if you want your private key to require three out of five pieces to reconstitute, the final pieces will be (string lengths will depend on exactly what &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v(3)&amp;lt;/code&amp;gt; are):&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 1 45 v(1) + v(2)*2 + v(3)*3&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 2 45 v(1) + v(2)*4 + v(3)*9&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 3 46 v(1) + v(2)*8 + v(3)*27&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 4 46 v(1) + v(2)*16 + v(3)*81&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 5 46 v(1) + v(2)*32 + v(3)*243&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you&#039;re done, the pieces can be kept as hex of base58 - either format works fine, and stored wherever you want.&lt;br /&gt;
&lt;br /&gt;
===Key Reconstitution===&lt;br /&gt;
&lt;br /&gt;
To reconstitute the private key, simply solve the linear system from any three pieces, inferring from the second byte of the pieces what all the coefficients are, and XOR all the results. &lt;br /&gt;
&lt;br /&gt;
For example imagine that you have pieces 1, 3 and 4 from above. You thus have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  v(1) + v(2)*2  + v(3)*3  = pc(1)&lt;br /&gt;
  v(1) + v(2)*8  + v(3)*27 = pc(2)&lt;br /&gt;
  v(1) + v(2)*16 + v(3)*81 = pc(3)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Elimination goes as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    v(1) + v(2)*8  + v(3)*27 =  pc(2)&lt;br /&gt;
  - v(1) - v(2)*2  - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*6  + v(3)*24 =  pc(2) - pc(1)&lt;br /&gt;
&lt;br /&gt;
    v(1) + v(2)*16  + v(3)*81 =  pc(3)&lt;br /&gt;
  - v(1) - v(2)*2   - v(3)*3  = -pc(1)&lt;br /&gt;
  .----------------------------------&lt;br /&gt;
           v(2)*14  + v(3)*78 =  pc(3) - pc(1)&lt;br /&gt;
&lt;br /&gt;
  v(2)*14  + v(3)*78  = pc(3) - pc(1)&lt;br /&gt;
  v(2)*6   - v(3)*24  = pc(2) - pc(1)&lt;br /&gt;
                      |  &lt;br /&gt;
                      v&lt;br /&gt;
  v(2)*84  + v(3)*468 = pc(3)*6  - pc(1)*6&lt;br /&gt;
  v(2)*84  - v(3)*336 = pc(2)*14 - pc(1)*14&lt;br /&gt;
  .----------------------------------------&lt;br /&gt;
             v(3)*132 = pc(3)*6  - pc(2)*14   + pc(1)*8&lt;br /&gt;
             v(3)     = pc(3)/22 - pc(2)*7/66 + pc(1)*2/33&lt;br /&gt;
                      &lt;br /&gt;
  v(2) = -v(3)*78/14 + pc(3) - pc(1)&lt;br /&gt;
  v(1) = pc(2) - v(2)*8 - v(3)*27&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You actually don&#039;t have to know what &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is because you can simply assume that &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is the number of pieces that you have, and if you have too many pieces solving the linear system will simply lead you to discover that the &amp;lt;code&amp;gt;n+1&amp;lt;/code&amp;gt;st, &amp;lt;code&amp;gt;n+2&amp;lt;/code&amp;gt;nd, etc pieces are all equal to zero.&lt;br /&gt;
&lt;br /&gt;
The scheme can easily be adapted to make the private key the EC product of &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt;, etc rather than an XOR, and even the linear systems can be changed to an multiplicative/exponential equivalent if desired, so it&#039;s pretty adaptable.&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
	<entry>
		<id>https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29430</id>
		<title>User:Vbuterin/K of N redundant offline private key proposal</title>
		<link rel="alternate" type="text/html" href="https://en.bitcoin.it/w/index.php?title=User:Vbuterin/K_of_N_redundant_offline_private_key_proposal&amp;diff=29430"/>
		<updated>2012-08-05T11:49:56Z</updated>

		<summary type="html">&lt;p&gt;Vbuterin: Created page with &amp;quot;There is an important tradeoff between security and recoverability when storing an offline wallet. The simplest setup, storing the entire private key in a single place in a lo...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There is an important tradeoff between security and recoverability when storing an offline wallet. The simplest setup, storing the entire private key in a single place in a lockbox, provides medium security but is vulnerable to accidental loss or destruction through accidents such as fire. Storing a simple backup of the key mitigates this risk, but at the same time decreases security, and the opposite strategy, splitting the key into multiple pieces, all of which must somehow be combined to retrieve the original key, increases security but makes the accidental loss problem even worse. The optimal solution is a setup which combines the two strategies, allowing the key to easily be split up into n pieces, any k of which can be used to recover the original key. The simplest such setup is storing k parts of the key and then an XOR of all k parts, but that approach is limiting as it only allows for n = k+1. What this document proposes is a setup which allows &#039;&#039;any&#039;&#039; n and k to be used. The steps are the following:&lt;br /&gt;
&lt;br /&gt;
===1. K-piece key splitting===&lt;br /&gt;
&lt;br /&gt;
Take your private key, &amp;lt;code&amp;gt;P&amp;lt;/code&amp;gt;, and find &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; values (which we&#039;ll call&amp;lt;code&amp;gt; v(1)&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;v(k)&amp;lt;/code&amp;gt;) which meet the following conditions:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;hex(SHA256(i))&amp;lt;/code&amp;gt; starts with &amp;lt;code&amp;gt;&#039;00&#039;&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; - this is the checksum&lt;br /&gt;
# &amp;lt;code&amp;gt;XOR&amp;lt;/code&amp;gt;(&amp;lt;code&amp;gt;v(i)&amp;lt;/code&amp;gt; for all &amp;lt;code&amp;gt;i 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt;) = the original private key&lt;br /&gt;
&lt;br /&gt;
Pseudocode implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def generate(P,k):&lt;br /&gt;
  v = array(k)&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    while hex(sha256(v[i]))[0:2] != &#039;00&#039;:&lt;br /&gt;
      v[i] = random(1,2^256)&lt;br /&gt;
  remainder = P&lt;br /&gt;
  for i in range(0,k-2):&lt;br /&gt;
    remainder = remainder XOR v[i]&lt;br /&gt;
  while hex(sha256(v[k-2]))[0:2] != &#039;00&#039; or hex(sha256(v[k-1]))[0:2] != &#039;00&#039;:&lt;br /&gt;
    v[k-2] = random(1,2^256)&lt;br /&gt;
    v[k-1] = remainder XOR v[k-2]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===2. N piece generation===&lt;br /&gt;
&lt;br /&gt;
Piece &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; will have the following format:&lt;br /&gt;
&lt;br /&gt;
* Byte 0 = &amp;lt;code&amp;gt;0x86&amp;lt;/code&amp;gt; (unique &amp;quot;format&amp;quot; identifier to make keyparts in base 58 recognizable to the untrained eye)&lt;br /&gt;
* Byte 1 =&amp;lt;code&amp;gt; i&amp;lt;/code&amp;gt;&lt;br /&gt;
* Byte 2 = byte length of everything coming after it (leave this blank at first, and calculate it at the end).&lt;br /&gt;
* Bytes 3-whatever = &amp;lt;code&amp;gt;v(1) + v(2)*2^i + v(3)*3^i + v(4)*4^i + ...&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, if you want your private key to require three out of five pieces to reconstitute, the final pieces will be (string lengths will depend on exactly what &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;v(3)&amp;lt;/code&amp;gt; are):&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 1 45 v(1) + v(2)*2 + v(3)*3&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 2 45 v(1) + v(2)*4 + v(3)*9&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 3 46 v(1) + v(2)*8 + v(3)*27&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 4 46 v(1) + v(2)*16 + v(3)*81&amp;lt;/code&amp;gt;&lt;br /&gt;
# &amp;lt;code&amp;gt;0x86 5 46 v(1) + v(2)*32 + v(3)*243&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you&#039;re done, the pieces can be kept as hex of base58 - either format works fine.&lt;br /&gt;
&lt;br /&gt;
To reconstitute the private key, simply solve the linear system from any three pieces, inferring from the second byte of the pieces what all the coefficients are, and XOR all the results. You actually don&#039;t have to know what &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is because you can simply assume that &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; is the number of pieces that you have, and if you have too many pieces solving the linear system will simply lead you to discover that the &amp;lt;code&amp;gt;n+1&amp;lt;/code&amp;gt;st, &amp;lt;code&amp;gt;n+2&amp;lt;/code&amp;gt;nd, etc pieces are all equal to zero.&lt;br /&gt;
&lt;br /&gt;
The scheme can easily be adapted to make the private key the EC product of &amp;lt;code&amp;gt;v(1)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v(2)&amp;lt;/code&amp;gt;, etc rather than an XOR, and even the linear systems can be changed to an multiplicative/exponential equivalent if desired, so it&#039;s pretty adaptable.&lt;/div&gt;</summary>
		<author><name>Vbuterin</name></author>
	</entry>
</feed>