Score:-1

Overflows in classic Shamir Secret Sharing Scheme

co flag

I've implemented classic Shamir Secret Sharing Scheme which looks like this:

  • get password as input (any length)
  • convert password text to big integer
  • generate polynomial coefs (an ... a1)
  • generate splits - pairs (xi, yi) with given threshold

It works great and this is how generating more shares of secret works:

  • getting shares and threshold as input
  • finding coeffs with gauss (so I know original polynomial)
  • finding secret value <-- this the problem
  • generating more shares - using timestamp as xi

Everything is working fine but when I use long passwords (10 chars and more) when reconstructing secret value it fails maybe because it lost precision for high numbers.

So how to overcome this classic approch? What should be changed in scheme that it shouldn't be sensitive to secret text legth?

kelalaka avatar
in flag
https://math.stackexchange.com/q/4329986/338051 and this turn into a parameter and encoding problem that may suit more into [so].
Vadym Fedyukovych avatar
in flag
Did you use some finite field to represent your passwords?
Macko avatar
co flag
@VadymFedyukovych no yet, please give some options how to do this right? How to encode password in sample finite field
Score:1
my flag

What should be changed in scheme that it shouldn't be sensitive to secret text legth?

Well, Vadym already mentioned that Shamir Secret Sharing should be done in a Finite Field; however it doesn't address your question.

With Shamir's Scheme, a single instance can share any value between $0$ and $p^k - 1$ (where $p^k$ is the size of the finite field you use [1]). And, with Shamir, there is no security difference between the various finite fields, hence we can pick one based on practical concerns (e.g. the number of secrets you want to be able to issue, the size of the secret, the easy of implementing the various finite field operations).

However, what you want to do is share a password as the secret; that password is fairly long, and is of variable length. Well, there are two obvious alternatives:

  • Pick a $p^k$ (or prime $p$ if you go with $k-1$) that's large enough to hold any password you want to share; for example, if you use $p=2^{521}-1$ (which is prime), you can share passwords up to 65 characters in length. This works, however the disadvantage is that values this large would need to be handled with a bignum library. If you are using a language with a bignum library built-in (for example, Python), this is not an issue - if not, it'd probably be easier to go with the second idea.

With this idea, if we had the password 'letmein' (0x6c 0x65 0x74 0x6d 0x65 0x69 0x6e in ASCII), we might encode that as the integer 0x6c65746d65696e = 30510848210725230.

  • Split the password up into multiple secrets, and share each secret separately. For example, for a 14 character password, we can split that up into 14 separate secrets (with each secret being one character from the password), and share each character using $p=257$ and $k=1$ (so each party would get a total of 14 shares, one share for each of the 14 characters). With this idea, it is safe to use the same identifier for all the shares a party gets; however it is important that each secret is generated using independent randomness (that is, each of the 14 random polynomials is generated separately).

With this idea, we would encode the password 'letmein' as the 8 independent secrets 0x6c 0x65 0x74 0x6d 0x65 0x69 0x6e

With this second idea, if you don't want to leak the length of the secret, what you can do is always share a fixed number of secrets (which will be the maximum length of password you can share, say, 32), and for passwords shorter than that, fill in the additional secret characters with a value that cannot occur in a real password (for my example of $p=257$, the obvious value to use would be $256$).


[1]: For any prime $p$ and any integer $k$, there is a finite field of size $p^k$. It would probably be easier for you to start with using a field with $k=1$ and $p$ an appropriate-sized prime - this makes the addition, subtraction and multiplication operations a lot closer to the standard algorithms you are familiar with (division is still wonky).

Macko avatar
co flag
hmm, second idea looks kinda strange to me because each party that gets share(s) shouldn't have enough shares to reconstruct protected password (secret). Second I don't get how sharing single chars of password could later be reconstructed to full length password. This approch looks more elastic.
Macko avatar
co flag
it looks that first approch is good option but it needs some try & error to find sweet spot of structures used internally - to find how long or complex password can be still processed by written algorithm.
poncho avatar
my flag
@Macko: if you don't understand the second idea, you are overthinking it. With it, you generate a secret sharing scheme for the first letter, and give out those shares. In parallel, you generate an ss for the second letter, and give out those shares to the same party, and the same for the third, fourth, etc. When it comes time to recombine, take all the shares the parties have, and combine their first shares together (to gen the first letter); same with the second, etc. Once you have all the letters, just concatinate them together, and you're done.
Macko avatar
co flag
I think that second option is overdesign and parties will end up with too many shares that would be hard to manage. I will stick with classic option 1 for now...
Score:0
in flag

From the description given, one might suggest that decimal numbers and floating-point operations would be a straightforward solution. There are no overflows and precision problems with finite fields.

Please consider arithmetic modulo some prime number, redefine standard c++ plus, minus, multiply and division. Pick a textbook that you can read. It's a long road. Good luck.

Macko avatar
co flag
Of course you are right but I need more details or confirmation how to do it right: first encode password to big number (in Java it would be BigInteger) than convert this value to number in some finite field? From now on all calculations like (generating coefs, interpolating) one should be doing only in defined field ?
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.