On Sun, May 12, 2024 at 06:04:09PM +0000, 'Rama Gan' via Bitcoin Development Mailing List wrote:
> I am excited to introduce Penlock, a printable paper-computer that guides users
> through secret-splitting their BIP39 seed phrase without an electronic device. A
> beta release is now available for peer-reviewing and early testing:
>
https://beta.penlock.io.
>
> <snip>
>
Hi Rama,
Very interesting project. I have a few unordered thoughts about this:
* You have instructions for generating BIP39 seed words, but if the goal
is to be compatible with existing setups, this really isn't necessary
(or even desireable). If somebody is willing to generate a whole new
seed and is willing to sweep their coins, they might as well just use
codex32. (Perhaps they have an urgent need to do so, and cannot wait
for codex32 support to arrive in mainstream wallets. Ok. But it's a
pretty niche user who is panickedly updating their coins while having
the patience to hand-compute things!)
* Furthermore, the "just grind checksum words til the string works"
approach, while ergonomic for 12 words (16 iterations max), is
unrealistic for 16 words (64 iterations) and basically impossible for
24 words (256 iterations). Probably worth mentioning this.
* The math underlying this all seems sound -- you map BIP39 characters
directly into the field of integers mod 29, then compute lines in this
field. However, the resulting checksum is then as long as your
original set of words. Again, probably ok for 12 words but
unreasonable for 24. (BTW, we have an unofficial BIP39 compatibility
layer for codex32 which has the same issue -- everything is horrible
for the 24-word case. But it is possible to do, and I've done it.)
* However, the use of a characteristic-greater-than-2 field means that
addition and subtraction are different operations and suddenly you
need to be careful about the exact order in which your read things
off the volvelles. It also makes recovering your share more
complicated. I see that you currently have a table for the 2-of-3
case where you read the volvelle in different ways depending on which
shares you have. Clever, but this will not extend to 2-of-n and I
suspect you'll basically need to implement the full "recovery wheel"
from codex32 (or the "recovery tables" which are faster to use for the
2-of-n case, though easier to use wrong).
Recovery is not really that important because you only do it when
you're going to put your seed into a computer, and in that case you
might as well make the computer do the recovery for you, but it is
unfortunate. Especially in this case where a stated goal is that the
computer -won't- do anything for you because it doesn't know about the
scheme.
* Furthermore, this encoding into GF29 is nonstandard. I think, for the
checksum construction this doesn't matter -- if the encoding becomes
lost then you can just forget about the checksum, and if it doesn't,
then you have a pretty great checksum (which can recover any number of
errors as long as they don't hit both the data and the checksum in the
same place). My feeling is that it's probably a good idea for people
to use your checksum scheme on top of their existing BIP39 words, but
the splitting stuff I'm less comfortable with.
Possibly you would rather just combine your checksum scheme with
seedxor? Though seedxor has the unfortunate need to convert your data
to binary before xoring, which is time-consuming and error-prone and
not compatible with the checksum so you don't have any good way to
catch or fix mistakes. (The "unofficial compatibility layer for
codex32" I mentioned works this way as well and it's horrible. But as
you say, for users who really don't want to sweep their coins, maybe
they are willing to make ugly tradeoffs..) Though I believe that
seedxor only works for 2-of-3 and cannot be generalized without making
the scheme unrecognizable.
Alternately, if you switched to a binary field, and chose a checksum
whose target residue was 0 (normally *not* recommended because it
allows some classes of errors, in particular prefixes of zeroes)
(though it does not allow any more substitution or erasure errors,
which is what we care about for short fixed-length like this) then
you could use an addition volvelle in the same way, the computation
would secretly be identical to the seedxor computation, and your
checksum would be preserved by it. So this is another way in which you
could try to make a "seedxor-compatible checksum". But by adding a
multiplicaion wheel that can do Lagrange multipliers you could
generalize it to 2-of-n in a "natural" way which would break seedxor
compatibility only for people who wanted more than 3 shares, and
possibly even only when actually using shares beyond the third..
As a final note about seedxor, they have as a design goal that the
shares look identical to full seeds; they preserve the broken bip39
checksum, have no extra characters, etc. Personally I think this goal
is terrible. If you are going to use obscure hand-computation tricks
you are far more likely to lose your data (or forget how to manipulate
it) than you are to be robbed by a thief who understands your scheme.
* More generally, you need to write up a specification and description
of the math and maybe even a PDF :). I learned the scheme by
reverse-engineering your Javascript, which is well-written and
dependency-free, but still pretty abstract and indirect and anyway JS
is not my language (nor is it likely to be the language for the
typical hand-computer user). Sadly your volvelles also don't render
properly in my browser (qutebrowser) which is chromium-based but maybe
I have some settings wrong.
Best
Andrew
--
Andrew Poelstra
Director, Blockstream Research
Email: apoelstra at
wpsoftware.net
Web:
https://www.wpsoftware.net/andrew
The sun is always shining in space
-Justin Lewis-Webster