<div dir="ltr"><div dir="ltr">With the help of Pieter I've recently made some interesting mathematical observations about Bech32 codewords and Shamir's secret sharing:<br><br>(1) Affine combinations of two Bech32 codewords is again a valid Bech32 codeword.<br>(2) Lagrange polynomials form a partition of unity.<br><br>The consequences of these facts is that when you perform Shamir's secret sharing where all your shares have valid Bech32 checksums, then the resulting secret will also have a valid Bech32 checksum.  Conversely, if your secret has a valid Bech32 checksum, and your random shares have valid Bech32 checksums, then all your derived shares will have valid Bech32 checksums.  This can form a basis on which we can build a simple secret sharing scheme for dividing up a BIP-32 master seed.<br><br>In order to illustrate this, I'll describe an example scheme for <i>k</i>-of-<i>n</i> Shamir's secret sharing scheme where <i>2 <= k</i> <= <i>n</i> <= 31.<br><br>Suppose we have a 128-bit master seed <span style="font-family:monospace">0xb6721d937d82f238672de4db91b87d0c</span>.  We encode this secret as the following Bech32 codeword: "<span style="font-family:monospace">donotusesss321s2name00keepmymasterseedunderwraps2n89wr</span>".  Let's deconstruct this codeword.<br><br>"<span style="font-family:monospace">donotusesss32</span>": A Bech32 hrp for this example scheme.<br>"<span style="font-family:monospace">1</span>": The Bech32 separator.<br>"<span style="font-family:monospace">s</span>": The first data character is the index of this share. Each index is a Bech32 character.  In this scheme the secret share is always at index "<span style="font-family:monospace">s</span>", which stands for "secret".<br>"<span style="font-family:monospace">2</span>": The second data character is the threshold.  In this example we are using a 2-of-n threshold.  We use the digits <span style="font-family:monospace">2</span>-<span style="font-family:monospace">9</span> for thresholds upto 9.  We use Bech32 characters <span style="font-family:monospace">a</span>-<span style="font-family:monospace">y</span> for thresholds from 10 to 31.<br>"<span style="font-family:monospace">name00</span>": The next 6 characters are an id for this set of shares.  This id isn't part of the secret data. It is used to ensure that the shares you are reconstructing were generated for the same secret.  This id just needs to be unique for all the secrets that you are dividing up with this scheme. The id can be chosen randomly, sequentially, or even set to the constant such as "<span style="font-family:monospace">qqqqqq</span>" if you do not want to use it for identification.<br>"<span style="font-family:monospace">keepmymasterseedunderwraps</span>": This is the 128-bit secret master seed <span style="font-family:monospace">0xb6721d937d82f238672de4db91b87d0c</span> encoded in Bech32.  The master seed can be a 128-bit, 256-bit or 512-bit value.<br>"<span style="font-family:monospace">2n89wr</span>" is the Bech32 checksum.<br><br>We will generate shares for a 2-of-3 threshold.  We generate the first share at index "<span style="font-family:monospace">a</span>".  In this example we generate "<span style="font-family:monospace">donotusesss321a2name00q0h5aajczn04g9sh0wtsl2f0y0g3vlkr</span>".<br><br>"<span style="font-family:monospace">donotusesss32</span>": The Bech32 hrp for this example scheme.<br>"<span style="font-family:monospace">1</span>": The Bech32 separator.<br>"<span style="font-family:monospace">a</span>": The first data character is the index of this share which we have chosen to be "<span style="font-family:monospace">a</span>".<br>"<span style="font-family:monospace">2</span>": The second data character is the threshold, which is 2.<br>"<span style="font-family:monospace">name00</span>": The next 6 characters is the id we chose above for this set of shares.<br>"<span style="font-family:monospace">q0h5aajczn04g9sh0wtsl2f0y0</span>": This is 26 randomly selected bech32 characters<br>"<span style="font-family:monospace">g3vlkr</span>" is the Bech32 checksum.<br><br>We generated the next two shares at index "<span style="font-family:monospace">c</span>" and and index "<span style="font-family:monospace">d</span>".  These shares are generated using characterwise Lagrange interpolation of the secret share and the above randomly generated share.<br>The resulting shares are "<span style="font-family:monospace">donotusesss321c2name00chzu58ep57hd9xmaw6zmuyjeau0kq4mr</span>" and "<span style="font-family:monospace">donotusesss321d2name00ung8rmkf2snftj57zu45g7z84hzmzk4r</span>"<br><br>Notice that the resulting strings have<br>(1) valid checksums;<br>(2) have correct indices;<br>(3) have the correct threshold values;<br>(4) have the correct ids.</div><div><br></div><div>This scheme still enjoys the perfect information hiding property of Shamir's secret sharing.  Even when you know <i>k</i>-1 shares, every possible master seed value has exactly one set of shares that includes those particular <i>k</i>-1 shares, so knowing <i>k</i>-1 shares tells you nothing about the secret data value.</div><div><br></div><div>One nice property of Lagrange interpolation is that it is simple enough to compute by hand with the help of a few lookup tables.  Bech32 checksums can also be computed and checked by hand with the help of lookup tables.  While the majority of users wouldn't do hand computations, those motivated users who have a healthy distrust of digital devices can generate and manipulate the secret shares by hand.  The Bech32 checksum property means that after generating the shares by hand, you can then validate the checksums by hand. With extremely high probability, you will catch any computation error you make.  My SSS32 repository at <a href="https://github.com/roconnor-blockstream/SSS32">https://github.com/roconnor-blockstream/SSS32</a> has a postscript file that generates the lookup tables needed for hand computation, although the document is a bit disorganized at the moment.<br></div><div><br></div><div> The main deficiency of the scheme presented here is that we want a longer checksum than used in BIP-173 that is more suitable for error correction, rather than simply error detection.</div><div><br></div><div>This example scheme was inspired in part by <a href="https://github.com/satoshilabs/slips/blob/master/slip-0032.md">SLIP-32</a> with the intent to be a hand computable version of the same idea.<br></div><div><br></div><div>P.S. It is possible that this all could be made obsolete by a threshold musig signature scheme.<br></div></div>