SSS32 icon indicating copy to clipboard operation
SSS32 copied to clipboard

Define long MS32 strings.

Open roconnor-blockstream opened this issue 2 years ago • 8 comments

roconnor-blockstream avatar Apr 16 '22 03:04 roconnor-blockstream

  • Is it worth saying a short sentence about the motivation for introducing a second checksum?

I've elaborated on why we are introducing a second checksum.

  • To avoid ambiguity with the term "secret shares", I renamed the "share data" component of the MS32 string to "payload". How do you feel about using the term "payload" here as well?

I've converted to using the term "payload"

  • Do we need more detailed instructions (or maybe just a test vector is enough) for the 64-byte case? I'm imagining the "splitting in the middle of a byte" could be a major source of mistakes if not.

I think the instructions are clear. We definitely want to add test vectors and also incorrect test vectors.

That said, maybe there is a design that somehow ensures the assembly cannot be done incorrectly? Seems impossible since the checksum operates on bech32 characters and the byte decoding operates at a lower layer.

Actually we could make the first payload 30 characters instead of 96. This is an illegal length for decoding a payload which may encourage people to concatenate first.

roconnor-blockstream avatar May 23 '22 16:05 roconnor-blockstream

I guess another alternative is to have the first payload be 32 characters so that it decodes to exactly 20 bytes. I'm leaning towards the 30 character prefix because it is illegal to decode otherwise.

roconnor-blockstream avatar May 23 '22 18:05 roconnor-blockstream

Why is it illegal to decode?

If we are going to do something other than "blocks of 93 characters, with the last one truncated" I'd rather try to make both blocks equal in size.

apoelstra avatar May 23 '22 21:05 apoelstra

Why is it illegal to decode?

Any incomplete group at the end MUST be 4 bits or less

roconnor-blockstream avatar May 23 '22 22:05 roconnor-blockstream

If we are going to do something other than "blocks of 93 characters, with the last one truncated" I'd rather try to make both blocks equal in size.

BIP-32 technically allows the secret to be any number of bytes between 16 and 64.

roconnor-blockstream avatar May 23 '22 22:05 roconnor-blockstream

Any incomplete group at the end MUST be 4 bits or less

Hah! I never noticed that this rule forbade certain lengths of bech32 strings. Very interesting.

Ok, I am torn between the elegance of this, and the fact that it will generalize very poorly to >512-bit data.

apoelstra avatar May 24 '22 01:05 apoelstra

I think the potential money losing(?) proposition of incorrectly implemented decoders for rare long strings is pretty scary and this proposal does help mitigate that somewhat.

roconnor-blockstream avatar May 24 '22 01:05 roconnor-blockstream

I'm doubtful that mistakes here would actually be money-losing: people would decode an incorrect string (in fact, I think if they concatenate after u5->u8 they'll get a wrong length string, which would be very visible), find no money on the resulting seed, and hopefully recognize that their decoder was broken and try again with a non-broken one.

I expect that production implementations of this code would have unit tests against exactly this scenario (we should create standard test vectors that exercise it) so even this scenario seems unlikely to me.

I'm also skeptical that somebody who screws up the concatenation logic would correctly implement the "at most 4 bits of padding" logic.

Having said this, there's an argument that the existing "natural" scheme is likely to be implemented without reading the spec very carefully, whereas if you throw curveballs like "30 character prefix which is illegal to decode on its own" into the mix then implementors might keep their eyes open. (But I personally still prefer the existing "natural" design.)

apoelstra avatar May 24 '22 01:05 apoelstra

Last year we more or less decided to move to using a longer checksum for long secrets.

Background: A 512 bit master seed requires 103 characters to encode it. We additionally have 6 header characters for threshold value, UID, and share index for a total of 109 characters, not including any checksum. The existing scheme has length 93 (80 data characters and 13 checksum characters), and our 109 characters exceed the 80 data character limit.

The following spec for a longer checksum for long data has been proposed:

gen=[23,4,22,5,6,21,23,6,21,25,9,26,25,10,15,1] degree=15 bch_length=1023 bch_dist=9 bch_gen=[23,4,22,5,6,21,23,6,21,25,9,26,25,10,15,1] bch_degree=15 bch_modulus=[25,6,1] bch_c=1019

This is a 15 character checksum. It has length 1023 and supports up to 1008 data characters which is more than we will ever need (as I recall the math works out so there isn't really anything in between). We only will use this checksum when the data length exceeds 80 characters as we don't want to burden hand computation with checksums longer than necessary.

The above code has distance 9 and can correct errors in up to 4 characters, same distance as our scheme for short strings. Note that the error correction rate decreases as data gets longer when the distance remains fixed.

roconnor-blockstream avatar Feb 10 '23 03:02 roconnor-blockstream

Sounds good to me. Good observation about the rate. We may want to highlight that for 128- and 256-bit secrets, which use the same code, 128-bit secrets have better error protection for this reason.

apoelstra avatar Feb 10 '23 17:02 apoelstra

I've redefined long strings to use a long checksum.

This now requires a thorough review, testing the python code, and we will need to generate at least one more test vector.

roconnor-blockstream avatar Feb 11 '23 17:02 roconnor-blockstream

Hold the presses. I've run into an issue.

gen=[23,4,22,5,6,21,23,6,21,25,9,26,25,10,15,1] degree=15

For some reason the generator actually has 16 elements...

roconnor-blockstream avatar Feb 12 '23 16:02 roconnor-blockstream

I've corrected the generators. The solution was to reverse the list and drop the leading 1.

roconnor-blockstream avatar Feb 13 '23 00:02 roconnor-blockstream

I added a 512 bit example test vector. This is probably ready to be merged now.

roconnor-blockstream avatar Feb 13 '23 20:02 roconnor-blockstream