Ssss: Shamir's Secret Sharing Scheme (2006)
point-at-infinity.org
point-at-infinity.org
FROST is one example of such a threshold scheme, for computing Schnorr signatures: https://eprint.iacr.org/2020/852.pdf
[1] https://en.wikipedia.org/wiki/Distributed_key_generation
One example is as follows: each party i generates a random polynomial P_i, and n secret shares of that polynomial (j, P_i(j)) for j in 1..n
Then, party i sends (j, P_i(j)) to party j. Party i similarly receives shares (i, P_j(i)) for j=1..n. Party i stores the share (i, sum(P_j(i))).
Then, parties reveal their shares as usual, the secret is then the sum_i P_i(0).
Of course, if the parties are dishonest, you might want some additional safety mechanisms, which can be dealt with with Kate commitments.
This papers https://eprint.iacr.org/2020/504.pdf goes into details, and much more.
Splitting the key safely is only part of the problem though, because you will then need a system that only -uses- the key in a way all parties consent to.
Threshold signing is a much easier alternative for many use cases but sometimes a cryptosystem requires just one key and SSSS is all we can do.
To avoid any single party accessing a complete SSSS split key you can:
1. Write an application that takes N public keys as input, and returns a newly generated key as SSSS shares encrypted to each respective public key as output.
2. Compile application deterministically as an immutable unikernel or firmware image targeting hardware that supports remote attestation (Nitro Enclave, Confidential VM, HSM, etc).
3. Publish source code such that all participants can access and review it, or confirm review was done by multiple parties they trust.
4. Have multiple parties trusted by all participants, or the participants themselves, build the application bundle and confirm they get the same hash
5. Any party deploys the bundle to a live remotely attestable system.
6. All parties use the remote attestation interface to confirm the target system is running the multi-party deterministically compiled application they expect.
7. All parties submit their public keys to the remote system.
8. The remote system generates new key, splits it, and returns SSSS shares to each party encrypted to their respective public key.
What you describe still trusts the distributor - you just found a way to make the distributor easy to trust. I'd be more interested in a mechanism that is mathematically correct, like some of the papers referenced elsewhere in this thread.
There is no avoiding standing up computers all parties trust and if you are going to do that anyway then you might as well use them for key generation and distribution too.
I mean, if we all agreed to perform the decryption, the secret's out anyway. But not before then.
The real world use cases I most commonly support are things like CAs, TLS keys, financial transaction signing keys, and sensitive document decryption keys. All of these require single keys to exist that needs to perform automated operations, and needs to be on systems that can be backed up, restored, upgraded, and maintained, while able to prove no single person can access or control the keys.
The scheme I described can allow one key to be created, split, restored, used, and split again many times without full trust in any individual.
You usually have a ring of people and need 3 out of the 7 to open the box. You simply encrypt the box in whatever combinations you want, and people run their keys against each layer of the box. You end up with a few different files but in the case of keys, and a small number of sharers this is not going to be a big data issue.
This saves the original entropy from which your BIP-39 phrase was generated, over several groups of multiple SLIP-39 mnemonics cards.
Later, recover enough cards from a few groups, recover your BIP-39, and recover your hardware wallet.
Much more reliable, and safer because an attacker must collect many independent mnemonics from groups they probably don’t know the members of.
EDIT: The SLIP-39 standard is probably the most accessible (and only?) usage of SSSS by "normals". As people find out how fragile and risky BIP-39 is, they'll want to secure their existing BIP-39 accounts, and they can do it using SLIP-39, which uses SSSS. You're welcome!
What a fun memory, other tricks we employed was to disable the TTY and any form of remote login; and heavily auditing and restricting the information coming in via a WAF.
It was very frustrating for them to have a fault because in order to reboot the system (which is basically all you can do): you need the CIO and one of the trusted product managers and one of the trusted sysadmins. The issue with that final one was that the trusted sysadmins could not be the same trusted sysadmins who could access the remote logging infrastructure. — also the CIO was a large bus factor, but I was told the CEO also had that key.
If you work on payment systems at Facebook/meta or Oracle Netsuite then likely some of that code still exist there. Maybe someone can confirm.
It combines the two separate commands in the article into one.
Implementation: https://github.com/dsprenkels/sss
I have not reviewed it (beyond a glance), but based on the readme I'm confident that this one has a good chance of being secure, which is a vast improvement over most.
I still think in general SSS has very limited real use (except embedded into a larger cryptosystem), but if you're going to use it at least use a version that doesn't introduce vulnerabilities!
I’ve written ones based off Vault’s Go version in both Nim and Elixir:
Should be GF(256). 255 isn't a prime power and can't be a field.
I dunno anything about nim but the GF arithmetic code appears to contain branching on values, so this implementation isn't sidechannel resistant and could reduce the users security if otherwise their use of cryptography would be sidechannel resistant.
I didn't look further, it's common for SSS implementations to contain cryptographic flaws that degrade or destroy their security entirely for the same reason people are advised to not home-roll their own constructions of other cryptosystems.
Yes they’re not side channel resistant —- I should add a note for that. The Nim one could be made so, but the Elixir one would be difficult due to its VM so I didn’t port the original constant time parts.
I certainly wouldn’t recommend these libraries for very high security needs as is. That being said, side channel resistance isn’t a necessity for many use cases.
SSS can be used for cases like making a scavenger hunt by splitting up a set of files among N USB keys. Perhaps even to give N family members Your Bitcoin wallet key in case you die or loose your key. Having a little GUI program run and present the combined data really wouldn’t benefit from side channel resistance, IMHO.
So while caution is advisable with any security related code, I think the “never write crypto” prevents a lot of valid and useful applications.
I think my contention for SSS implementations has mostly been that the need/benefit seldom justifies the extra effort required to be confident you got it right. Obviously for a treasure hunt the bar is pretty low. :)
It's hard to be sure when sidechannel resistance is really needed. Right now you could have some JS running in silently in a browser thats conducting a sidechannel attack to steal data. Probably not, but these attacks have been witnessed.
Common issues aren't limited to sidechannels, e.g. it's pretty common for there to be "random" number generation problems that make it possible to recover the secret with fewer shares than the threshold. (the bitcoin wiki page I linked to gives two examples of that)
I'd also agree that the "abstinence only" approach to cryptography doesn't work. But the underlying issue that drives that advice is real.
The best alternative to overkilling the implementation is documenting the intended uses and known weaknesses, I guess!
> Some people reported compilation probems with ssss-0.5. This will be fixed in the upcoming release. If the code isn't processed correctly on your machine, replace line 351 of ssss.c by
> int restore_secret(int n, void *A, mpz_t b[])
Edit: We've come a long way in open source software development....
Sadly companies like Unbound were acquired by Coinbase and the OSS codebase is not longer maintained: https://github.com/unboundsecurity/blockchain-crypto-mpc
I wish more apps used this tech.
https://support.argent.xyz/hc/en-us/articles/360022631992-Ab...
There are implementations of the algorithm in other languages on github[0].
The difference is that Shamir's makes it so that having up to K-1 pieces reveals _no_ information about the original data. You may be able to infer certain data from less than K shards in Reed Solomon.
this has obvious timing and cache sidechannels on the secret data.
(IIRC SSSS is even worse, however.)